merge-requests/25/head
Bob Mottram 2022-05-30 19:33:51 +01:00
parent 865c316254
commit 967cd84ce7
12 changed files with 145 additions and 143 deletions

View File

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

View File

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

View File

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

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,
http_prefix: str, translate: {},
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,
front_page: bool, theme: str,
access_keys: {},
@ -146,7 +146,7 @@ def get_left_column_content(base_dir: str, nickname: str, domain_full: str,
if show_back_button:
html_str += \
' <div> <a href="' + timelinePath + '">' + \
' <div> <a href="' + timeline_path + '">' + \
'<button class="cancelbtn">' + \
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,
nickname: str, domain_full: str,
http_prefix: str, translate,
timelinePath: str, authorized: bool,
timeline_path: str, authorized: bool,
rss_icon_at_top: bool,
icons_as_buttons: bool,
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,
http_prefix, translate,
editor, artist,
False, timelinePath,
False, timeline_path,
rss_icon_at_top, False, False,
theme, access_keys,
shared_items_federated_domains)

View File

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

View File

@ -40,7 +40,7 @@ def html_likers_of_post(base_dir: str, nickname: str,
system_language: str,
max_like_count: int, signing_priv_key_pem: str,
cw_lists: {}, lists_enabled: str,
boxName: str, default_timeline: str,
box_name: str, default_timeline: str,
bold_reading: bool,
dict_name: str = 'likes') -> str:
"""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,
http_prefix,
project_version,
boxName,
box_name,
yt_replace_domain,
twitter_replacement_domain,
show_published_date_only,

View File

@ -118,7 +118,7 @@ def _html_podcast_transcripts(podcast_properties: {}, translate: {}) -> str:
return ''
ctr = 1
html_str = ''
for transcript in podcast_properties[key]:
for _ in podcast_properties[key]:
transcript_url = None
if podcast_properties[key].get('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,
debugId: str) -> None:
debug_id: str) -> None:
"""Create a log of timings for performance tuning
"""
if not enable_timing_log:
return
time_diff = int((time.time() - post_start_time) * 1000)
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:
@ -374,7 +374,7 @@ def _get_post_from_recent_cache(session,
return post_html
def _get_avatar_image_html(showAvatarOptions: bool,
def _get_avatar_image_html(show_avatar_options: bool,
nickname: str, domain_full: str,
avatar_url: str, post_actor: str,
translate: {}, avatar_position: str,
@ -399,7 +399,7 @@ def _get_avatar_image_html(showAvatarOptions: bool,
show_profile_str + '" alt=" "' + avatar_position + \
get_broken_link_substitute() + '/></a>\n'
if showAvatarOptions and \
if show_avatar_options and \
domain_full + '/users/' + nickname not in post_actor:
show_options_for_this_person_str = 'Show options for this person'
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,
post_json_object: {}, actor_nickname: str,
translate: {}, isEvent: bool) -> str:
translate: {}, is_event: bool) -> str:
"""Returns html for the edit icon/button
"""
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="' + \
edit_blog_post_str + '" alt="' + edit_blog_post_str + \
' |" src="/icons/edit.png"/></a>\n'
elif isEvent:
elif is_event:
edit_event_str = 'Edit event'
if translate.get(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: {},
nickname: str, domain: str, port: int,
post_json_object: {},
avatar_url: str, showAvatarOptions: bool,
avatar_url: str, show_avatar_options: bool,
allow_deletion: bool,
http_prefix: str, project_version: 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')
avatar_link = \
_get_avatar_image_html(showAvatarOptions,
_get_avatar_image_html(show_avatar_options,
nickname, domain_full,
avatar_url, post_actor,
translate, avatar_position,

View File

@ -613,7 +613,7 @@ def html_profile(signing_priv_key_pem: str,
debug: bool, access_keys: {}, city: str,
system_language: str, max_like_count: int,
shared_items_federated_domains: [],
extraJson: {}, page_number: int,
extra_json: {}, page_number: int,
max_items_per_page: int,
cw_lists: {}, lists_enabled: str,
content_license_url: str,
@ -636,7 +636,7 @@ def html_profile(signing_priv_key_pem: str,
yt_replace_domain,
twitter_replacement_domain,
show_published_date_only,
newswire, theme, extraJson,
newswire, theme, extra_json,
allow_local_network_access, access_keys,
system_language, max_like_count,
shared_items_federated_domains, None,
@ -1042,7 +1042,7 @@ def html_profile(signing_priv_key_pem: str,
authorized, nickname,
domain, port, session,
cached_webfingers,
person_cache, extraJson,
person_cache, extra_json,
project_version, ["unfollow"],
selected,
users_path, page_number,
@ -1055,7 +1055,7 @@ def html_profile(signing_priv_key_pem: str,
authorized, nickname,
domain, port, session,
cached_webfingers,
person_cache, extraJson,
person_cache, extra_json,
project_version, ["block"],
selected, users_path, page_number,
max_items_per_page, dormant_months, debug,
@ -1064,21 +1064,21 @@ def html_profile(signing_priv_key_pem: str,
if selected == 'roles':
profile_str += \
_html_profile_roles(translate, nickname, domain_full,
extraJson)
extra_json)
elif selected == 'skills':
profile_str += \
_html_profile_skills(translate, nickname, domain_full,
extraJson)
extra_json)
# elif selected == 'shares':
# profile_str += \
# _html_profile_shares(actor, translate,
# nickname, domain_full,
# extraJson, 'shares') + license_str
# extra_json, 'shares') + license_str
# elif selected == 'wanted':
# profile_str += \
# _html_profile_shares(actor, translate,
# nickname, domain_full,
# extraJson, 'wanted') + license_str
# extra_json, 'wanted') + license_str
# end of #timeline
profile_str += '</div>'
@ -1232,13 +1232,13 @@ def _html_profile_following(translate: {}, base_dir: str, http_prefix: str,
def _html_profile_roles(translate: {}, nickname: str, domain: str,
rolesList: []) -> str:
roles_list: []) -> str:
"""Shows roles on the profile screen
"""
profile_str = ''
profile_str += \
'<div class="roles">\n<div class="roles-inner">\n'
for role in rolesList:
for role in roles_list:
if translate.get(role):
profile_str += '<h3>' + translate[role] + '</h3>\n'
else:
@ -2462,7 +2462,7 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
base_dir: str, session,
cached_webfingers: {},
person_cache: {}, domain: str,
followUrl: str,
follow_url: str,
authorized: bool,
actor_nickname: str,
http_prefix: str,
@ -2472,21 +2472,22 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
buttons=[]) -> str:
"""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:
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 = \
get_full_domain(follow_url_domain, follow_url_port)
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:
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
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_wf = \
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':
buttons_str += \
'<a href="/users/' + actor_nickname + \
'?options=' + followUrl + \
'?options=' + follow_url + \
';1;' + avatar_url + \
'"><button class="buttonunfollow">' + \
translate['Block'] + '</button></a>\n'
@ -2536,7 +2537,7 @@ def _individual_follow_as_html(signing_priv_key_pem: str,
unfollow_str = 'Leave'
buttons_str += \
'<a href="/users/' + actor_nickname + \
'?options=' + followUrl + \
'?options=' + follow_url + \
';1;' + avatar_url + \
'"><button class="buttonunfollow">' + \
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 += \
'<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" ' + \
'src="' + avatar_url + '" alt=" ">'
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: {},
nickname: str, domain: str, port: int,
content: str,
post_json_object: {}, pageNumber: int) -> str:
post_json_object: {}, page_number: int) -> str:
""" Inserts question selection into a post
"""
if not is_question(post_json_object):
return content
if len(post_json_object['object']['oneOf']) == 0:
return content
messageId = remove_id_ending(post_json_object['id'])
if '#' in messageId:
messageId = messageId.split('#', 1)[0]
pageNumberStr = ''
if pageNumber:
pageNumberStr = '?page=' + str(pageNumber)
message_id = remove_id_ending(post_json_object['id'])
if '#' in message_id:
message_id = message_id.split('#', 1)[0]
page_number_str = ''
if page_number:
page_number_str = '?page=' + str(page_number)
votesFilename = \
votes_filename = \
acct_dir(base_dir, nickname, domain) + '/questions.txt'
showQuestionResults = False
if os.path.isfile(votesFilename):
if messageId in open(votesFilename).read():
showQuestionResults = True
show_question_results = False
if os.path.isfile(votes_filename):
if message_id in open(votes_filename).read():
show_question_results = True
if not showQuestionResults:
if not show_question_results:
# show the question options
content += '<div class="question">'
content += \
'<form method="POST" action="/users/' + \
nickname + '/question' + pageNumberStr + '">\n'
nickname + '/question' + page_number_str + '">\n'
content += \
'<input type="hidden" name="messageId" value="' + \
messageId + '">\n<br>\n'
message_id + '">\n<br>\n'
for choice in post_json_object['object']['oneOf']:
if not choice.get('type'):
continue
@ -64,45 +64,43 @@ def insert_question(base_dir: str, translate: {},
content += '<div class="questionresult">\n'
# get the maximum number of votes
maxVotes = 1
for questionOption in post_json_object['object']['oneOf']:
if not questionOption.get('name'):
max_votes = 1
for question_option in post_json_object['object']['oneOf']:
if not question_option.get('name'):
continue
if not questionOption.get('replies'):
if not question_option.get('replies'):
continue
votes = 0
try:
votes = int(questionOption['replies']['totalItems'])
votes = int(question_option['replies']['totalItems'])
except BaseException:
print('EX: insert_question unable to convert to int')
if votes > maxVotes:
maxVotes = int(votes+1)
if votes > max_votes:
max_votes = int(votes+1)
# show the votes as sliders
questionCtr = 1
for questionOption in post_json_object['object']['oneOf']:
if not questionOption.get('name'):
for question_option in post_json_object['object']['oneOf']:
if not question_option.get('name'):
continue
if not questionOption.get('replies'):
if not question_option.get('replies'):
continue
votes = 0
try:
votes = int(questionOption['replies']['totalItems'])
votes = int(question_option['replies']['totalItems'])
except BaseException:
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 += \
'<p>\n' + \
' <label class="labels">' + \
questionOption['name'] + '</label><br>\n' + \
question_option['name'] + '</label><br>\n' + \
' <svg class="voteresult">\n' + \
' <rect width="' + votesPercent + \
' <rect width="' + votes_percent + \
'%" class="voteresultbar" />\n' + \
' </svg>' + \
' <label class="labels">' + votesPercent + '%</label>\n' + \
' <label class="labels">' + votes_percent + '%</label>\n' + \
'</p>\n'
questionCtr += 1
content += '</div>\n'
return content

View File

@ -490,30 +490,31 @@ def html_skills_search(actor: str,
continue
actor_filename = os.path.join(subdir, fname)
actor_json = load_json(actor_filename)
if actor_json:
if actor_json.get('id') and \
no_of_actor_skills(actor_json) > 0 and \
actor_json.get('name') and \
actor_json.get('icon'):
actor = actor_json['id']
actor_skills_list = actor_json['hasOccupation']['skills']
skills = get_skills_from_list(actor_skills_list)
for skill_name, skill_level in skills.items():
skill_name = skill_name.lower()
if not (skill_name in skillsearch or
skillsearch in skill_name):
continue
skill_level_str = str(skill_level)
if skill_level < 100:
skill_level_str = '0' + skill_level_str
if skill_level < 10:
skill_level_str = '0' + skill_level_str
index_str = \
skill_level_str + ';' + actor + ';' + \
actor_json['name'] + \
';' + actor_json['icon']['url']
if index_str not in results:
results.append(index_str)
if not actor_json:
continue
if actor_json.get('id') and \
no_of_actor_skills(actor_json) > 0 and \
actor_json.get('name') and \
actor_json.get('icon'):
actor = actor_json['id']
actor_skills_list = actor_json['hasOccupation']['skills']
skills = get_skills_from_list(actor_skills_list)
for skill_name, skill_level in skills.items():
skill_name = skill_name.lower()
if not (skill_name in skillsearch or
skillsearch in skill_name):
continue
skill_level_str = str(skill_level)
if skill_level < 100:
skill_level_str = '0' + skill_level_str
if skill_level < 10:
skill_level_str = '0' + skill_level_str
index_str = \
skill_level_str + ';' + actor + ';' + \
actor_json['name'] + \
';' + actor_json['icon']['url']
if index_str not in results:
results.append(index_str)
break
if not instance_only:
# search actor cache
@ -525,33 +526,34 @@ def html_skills_search(actor: str,
continue
actor_filename = os.path.join(subdir, fname)
cached_actor_json = load_json(actor_filename)
if cached_actor_json:
if cached_actor_json.get('actor'):
actor_json = cached_actor_json['actor']
if actor_json.get('id') and \
no_of_actor_skills(actor_json) > 0 and \
actor_json.get('name') and \
actor_json.get('icon'):
actor = actor_json['id']
actor_skills_list = \
actor_json['hasOccupation']['skills']
skills = get_skills_from_list(actor_skills_list)
for skill_name, skill_level in skills.items():
skill_name = skill_name.lower()
if not (skill_name in skillsearch or
skillsearch in skill_name):
continue
skill_level_str = str(skill_level)
if skill_level < 100:
skill_level_str = '0' + skill_level_str
if skill_level < 10:
skill_level_str = '0' + skill_level_str
index_str = \
skill_level_str + ';' + actor + ';' + \
actor_json['name'] + \
';' + actor_json['icon']['url']
if index_str not in results:
results.append(index_str)
if not cached_actor_json:
continue
if cached_actor_json.get('actor'):
actor_json = cached_actor_json['actor']
if actor_json.get('id') and \
no_of_actor_skills(actor_json) > 0 and \
actor_json.get('name') and \
actor_json.get('icon'):
actor = actor_json['id']
actor_skills_list = \
actor_json['hasOccupation']['skills']
skills = get_skills_from_list(actor_skills_list)
for skill_name, skill_level in skills.items():
skill_name = skill_name.lower()
if not (skill_name in skillsearch or
skillsearch in skill_name):
continue
skill_level_str = str(skill_level)
if skill_level < 100:
skill_level_str = '0' + skill_level_str
if skill_level < 10:
skill_level_str = '0' + skill_level_str
index_str = \
skill_level_str + ';' + actor + ';' + \
actor_json['name'] + \
';' + actor_json['icon']['url']
if index_str not in results:
results.append(index_str)
break
results.sort(reverse=True)
@ -616,7 +618,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str,
show_published_date_only: bool,
peertube_instances: [],
allow_local_network_access: bool,
theme_name: str, boxName: str,
theme_name: str, box_name: str,
system_language: str,
max_like_count: int,
signing_priv_key_pem: str,
@ -632,7 +634,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str,
box_filenames = \
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'
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)
actor = local_actor_url(http_prefix, nickname, domain_full)
history_search_title = '🔍 ' + translate['Your Posts']
if boxName == 'bookmarks':
if box_name == 'bookmarks':
history_search_title = '🔍 ' + translate['Bookmarks']
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_label = variable_name_str
if contrast_warning:
if variable_name == 'main-bg-color' or \
variable_name == 'main-fg-color':
if variable_name in ('main-bg-color', 'main-fg-color'):
variable_name_label = contrast_warning + variable_name_str
font_str += \
' <tr><td><label class="labels">' + \
@ -397,6 +396,4 @@ def color_contrast(background: str, foreground: str) -> float:
foreground_luminance = _relative_luminance(foreground)
if background_luminance > foreground_luminance:
return (0.05 + background_luminance) / (0.05 + foreground_luminance)
else:
return (0.05 + foreground_luminance) / (0.05 + background_luminance)
return None
return (0.05 + foreground_luminance) / (0.05 + background_luminance)