diff --git a/question.py b/question.py index d9f7d2c3e..124b74a74 100644 --- a/question.py +++ b/question.py @@ -17,6 +17,8 @@ from utils import dangerous_markup from utils import get_reply_to from utils import get_actor_from_post from data import load_list +from data import save_string +from data import append_string def is_vote(base_dir: str, nickname: str, domain: str, @@ -125,25 +127,17 @@ def question_update_votes(base_dir: str, nickname: str, domain: str, actor_url = get_actor_from_post(reply_json) if not os.path.isfile(voters_filename): # create a new voters file - try: - with open(voters_filename, 'w+', - encoding='utf-8') as fp_voters: - fp_voters.write(actor_url + - voters_file_separator + - reply_vote + '\n') - except OSError: - print('EX: unable to write voters file ' + voters_filename) + save_string(actor_url + voters_file_separator + reply_vote + '\n', + voters_filename, + 'EX: unable to write voters file ' + voters_filename) else: if not text_in_file(actor_url, voters_filename): # append to the voters file - try: - with open(voters_filename, 'a+', - encoding='utf-8') as fp_voters: - fp_voters.write(actor_url + - voters_file_separator + - reply_vote + '\n') - except OSError: - print('EX: unable to append to voters file ' + voters_filename) + append_string(actor_url + voters_file_separator + + reply_vote + '\n', + voters_filename, + 'EX: unable to append to voters file ' + + voters_filename) else: # change an entry in the voters file lines: list[str] = \ diff --git a/reaction.py b/reaction.py index e840ccb23..729794c18 100644 --- a/reaction.py +++ b/reaction.py @@ -39,6 +39,7 @@ from webfinger import webfinger_handle from auth import create_basic_auth_header from posts import get_person_box from data import load_list +from data import save_string # the maximum number of reactions from individual actors which can be # added to a post. Hence an adversary can't bombard you with sockpuppet @@ -519,12 +520,8 @@ def _update_common_reactions(base_dir: str, emoji_content: str) -> None: return else: line = str(1).zfill(16) + ' ' + emoji_content + '\n' - try: - with open(common_reactions_filename, 'w+', - encoding='utf-8') as fp_react: - fp_react.write(line) - except OSError: - print('EX: error writing common reactions 2') + if not save_string(line, common_reactions_filename, + 'EX: error writing common reactions 2'): return diff --git a/reading.py b/reading.py index 15bdb69ec..5d57fc155 100644 --- a/reading.py +++ b/reading.py @@ -22,6 +22,8 @@ from utils import remove_html from formats import get_image_extensions from timeFunctions import date_epoch from timeFunctions import date_from_string_format +from data import save_string +from data import load_string def get_book_link_from_content(content: str) -> str: @@ -407,13 +409,9 @@ def _update_recent_books_list(base_dir: str, book_id: str, print('WARN: Failed to write entry to recent books ' + recent_books_filename + ' ' + str(ex)) else: - try: - with open(recent_books_filename, 'w+', - encoding='utf-8') as fp_recent: - fp_recent.write(book_id + '\n') - except OSError: - print('EX: unable to write recent books ' + - recent_books_filename) + save_string(book_id + '\n', recent_books_filename, + 'EX: unable to write recent books ' + + recent_books_filename) def _deduplicate_recent_books_list(base_dir: str, @@ -426,13 +424,12 @@ def _deduplicate_recent_books_list(base_dir: str, # load recent books as a list recent_lines: list[str] = [] - try: - with open(recent_books_filename, 'r', - encoding='utf-8') as fp_recent: - recent_lines = fp_recent.read().split('\n') - except OSError as ex: - print('WARN: Failed to read recent books trim ' + - recent_books_filename + ' ' + str(ex)) + recent_lines_str = \ + load_string(recent_books_filename, + 'WARN: Failed to read recent books trim ' + + recent_books_filename + ' [ex]') + if recent_lines_str: + recent_lines = recent_lines_str.split('\n') # deduplicate the list new_recent_lines: list[str] = [] @@ -444,26 +441,18 @@ def _deduplicate_recent_books_list(base_dir: str, result = '' for line in recent_lines: result += line + '\n' - try: - with open(recent_books_filename, 'w+', - encoding='utf-8') as fp_recent: - fp_recent.write(result) - except OSError: - print('EX: unable to deduplicate recent books ' + - recent_books_filename) + save_string(result, recent_books_filename, + 'EX: unable to deduplicate recent books ' + + recent_books_filename) # remove excess lines from the list if len(recent_lines) > max_recent_books: result = '' for ctr in range(max_recent_books): result += recent_lines[ctr] + '\n' - try: - with open(recent_books_filename, 'w+', - encoding='utf-8') as fp_recent: - fp_recent.write(result) - except OSError: - print('EX: unable to trim recent books ' + - recent_books_filename) + save_string(result, recent_books_filename, + 'EX: unable to trim recent books ' + + recent_books_filename) def store_book_events(base_dir: str, diff --git a/relationships.py b/relationships.py index feea91acf..234ecedd1 100644 --- a/relationships.py +++ b/relationships.py @@ -22,6 +22,8 @@ from utils import is_account_dir from utils import get_nickname_from_actor from utils import get_domain_from_actor from utils import load_json +from data import load_string +from data import save_string def get_moved_accounts(base_dir: str, nickname: str, domain: str, @@ -31,27 +33,23 @@ def get_moved_accounts(base_dir: str, nickname: str, domain: str, moved_accounts_filename = data_dir(base_dir) + '/actors_moved.txt' if not os.path.isfile(moved_accounts_filename): return {} - refollow_str = '' - try: - with open(moved_accounts_filename, 'r', - encoding='utf-8') as fp_refollow: - refollow_str = fp_refollow.read() - except OSError: - print('EX: get_moved_accounts unable to read 1 ' + - moved_accounts_filename) + refollow_str = \ + load_string(moved_accounts_filename, + 'EX: get_moved_accounts unable to read 1 ' + + moved_accounts_filename) + if refollow_str is None: + refollow_str = '' refollow_list = refollow_str.split('\n') refollow_dict = {} follow_filename = \ acct_dir(base_dir, nickname, domain) + '/' + filename - follow_str = '' - try: - with open(follow_filename, 'r', - encoding='utf-8') as fp_follow: - follow_str = fp_follow.read() - except OSError: - print('EX: get_moved_accounts unable to read 2 ' + - follow_filename) + follow_str = \ + load_string(follow_filename, + 'EX: get_moved_accounts unable to read 2 ' + + follow_filename) + if follow_str is None: + follow_str = '' follow_list = follow_str.split('\n') ctr = 0 @@ -248,14 +246,11 @@ def update_moved_actors(base_dir: str, debug: bool) -> None: following_filename = dir_str + '/' + account + '/following.txt' if not os.path.isfile(following_filename): continue - following_str = '' - try: - with open(following_filename, 'r', - encoding='utf-8') as fp_foll: - following_str = fp_foll.read() - except OSError: - print('EX: update_moved_actors unable to read ' + - following_filename) + following_str = \ + load_string(following_filename, + 'EX: update_moved_actors unable to read ' + + following_filename) + if following_str is None: continue following_list = following_str.split('\n') for handle in following_list: @@ -318,13 +313,9 @@ def update_moved_actors(base_dir: str, debug: bool) -> None: moved_accounts_filename) return - try: - with open(moved_accounts_filename, 'w+', - encoding='utf-8') as fp_moved: - fp_moved.write(moved_str) - except OSError: - print('EX: update_moved_actors unable to save ' + - moved_accounts_filename) + save_string(moved_str, moved_accounts_filename, + 'EX: update_moved_actors unable to save ' + + moved_accounts_filename) def _get_inactive_accounts(base_dir: str, nickname: str, domain: str, @@ -335,14 +326,12 @@ def _get_inactive_accounts(base_dir: str, nickname: str, domain: str, # get the list of followers followers_filename = \ acct_dir(base_dir, nickname, domain) + '/followers.txt' - followers_str = '' - try: - with open(followers_filename, 'r', - encoding='utf-8') as fp_follow: - followers_str = fp_follow.read() - except OSError: - print('EX: get_moved_accounts unable to read ' + - followers_filename) + followers_str = \ + load_string(followers_filename, + 'EX: get_moved_accounts unable to read ' + + followers_filename) + if followers_str is None: + followers_str = '' followers_list = followers_str.split('\n') result: list[str] = [] diff --git a/roles.py b/roles.py index a39ad2e05..01600a67c 100644 --- a/roles.py +++ b/roles.py @@ -17,6 +17,7 @@ from utils import text_in_file from utils import get_config_param from status import get_status_number from data import load_list +from data import save_string def _clear_role_status(base_dir: str, role: str) -> None: @@ -78,13 +79,11 @@ def _add_role(base_dir: str, nickname: str, domain: str, except OSError: print('EX: _add_role, failed to write roles file1 ' + role_file) else: - try: - with open(role_file, 'w+', encoding='utf-8') as fp_role: - account_dir = acct_dir(base_dir, nickname, domain) - if os.path.isdir(account_dir): - fp_role.write(nickname + '\n') - except OSError: - print('EX: _add_role, failed to write roles file2 ' + role_file) + account_dir = acct_dir(base_dir, nickname, domain) + if os.path.isdir(account_dir): + save_string(nickname + '\n', role_file, + 'EX: _add_role, failed to write roles file2 ' + + role_file) def _remove_role(base_dir: str, nickname: str, role_filename: str) -> None: diff --git a/searchable.py b/searchable.py index 50ac2bc94..b90650a49 100644 --- a/searchable.py +++ b/searchable.py @@ -20,6 +20,8 @@ from utils import get_domain_from_actor from utils import get_full_domain from utils import get_followers_list from utils import get_mutuals_of_person +from data import load_string +from data import save_string def load_searchable_by_default(base_dir: str) -> {}: @@ -34,11 +36,11 @@ def load_searchable_by_default(base_dir: str) -> {}: nickname = account.split('@')[0] filename = os.path.join(dir_str, account) + '/.searchableByDefault' if os.path.isfile(filename): - try: - with open(filename, 'r', encoding='utf-8') as fp_search: - result[nickname] = fp_search.read().strip() - except OSError: - print('EX: unable to load searchableByDefault ' + filename) + text = load_string(filename, + 'EX: unable to load searchableByDefault ' + + filename) + if text: + result[nickname] = text.strip() break return result @@ -58,11 +60,8 @@ def set_searchable_by(base_dir: str, nickname: str, domain: str, return # write the new state - try: - with open(filename, 'w+', encoding='utf-8') as fp_search: - fp_search.write(searchable_by) - except OSError: - print('EX: unable to write searchableByDropdown ' + filename) + save_string(searchable_by, filename, + 'EX: unable to write searchableByDropdown ' + filename) def _actor_in_searchable_by(searchable_by: str, following_list: []) -> bool: diff --git a/session.py b/session.py index 99f2cd054..38ed6e923 100644 --- a/session.py +++ b/session.py @@ -26,6 +26,8 @@ from utils import is_yggdrasil_url from formats import image_mime_types_dict from mitm import detect_mitm from httpsig import create_signed_header +from data import append_string +from data import save_string def create_session(proxy_type: str): @@ -562,13 +564,14 @@ def site_is_verified(session, base_dir: str, http_prefix: str, write_type = 'a+' if not verified_file_exists: write_type = 'w+' - try: - with open(verified_sites_filename, write_type, - encoding='utf-8') as fp_verified: - fp_verified.write(url + '\n') - except OSError: - print('EX: Verified sites could not be updated ' + - verified_sites_filename) + if write_type == 'a+': + append_string(url + '\n', verified_sites_filename, + 'EX: Verified sites could not be updated 1 ' + + verified_sites_filename) + else: + save_string(url + '\n', verified_sites_filename, + 'EX: Verified sites could not be updated 2 ' + + verified_sites_filename) return verified diff --git a/shares.py b/shares.py index 7a0c11039..4aa09763c 100644 --- a/shares.py +++ b/shares.py @@ -60,6 +60,8 @@ from threads import begin_thread from threads import thread_with_trace from cache import remove_person_from_cache from cache import store_person_in_cache +from data import save_string +from data import load_string def _load_dfc_ids(base_dir: str, system_language: str, @@ -318,15 +320,15 @@ def _indicate_new_share_available(base_dir: str, http_prefix: str, continue local_actor = \ local_actor_url(http_prefix, account_nickname, domain_full) - try: - with open(new_share_file, 'w+', encoding='utf-8') as fp_new: - if shares_file_type == 'shares': - fp_new.write(local_actor + '/tlshares') - else: - fp_new.write(local_actor + '/tlwanted') - except OSError: - print('EX: _indicate_new_share_available unable to write ' + - str(new_share_file)) + exc_text = \ + 'EX: _indicate_new_share_available unable to write ' + \ + str(new_share_file) + if shares_file_type == 'shares': + save_string(local_actor + '/tlshares', new_share_file, + exc_text) + else: + save_string(local_actor + '/tlwanted', new_share_file, + exc_text) break @@ -1828,15 +1830,14 @@ def _generate_next_shares_token_update(base_dir: str, token_update_filename = token_update_dir + '/.tokenUpdate' next_update_sec = None if os.path.isfile(token_update_filename): - try: - with open(token_update_filename, 'r', encoding='utf-8') as fp_tok: - next_update_str = fp_tok.read() - if next_update_str: - if next_update_str.isdigit(): - next_update_sec = int(next_update_str) - except OSError: - print('EX: _generate_next_shares_token_update unable to read ' + - token_update_filename) + next_update_str = \ + load_string(token_update_filename, + 'EX: _generate_next_shares_token_update ' + + 'unable to read ' + + token_update_filename) + if next_update_str: + if next_update_str.isdigit(): + next_update_sec = int(next_update_str) curr_time = get_current_time_int() updated = False if next_update_sec: @@ -1851,12 +1852,10 @@ def _generate_next_shares_token_update(base_dir: str, next_update_sec = curr_time + next_update_interval updated = True if updated: - try: - with open(token_update_filename, 'w+', encoding='utf-8') as fp_tok: - fp_tok.write(str(next_update_sec)) - except OSError: - print('EX: _generate_next_shares_token_update unable to write' + - token_update_filename) + text = str(next_update_sec) + save_string(text, token_update_filename, + 'EX: _generate_next_shares_token_update unable to write' + + token_update_filename) def _regenerate_shares_token(base_dir: str, domain_full: str, @@ -1880,15 +1879,13 @@ def _regenerate_shares_token(base_dir: str, domain_full: str, if not os.path.isfile(token_update_filename): return next_update_sec = None - try: - with open(token_update_filename, 'r', encoding='utf-8') as fp_tok: - next_update_str = fp_tok.read() - if next_update_str: - if next_update_str.isdigit(): - next_update_sec = int(next_update_str) - except OSError: - print('EX: _regenerate_shares_token unable to read ' + - token_update_filename) + next_update_str = \ + load_string(token_update_filename, + 'EX: _regenerate_shares_token unable to read ' + + token_update_filename) + if next_update_str: + if next_update_str.isdigit(): + next_update_sec = int(next_update_str) if not next_update_sec: return curr_time = get_current_time_int() diff --git a/siteactive.py b/siteactive.py index 2785a9e41..ee8eccd09 100644 --- a/siteactive.py +++ b/siteactive.py @@ -14,6 +14,7 @@ import socket from urllib.parse import urlparse from utils import data_dir from utils import string_starts_with +from data import load_string class Result: @@ -177,13 +178,12 @@ def load_unavailable_sites(base_dir: str) -> []: """ unavailable_sites_filename = data_dir(base_dir) + '/unavailable_sites.txt' sites_unavailable: list[str] = [] - try: - with open(unavailable_sites_filename, 'r', - encoding='utf-8') as fp_sites: - sites_unavailable = fp_sites.read().split('\n') - except OSError: - print('EX: unable to read unavailable sites ' + - unavailable_sites_filename) + sites_unavailable_str = \ + load_string(unavailable_sites_filename, + 'EX: unable to read unavailable sites ' + + unavailable_sites_filename) + if sites_unavailable_str: + sites_unavailable = sites_unavailable_str.split('\n') return sites_unavailable diff --git a/speaker.py b/speaker.py index eb380a70d..993854755 100644 --- a/speaker.py +++ b/speaker.py @@ -33,6 +33,8 @@ from utils import get_actor_from_post from content import html_replace_quote_marks from content import html_replace_inline_quotes from data import load_list +from data import load_string +from data import save_string SPEAKER_REMOVE_CHARS = ('.\n', '. ', ',', ';', '?', '!') @@ -560,12 +562,11 @@ def _post_to_speaker_json(base_dir: str, http_prefix: str, liked_by = '' like_filename = accounts_dir + '/.newLike' if os.path.isfile(like_filename): - try: - with open(like_filename, 'r', encoding='utf-8') as fp_like: - liked_by = fp_like.read() - except OSError: - print('EX: _post_to_speaker_json unable to read 2 ' + - like_filename) + liked_by = load_string(like_filename, + 'EX: _post_to_speaker_json unable to read 2 ' + + like_filename) + if liked_by is None: + liked_by = '' calendar_filename = accounts_dir + '/.newCalendar' post_cal = os.path.isfile(calendar_filename) share_filename = accounts_dir + '/.newShare' @@ -622,8 +623,5 @@ def update_speaker(base_dir: str, http_prefix: str, speaker_json['say'], system_language, gender, box_name) - try: - with open(cached_ssml_filename, 'w+', encoding='utf-8') as fp_ssml: - fp_ssml.write(ssml_str) - except OSError: - print('EX: unable to write ssml ' + cached_ssml_filename) + save_string(ssml_str, cached_ssml_filename, + 'EX: unable to write ssml ' + cached_ssml_filename) diff --git a/textmode.py b/textmode.py index 3f24f71b9..7366327c8 100644 --- a/textmode.py +++ b/textmode.py @@ -10,6 +10,7 @@ __module_group__ = "Web Interface" import os from shutil import copyfile from utils import data_dir +from data import load_string def text_mode_browser(ua_str: str) -> bool: @@ -43,11 +44,11 @@ def get_text_mode_banner(base_dir: str) -> str: """ text_mode_banner_filename = data_dir(base_dir) + '/banner.txt' if os.path.isfile(text_mode_banner_filename): - with open(text_mode_banner_filename, 'r', - encoding='utf-8') as fp_text: - banner_str = fp_text.read() - if banner_str: - return banner_str.replace('\n', '
') + banner_str = load_string(text_mode_banner_filename, + 'EX: unable to load text mode banner ' + + text_mode_banner_filename) + if banner_str: + return banner_str.replace('\n', '
') return None @@ -58,10 +59,11 @@ def get_text_mode_logo(base_dir: str) -> str: if not os.path.isfile(text_mode_logo_filename): text_mode_logo_filename = base_dir + '/img/logo.txt' - with open(text_mode_logo_filename, 'r', encoding='utf-8') as fp_text: - logo_str = fp_text.read() - if logo_str: - return logo_str.replace('\n', '
') + logo_str = load_string(text_mode_logo_filename, + 'EX: unable to load text mode logo ' + + text_mode_logo_filename) + if logo_str: + return logo_str.replace('\n', '
') return None