merge-requests/30/head
Bob Mottram 2022-05-30 23:03:25 +01:00
commit 420a30a92f
34 changed files with 351 additions and 354 deletions

View File

@ -704,7 +704,7 @@ def _no_of_blog_accounts(base_dir: str) -> int:
"""Returns the number of blog accounts """Returns the number of blog accounts
""" """
ctr = 0 ctr = 0
for subdir, dirs, files in os.walk(base_dir + '/accounts'): for _, dirs, _ in os.walk(base_dir + '/accounts'):
for acct in dirs: for acct in dirs:
if not is_account_dir(acct): if not is_account_dir(acct):
continue continue
@ -719,7 +719,7 @@ def _no_of_blog_accounts(base_dir: str) -> int:
def _single_blog_account_nickname(base_dir: str) -> str: def _single_blog_account_nickname(base_dir: str) -> str:
"""Returns the nickname of a single blog account """Returns the nickname of a single blog account
""" """
for subdir, dirs, files in os.walk(base_dir + '/accounts'): for _, dirs, _ in os.walk(base_dir + '/accounts'):
for acct in dirs: for acct in dirs:
if not is_account_dir(acct): if not is_account_dir(acct):
continue continue

View File

@ -50,7 +50,7 @@ def get_hashtag_categories(base_dir: str,
days_since_epoch = (curr_time - datetime.datetime(1970, 1, 1)).days days_since_epoch = (curr_time - datetime.datetime(1970, 1, 1)).days
recently = days_since_epoch - 1 recently = days_since_epoch - 1
for subdir, dirs, files in os.walk(base_dir + '/tags'): for _, _, files in os.walk(base_dir + '/tags'):
for catfile in files: for catfile in files:
if not catfile.endswith('.category'): if not catfile.endswith('.category'):
continue continue

View File

@ -380,7 +380,6 @@ def _update_common_emoji(base_dir: str, emoji_content: str) -> None:
common_emoji = fp_emoji.readlines() common_emoji = fp_emoji.readlines()
except OSError: except OSError:
print('EX: unable to load common emoji file') print('EX: unable to load common emoji file')
pass
if common_emoji: if common_emoji:
new_common_emoji = [] new_common_emoji = []
emoji_found = False emoji_found = False
@ -1579,7 +1578,7 @@ def import_emoji(base_dir: str, import_filename: str, session) -> None:
def content_diff(content: str, prev_content: str) -> str: def content_diff(content: str, prev_content: str) -> str:
"""Returns a diff for the given content """Returns a diff for the given content
""" """
d = difflib.Differ() cdiff = difflib.Differ()
text1_lines = content.splitlines() text1_lines = content.splitlines()
text1_sentences = [] text1_sentences = []
for line in text1_lines: for line in text1_lines:
@ -1594,7 +1593,7 @@ def content_diff(content: str, prev_content: str) -> str:
for sentence in sentences: for sentence in sentences:
text2_sentences.append(sentence.strip()) text2_sentences.append(sentence.strip())
diff = d.compare(text1_sentences, text2_sentences) diff = cdiff.compare(text1_sentences, text2_sentences)
diff_text = '' diff_text = ''
for line in diff: for line in diff:
@ -1629,7 +1628,7 @@ def create_edits_html(edits_json: {}, post_json_object: {},
if not post_json_object['object'].get('contentMap'): if not post_json_object['object'].get('contentMap'):
return '' return ''
edit_dates_list = [] edit_dates_list = []
for modified, item in edits_json.items(): for modified, _ in edits_json.items():
edit_dates_list.append(modified) edit_dates_list.append(modified)
edit_dates_list.sort(reverse=True) edit_dates_list.sort(reverse=True)
edits_str = '' edits_str = ''
@ -1708,11 +1707,11 @@ def remove_script(content: str, log_filename: str,
if log_filename and actor: if log_filename and actor:
# write the detected script to a log file # write the detected script to a log file
log_str = actor + ' ' + url + ' ' + text + '\n' log_str = actor + ' ' + url + ' ' + text + '\n'
writeType = 'a+' write_type = 'a+'
if os.path.isfile(log_filename): if os.path.isfile(log_filename):
writeType = 'w+' write_type = 'w+'
try: try:
with open(log_filename, writeType) as fp_log: with open(log_filename, write_type) as fp_log:
fp_log.write(log_str) fp_log.write(log_str)
except OSError: except OSError:
print('EX: cannot append to svg script log') print('EX: cannot append to svg script log')

View File

@ -100,7 +100,7 @@ def set_cwtch_address(actor_json: {}, cwtch_address: str) -> None:
continue continue
if not property_value['type'].endswith('PropertyValue'): if not property_value['type'].endswith('PropertyValue'):
continue continue
prop_value_name, prop_value = \ prop_value_name, _ = \
get_attachment_property_value(property_value) get_attachment_property_value(property_value)
if not prop_value_name: if not prop_value_name:
continue continue

View File

@ -2230,12 +2230,12 @@ class PubServer(BaseHTTPRequestHandler):
moderation_text = None moderation_text = None
moderation_button = None moderation_button = None
# get the moderation text first # get the moderation text first
actStr = 'moderationAction=' act_str = 'moderationAction='
for moderation_str in moderation_params.split('&'): for moderation_str in moderation_params.split('&'):
if moderation_str.startswith(actStr): if moderation_str.startswith(act_str):
if actStr in moderation_str: if act_str in moderation_str:
moderation_text = \ moderation_text = \
moderation_str.split(actStr)[1].strip() moderation_str.split(act_str)[1].strip()
mod_text = moderation_text.replace('+', ' ') mod_text = moderation_text.replace('+', ' ')
moderation_text = \ moderation_text = \
urllib.parse.unquote_plus(mod_text.strip()) urllib.parse.unquote_plus(mod_text.strip())
@ -4672,7 +4672,7 @@ class PubServer(BaseHTTPRequestHandler):
print('origin_path_str: ' + origin_path_str) print('origin_path_str: ' + origin_path_str)
print('remove_post_actor: ' + remove_post_actor) print('remove_post_actor: ' + remove_post_actor)
if origin_path_str in remove_post_actor: if origin_path_str in remove_post_actor:
toList = [ to_list = [
'https://www.w3.org/ns/activitystreams#Public', 'https://www.w3.org/ns/activitystreams#Public',
remove_post_actor remove_post_actor
] ]
@ -4680,7 +4680,7 @@ class PubServer(BaseHTTPRequestHandler):
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
'actor': remove_post_actor, 'actor': remove_post_actor,
'object': remove_message_id, 'object': remove_message_id,
'to': toList, 'to': to_list,
'cc': [remove_post_actor + '/followers'], 'cc': [remove_post_actor + '/followers'],
'type': 'Delete' 'type': 'Delete'
} }
@ -5461,7 +5461,7 @@ class PubServer(BaseHTTPRequestHandler):
acct_dir(base_dir, nickname, domain) + \ acct_dir(base_dir, nickname, domain) + \
'/' + m_type + '.temp' '/' + m_type + '.temp'
filename, attachment_media_type = \ filename, _ = \
save_media_in_form_post(media_bytes, debug, save_media_in_form_post(media_bytes, debug,
filename_base) filename_base)
if filename: if filename:
@ -14956,16 +14956,16 @@ class PubServer(BaseHTTPRequestHandler):
calling_domain: str, referer_domain: str, calling_domain: str, referer_domain: str,
http_prefix: str, http_prefix: str,
domain: str, port: int, domain: str, port: int,
followingItemsPerPage: int, following_items_per_page: int,
debug: bool, listName='following') -> None: debug: bool, list_name: str = 'following') -> None:
"""Returns json collection for following.txt """Returns json collection for following.txt
""" """
following_json = \ following_json = \
get_following_feed(base_dir, domain, port, path, http_prefix, get_following_feed(base_dir, domain, port, path, http_prefix,
True, followingItemsPerPage, listName) True, following_items_per_page, list_name)
if not following_json: if not following_json:
if debug: if debug:
print(listName + ' json feed not found for ' + path) print(list_name + ' json feed not found for ' + path)
self._404() self._404()
return return
msg_str = json.dumps(following_json, msg_str = json.dumps(following_json,
@ -15280,7 +15280,6 @@ class PubServer(BaseHTTPRequestHandler):
known_bots_str = '' known_bots_str = ''
for bot_name in self.server.known_bots: for bot_name in self.server.known_bots:
known_bots_str += bot_name + '\n' known_bots_str += bot_name + '\n'
# TODO
msg = known_bots_str.encode('utf-8') msg = known_bots_str.encode('utf-8')
msglen = len(msg) msglen = len(msg)
self._set_headers('text/plain; charset=utf-8', self._set_headers('text/plain; charset=utf-8',
@ -16395,8 +16394,7 @@ class PubServer(BaseHTTPRequestHandler):
'_GET', 'show welcome screen', '_GET', 'show welcome screen',
self.server.debug) self.server.debug)
return return
else: self.path = self.path.replace('/welcome', '')
self.path = self.path.replace('/welcome', '')
# the welcome screen which allows you to set an avatar image # the welcome screen which allows you to set an avatar image
if html_getreq and authorized and \ if html_getreq and authorized and \
@ -18556,10 +18554,11 @@ class PubServer(BaseHTTPRequestHandler):
return return
if response_str == 'Not modified': if response_str == 'Not modified':
if endpoint_type == 'put': if endpoint_type == 'put':
return self._200() self._200()
else: return
return self._304() self._304()
elif response_str.startswith('ETag:') and endpoint_type == 'put': return
if response_str.startswith('ETag:') and endpoint_type == 'put':
response_etag = response_str.split('ETag:', 1)[1] response_etag = response_str.split('ETag:', 1)[1]
self._201(response_etag) self._201(response_etag)
elif response_str != 'Ok': elif response_str != 'Ok':
@ -19483,7 +19482,7 @@ class PubServer(BaseHTTPRequestHandler):
curr_session, proxy_type): curr_session, proxy_type):
return 1 return 1
return -1 return -1
elif post_type == 'newshare' or post_type == 'newwanted': elif post_type in ('newshare', 'newwanted'):
if not fields.get('itemQty'): if not fields.get('itemQty'):
print(post_type + ' no itemQty') print(post_type + ' no itemQty')
return -1 return -1

View File

@ -28,7 +28,7 @@ from posts import get_person_box
def send_delete_via_server(base_dir: str, session, def send_delete_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, delete_object_url: str, http_prefix: str, delete_object_url: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -39,7 +39,7 @@ def send_delete_via_server(base_dir: str, session,
print('WARN: No session for send_delete_via_server') print('WARN: No session for send_delete_via_server')
return 6 return 6
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
to_url = 'https://www.w3.org/ns/activitystreams#Public' to_url = 'https://www.w3.org/ns/activitystreams#Public'
@ -178,8 +178,7 @@ def outbox_delete(base_dir: str, http_prefix: str,
def remove_old_hashtags(base_dir: str, max_months: int) -> str: def remove_old_hashtags(base_dir: str, max_months: int) -> str:
"""Remove old hashtags """Remove old hashtags
""" """
if max_months > 11: max_months = min(max_months, 11)
max_months = 11
max_days_since_epoch = \ max_days_since_epoch = \
(datetime.utcnow() - datetime(1970, 1 + max_months, 1)).days (datetime.utcnow() - datetime(1970, 1 + max_months, 1)).days
remove_hashtags = [] remove_hashtags = []

View File

@ -65,7 +65,7 @@ def set_enigma_pub_key(actor_json: {}, enigma_pub_key: str) -> None:
property_found = property_value property_found = property_value
break break
if property_found: if property_found:
actor_json['attachment'].remove(property_value) actor_json['attachment'].remove(property_found)
if remove_key: if remove_key:
return return

View File

@ -9,6 +9,8 @@ __module_group__ = "RSS Feeds"
def rss2tag_header(hashtag: str, http_prefix: str, domain_full: str) -> str: def rss2tag_header(hashtag: str, http_prefix: str, domain_full: str) -> str:
"""Header for rss 2
"""
return \ return \
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + \ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + \
"<rss version=\"2.0\">" + \ "<rss version=\"2.0\">" + \
@ -19,4 +21,6 @@ def rss2tag_header(hashtag: str, http_prefix: str, domain_full: str) -> str:
def rss2tag_footer() -> str: def rss2tag_footer() -> str:
"""Footer for rss 2
"""
return '</channel></rss>' return '</channel></rss>'

View File

@ -560,8 +560,7 @@ def get_following_feed(base_dir: str, domain: str, port: int, path: str,
curr_page += 1 curr_page += 1
following['totalItems'] = total_ctr following['totalItems'] = total_ctr
last_page = int(total_ctr / follows_per_page) last_page = int(total_ctr / follows_per_page)
if last_page < 1: last_page = max(last_page, 1)
last_page = 1
if next_page_number > last_page: if next_page_number > last_page:
following['next'] = \ following['next'] = \
local_actor_url(http_prefix, nickname, domain) + \ local_actor_url(http_prefix, nickname, domain) + \
@ -731,10 +730,10 @@ def followed_account_accepts(session, base_dir: str, http_prefix: str,
port: int, port: int,
nickname: str, domain: str, from_port: int, nickname: str, domain: str, from_port: int,
person_url: str, federation_list: [], person_url: str, federation_list: [],
follow_json: {}, send_threads: [], postLog: [], follow_json: {}, send_threads: [], post_log: [],
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
removeFollowActivity: bool, remove_follow_activity: bool,
signing_priv_key_pem: str, signing_priv_key_pem: str,
curr_domain: str, curr_domain: str,
onion_domain: str, i2p_domain: str): onion_domain: str, i2p_domain: str):
@ -759,7 +758,7 @@ def followed_account_accepts(session, base_dir: str, http_prefix: str,
accept_handle + ' port ' + str(from_port)) accept_handle + ' port ' + str(from_port))
client_to_server = False client_to_server = False
if removeFollowActivity: if remove_follow_activity:
# remove the follow request json # remove the follow request json
follow_activity_filename = \ follow_activity_filename = \
acct_dir(base_dir, nickname_to_follow, domain_to_follow) + \ acct_dir(base_dir, nickname_to_follow, domain_to_follow) + \
@ -783,7 +782,7 @@ def followed_account_accepts(session, base_dir: str, http_prefix: str,
nickname, domain, from_port, '', nickname, domain, from_port, '',
http_prefix, True, client_to_server, http_prefix, True, client_to_server,
federation_list, federation_list,
send_threads, postLog, cached_webfingers, send_threads, post_log, cached_webfingers,
person_cache, debug, project_version, None, person_cache, debug, project_version, None,
group_account, signing_priv_key_pem, group_account, signing_priv_key_pem,
7856837, curr_domain, onion_domain, i2p_domain) 7856837, curr_domain, onion_domain, i2p_domain)
@ -796,7 +795,7 @@ def followed_account_rejects(session, session_onion, session_i2p,
port: int, port: int,
nickname: str, domain: str, from_port: int, nickname: str, domain: str, from_port: int,
federation_list: [], federation_list: [],
send_threads: [], postLog: [], send_threads: [], post_log: [],
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
signing_priv_key_pem: str): signing_priv_key_pem: str):
@ -853,7 +852,7 @@ def followed_account_rejects(session, session_onion, session_i2p,
nickname, domain, from_port, '', nickname, domain, from_port, '',
http_prefix, True, client_to_server, http_prefix, True, client_to_server,
federation_list, federation_list,
send_threads, postLog, cached_webfingers, send_threads, post_log, cached_webfingers,
person_cache, debug, project_version, None, person_cache, debug, project_version, None,
group_account, signing_priv_key_pem, group_account, signing_priv_key_pem,
6393063, 6393063,
@ -865,10 +864,10 @@ def send_follow_request(session, base_dir: str,
sender_domain: str, sender_port: int, sender_domain: str, sender_port: int,
http_prefix: str, http_prefix: str,
follow_nickname: str, follow_domain: str, follow_nickname: str, follow_domain: str,
followedActor: str, followed_actor: str,
followPort: int, followHttpPrefix: str, follow_port: int, follow_http_prefix: str,
client_to_server: bool, federation_list: [], client_to_server: bool, federation_list: [],
send_threads: [], postLog: [], cached_webfingers: {}, send_threads: [], post_log: [], cached_webfingers: {},
person_cache: {}, debug: bool, person_cache: {}, debug: bool,
project_version: str, signing_priv_key_pem: str, project_version: str, signing_priv_key_pem: str,
curr_domain: str, curr_domain: str,
@ -885,22 +884,22 @@ def send_follow_request(session, base_dir: str,
full_domain = get_full_domain(sender_domain, sender_port) full_domain = get_full_domain(sender_domain, sender_port)
follow_actor = local_actor_url(http_prefix, nickname, full_domain) follow_actor = local_actor_url(http_prefix, nickname, full_domain)
request_domain = get_full_domain(follow_domain, followPort) request_domain = get_full_domain(follow_domain, follow_port)
status_number, _ = get_status_number() status_number, _ = get_status_number()
group_account = False group_account = False
if follow_nickname: if follow_nickname:
followed_id = followedActor followed_id = followed_actor
follow_handle = follow_nickname + '@' + request_domain follow_handle = follow_nickname + '@' + request_domain
group_account = has_group_type(base_dir, followedActor, person_cache) group_account = has_group_type(base_dir, followed_actor, person_cache)
if group_account: if group_account:
follow_handle = '!' + follow_handle follow_handle = '!' + follow_handle
print('Follow request being sent to group account') print('Follow request being sent to group account')
else: else:
if debug: if debug:
print('DEBUG: send_follow_request - assuming single user instance') print('DEBUG: send_follow_request - assuming single user instance')
followed_id = followHttpPrefix + '://' + request_domain followed_id = follow_http_prefix + '://' + request_domain
single_user_nickname = 'dev' single_user_nickname = 'dev'
follow_handle = single_user_nickname + '@' + request_domain follow_handle = single_user_nickname + '@' + request_domain
@ -947,11 +946,11 @@ def send_follow_request(session, base_dir: str,
send_signed_json(new_follow_json, session, base_dir, send_signed_json(new_follow_json, session, base_dir,
nickname, sender_domain, sender_port, nickname, sender_domain, sender_port,
follow_nickname, follow_domain, followPort, follow_nickname, follow_domain, follow_port,
'https://www.w3.org/ns/activitystreams#Public', 'https://www.w3.org/ns/activitystreams#Public',
http_prefix, True, client_to_server, http_prefix, True, client_to_server,
federation_list, federation_list,
send_threads, postLog, cached_webfingers, person_cache, send_threads, post_log, cached_webfingers, person_cache,
debug, project_version, None, group_account, debug, project_version, None, group_account,
signing_priv_key_pem, 8234389, signing_priv_key_pem, 8234389,
curr_domain, onion_domain, i2p_domain) curr_domain, onion_domain, i2p_domain)
@ -963,7 +962,7 @@ def send_follow_request_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, from_port: int, from_domain: str, from_port: int,
follow_nickname: str, follow_domain: str, follow_nickname: str, follow_domain: str,
followPort: int, follow_port: int,
http_prefix: str, http_prefix: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -976,7 +975,7 @@ def send_follow_request_via_server(base_dir: str, session,
from_domain_full = get_full_domain(from_domain, from_port) from_domain_full = get_full_domain(from_domain, from_port)
follow_domain_full = get_full_domain(follow_domain, followPort) follow_domain_full = get_full_domain(follow_domain, follow_port)
follow_actor = \ follow_actor = \
local_actor_url(http_prefix, from_nickname, from_domain_full) local_actor_url(http_prefix, from_nickname, from_domain_full)
@ -1055,7 +1054,7 @@ def send_unfollow_request_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, from_port: int, from_domain: str, from_port: int,
follow_nickname: str, follow_domain: str, follow_nickname: str, follow_domain: str,
followPort: int, follow_port: int,
http_prefix: str, http_prefix: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -1067,13 +1066,13 @@ def send_unfollow_request_via_server(base_dir: str, session,
return 6 return 6
from_domain_full = get_full_domain(from_domain, from_port) from_domain_full = get_full_domain(from_domain, from_port)
follow_domain_full = get_full_domain(follow_domain, followPort) follow_domain_full = get_full_domain(follow_domain, follow_port)
follow_actor = \ follow_actor = \
local_actor_url(http_prefix, from_nickname, from_domain_full) local_actor_url(http_prefix, from_nickname, from_domain_full)
followed_id = \ followed_id = \
http_prefix + '://' + follow_domain_full + '/@' + follow_nickname http_prefix + '://' + follow_domain_full + '/@' + follow_nickname
status_number, published = get_status_number() status_number, _ = get_status_number()
unfollow_json = { unfollow_json = {
'@context': 'https://www.w3.org/ns/activitystreams', '@context': 'https://www.w3.org/ns/activitystreams',
@ -1173,13 +1172,12 @@ def get_following_via_server(base_dir: str, session,
'Authorization': auth_header 'Authorization': auth_header
} }
if page_number < 1: page_number = max(page_number, 1)
page_number = 1
url = follow_actor + '/following?page=' + str(page_number) url = follow_actor + '/following?page=' + str(page_number)
followingJson = \ following_json = \
get_json(signing_priv_key_pem, session, url, headers, {}, debug, get_json(signing_priv_key_pem, session, url, headers, {}, debug,
__version__, http_prefix, domain, 10, True) __version__, http_prefix, domain, 10, True)
if not followingJson: if not following_json:
if debug: if debug:
print('DEBUG: GET following list failed for c2s to ' + url) print('DEBUG: GET following list failed for c2s to ' + url)
return 5 return 5
@ -1187,7 +1185,7 @@ def get_following_via_server(base_dir: str, session,
if debug: if debug:
print('DEBUG: c2s GET following list request success') print('DEBUG: c2s GET following list request success')
return followingJson return following_json
def get_followers_via_server(base_dir: str, session, def get_followers_via_server(base_dir: str, session,
@ -1255,8 +1253,7 @@ def get_follow_requests_via_server(base_dir: str, session,
'Authorization': auth_header 'Authorization': auth_header
} }
if page_number < 1: page_number = max(page_number, 1)
page_number = 1
url = follow_actor + '/followrequests?page=' + str(page_number) url = follow_actor + '/followrequests?page=' + str(page_number)
followers_json = \ followers_json = \
get_json(signing_priv_key_pem, session, url, headers, {}, debug, get_json(signing_priv_key_pem, session, url, headers, {}, debug,

View File

@ -62,7 +62,7 @@ def get_digest_algorithm_from_headers(http_headers: {}) -> str:
return 'rsa-sha256' return 'rsa-sha256'
def sign_post_headers(dateStr: str, private_key_pem: str, def sign_post_headers(date_str: str, private_key_pem: str,
nickname: str, domain: str, port: int, nickname: str, domain: str, port: int,
to_domain: str, to_port: int, to_domain: str, to_port: int,
path: str, http_prefix: str, path: str, http_prefix: str,
@ -76,8 +76,8 @@ def sign_post_headers(dateStr: str, private_key_pem: str,
to_domain = get_full_domain(to_domain, to_port) to_domain = get_full_domain(to_domain, to_port)
if not dateStr: if not date_str:
dateStr = strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime()) date_str = strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime())
if nickname != domain and nickname.lower() != 'actor': if nickname != domain and nickname.lower() != 'actor':
key_id = local_actor_url(http_prefix, nickname, domain) key_id = local_actor_url(http_prefix, nickname, domain)
else: else:
@ -88,7 +88,7 @@ def sign_post_headers(dateStr: str, private_key_pem: str,
headers = { headers = {
'(request-target)': f'get {path}', '(request-target)': f'get {path}',
'host': to_domain, 'host': to_domain,
'date': dateStr, 'date': date_str,
'accept': content_type 'accept': content_type
} }
else: else:
@ -99,7 +99,7 @@ def sign_post_headers(dateStr: str, private_key_pem: str,
headers = { headers = {
'(request-target)': f'post {path}', '(request-target)': f'post {path}',
'host': to_domain, 'host': to_domain,
'date': dateStr, 'date': date_str,
'digest': f'{digest_prefix}={body_digest}', 'digest': f'{digest_prefix}={body_digest}',
'content-type': 'application/activity+json', 'content-type': 'application/activity+json',
'content-length': str(content_length) 'content-length': str(content_length)
@ -138,7 +138,7 @@ def sign_post_headers(dateStr: str, private_key_pem: str,
return signature_header return signature_header
def sign_post_headers_new(dateStr: str, private_key_pem: str, def sign_post_headers_new(date_str: str, private_key_pem: str,
nickname: str, nickname: str,
domain: str, port: int, domain: str, port: int,
to_domain: str, to_port: int, to_domain: str, to_port: int,
@ -157,11 +157,11 @@ def sign_post_headers_new(dateStr: str, private_key_pem: str,
to_domain = get_full_domain(to_domain, to_port) to_domain = get_full_domain(to_domain, to_port)
time_format = "%a, %d %b %Y %H:%M:%S %Z" time_format = "%a, %d %b %Y %H:%M:%S %Z"
if not dateStr: if not date_str:
curr_time = gmtime() curr_time = gmtime()
dateStr = strftime(time_format, curr_time) date_str = strftime(time_format, curr_time)
else: else:
curr_time = datetime.datetime.strptime(dateStr, time_format) curr_time = datetime.datetime.strptime(date_str, time_format)
seconds_since_epoch = \ seconds_since_epoch = \
int((curr_time - datetime.datetime(1970, 1, 1)).total_seconds()) int((curr_time - datetime.datetime(1970, 1, 1)).total_seconds())
key_id = local_actor_url(http_prefix, nickname, domain) + '#main-key' key_id = local_actor_url(http_prefix, nickname, domain) + '#main-key'
@ -170,7 +170,7 @@ def sign_post_headers_new(dateStr: str, private_key_pem: str,
'@request-target': f'get {path}', '@request-target': f'get {path}',
'@created': str(seconds_since_epoch), '@created': str(seconds_since_epoch),
'host': to_domain, 'host': to_domain,
'date': dateStr 'date': date_str
} }
else: else:
body_digest = message_content_digest(message_body_json_str, body_digest = message_content_digest(message_body_json_str,
@ -181,7 +181,7 @@ def sign_post_headers_new(dateStr: str, private_key_pem: str,
'@request-target': f'post {path}', '@request-target': f'post {path}',
'@created': str(seconds_since_epoch), '@created': str(seconds_since_epoch),
'host': to_domain, 'host': to_domain,
'date': dateStr, 'date': date_str,
'digest': f'{digest_prefix}={body_digest}', 'digest': f'{digest_prefix}={body_digest}',
'content-type': 'application/activity+json', 'content-type': 'application/activity+json',
'content-length': str(content_length) 'content-length': str(content_length)
@ -234,10 +234,10 @@ def sign_post_headers_new(dateStr: str, private_key_pem: str,
return signature_index_header, signature_header return signature_index_header, signature_header
def create_signed_header(dateStr: str, private_key_pem: str, nickname: str, def create_signed_header(date_str: str, private_key_pem: str, nickname: str,
domain: str, port: int, domain: str, port: int,
to_domain: str, to_port: int, to_domain: str, to_port: int,
path: str, http_prefix: str, withDigest: bool, path: str, http_prefix: str, with_digest: bool,
message_body_json_str: str, message_body_json_str: str,
content_type: str) -> {}: content_type: str) -> {}:
"""Note that the domain is the destination, not the sender """Note that the domain is the destination, not the sender
@ -247,22 +247,22 @@ def create_signed_header(dateStr: str, private_key_pem: str, nickname: str,
header_domain = get_full_domain(to_domain, to_port) header_domain = get_full_domain(to_domain, to_port)
# if no date is given then create one # if no date is given then create one
if not dateStr: if not date_str:
dateStr = strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime()) date_str = strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime())
# Content-Type or Accept header # Content-Type or Accept header
if not content_type: if not content_type:
content_type = 'application/activity+json' content_type = 'application/activity+json'
if not withDigest: if not with_digest:
headers = { headers = {
'(request-target)': f'get {path}', '(request-target)': f'get {path}',
'host': header_domain, 'host': header_domain,
'date': dateStr, 'date': date_str,
'accept': content_type 'accept': content_type
} }
signature_header = \ signature_header = \
sign_post_headers(dateStr, private_key_pem, nickname, sign_post_headers(date_str, private_key_pem, nickname,
domain, port, to_domain, to_port, domain, port, to_domain, to_port,
path, http_prefix, None, content_type, path, http_prefix, None, content_type,
algorithm, None) algorithm, None)
@ -274,13 +274,13 @@ def create_signed_header(dateStr: str, private_key_pem: str, nickname: str,
headers = { headers = {
'(request-target)': f'post {path}', '(request-target)': f'post {path}',
'host': header_domain, 'host': header_domain,
'date': dateStr, 'date': date_str,
'digest': f'{digest_prefix}={body_digest}', 'digest': f'{digest_prefix}={body_digest}',
'content-length': str(content_length), 'content-length': str(content_length),
'content-type': content_type 'content-type': content_type
} }
signature_header = \ signature_header = \
sign_post_headers(dateStr, private_key_pem, nickname, sign_post_headers(date_str, private_key_pem, nickname,
domain, port, domain, port,
to_domain, to_port, to_domain, to_port,
path, http_prefix, message_body_json_str, path, http_prefix, message_body_json_str,
@ -310,33 +310,33 @@ def _verify_recent_signature(signed_date_str: str) -> bool:
def verify_post_headers(http_prefix: str, def verify_post_headers(http_prefix: str,
publicKeyPem: str, headers: dict, public_key_pem: str, headers: dict,
path: str, GETmethod: bool, path: str, get_method: bool,
messageBodyDigest: str, message_body_digest: str,
message_body_json_str: str, debug: bool, message_body_json_str: str, debug: bool,
noRecencyCheck: bool = False) -> bool: no_recency_check: bool = False) -> bool:
"""Returns true or false depending on if the key that we plugged in here """Returns true or false depending on if the key that we plugged in here
validates against the headers, method, and path. validates against the headers, method, and path.
publicKeyPem - the public key from an rsa key pair public_key_pem - the public key from an rsa key pair
headers - should be a dictionary of request headers headers - should be a dictionary of request headers
path - the relative url that was requested from this site path - the relative url that was requested from this site
GETmethod - GET or POST get_method - GET or POST
message_body_json_str - the received request body (used for digest) message_body_json_str - the received request body (used for digest)
""" """
if GETmethod: if get_method:
method = 'GET' method = 'GET'
else: else:
method = 'POST' method = 'POST'
if debug: if debug:
print('DEBUG: verify_post_headers ' + method) print('DEBUG: verify_post_headers ' + method)
print('verify_post_headers publicKeyPem: ' + str(publicKeyPem)) print('verify_post_headers public_key_pem: ' + str(public_key_pem))
print('verify_post_headers headers: ' + str(headers)) print('verify_post_headers headers: ' + str(headers))
print('verify_post_headers message_body_json_str: ' + print('verify_post_headers message_body_json_str: ' +
str(message_body_json_str)) str(message_body_json_str))
pubkey = load_pem_public_key(publicKeyPem.encode('utf-8'), pubkey = load_pem_public_key(public_key_pem.encode('utf-8'),
backend=default_backend()) backend=default_backend())
# Build a dictionary of the signature values # Build a dictionary of the signature values
if headers.get('Signature-Input') or headers.get('signature-input'): if headers.get('Signature-Input') or headers.get('signature-input'):
@ -422,8 +422,8 @@ def verify_post_headers(http_prefix: str,
if debug: if debug:
print('http signature algorithm: ' + algorithm) print('http signature algorithm: ' + algorithm)
elif signed_header == 'digest': elif signed_header == 'digest':
if messageBodyDigest: if message_body_digest:
body_digest = messageBodyDigest body_digest = message_body_digest
else: else:
body_digest = \ body_digest = \
message_content_digest(message_body_json_str, message_content_digest(message_body_json_str,
@ -446,7 +446,7 @@ def verify_post_headers(http_prefix: str,
' not found in ' + str(headers)) ' not found in ' + str(headers))
else: else:
if headers.get(signed_header): if headers.get(signed_header):
if signed_header == 'date' and not noRecencyCheck: if signed_header == 'date' and not no_recency_check:
if not _verify_recent_signature(headers[signed_header]): if not _verify_recent_signature(headers[signed_header]):
if debug: if debug:
print('DEBUG: ' + print('DEBUG: ' +

View File

@ -153,7 +153,7 @@ def libretranslate_languages(url: str, api_key: str = None) -> []:
else: else:
url += "languages" url += "languages"
params = dict() params = {}
if api_key: if api_key:
params["api_key"] = api_key params["api_key"] = api_key
@ -162,9 +162,9 @@ def libretranslate_languages(url: str, api_key: str = None) -> []:
req = request.Request(url, data=url_params.encode()) req = request.Request(url, data=url_params.encode())
response = request.urlopen(req) response_str = ''
with request.urlopen(req) as response:
response_str = response.read().decode() response_str = response.read().decode()
result = json.loads(response_str) result = json.loads(response_str)
if not result: if not result:
@ -270,13 +270,16 @@ def libretranslate(url: str, text: str,
url_params = parse.urlencode(lt_params) url_params = parse.urlencode(lt_params)
req = request.Request(url, data=url_params.encode()) req = request.Request(url, data=url_params.encode())
response_str = None
try: try:
response = request.urlopen(req) with request.urlopen(req) as response:
except BaseException: response_str = response.read().decode()
print('EX: Unable to translate: ' + text) except BaseException as ex:
print('EX: Unable to translate: ' + text + ' ' + str(ex))
return original_text return original_text
response_str = response.read().decode() if not response_str:
return original_text
translated_text = \ translated_text = \
'<p>' + json.loads(response_str)['translatedText'] + '</p>' '<p>' + json.loads(response_str)['translatedText'] + '</p>'

View File

@ -74,7 +74,7 @@ def _create_like(recent_posts_cache: {},
cc_list: [], http_prefix: str, cc_list: [], http_prefix: str,
object_url: str, actor_liked: str, object_url: str, actor_liked: str,
client_to_server: bool, client_to_server: bool,
send_threads: [], postLog: [], send_threads: [], post_log: [],
person_cache: {}, cached_webfingers: {}, person_cache: {}, cached_webfingers: {},
debug: bool, project_version: str, debug: bool, project_version: str,
signing_priv_key_pem: str, signing_priv_key_pem: str,
@ -141,7 +141,7 @@ def _create_like(recent_posts_cache: {},
liked_post_port, liked_post_port,
'https://www.w3.org/ns/activitystreams#Public', 'https://www.w3.org/ns/activitystreams#Public',
http_prefix, True, client_to_server, federation_list, http_prefix, True, client_to_server, federation_list,
send_threads, postLog, cached_webfingers, send_threads, post_log, cached_webfingers,
person_cache, person_cache,
debug, project_version, None, group_account, debug, project_version, None, group_account,
signing_priv_key_pem, 7367374, signing_priv_key_pem, 7367374,
@ -156,7 +156,7 @@ def like_post(recent_posts_cache: {},
like_nickname: str, like_domain: str, like_port: int, like_nickname: str, like_domain: str, like_port: int,
cc_list: [], cc_list: [],
like_status_number: int, client_to_server: bool, like_status_number: int, client_to_server: bool,
send_threads: [], postLog: [], send_threads: [], post_log: [],
person_cache: {}, cached_webfingers: {}, person_cache: {}, cached_webfingers: {},
debug: bool, project_version: str, debug: bool, project_version: str,
signing_priv_key_pem: str, signing_priv_key_pem: str,
@ -173,7 +173,8 @@ def like_post(recent_posts_cache: {},
nickname, domain, port, nickname, domain, port,
cc_list, http_prefix, object_url, actor_liked, cc_list, http_prefix, object_url, actor_liked,
client_to_server, client_to_server,
send_threads, postLog, person_cache, cached_webfingers, send_threads, post_log, person_cache,
cached_webfingers,
debug, project_version, signing_priv_key_pem, debug, project_version, signing_priv_key_pem,
curr_domain, onion_domain, i2p_domain) curr_domain, onion_domain, i2p_domain)

View File

@ -87,8 +87,8 @@ def verify_json_signature(doc: {}, public_key_pem: str) -> bool:
padding.PKCS1v15(), padding.PKCS1v15(),
hazutils.Prehashed(hashes.SHA256())) hazutils.Prehashed(hashes.SHA256()))
return True return True
except BaseException: except BaseException as ex:
print('EX: verify_json_signature unable to verify') print('EX: verify_json_signature unable to verify ' + str(ex))
return False return False

View File

@ -202,13 +202,13 @@ def geocoords_from_map_link(url: str,
""" """
if osm_domain in url: if osm_domain in url:
return _geocoords_from_osm_link(url, osm_domain) return _geocoords_from_osm_link(url, osm_domain)
elif '.google.co' in url: if '.google.co' in url:
return _geocoords_from_gmaps_link(url) return _geocoords_from_gmaps_link(url)
elif '.bing.co' in url: if '.bing.co' in url:
return _geocoords_from_bmaps_link(url) return _geocoords_from_bmaps_link(url)
elif '.waze.co' in url: if '.waze.co' in url:
return _geocoords_from_waze_link(url) return _geocoords_from_waze_link(url)
elif 'wego.here.co' in url: if 'wego.here.co' in url:
return _geocoords_from_wego_link(url) return _geocoords_from_wego_link(url)
return None, None, None return None, None, None

View File

@ -35,7 +35,7 @@ def meta_data_node_info(base_dir: str,
about_url: str, about_url: str,
terms_of_service_url: str, terms_of_service_url: str,
registration: bool, version: str, registration: bool, version: str,
showAccounts: bool) -> {}: show_accounts: bool) -> {}:
""" /nodeinfo/2.0 endpoint """ /nodeinfo/2.0 endpoint
Also see https://socialhub.activitypub.rocks/t/ Also see https://socialhub.activitypub.rocks/t/
fep-f1d5-nodeinfo-in-fediverse-software/1190/4 fep-f1d5-nodeinfo-in-fediverse-software/1190/4
@ -46,7 +46,7 @@ def meta_data_node_info(base_dir: str,
Also exposure of the version number and number of accounts could be Also exposure of the version number and number of accounts could be
sensitive sensitive
""" """
if showAccounts: if show_accounts:
active_accounts = no_of_accounts(base_dir) active_accounts = no_of_accounts(base_dir)
active_accounts_monthly = no_of_active_accounts_monthly(base_dir, 1) active_accounts_monthly = no_of_active_accounts_monthly(base_dir, 1)
active_accounts_half_year = no_of_active_accounts_monthly(base_dir, 6) active_accounts_half_year = no_of_active_accounts_monthly(base_dir, 6)
@ -81,7 +81,7 @@ def meta_data_node_info(base_dir: str,
return nodeinfo return nodeinfo
def meta_data_instance(showAccounts: bool, def meta_data_instance(show_accounts: bool,
instance_title: str, instance_title: str,
instance_description_short: str, instance_description_short: str,
instance_description: str, instance_description: str,
@ -131,7 +131,7 @@ def meta_data_instance(showAccounts: bool,
http_prefix + '://' + domain_full + '/@' + \ http_prefix + '://' + domain_full + '/@' + \
admin_actor['preferredUsername'] admin_actor['preferredUsername']
if showAccounts: if show_accounts:
active_accounts = no_of_accounts(base_dir) active_accounts = no_of_accounts(base_dir)
local_posts = _get_status_count(base_dir) local_posts = _get_status_count(base_dir)
else: else:

View File

@ -54,7 +54,7 @@ def _update_feeds_outbox_index(base_dir: str, domain: str,
feeds_file.seek(0, 0) feeds_file.seek(0, 0)
feeds_file.write(post_id + '\n' + content) feeds_file.write(post_id + '\n' + content)
print('DEBUG: feeds post added to index') print('DEBUG: feeds post added to index')
except BaseException as ex: except OSError as ex:
print('EX: Failed to write entry to feeds posts index ' + print('EX: Failed to write entry to feeds posts index ' +
index_filename + ' ' + str(ex)) index_filename + ' ' + str(ex))
else: else:
@ -803,8 +803,7 @@ def run_newswire_daemon(base_dir: str, httpd,
print('Newswire daemon has no session') print('Newswire daemon has no session')
time.sleep(60) time.sleep(60)
continue continue
else: print('Newswire daemon session established')
print('Newswire daemon session established')
# try to update the feeds # try to update the feeds
print('Updating newswire feeds') print('Updating newswire feeds')

View File

@ -471,7 +471,7 @@ def _valid_podcast_entry(base_dir: str, key: str, entry: {}) -> bool:
https://github.com/Podcastindex-org/podcast-namespace/ https://github.com/Podcastindex-org/podcast-namespace/
blob/main/proposal-docs/social/social.md#socialinteract-element blob/main/proposal-docs/social/social.md#socialinteract-element
""" """
if key == 'socialInteract' or key == 'discussion': if key in ('socialInteract', 'discussion'):
if not entry.get('protocol'): if not entry.get('protocol'):
return False return False
if not entry.get('uri'): if not entry.get('uri'):
@ -678,10 +678,9 @@ def get_link_from_rss_item(rss_item: str,
'.i2p/' not in link: '.i2p/' not in link:
continue continue
return link, mime_type return link, mime_type
else: if '.onion/' not in link and \
if '.onion/' not in link and \ '.i2p/' not in link:
'.i2p/' not in link: return link, mime_type
return link, mime_type
if '<enclosure ' in rss_item: if '<enclosure ' in rss_item:
# get link from audio or video enclosure # get link from audio or video enclosure
@ -1322,9 +1321,8 @@ def get_rss(base_dir: str, domain: str, session, url: str,
max_categories_feedItem_size_kb, max_categories_feedItem_size_kb,
session, debug, session, debug,
preferred_podcast_formats) preferred_podcast_formats)
else: print('WARN: feed is too large, ' +
print('WARN: feed is too large, ' + 'or contains invalid characters: ' + url)
'or contains invalid characters: ' + url)
else: else:
print('WARN: no result returned for feed ' + url) print('WARN: no result returned for feed ' + url)
except requests.exceptions.RequestException as ex: except requests.exceptions.RequestException as ex:

4
pgp.py
View File

@ -220,7 +220,7 @@ def set_pgp_pub_key(actor_json: {}, pgp_pub_key: str) -> None:
property_found = property_value property_found = property_value
break break
if property_found: if property_found:
actor_json['attachment'].remove(property_value) actor_json['attachment'].remove(property_found)
if remove_key: if remove_key:
return return
@ -283,7 +283,7 @@ def set_pgp_fingerprint(actor_json: {}, fingerprint: str) -> None:
property_found = property_value property_found = property_value
break break
if property_found: if property_found:
actor_json['attachment'].remove(property_value) actor_json['attachment'].remove(property_found)
if remove_fingerprint: if remove_fingerprint:
return return

View File

@ -1451,7 +1451,7 @@ def _create_post_base(base_dir: str,
break break
if music_metadata: if music_metadata:
for audio_tag, audio_value in music_metadata.items(): for audio_tag, audio_value in music_metadata.items():
if audio_tag == 'title' or audio_tag == 'track': if audio_tag in ('title', 'track'):
continue continue
# capitalize and remove any spaces # capitalize and remove any spaces
audio_value = audio_value.title().replace(' ', '') audio_value = audio_value.title().replace(' ', '')
@ -1984,7 +1984,7 @@ def create_question_post(base_dir: str,
client_to_server: bool, comments_enabled: bool, client_to_server: bool, comments_enabled: bool,
attach_image_filename: str, media_type: str, attach_image_filename: str, media_type: str,
image_description: str, city: str, image_description: str, city: str,
subject: str, durationDays: int, subject: str, duration_days: int,
system_language: str, low_bandwidth: bool, system_language: str, low_bandwidth: bool,
content_license_url: str, content_license_url: str,
languages_understood: []) -> {}: languages_understood: []) -> {}:
@ -2011,7 +2011,7 @@ def create_question_post(base_dir: str,
message_json['object']['votersCount'] = 0 message_json['object']['votersCount'] = 0
curr_time = datetime.datetime.utcnow() curr_time = datetime.datetime.utcnow()
days_since_epoch = \ days_since_epoch = \
int((curr_time - datetime.datetime(1970, 1, 1)).days + durationDays) int((curr_time - datetime.datetime(1970, 1, 1)).days + duration_days)
end_time = datetime.datetime(1970, 1, 1) + \ end_time = datetime.datetime(1970, 1, 1) + \
datetime.timedelta(days_since_epoch) datetime.timedelta(days_since_epoch)
message_json['object']['endTime'] = end_time.strftime("%Y-%m-%dT%H:%M:%SZ") message_json['object']['endTime'] = end_time.strftime("%Y-%m-%dT%H:%M:%SZ")
@ -2394,7 +2394,7 @@ def thread_send_post(session, post_json_str: str, federation_list: [],
def send_post(signing_priv_key_pem: str, project_version: str, def send_post(signing_priv_key_pem: str, project_version: str,
session, base_dir: str, nickname: str, domain: str, port: int, session, base_dir: str, nickname: str, domain: str, port: int,
to_nickname: str, to_domain: str, to_port: int, cc: str, to_nickname: str, to_domain: str, to_port: int, cc_str: str,
http_prefix: str, content: str, followers_only: bool, http_prefix: str, content: str, followers_only: bool,
save_to_file: bool, client_to_server: bool, save_to_file: bool, client_to_server: bool,
comments_enabled: bool, comments_enabled: bool,
@ -2462,7 +2462,7 @@ def send_post(signing_priv_key_pem: str, project_version: str,
post_json_object = \ post_json_object = \
_create_post_base(base_dir, nickname, domain, port, _create_post_base(base_dir, nickname, domain, port,
to_person_id, cc, http_prefix, content, to_person_id, cc_str, http_prefix, content,
followers_only, save_to_file, client_to_server, followers_only, save_to_file, client_to_server,
comments_enabled, comments_enabled,
attach_image_filename, media_type, attach_image_filename, media_type,
@ -2559,7 +2559,7 @@ def send_post_via_server(signing_priv_key_pem: str, project_version: str,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, from_port: int, from_domain: str, from_port: int,
to_nickname: str, to_domain: str, to_port: int, to_nickname: str, to_domain: str, to_port: int,
cc: str, cc_str: str,
http_prefix: str, content: str, followers_only: bool, http_prefix: str, content: str, followers_only: bool,
comments_enabled: bool, comments_enabled: bool,
attach_image_filename: str, media_type: str, attach_image_filename: str, media_type: str,
@ -2631,7 +2631,8 @@ def send_post_via_server(signing_priv_key_pem: str, project_version: str,
client_to_server = True client_to_server = True
if to_domain.lower().endswith('public'): if to_domain.lower().endswith('public'):
to_person_id = 'https://www.w3.org/ns/activitystreams#Public' to_person_id = 'https://www.w3.org/ns/activitystreams#Public'
cc = local_actor_url(http_prefix, from_nickname, from_domain_full) + \ cc_str = \
local_actor_url(http_prefix, from_nickname, from_domain_full) + \
'/followers' '/followers'
else: else:
if to_domain.lower().endswith('followers') or \ if to_domain.lower().endswith('followers') or \
@ -2648,7 +2649,7 @@ def send_post_via_server(signing_priv_key_pem: str, project_version: str,
post_json_object = \ post_json_object = \
_create_post_base(base_dir, _create_post_base(base_dir,
from_nickname, from_domain, from_port, from_nickname, from_domain, from_port,
to_person_id, cc, http_prefix, content, to_person_id, cc_str, http_prefix, content,
followers_only, save_to_file, client_to_server, followers_only, save_to_file, client_to_server,
comments_enabled, comments_enabled,
attach_image_filename, media_type, attach_image_filename, media_type,
@ -2760,7 +2761,8 @@ def _add_followers_to_public_post(post_json_object: {}) -> None:
def send_signed_json(post_json_object: {}, session, base_dir: str, def send_signed_json(post_json_object: {}, session, base_dir: str,
nickname: str, domain: str, port: int, nickname: str, domain: str, port: int,
to_nickname: str, to_domain: str, to_port: int, cc: str, to_nickname: str, to_domain: str,
to_port: int, cc_str: str,
http_prefix: str, save_to_file: bool, http_prefix: str, save_to_file: bool,
client_to_server: bool, federation_list: [], client_to_server: bool, federation_list: [],
send_threads: [], post_log: [], cached_webfingers: {}, send_threads: [], post_log: [], cached_webfingers: {},

View File

@ -182,8 +182,8 @@ def reaction_post(recent_posts_cache: {},
def send_reaction_via_server(base_dir: str, session, def send_reaction_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, reactionUrl: str, http_prefix: str, reaction_url: str,
emoji_content: str, emoji_content: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -198,7 +198,7 @@ def send_reaction_via_server(base_dir: str, session,
emoji_content + '"') emoji_content + '"')
return 7 return 7
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
@ -206,7 +206,7 @@ def send_reaction_via_server(base_dir: str, session,
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
'type': 'EmojiReact', 'type': 'EmojiReact',
'actor': actor, 'actor': actor,
'object': reactionUrl, 'object': reaction_url,
'content': emoji_content 'content': emoji_content
} }
@ -272,8 +272,8 @@ def send_reaction_via_server(base_dir: str, session,
def send_undo_reaction_via_server(base_dir: str, session, def send_undo_reaction_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, reactionUrl: str, http_prefix: str, reaction_url: str,
emoji_content: str, emoji_content: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -284,7 +284,7 @@ def send_undo_reaction_via_server(base_dir: str, session,
print('WARN: No session for send_undo_reaction_via_server') print('WARN: No session for send_undo_reaction_via_server')
return 6 return 6
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
@ -295,7 +295,7 @@ def send_undo_reaction_via_server(base_dir: str, session,
'object': { 'object': {
'type': 'EmojiReact', 'type': 'EmojiReact',
'actor': actor, 'actor': actor,
'object': reactionUrl, 'object': reaction_url,
'content': emoji_content 'content': emoji_content
} }
} }
@ -457,7 +457,6 @@ def _update_common_reactions(base_dir: str, emoji_content: str) -> None:
common_reactions = fp_react.readlines() common_reactions = fp_react.readlines()
except OSError: except OSError:
print('EX: unable to load common reactions file') print('EX: unable to load common reactions file')
pass
if common_reactions: if common_reactions:
new_common_reactions = [] new_common_reactions = []
reaction_found = False reaction_found = False

View File

@ -49,7 +49,7 @@ def create_session(proxy_type: str):
session.proxies = {} session.proxies = {}
session.proxies['http'] = 'socks5h://localhost:7777' session.proxies['http'] = 'socks5h://localhost:7777'
session.proxies['https'] = 'socks5h://localhost:7777' session.proxies['https'] = 'socks5h://localhost:7777'
elif proxy_type == 'ipfs' or proxy_type == 'ipns': elif proxy_type in ('ipfs', 'ipns'):
session.proxies = {} session.proxies = {}
session.proxies['ipfs'] = 'socks5h://localhost:4001' session.proxies['ipfs'] = 'socks5h://localhost:4001'
# print('New session created with proxy ' + str(proxy_type)) # print('New session created with proxy ' + str(proxy_type))
@ -79,8 +79,7 @@ def url_exists(session, url: str, timeout_sec: int = 3,
timeout=timeout_sec, timeout=timeout_sec,
allow_redirects=False) allow_redirects=False)
if result: if result:
if result.status_code == 200 or \ if result.status_code in (200, 304):
result.status_code == 304:
return True return True
print('url_exists for ' + url + ' returned ' + print('url_exists for ' + url + ' returned ' +
str(result.status_code)) str(result.status_code))
@ -775,7 +774,7 @@ def get_method(method_name: str, xml_str: str,
result = session.request(method_name, url, headers=session_headers, result = session.request(method_name, url, headers=session_headers,
data=xml_str, data=xml_str,
params=session_params, timeout=timeout_sec) params=session_params, timeout=timeout_sec)
if result.status_code != 200 and result.status_code != 207: if result.status_code not in (200, 207):
if result.status_code == 401: if result.status_code == 401:
print("WARN: get_method " + url + ' rejected by secure mode') print("WARN: get_method " + url + ' rejected by secure mode')
elif result.status_code == 403: elif result.status_code == 403:

View File

@ -543,8 +543,7 @@ def get_shares_feed_for_person(base_dir: str,
curr_page += 1 curr_page += 1
shares['totalItems'] = total_ctr shares['totalItems'] = total_ctr
last_page = int(total_ctr / shares_per_page) last_page = int(total_ctr / shares_per_page)
if last_page < 1: last_page = max(last_page, 1)
last_page = 1
if next_page_number > last_page: if next_page_number > last_page:
shares['next'] = \ shares['next'] = \
local_actor_url(http_prefix, nickname, domain) + \ local_actor_url(http_prefix, nickname, domain) + \
@ -554,14 +553,14 @@ def get_shares_feed_for_person(base_dir: str,
def send_share_via_server(base_dir, session, def send_share_via_server(base_dir, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, display_name: str, http_prefix: str, display_name: str,
summary: str, image_filename: str, summary: str, image_filename: str,
item_qty: float, item_type: str, item_category: str, item_qty: float, item_type: str, item_category: str,
location: str, duration: str, location: str, duration: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
itemPrice: str, item_currency: str, item_price: str, item_currency: str,
signing_priv_key_pem: str) -> {}: signing_priv_key_pem: str) -> {}:
"""Creates an item share via c2s """Creates an item share via c2s
""" """
@ -570,14 +569,14 @@ def send_share_via_server(base_dir, session,
return 6 return 6
# convert $4.23 to 4.23 USD # convert $4.23 to 4.23 USD
new_item_price, new_item_currency = get_price_from_string(itemPrice) new_item_price, new_item_currency = get_price_from_string(item_price)
if new_item_price != itemPrice: if new_item_price != item_price:
itemPrice = new_item_price item_price = new_item_price
if not item_currency: if not item_currency:
if new_item_currency != item_currency: if new_item_currency != item_currency:
item_currency = new_item_currency item_currency = new_item_currency
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
to_url = 'https://www.w3.org/ns/activitystreams#Public' to_url = 'https://www.w3.org/ns/activitystreams#Public'
@ -597,7 +596,7 @@ def send_share_via_server(base_dir, session,
"category": item_category, "category": item_category,
"location": location, "location": location,
"duration": duration, "duration": duration,
"itemPrice": itemPrice, "itemPrice": item_price,
"itemCurrency": item_currency, "itemCurrency": item_currency,
'to': [to_url], 'to': [to_url],
'cc': [cc_url] 'cc': [cc_url]
@ -679,7 +678,7 @@ def send_share_via_server(base_dir, session,
def send_undo_share_via_server(base_dir: str, session, def send_undo_share_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, display_name: str, http_prefix: str, display_name: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -690,7 +689,7 @@ def send_undo_share_via_server(base_dir: str, session,
print('WARN: No session for send_undo_share_via_server') print('WARN: No session for send_undo_share_via_server')
return 6 return 6
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
to_url = 'https://www.w3.org/ns/activitystreams#Public' to_url = 'https://www.w3.org/ns/activitystreams#Public'
@ -774,14 +773,14 @@ def send_undo_share_via_server(base_dir: str, session,
def send_wanted_via_server(base_dir, session, def send_wanted_via_server(base_dir, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, display_name: str, http_prefix: str, display_name: str,
summary: str, image_filename: str, summary: str, image_filename: str,
item_qty: float, item_type: str, item_category: str, item_qty: float, item_type: str, item_category: str,
location: str, duration: str, location: str, duration: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
itemMaxPrice: str, item_currency: str, item_max_price: str, item_currency: str,
signing_priv_key_pem: str) -> {}: signing_priv_key_pem: str) -> {}:
"""Creates a wanted item via c2s """Creates a wanted item via c2s
""" """
@ -790,14 +789,15 @@ def send_wanted_via_server(base_dir, session,
return 6 return 6
# convert $4.23 to 4.23 USD # convert $4.23 to 4.23 USD
new_item_max_price, new_item_currency = get_price_from_string(itemMaxPrice) new_item_max_price, new_item_currency = \
if new_item_max_price != itemMaxPrice: get_price_from_string(item_max_price)
itemMaxPrice = new_item_max_price if new_item_max_price != item_max_price:
item_max_price = new_item_max_price
if not item_currency: if not item_currency:
if new_item_currency != item_currency: if new_item_currency != item_currency:
item_currency = new_item_currency item_currency = new_item_currency
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
to_url = 'https://www.w3.org/ns/activitystreams#Public' to_url = 'https://www.w3.org/ns/activitystreams#Public'
@ -817,7 +817,7 @@ def send_wanted_via_server(base_dir, session,
"category": item_category, "category": item_category,
"location": location, "location": location,
"duration": duration, "duration": duration,
"itemPrice": itemMaxPrice, "itemPrice": item_max_price,
"itemCurrency": item_currency, "itemCurrency": item_currency,
'to': [to_url], 'to': [to_url],
'cc': [cc_url] 'cc': [cc_url]
@ -899,7 +899,7 @@ def send_wanted_via_server(base_dir, session,
def send_undo_wanted_via_server(base_dir: str, session, def send_undo_wanted_via_server(base_dir: str, session,
from_nickname: str, password: str, from_nickname: str, password: str,
from_domain: str, fromPort: int, from_domain: str, from_port: int,
http_prefix: str, display_name: str, http_prefix: str, display_name: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
debug: bool, project_version: str, debug: bool, project_version: str,
@ -910,7 +910,7 @@ def send_undo_wanted_via_server(base_dir: str, session,
print('WARN: No session for send_undo_wanted_via_server') print('WARN: No session for send_undo_wanted_via_server')
return 6 return 6
from_domain_full = get_full_domain(from_domain, fromPort) from_domain_full = get_full_domain(from_domain, from_port)
actor = local_actor_url(http_prefix, from_nickname, from_domain_full) actor = local_actor_url(http_prefix, from_nickname, from_domain_full)
to_url = 'https://www.w3.org/ns/activitystreams#Public' to_url = 'https://www.w3.org/ns/activitystreams#Public'
@ -1488,7 +1488,7 @@ def create_shared_item_federation_token(base_dir: str,
def authorize_shared_items(shared_items_federated_domains: [], def authorize_shared_items(shared_items_federated_domains: [],
base_dir: str, base_dir: str,
origin_domain_full: str, origin_domain_full: str,
calling_domainFull: str, calling_domain_full: str,
auth_header: str, auth_header: str,
debug: bool, debug: bool,
tokens_json: {} = None) -> bool: tokens_json: {} = None) -> bool:
@ -1528,16 +1528,16 @@ def authorize_shared_items(shared_items_federated_domains: [],
tokens_json = load_json(tokens_filename, 1, 2) tokens_json = load_json(tokens_filename, 1, 2)
if not tokens_json: if not tokens_json:
return False return False
if not tokens_json.get(calling_domainFull): if not tokens_json.get(calling_domain_full):
if debug: if debug:
print('DEBUG: shared item federation token ' + print('DEBUG: shared item federation token ' +
'check failed for ' + calling_domainFull) 'check failed for ' + calling_domain_full)
return False return False
if not constant_time_string_check(tokens_json[calling_domainFull], if not constant_time_string_check(tokens_json[calling_domain_full],
provided_token): provided_token):
if debug: if debug:
print('DEBUG: shared item federation token ' + print('DEBUG: shared item federation token ' +
'mismatch for ' + calling_domainFull) 'mismatch for ' + calling_domain_full)
return False return False
return True return True

View File

@ -2050,7 +2050,7 @@ def _is_valid_language(text: str) -> bool:
"Phonetic Extensions": [7467, 7544], "Phonetic Extensions": [7467, 7544],
"Combining Half Marks": [65070, 65071] "Combining Half Marks": [65070, 65071]
} }
for lang_name, lang_range in natural_languages.items(): for _, lang_range in natural_languages.items():
ok_lang = True ok_lang = True
for char in text: for char in text:
if char.isdigit() or char == '_': if char.isdigit() or char == '_':
@ -2134,7 +2134,7 @@ def no_of_accounts(base_dir: str) -> bool:
"""Returns the number of accounts on the system """Returns the number of accounts on the system
""" """
account_ctr = 0 account_ctr = 0
for subdir, dirs, files in os.walk(base_dir + '/accounts'): for _, dirs, _ in os.walk(base_dir + '/accounts'):
for account in dirs: for account in dirs:
if is_account_dir(account): if is_account_dir(account):
account_ctr += 1 account_ctr += 1
@ -2148,7 +2148,7 @@ def no_of_active_accounts_monthly(base_dir: str, months: int) -> bool:
account_ctr = 0 account_ctr = 0
curr_time = int(time.time()) curr_time = int(time.time())
month_seconds = int(60*60*24*30*months) month_seconds = int(60*60*24*30*months)
for subdir, dirs, files in os.walk(base_dir + '/accounts'): for _, dirs, _ in os.walk(base_dir + '/accounts'):
for account in dirs: for account in dirs:
if not is_account_dir(account): if not is_account_dir(account):
continue continue
@ -2427,7 +2427,7 @@ def search_box_posts(base_dir: str, nickname: str, domain: str,
search_words = [search_str] search_words = [search_str]
res = [] res = []
for root, dirs, fnames in os.walk(path): for root, _, fnames in os.walk(path):
for fname in fnames: for fname in fnames:
file_path = os.path.join(root, fname) file_path = os.path.join(root, fname)
with open(file_path, 'r') as post_file: with open(file_path, 'r') as post_file:
@ -3485,7 +3485,7 @@ def has_object_string_object(post_json_object: {}, debug: bool) -> bool:
if post_json_object['object'].get('object'): if post_json_object['object'].get('object'):
if isinstance(post_json_object['object']['object'], str): if isinstance(post_json_object['object']['object'], str):
return True return True
elif debug: if debug:
if post_json_object.get('type'): if post_json_object.get('type'):
print('DEBUG: ' + post_json_object['type'] + print('DEBUG: ' + post_json_object['type'] +
' object within dict is not a string') ' object within dict is not a string')
@ -3566,14 +3566,14 @@ def load_account_timezones(base_dir: str) -> {}:
"""Returns a dictionary containing the preferred timezone for each account """Returns a dictionary containing the preferred timezone for each account
""" """
account_timezone = {} account_timezone = {}
for subdir, dirs, files in os.walk(base_dir + '/accounts'): for _, dirs, _ in os.walk(base_dir + '/accounts'):
for acct in dirs: for acct in dirs:
if '@' not in acct: if '@' not in acct:
continue continue
if acct.startswith('inbox@') or acct.startswith('Actor@'): if acct.startswith('inbox@') or acct.startswith('Actor@'):
continue continue
acct_dir = os.path.join(base_dir + '/accounts', acct) acct_directory = os.path.join(base_dir + '/accounts', acct)
tz_filename = acct_dir + '/timezone.txt' tz_filename = acct_directory + '/timezone.txt'
if not os.path.isfile(tz_filename): if not os.path.isfile(tz_filename):
continue continue
timezone = None timezone = None
@ -3590,7 +3590,7 @@ def load_bold_reading(base_dir: str) -> {}:
"""Returns a dictionary containing the bold reading status for each account """Returns a dictionary containing the bold reading status for each account
""" """
bold_reading = {} bold_reading = {}
for subdir, dirs, files in os.walk(base_dir + '/accounts'): for _, dirs, _ in os.walk(base_dir + '/accounts'):
for acct in dirs: for acct in dirs:
if '@' not in acct: if '@' not in acct:
continue continue
@ -3601,6 +3601,7 @@ def load_bold_reading(base_dir: str) -> {}:
if os.path.isfile(bold_reading_filename): if os.path.isfile(bold_reading_filename):
nickname = acct.split('@')[0] nickname = acct.split('@')[0]
bold_reading[nickname] = True bold_reading[nickname] = True
break
return bold_reading return bold_reading

View File

@ -117,7 +117,7 @@ def _get_left_column_wanted(base_dir: str,
def get_left_column_content(base_dir: str, nickname: str, domain_full: str, def get_left_column_content(base_dir: str, nickname: str, domain_full: str,
http_prefix: str, translate: {}, http_prefix: str, translate: {},
editor: bool, artist: bool, editor: bool, artist: bool,
show_back_button: bool, timelinePath: str, show_back_button: bool, timeline_path: str,
rss_icon_at_top: bool, show_header_image: bool, rss_icon_at_top: bool, show_header_image: bool,
front_page: bool, theme: str, front_page: bool, theme: str,
access_keys: {}, access_keys: {},
@ -146,7 +146,7 @@ def get_left_column_content(base_dir: str, nickname: str, domain_full: str,
if show_back_button: if show_back_button:
html_str += \ html_str += \
' <div> <a href="' + timelinePath + '">' + \ ' <div> <a href="' + timeline_path + '">' + \
'<button class="cancelbtn">' + \ '<button class="cancelbtn">' + \
translate['Go Back'] + '</button></a>\n' translate['Go Back'] + '</button></a>\n'
@ -359,7 +359,7 @@ def get_left_column_content(base_dir: str, nickname: str, domain_full: str,
def html_links_mobile(css_cache: {}, base_dir: str, def html_links_mobile(css_cache: {}, base_dir: str,
nickname: str, domain_full: str, nickname: str, domain_full: str,
http_prefix: str, translate, http_prefix: str, translate,
timelinePath: str, authorized: bool, timeline_path: str, authorized: bool,
rss_icon_at_top: bool, rss_icon_at_top: bool,
icons_as_buttons: bool, icons_as_buttons: bool,
default_timeline: str, default_timeline: str,
@ -406,7 +406,7 @@ def html_links_mobile(css_cache: {}, base_dir: str,
get_left_column_content(base_dir, nickname, domain_full, get_left_column_content(base_dir, nickname, domain_full,
http_prefix, translate, http_prefix, translate,
editor, artist, editor, artist,
False, timelinePath, False, timeline_path,
rss_icon_at_top, False, False, rss_icon_at_top, False, False,
theme, access_keys, theme, access_keys,
shared_items_federated_domains) shared_items_federated_domains)

View File

@ -22,7 +22,7 @@ def header_buttons_timeline(default_timeline: str,
page_number: int, page_number: int,
translate: {}, translate: {},
users_path: str, users_path: str,
mediaButton: str, media_button: str,
blogs_button: str, blogs_button: str,
features_button: str, features_button: str,
news_button: str, news_button: str,
@ -62,7 +62,7 @@ def header_buttons_timeline(default_timeline: str,
tl_str += ' aria-current="location"' tl_str += ' aria-current="location"'
tl_str += \ tl_str += \
'><button class="' + \ '><button class="' + \
mediaButton + '"><span>' + translate['Media'] + \ media_button + '"><span>' + translate['Media'] + \
'</span></button></a>' '</span></button></a>'
elif default_timeline == 'tlblogs': elif default_timeline == 'tlblogs':
tl_str += \ tl_str += \
@ -134,7 +134,7 @@ def header_buttons_timeline(default_timeline: str,
tl_str += ' aria-current="location"' tl_str += ' aria-current="location"'
tl_str += \ tl_str += \
'><button class="' + \ '><button class="' + \
mediaButton + '"><span>' + translate['Media'] + \ media_button + '"><span>' + translate['Media'] + \
'</span></button></a>' '</span></button></a>'
else: else:
if not minimal: if not minimal:

View File

@ -40,7 +40,7 @@ def html_likers_of_post(base_dir: str, nickname: str,
system_language: str, system_language: str,
max_like_count: int, signing_priv_key_pem: str, max_like_count: int, signing_priv_key_pem: str,
cw_lists: {}, lists_enabled: str, cw_lists: {}, lists_enabled: str,
boxName: str, default_timeline: str, box_name: str, default_timeline: str,
bold_reading: bool, bold_reading: bool,
dict_name: str = 'likes') -> str: dict_name: str = 'likes') -> str:
"""Returns html for a screen showing who liked a post """Returns html for a screen showing who liked a post
@ -96,7 +96,7 @@ def html_likers_of_post(base_dir: str, nickname: str,
None, True, False, None, True, False,
http_prefix, http_prefix,
project_version, project_version,
boxName, box_name,
yt_replace_domain, yt_replace_domain,
twitter_replacement_domain, twitter_replacement_domain,
show_published_date_only, show_published_date_only,

View File

@ -118,7 +118,7 @@ def _html_podcast_transcripts(podcast_properties: {}, translate: {}) -> str:
return '' return ''
ctr = 1 ctr = 1
html_str = '' html_str = ''
for transcript in podcast_properties[key]: for _ in podcast_properties[key]:
transcript_url = None transcript_url = None
if podcast_properties[key].get('url'): if podcast_properties[key].get('url'):
transcript_url = podcast_properties[key]['url'] transcript_url = podcast_properties[key]['url']

View File

@ -214,14 +214,14 @@ def _html_post_metadata_open_graph(domain: str, post_json_object: {},
def _log_post_timing(enable_timing_log: bool, post_start_time, def _log_post_timing(enable_timing_log: bool, post_start_time,
debugId: str) -> None: debug_id: str) -> None:
"""Create a log of timings for performance tuning """Create a log of timings for performance tuning
""" """
if not enable_timing_log: if not enable_timing_log:
return return
time_diff = int((time.time() - post_start_time) * 1000) time_diff = int((time.time() - post_start_time) * 1000)
if time_diff > 100: if time_diff > 100:
print('TIMING INDIV ' + debugId + ' = ' + str(time_diff)) print('TIMING INDIV ' + debug_id + ' = ' + str(time_diff))
def prepare_html_post_nickname(nickname: str, post_html: str) -> str: def prepare_html_post_nickname(nickname: str, post_html: str) -> str:
@ -374,7 +374,7 @@ def _get_post_from_recent_cache(session,
return post_html return post_html
def _get_avatar_image_html(showAvatarOptions: bool, def _get_avatar_image_html(show_avatar_options: bool,
nickname: str, domain_full: str, nickname: str, domain_full: str,
avatar_url: str, post_actor: str, avatar_url: str, post_actor: str,
translate: {}, avatar_position: str, translate: {}, avatar_position: str,
@ -399,7 +399,7 @@ def _get_avatar_image_html(showAvatarOptions: bool,
show_profile_str + '" alt=" "' + avatar_position + \ show_profile_str + '" alt=" "' + avatar_position + \
get_broken_link_substitute() + '/></a>\n' get_broken_link_substitute() + '/></a>\n'
if showAvatarOptions and \ if show_avatar_options and \
domain_full + '/users/' + nickname not in post_actor: domain_full + '/users/' + nickname not in post_actor:
show_options_for_this_person_str = 'Show options for this person' show_options_for_this_person_str = 'Show options for this person'
if translate.get(show_options_for_this_person_str): if translate.get(show_options_for_this_person_str):
@ -528,7 +528,7 @@ def _get_reply_icon_html(base_dir: str, nickname: str, domain: str,
def _get_edit_icon_html(base_dir: str, nickname: str, domain_full: str, def _get_edit_icon_html(base_dir: str, nickname: str, domain_full: str,
post_json_object: {}, actor_nickname: str, post_json_object: {}, actor_nickname: str,
translate: {}, isEvent: bool) -> str: translate: {}, is_event: bool) -> str:
"""Returns html for the edit icon/button """Returns html for the edit icon/button
""" """
edit_str = '' edit_str = ''
@ -573,7 +573,7 @@ def _get_edit_icon_html(base_dir: str, nickname: str, domain_full: str,
'<img loading="lazy" decoding="async" title="' + \ '<img loading="lazy" decoding="async" title="' + \
edit_blog_post_str + '" alt="' + edit_blog_post_str + \ edit_blog_post_str + '" alt="' + edit_blog_post_str + \
' |" src="/icons/edit.png"/></a>\n' ' |" src="/icons/edit.png"/></a>\n'
elif isEvent: elif is_event:
edit_event_str = 'Edit event' edit_event_str = 'Edit event'
if translate.get(edit_event_str): if translate.get(edit_event_str):
edit_event_str = translate[edit_event_str] edit_event_str = translate[edit_event_str]
@ -1488,7 +1488,7 @@ def individual_post_as_html(signing_priv_key_pem: str,
session, cached_webfingers: {}, person_cache: {}, session, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, nickname: str, domain: str, port: int,
post_json_object: {}, post_json_object: {},
avatar_url: str, showAvatarOptions: bool, avatar_url: str, show_avatar_options: bool,
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
box_name: str, box_name: str,
@ -1642,7 +1642,7 @@ def individual_post_as_html(signing_priv_key_pem: str,
_log_post_timing(enable_timing_log, post_start_time, '7') _log_post_timing(enable_timing_log, post_start_time, '7')
avatar_link = \ avatar_link = \
_get_avatar_image_html(showAvatarOptions, _get_avatar_image_html(show_avatar_options,
nickname, domain_full, nickname, domain_full,
avatar_url, post_actor, avatar_url, post_actor,
translate, avatar_position, translate, avatar_position,

View File

@ -613,7 +613,7 @@ def html_profile(signing_priv_key_pem: str,
debug: bool, access_keys: {}, city: str, debug: bool, access_keys: {}, city: str,
system_language: str, max_like_count: int, system_language: str, max_like_count: int,
shared_items_federated_domains: [], shared_items_federated_domains: [],
extraJson: {}, page_number: int, extra_json: {}, page_number: int,
max_items_per_page: int, max_items_per_page: int,
cw_lists: {}, lists_enabled: str, cw_lists: {}, lists_enabled: str,
content_license_url: str, content_license_url: str,
@ -636,7 +636,7 @@ def html_profile(signing_priv_key_pem: str,
yt_replace_domain, yt_replace_domain,
twitter_replacement_domain, twitter_replacement_domain,
show_published_date_only, show_published_date_only,
newswire, theme, extraJson, newswire, theme, extra_json,
allow_local_network_access, access_keys, allow_local_network_access, access_keys,
system_language, max_like_count, system_language, max_like_count,
shared_items_federated_domains, None, shared_items_federated_domains, None,
@ -1042,7 +1042,7 @@ def html_profile(signing_priv_key_pem: str,
authorized, nickname, authorized, nickname,
domain, port, session, domain, port, session,
cached_webfingers, cached_webfingers,
person_cache, extraJson, person_cache, extra_json,
project_version, ["unfollow"], project_version, ["unfollow"],
selected, selected,
users_path, page_number, users_path, page_number,
@ -1055,7 +1055,7 @@ def html_profile(signing_priv_key_pem: str,
authorized, nickname, authorized, nickname,
domain, port, session, domain, port, session,
cached_webfingers, cached_webfingers,
person_cache, extraJson, person_cache, extra_json,
project_version, ["block"], project_version, ["block"],
selected, users_path, page_number, selected, users_path, page_number,
max_items_per_page, dormant_months, debug, max_items_per_page, dormant_months, debug,
@ -1064,21 +1064,21 @@ def html_profile(signing_priv_key_pem: str,
if selected == 'roles': if selected == 'roles':
profile_str += \ profile_str += \
_html_profile_roles(translate, nickname, domain_full, _html_profile_roles(translate, nickname, domain_full,
extraJson) extra_json)
elif selected == 'skills': elif selected == 'skills':
profile_str += \ profile_str += \
_html_profile_skills(translate, nickname, domain_full, _html_profile_skills(translate, nickname, domain_full,
extraJson) extra_json)
# elif selected == 'shares': # elif selected == 'shares':
# profile_str += \ # profile_str += \
# _html_profile_shares(actor, translate, # _html_profile_shares(actor, translate,
# nickname, domain_full, # nickname, domain_full,
# extraJson, 'shares') + license_str # extra_json, 'shares') + license_str
# elif selected == 'wanted': # elif selected == 'wanted':
# profile_str += \ # profile_str += \
# _html_profile_shares(actor, translate, # _html_profile_shares(actor, translate,
# nickname, domain_full, # nickname, domain_full,
# extraJson, 'wanted') + license_str # extra_json, 'wanted') + license_str
# end of #timeline # end of #timeline
profile_str += '</div>' profile_str += '</div>'
@ -1174,7 +1174,7 @@ def _html_profile_following(translate: {}, base_dir: str, http_prefix: str,
session, cached_webfingers: {}, person_cache: {}, session, cached_webfingers: {}, person_cache: {},
following_json: {}, project_version: str, following_json: {}, project_version: str,
buttons: [], buttons: [],
feedName: str, actor: str, feed_name: str, actor: str,
page_number: int, page_number: int,
max_items_per_page: int, max_items_per_page: int,
dormant_months: int, debug: bool, dormant_months: int, debug: bool,
@ -1188,7 +1188,7 @@ def _html_profile_following(translate: {}, base_dir: str, http_prefix: str,
# page up arrow # page up arrow
profile_str += \ profile_str += \
' <center>\n' + \ ' <center>\n' + \
' <a href="' + actor + '/' + feedName + \ ' <a href="' + actor + '/' + feed_name + \
'?page=' + str(page_number - 1) + '#buttonheader' + \ '?page=' + str(page_number - 1) + '#buttonheader' + \
'"><img loading="lazy" decoding="async" ' + \ '"><img loading="lazy" decoding="async" ' + \
'class="pageicon" src="/' + \ 'class="pageicon" src="/' + \
@ -1200,7 +1200,7 @@ def _html_profile_following(translate: {}, base_dir: str, http_prefix: str,
for following_actor in following_json['orderedItems']: for following_actor in following_json['orderedItems']:
# is this a dormant followed account? # is this a dormant followed account?
dormant = False dormant = False
if authorized and feedName == 'following': if authorized and feed_name == 'following':
dormant = \ dormant = \
is_dormant(base_dir, nickname, domain, following_actor, is_dormant(base_dir, nickname, domain, following_actor,
dormant_months) dormant_months)
@ -1219,7 +1219,7 @@ def _html_profile_following(translate: {}, base_dir: str, http_prefix: str,
# page down arrow # page down arrow
profile_str += \ profile_str += \
' <center>\n' + \ ' <center>\n' + \
' <a href="' + actor + '/' + feedName + \ ' <a href="' + actor + '/' + feed_name + \
'?page=' + str(page_number + 1) + '#buttonheader' + \ '?page=' + str(page_number + 1) + '#buttonheader' + \
'"><img loading="lazy" decoding="async" ' + \ '"><img loading="lazy" decoding="async" ' + \
'class="pageicon" src="/' + \ 'class="pageicon" src="/' + \
@ -1232,13 +1232,13 @@ def _html_profile_following(translate: {}, base_dir: str, http_prefix: str,
def _html_profile_roles(translate: {}, nickname: str, domain: str, def _html_profile_roles(translate: {}, nickname: str, domain: str,
rolesList: []) -> str: roles_list: []) -> str:
"""Shows roles on the profile screen """Shows roles on the profile screen
""" """
profile_str = '' profile_str = ''
profile_str += \ profile_str += \
'<div class="roles">\n<div class="roles-inner">\n' '<div class="roles">\n<div class="roles-inner">\n'
for role in rolesList: for role in roles_list:
if translate.get(role): if translate.get(role):
profile_str += '<h3>' + translate[role] + '</h3>\n' profile_str += '<h3>' + translate[role] + '</h3>\n'
else: else:
@ -2462,7 +2462,7 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
base_dir: str, session, base_dir: str, session,
cached_webfingers: {}, cached_webfingers: {},
person_cache: {}, domain: str, person_cache: {}, domain: str,
followUrl: str, follow_url: str,
authorized: bool, authorized: bool,
actor_nickname: str, actor_nickname: str,
http_prefix: str, http_prefix: str,
@ -2472,21 +2472,22 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
buttons=[]) -> str: buttons=[]) -> str:
"""An individual follow entry on the profile screen """An individual follow entry on the profile screen
""" """
follow_url_nickname = get_nickname_from_actor(followUrl) follow_url_nickname = get_nickname_from_actor(follow_url)
if not follow_url_nickname: if not follow_url_nickname:
return '' return ''
follow_url_domain, follow_url_port = get_domain_from_actor(followUrl) follow_url_domain, follow_url_port = get_domain_from_actor(follow_url)
follow_url_domain_full = \ follow_url_domain_full = \
get_full_domain(follow_url_domain, follow_url_port) get_full_domain(follow_url_domain, follow_url_port)
title_str = '@' + follow_url_nickname + '@' + follow_url_domain_full title_str = '@' + follow_url_nickname + '@' + follow_url_domain_full
avatar_url = get_person_avatar_url(base_dir, followUrl, person_cache, True) avatar_url = \
get_person_avatar_url(base_dir, follow_url, person_cache, True)
if not avatar_url: if not avatar_url:
avatar_url = followUrl + '/avatar.png' avatar_url = follow_url + '/avatar.png'
display_name = get_display_name(base_dir, followUrl, person_cache) display_name = get_display_name(base_dir, follow_url, person_cache)
is_group = False is_group = False
if not display_name: if not display_name:
# lookup the correct webfinger for the followUrl # lookup the correct webfinger for the follow_url
follow_url_handle = follow_url_nickname + '@' + follow_url_domain_full follow_url_handle = follow_url_nickname + '@' + follow_url_domain_full
follow_url_wf = \ follow_url_wf = \
webfinger_handle(session, follow_url_handle, http_prefix, webfinger_handle(session, follow_url_handle, http_prefix,
@ -2524,7 +2525,7 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
if btn == 'block': if btn == 'block':
buttons_str += \ buttons_str += \
'<a href="/users/' + actor_nickname + \ '<a href="/users/' + actor_nickname + \
'?options=' + followUrl + \ '?options=' + follow_url + \
';1;' + avatar_url + \ ';1;' + avatar_url + \
'"><button class="buttonunfollow">' + \ '"><button class="buttonunfollow">' + \
translate['Block'] + '</button></a>\n' translate['Block'] + '</button></a>\n'
@ -2536,7 +2537,7 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
unfollow_str = 'Leave' unfollow_str = 'Leave'
buttons_str += \ buttons_str += \
'<a href="/users/' + actor_nickname + \ '<a href="/users/' + actor_nickname + \
'?options=' + followUrl + \ '?options=' + follow_url + \
';1;' + avatar_url + \ ';1;' + avatar_url + \
'"><button class="buttonunfollow">' + \ '"><button class="buttonunfollow">' + \
translate[unfollow_str] + '</button></a>\n' translate[unfollow_str] + '</button></a>\n'
@ -2544,7 +2545,7 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
result_str = '<div class="container">\n' result_str = '<div class="container">\n'
result_str += \ result_str += \
'<a href="/users/' + actor_nickname + '?options=' + \ '<a href="/users/' + actor_nickname + '?options=' + \
followUrl + ';1;' + avatar_url + '">\n' follow_url + ';1;' + avatar_url + '">\n'
result_str += '<p><img loading="lazy" decoding="async" ' + \ result_str += '<p><img loading="lazy" decoding="async" ' + \
'src="' + avatar_url + '" alt=" ">' 'src="' + avatar_url + '" alt=" ">'
result_str += title_str + '</a>' + buttons_str + '</p>\n' result_str += title_str + '</a>' + buttons_str + '</p>\n'

View File

@ -16,37 +16,37 @@ from utils import acct_dir
def insert_question(base_dir: str, translate: {}, def insert_question(base_dir: str, translate: {},
nickname: str, domain: str, port: int, nickname: str, domain: str, port: int,
content: str, content: str,
post_json_object: {}, pageNumber: int) -> str: post_json_object: {}, page_number: int) -> str:
""" Inserts question selection into a post """ Inserts question selection into a post
""" """
if not is_question(post_json_object): if not is_question(post_json_object):
return content return content
if len(post_json_object['object']['oneOf']) == 0: if len(post_json_object['object']['oneOf']) == 0:
return content return content
messageId = remove_id_ending(post_json_object['id']) message_id = remove_id_ending(post_json_object['id'])
if '#' in messageId: if '#' in message_id:
messageId = messageId.split('#', 1)[0] message_id = message_id.split('#', 1)[0]
pageNumberStr = '' page_number_str = ''
if pageNumber: if page_number:
pageNumberStr = '?page=' + str(pageNumber) page_number_str = '?page=' + str(page_number)
votesFilename = \ votes_filename = \
acct_dir(base_dir, nickname, domain) + '/questions.txt' acct_dir(base_dir, nickname, domain) + '/questions.txt'
showQuestionResults = False show_question_results = False
if os.path.isfile(votesFilename): if os.path.isfile(votes_filename):
if messageId in open(votesFilename).read(): if message_id in open(votes_filename).read():
showQuestionResults = True show_question_results = True
if not showQuestionResults: if not show_question_results:
# show the question options # show the question options
content += '<div class="question">' content += '<div class="question">'
content += \ content += \
'<form method="POST" action="/users/' + \ '<form method="POST" action="/users/' + \
nickname + '/question' + pageNumberStr + '">\n' nickname + '/question' + page_number_str + '">\n'
content += \ content += \
'<input type="hidden" name="messageId" value="' + \ '<input type="hidden" name="messageId" value="' + \
messageId + '">\n<br>\n' message_id + '">\n<br>\n'
for choice in post_json_object['object']['oneOf']: for choice in post_json_object['object']['oneOf']:
if not choice.get('type'): if not choice.get('type'):
continue continue
@ -64,45 +64,43 @@ def insert_question(base_dir: str, translate: {},
content += '<div class="questionresult">\n' content += '<div class="questionresult">\n'
# get the maximum number of votes # get the maximum number of votes
maxVotes = 1 max_votes = 1
for questionOption in post_json_object['object']['oneOf']: for question_option in post_json_object['object']['oneOf']:
if not questionOption.get('name'): if not question_option.get('name'):
continue continue
if not questionOption.get('replies'): if not question_option.get('replies'):
continue continue
votes = 0 votes = 0
try: try:
votes = int(questionOption['replies']['totalItems']) votes = int(question_option['replies']['totalItems'])
except BaseException: except BaseException:
print('EX: insert_question unable to convert to int') print('EX: insert_question unable to convert to int')
if votes > maxVotes: if votes > max_votes:
maxVotes = int(votes+1) max_votes = int(votes+1)
# show the votes as sliders # show the votes as sliders
questionCtr = 1 for question_option in post_json_object['object']['oneOf']:
for questionOption in post_json_object['object']['oneOf']: if not question_option.get('name'):
if not questionOption.get('name'):
continue continue
if not questionOption.get('replies'): if not question_option.get('replies'):
continue continue
votes = 0 votes = 0
try: try:
votes = int(questionOption['replies']['totalItems']) votes = int(question_option['replies']['totalItems'])
except BaseException: except BaseException:
print('EX: insert_question unable to convert to int 2') print('EX: insert_question unable to convert to int 2')
votesPercent = str(int(votes * 100 / maxVotes)) votes_percent = str(int(votes * 100 / max_votes))
content += \ content += \
'<p>\n' + \ '<p>\n' + \
' <label class="labels">' + \ ' <label class="labels">' + \
questionOption['name'] + '</label><br>\n' + \ question_option['name'] + '</label><br>\n' + \
' <svg class="voteresult">\n' + \ ' <svg class="voteresult">\n' + \
' <rect width="' + votesPercent + \ ' <rect width="' + votes_percent + \
'%" class="voteresultbar" />\n' + \ '%" class="voteresultbar" />\n' + \
' </svg>' + \ ' </svg>' + \
' <label class="labels">' + votesPercent + '%</label>\n' + \ ' <label class="labels">' + votes_percent + '%</label>\n' + \
'</p>\n' '</p>\n'
questionCtr += 1
content += '</div>\n' content += '</div>\n'
return content return content

View File

@ -490,30 +490,31 @@ def html_skills_search(actor: str,
continue continue
actor_filename = os.path.join(subdir, fname) actor_filename = os.path.join(subdir, fname)
actor_json = load_json(actor_filename) actor_json = load_json(actor_filename)
if actor_json: if not actor_json:
if actor_json.get('id') and \ continue
no_of_actor_skills(actor_json) > 0 and \ if actor_json.get('id') and \
actor_json.get('name') and \ no_of_actor_skills(actor_json) > 0 and \
actor_json.get('icon'): actor_json.get('name') and \
actor = actor_json['id'] actor_json.get('icon'):
actor_skills_list = actor_json['hasOccupation']['skills'] actor = actor_json['id']
skills = get_skills_from_list(actor_skills_list) actor_skills_list = actor_json['hasOccupation']['skills']
for skill_name, skill_level in skills.items(): skills = get_skills_from_list(actor_skills_list)
skill_name = skill_name.lower() for skill_name, skill_level in skills.items():
if not (skill_name in skillsearch or skill_name = skill_name.lower()
skillsearch in skill_name): if not (skill_name in skillsearch or
continue skillsearch in skill_name):
skill_level_str = str(skill_level) continue
if skill_level < 100: skill_level_str = str(skill_level)
skill_level_str = '0' + skill_level_str if skill_level < 100:
if skill_level < 10: skill_level_str = '0' + skill_level_str
skill_level_str = '0' + skill_level_str if skill_level < 10:
index_str = \ skill_level_str = '0' + skill_level_str
skill_level_str + ';' + actor + ';' + \ index_str = \
actor_json['name'] + \ skill_level_str + ';' + actor + ';' + \
';' + actor_json['icon']['url'] actor_json['name'] + \
if index_str not in results: ';' + actor_json['icon']['url']
results.append(index_str) if index_str not in results:
results.append(index_str)
break break
if not instance_only: if not instance_only:
# search actor cache # search actor cache
@ -525,33 +526,34 @@ def html_skills_search(actor: str,
continue continue
actor_filename = os.path.join(subdir, fname) actor_filename = os.path.join(subdir, fname)
cached_actor_json = load_json(actor_filename) cached_actor_json = load_json(actor_filename)
if cached_actor_json: if not cached_actor_json:
if cached_actor_json.get('actor'): continue
actor_json = cached_actor_json['actor'] if cached_actor_json.get('actor'):
if actor_json.get('id') and \ actor_json = cached_actor_json['actor']
no_of_actor_skills(actor_json) > 0 and \ if actor_json.get('id') and \
actor_json.get('name') and \ no_of_actor_skills(actor_json) > 0 and \
actor_json.get('icon'): actor_json.get('name') and \
actor = actor_json['id'] actor_json.get('icon'):
actor_skills_list = \ actor = actor_json['id']
actor_json['hasOccupation']['skills'] actor_skills_list = \
skills = get_skills_from_list(actor_skills_list) actor_json['hasOccupation']['skills']
for skill_name, skill_level in skills.items(): skills = get_skills_from_list(actor_skills_list)
skill_name = skill_name.lower() for skill_name, skill_level in skills.items():
if not (skill_name in skillsearch or skill_name = skill_name.lower()
skillsearch in skill_name): if not (skill_name in skillsearch or
continue skillsearch in skill_name):
skill_level_str = str(skill_level) continue
if skill_level < 100: skill_level_str = str(skill_level)
skill_level_str = '0' + skill_level_str if skill_level < 100:
if skill_level < 10: skill_level_str = '0' + skill_level_str
skill_level_str = '0' + skill_level_str if skill_level < 10:
index_str = \ skill_level_str = '0' + skill_level_str
skill_level_str + ';' + actor + ';' + \ index_str = \
actor_json['name'] + \ skill_level_str + ';' + actor + ';' + \
';' + actor_json['icon']['url'] actor_json['name'] + \
if index_str not in results: ';' + actor_json['icon']['url']
results.append(index_str) if index_str not in results:
results.append(index_str)
break break
results.sort(reverse=True) results.sort(reverse=True)
@ -616,7 +618,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str,
show_published_date_only: bool, show_published_date_only: bool,
peertube_instances: [], peertube_instances: [],
allow_local_network_access: bool, allow_local_network_access: bool,
theme_name: str, boxName: str, theme_name: str, box_name: str,
system_language: str, system_language: str,
max_like_count: int, max_like_count: int,
signing_priv_key_pem: str, signing_priv_key_pem: str,
@ -632,7 +634,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str,
box_filenames = \ box_filenames = \
search_box_posts(base_dir, nickname, domain, search_box_posts(base_dir, nickname, domain,
historysearch, posts_per_page, boxName) historysearch, posts_per_page, box_name)
css_filename = base_dir + '/epicyon-profile.css' css_filename = base_dir + '/epicyon-profile.css'
if os.path.isfile(base_dir + '/epicyon.css'): if os.path.isfile(base_dir + '/epicyon.css'):
@ -647,7 +649,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str,
domain_full = get_full_domain(domain, port) domain_full = get_full_domain(domain, port)
actor = local_actor_url(http_prefix, nickname, domain_full) actor = local_actor_url(http_prefix, nickname, domain_full)
history_search_title = '🔍 ' + translate['Your Posts'] history_search_title = '🔍 ' + translate['Your Posts']
if boxName == 'bookmarks': if box_name == 'bookmarks':
history_search_title = '🔍 ' + translate['Bookmarks'] history_search_title = '🔍 ' + translate['Bookmarks']
history_search_form += \ history_search_form += \

View File

@ -255,8 +255,7 @@ def html_theme_designer(css_cache: {}, base_dir: str,
variable_name_str = variable_name_str.title() variable_name_str = variable_name_str.title()
variable_name_label = variable_name_str variable_name_label = variable_name_str
if contrast_warning: if contrast_warning:
if variable_name == 'main-bg-color' or \ if variable_name in ('main-bg-color', 'main-fg-color'):
variable_name == 'main-fg-color':
variable_name_label = contrast_warning + variable_name_str variable_name_label = contrast_warning + variable_name_str
font_str += \ font_str += \
' <tr><td><label class="labels">' + \ ' <tr><td><label class="labels">' + \
@ -397,6 +396,4 @@ def color_contrast(background: str, foreground: str) -> float:
foreground_luminance = _relative_luminance(foreground) foreground_luminance = _relative_luminance(foreground)
if background_luminance > foreground_luminance: if background_luminance > foreground_luminance:
return (0.05 + background_luminance) / (0.05 + foreground_luminance) return (0.05 + background_luminance) / (0.05 + foreground_luminance)
else: return (0.05 + foreground_luminance) / (0.05 + background_luminance)
return (0.05 + foreground_luminance) / (0.05 + background_luminance)
return None

View File

@ -433,8 +433,7 @@ def _page_number_buttons(users_path: str, box_name: str,
""" """
pages_width = 3 pages_width = 3
min_page_number = page_number - pages_width min_page_number = page_number - pages_width
if min_page_number < 1: min_page_number = max(min_page_number, 1)
min_page_number = 1
max_page_number = min_page_number + 1 + (pages_width * 2) max_page_number = min_page_number + 1 + (pages_width * 2)
num_str = '' num_str = ''
for page in range(min_page_number, max_page_number): for page in range(min_page_number, max_page_number):
@ -1058,7 +1057,7 @@ def html_timeline(css_cache: {}, default_timeline: str,
def html_individual_share(domain: str, share_id: str, def html_individual_share(domain: str, share_id: str,
actor: str, shared_item: {}, translate: {}, actor: str, shared_item: {}, translate: {},
show_contact: bool, remove_button: bool, show_contact: bool, remove_button: bool,
sharesFileType: str) -> str: shares_file_type: str) -> str:
"""Returns an individual shared item as html """Returns an individual shared item as html
""" """
profile_str = '<div class="container">\n' profile_str = '<div class="container">\n'
@ -1115,7 +1114,7 @@ def html_individual_share(domain: str, share_id: str,
'<a href="' + contact_actor + '"><button class="button">' + \ '<a href="' + contact_actor + '"><button class="button">' + \
translate['Profile'] + '</button></a>\n' translate['Profile'] + '</button></a>\n'
if remove_button and domain in share_id: if remove_button and domain in share_id:
if sharesFileType == 'shares': if shares_file_type == 'shares':
profile_str += \ profile_str += \
' <a href="' + actor + '?rmshare=' + share_id + \ ' <a href="' + actor + '?rmshare=' + share_id + \
'"><button class="button">' + \ '"><button class="button">' + \
@ -1134,14 +1133,14 @@ def _html_shares_timeline(translate: {}, page_number: int, items_per_page: int,
nickname: str, domain: str, port: int, nickname: str, domain: str, port: int,
max_shares_per_account: int, http_prefix: str, max_shares_per_account: int, http_prefix: str,
shared_items_federated_domains: [], shared_items_federated_domains: [],
sharesFileType: str) -> str: shares_file_type: str) -> str:
"""Show shared items timeline as html """Show shared items timeline as html
""" """
shares_json, lastPage = \ shares_json, last_page = \
shares_timeline_json(actor, page_number, items_per_page, shares_timeline_json(actor, page_number, items_per_page,
base_dir, domain, nickname, base_dir, domain, nickname,
max_shares_per_account, max_shares_per_account,
shared_items_federated_domains, sharesFileType) shared_items_federated_domains, shares_file_type)
domain_full = get_full_domain(domain, port) domain_full = get_full_domain(domain, port)
actor = local_actor_url(http_prefix, nickname, domain_full) actor = local_actor_url(http_prefix, nickname, domain_full)
admin_nickname = get_config_param(base_dir, 'admin') admin_nickname = get_config_param(base_dir, 'admin')
@ -1153,10 +1152,10 @@ def _html_shares_timeline(translate: {}, page_number: int, items_per_page: int,
if page_number > 1: if page_number > 1:
timeline_str += '<br>' + \ timeline_str += '<br>' + \
_page_number_buttons(actor, 'tl' + sharesFileType, page_number) _page_number_buttons(actor, 'tl' + shares_file_type, page_number)
timeline_str += \ timeline_str += \
' <center>\n' + \ ' <center>\n' + \
' <a href="' + actor + '/tl' + sharesFileType + '?page=' + \ ' <a href="' + actor + '/tl' + shares_file_type + '?page=' + \
str(page_number - 1) + \ str(page_number - 1) + \
'#timelineposts" class="imageAnchor" tabindex="9">' + \ '#timelineposts" class="imageAnchor" tabindex="9">' + \
'<img loading="lazy" decoding="async" ' + \ '<img loading="lazy" decoding="async" ' + \
@ -1188,17 +1187,18 @@ def _html_shares_timeline(translate: {}, page_number: int, items_per_page: int,
html_individual_share(domain, shared_item['shareId'], html_individual_share(domain, shared_item['shareId'],
actor, shared_item, translate, actor, shared_item, translate,
show_contact_button, show_remove_button, show_contact_button, show_remove_button,
sharesFileType) shares_file_type)
timeline_str += separator_str timeline_str += separator_str
ctr += 1 ctr += 1
if ctr == 0: if ctr == 0:
timeline_str += _get_help_for_timeline(base_dir, 'tl' + sharesFileType) timeline_str += \
_get_help_for_timeline(base_dir, 'tl' + shares_file_type)
if not lastPage: if not last_page:
timeline_str += \ timeline_str += \
' <center>\n' + \ ' <center>\n' + \
' <a href="' + actor + '/tl' + sharesFileType + '?page=' + \ ' <a href="' + actor + '/tl' + shares_file_type + '?page=' + \
str(page_number + 1) + \ str(page_number + 1) + \
'#timelineposts" class="imageAnchor" tabindex="9">' + \ '#timelineposts" class="imageAnchor" tabindex="9">' + \
'<img loading="lazy" decoding="async" ' + \ '<img loading="lazy" decoding="async" ' + \
@ -1207,7 +1207,7 @@ def _html_shares_timeline(translate: {}, page_number: int, items_per_page: int,
'" alt="' + translate['Page down'] + '"></a>\n' + \ '" alt="' + translate['Page down'] + '"></a>\n' + \
' </center>\n' ' </center>\n'
timeline_str += \ timeline_str += \
_page_number_buttons(actor, 'tl' + sharesFileType, page_number) _page_number_buttons(actor, 'tl' + shares_file_type, page_number)
timeline_str += '<br>' timeline_str += '<br>'
return timeline_str return timeline_str
@ -1338,7 +1338,7 @@ def html_inbox(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1372,7 +1372,7 @@ def html_inbox(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, nickname, domain, port, inbox_json,
'inbox', allow_deletion, 'inbox', allow_deletion,
http_prefix, project_version, http_prefix, project_version,
manually_approve_followers, manually_approve_followers,
@ -1399,7 +1399,7 @@ def html_bookmarks(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, bookmarksJson: {}, nickname: str, domain: str, port: int, bookmarks_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1433,7 +1433,7 @@ def html_bookmarks(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, bookmarksJson, nickname, domain, port, bookmarks_json,
'tlbookmarks', allow_deletion, 'tlbookmarks', allow_deletion,
http_prefix, project_version, http_prefix, project_version,
manually_approve_followers, manually_approve_followers,
@ -1459,7 +1459,7 @@ def html_inbox_dms(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1490,7 +1490,7 @@ def html_inbox_dms(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, nickname, domain, port, inbox_json,
'dm', allow_deletion, 'dm', allow_deletion,
http_prefix, project_version, False, minimal, http_prefix, project_version, False, minimal,
yt_replace_domain, yt_replace_domain,
@ -1515,7 +1515,7 @@ def html_inbox_replies(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1546,7 +1546,7 @@ def html_inbox_replies(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, 'tlreplies', nickname, domain, port, inbox_json, 'tlreplies',
allow_deletion, http_prefix, project_version, False, allow_deletion, http_prefix, project_version, False,
minimal, minimal,
yt_replace_domain, yt_replace_domain,
@ -1569,7 +1569,7 @@ def html_inbox_media(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1600,7 +1600,7 @@ def html_inbox_media(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, 'tlmedia', nickname, domain, port, inbox_json, 'tlmedia',
allow_deletion, http_prefix, project_version, False, allow_deletion, http_prefix, project_version, False,
minimal, minimal,
yt_replace_domain, yt_replace_domain,
@ -1623,7 +1623,7 @@ def html_inbox_blogs(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1654,7 +1654,7 @@ def html_inbox_blogs(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, 'tlblogs', nickname, domain, port, inbox_json, 'tlblogs',
allow_deletion, http_prefix, project_version, False, allow_deletion, http_prefix, project_version, False,
minimal, minimal,
yt_replace_domain, yt_replace_domain,
@ -1677,7 +1677,7 @@ def html_inbox_features(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1708,7 +1708,7 @@ def html_inbox_features(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, 'tlfeatures', nickname, domain, port, inbox_json, 'tlfeatures',
allow_deletion, http_prefix, project_version, False, allow_deletion, http_prefix, project_version, False,
minimal, minimal,
yt_replace_domain, yt_replace_domain,
@ -1731,7 +1731,7 @@ def html_inbox_news(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, inboxJson: {}, nickname: str, domain: str, port: int, inbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1761,7 +1761,7 @@ def html_inbox_news(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, inboxJson, 'tlnews', nickname, domain, port, inbox_json, 'tlnews',
allow_deletion, http_prefix, project_version, False, allow_deletion, http_prefix, project_version, False,
minimal, minimal,
yt_replace_domain, yt_replace_domain,
@ -1784,7 +1784,7 @@ def html_outbox(css_cache: {}, default_timeline: str,
translate: {}, page_number: int, items_per_page: int, translate: {}, page_number: int, items_per_page: int,
session, base_dir: str, session, base_dir: str,
cached_webfingers: {}, person_cache: {}, cached_webfingers: {}, person_cache: {},
nickname: str, domain: str, port: int, outboxJson: {}, nickname: str, domain: str, port: int, outbox_json: {},
allow_deletion: bool, allow_deletion: bool,
http_prefix: str, project_version: str, http_prefix: str, project_version: str,
minimal: bool, minimal: bool,
@ -1817,7 +1817,7 @@ def html_outbox(css_cache: {}, default_timeline: str,
translate, page_number, translate, page_number,
items_per_page, session, base_dir, items_per_page, session, base_dir,
cached_webfingers, person_cache, cached_webfingers, person_cache,
nickname, domain, port, outboxJson, 'outbox', nickname, domain, port, outbox_json, 'outbox',
allow_deletion, http_prefix, project_version, allow_deletion, http_prefix, project_version,
manually_approve_followers, minimal, manually_approve_followers, minimal,
yt_replace_domain, yt_replace_domain,

View File

@ -457,8 +457,7 @@ def shares_timeline_json(actor: str, pageNumber: int, items_per_page: int,
if start_index >= max_index - items_per_page: if start_index >= max_index - items_per_page:
last_page = True last_page = True
start_index = max_index - items_per_page start_index = max_index - items_per_page
if start_index < 0: start_index = max(start_index, 0)
start_index = 0
ctr = 0 ctr = 0
result_json = {} result_json = {}
for published, item in shares_json.items(): for published, item in shares_json.items():