Function to remove book events

merge-requests/30/head
Bob Mottram 2024-01-05 15:07:57 +00:00
parent 6f4ff8163e
commit 585e858d1b
2 changed files with 170 additions and 3 deletions

View File

@ -467,6 +467,7 @@ from relationships import get_inactive_feed
from relationships import update_moved_actors
from git import get_repo_url
from webapp_pwa import pwa_manifest
from reading import remove_reading_event
# maximum number of posts to list in outbox feed
MAX_POSTS_IN_FEED = 12
@ -4477,6 +4478,80 @@ class PubServer(BaseHTTPRequestHandler):
self._redirect_headers(origin_path_str, cookie, calling_domain)
self.server.postreq_busy = False
def _remove_reading_status(self, calling_domain: str, cookie: str,
path: str, base_dir: str, http_prefix: str,
domain: str, domain_full: str,
onion_domain: str, i2p_domain: str,
debug: bool,
books_cache: {}) -> None:
"""Remove a reading status from the profile screen
"""
users_path = path.split('/removereadingstatus')[0]
origin_path_str = http_prefix + '://' + domain_full + users_path
reader_nickname = get_nickname_from_actor(origin_path_str)
if not reader_nickname:
self.send_response(400)
self.end_headers()
self.server.postreq_busy = False
return
length = int(self.headers['Content-length'])
try:
remove_reading_status_params = \
self.rfile.read(length).decode('utf-8')
except SocketError as ex:
if ex.errno == errno.ECONNRESET:
print('EX: POST remove_reading_status_params ' +
'connection was reset')
else:
print('EX: POST remove_reading_status_params socket error')
self.send_response(400)
self.end_headers()
self.server.postreq_busy = False
return
except ValueError as ex:
print('EX: POST remove_reading_status_params rfile.read failed, ' +
str(ex))
self.send_response(400)
self.end_headers()
self.server.postreq_busy = False
return
if '&submitRemoveReadingStatus=' in remove_reading_status_params:
reader_actor = \
urllib.parse.unquote_plus(remove_reading_status_params)
reading_actor = reader_actor.split('actor=')[1]
if '&' in reader_actor:
reading_actor = reader_actor.split('&')[0]
if reader_actor == origin_path_str:
post_secs_since_epoch = \
urllib.parse.unquote_plus(remove_reading_status_params)
post_secs_since_epoch = \
post_secs_since_epoch.split('publishedtimesec=')[1]
if '&' in post_secs_since_epoch:
post_secs_since_epoch = post_secs_since_epoch.split('&')[0]
post_secs_since_epoch = float(post_secs_since_epoch)
book_event_type = \
urllib.parse.unquote_plus(remove_reading_status_params)
book_event_type = \
book_event_type.split('bookeventtype=')[1]
if '&' in book_event_type:
book_event_type = book_event_type.split('&')[0]
remove_reading_event(base_dir,
reading_actor, post_secs_since_epoch,
book_event_type, books_cache, debug)
if calling_domain.endswith('.onion') and onion_domain:
origin_path_str = 'http://' + onion_domain + users_path
elif (calling_domain.endswith('.i2p') and i2p_domain):
origin_path_str = 'http://' + i2p_domain + users_path
self._redirect_headers(origin_path_str, cookie, calling_domain)
self.server.postreq_busy = False
def _block_confirm(self, calling_domain: str, cookie: str,
path: str, base_dir: str, http_prefix: str,
domain: str, domain_full: str, port: int,
@ -23596,6 +23671,25 @@ class PubServer(BaseHTTPRequestHandler):
'_POST', '_follow_confirm',
self.server.debug)
# remove a reading status from the profile screen
if self.path.endswith('/removereadingstatus'):
self._remove_reading_status(calling_domain, cookie,
self.path,
self.server.base_dir,
self.server.http_prefix,
self.server.domain,
self.server.domain_full,
self.server.onion_domain,
self.server.i2p_domain,
self.server.debug,
self.server.books_cache)
self.server.postreq_busy = False
return
fitness_performance(postreq_start_time, self.server.fitness,
'_POST', '_remove_reading_status',
self.server.debug)
# decision to unfollow in the web interface is confirmed
if self.path.endswith('/unfollowconfirm'):
self._unfollow_confirm(calling_domain, cookie,

View File

@ -249,6 +249,66 @@ def get_reading_status(post_json_object: {},
return {}
def remove_reading_event(base_dir: str,
actor: str, post_secs_since_epoch: str,
book_event_type: str,
books_cache: {},
debug: bool) -> bool:
"""Removes a reading status for the given actor
"""
if not book_event_type:
print('remove_reading_event no book event')
return False
reading_path = base_dir + '/accounts/reading'
readers_path = reading_path + '/readers'
reader_books_filename = \
readers_path + '/' + actor.replace('/', '#') + '.json'
reader_books_json = {}
if books_cache['readers'].get(actor):
reader_books_json = books_cache['readers'][actor]
elif os.path.isfile(reader_books_filename):
# if not in cache then load from file
reader_books_json = load_json(reader_books_filename)
if not reader_books_json:
if debug:
print('remove_reading_event reader_books_json does not exist')
return False
if not reader_books_json.get('timeline'):
if debug:
print('remove_reading_event ' +
'reader_books_json timeline does not exist')
return False
if not reader_books_json['timeline'].get(post_secs_since_epoch):
if debug:
print('remove_reading_event ' +
'reader_books_json timeline event does not exist ' +
str(post_secs_since_epoch))
return False
book_url = reader_books_json['timeline'][post_secs_since_epoch]
if not book_url:
if debug:
print('remove_reading_event no book_url')
return False
if not reader_books_json.get(book_url):
if debug:
print('remove_reading_event ' +
'book_url not found in reader_books_json ' + book_url)
return False
if not reader_books_json[book_url].get(book_event_type):
if debug:
print('remove_reading_event ' +
'book event not found in reader_books_json ' +
book_url + ' ' + book_event_type)
return False
del reader_books_json[book_url][book_event_type]
if not save_json(reader_books_json, reader_books_filename):
if debug:
print('DEBUG: unable to save reader book event')
return False
return True
def _add_book_to_reader(reader_books_json: {}, book_dict: {},
debug: bool) -> bool:
"""Updates reader books
@ -298,8 +358,8 @@ def _add_book_to_reader(reader_books_json: {}, book_dict: {},
if post_time_object:
baseline_time = date_epoch()
days_diff = post_time_object - baseline_time
post_days_since_epoch = days_diff.total_seconds()
reader_books_json['timeline'][post_days_since_epoch] = book_url
post_secs_since_epoch = days_diff.total_seconds()
reader_books_json['timeline'][post_secs_since_epoch] = book_url
return True
elif debug:
print('_add_book_to_reader published date not recognised ' + published)
@ -511,13 +571,14 @@ def html_profile_book_list(base_dir: str, actor: str, no_of_books: int,
html_str = '<div class="book_list_section">\n'
html_str += ' <ul class="book_list">\n'
ctr = 0
for _, book_url in recent_books_json.items():
for published_time_sec, book_url in recent_books_json.items():
if not reader_books_json.get(book_url):
continue
book_rating = None
book_wanted = False
book_reading = False
book_finished = False
book_event_type = ''
for event_type in ('want', 'finished', 'rated'):
if not reader_books_json[book_url].get(event_type):
continue
@ -528,12 +589,16 @@ def html_profile_book_list(base_dir: str, actor: str, no_of_books: int,
book_image_url = book_dict['image_url']
if event_type == 'rated':
book_rating = book_dict['rating']
book_event_type = event_type
elif event_type == 'want':
book_wanted = True
book_event_type = event_type
elif event_type == 'reading':
book_reading = True
book_event_type = event_type
elif event_type == 'finished':
book_finished = True
book_event_type = event_type
if book_title:
book_title = remove_html(book_title)
html_str += ' <li class="book_event">\n'
@ -583,6 +648,14 @@ def html_profile_book_list(base_dir: str, actor: str, no_of_books: int,
'<input type="hidden" name="actor" value="' + \
actor + '">\n' + \
' ' + \
'<input type="hidden" ' + \
'name="publishedtimesec" value="' + \
str(published_time_sec) + '">\n' + \
' ' + \
'<input type="hidden" ' + \
'name="bookeventtype" value="' + \
book_event_type + '">\n' + \
' ' + \
'<button type="submit" class="button" ' + \
'name="submitRemoveReadingStatus">' + \
translate['Remove'] + '</button>\n' + \