Merge branch 'main' of gitlab.com:bashrc2/epicyon

merge-requests/30/head
Bob Mottram 2022-06-14 17:20:57 +01:00
commit c088283d03
16 changed files with 571 additions and 168 deletions

View File

@ -324,7 +324,7 @@ def _save_custom_emoji(session, base_dir: str, emojiName: str, url: str,
if not os.path.isdir(custom_emoji_dir):
os.mkdir(custom_emoji_dir)
emoji_image_filename = custom_emoji_dir + '/' + emojiName + '.' + ext
if not download_image(session, base_dir, url,
if not download_image(session, url,
emoji_image_filename, debug, False):
if debug:
print('EX: custom emoji not downloaded ' + url)
@ -1573,7 +1573,7 @@ def import_emoji(base_dir: str, import_filename: str, session) -> None:
emoji_image_filename = base_dir + '/emoji/' + tag + '.png'
if os.path.isfile(emoji_image_filename):
continue
if download_image(session, base_dir, url,
if download_image(session, url,
emoji_image_filename, True, False):
emoji_dict[tag] = tag
added += 1

View File

@ -852,12 +852,10 @@ def _desktop_show_actor(base_dir: str, actor_json: {}, translate: {},
def _desktop_show_profile(session, nickname: str, domain: str,
http_prefix: str, base_dir: str, box_name: str,
page_number: int, index: int, box_json: {},
base_dir: str, index: int, box_json: {},
system_language: str,
screenreader: str, espeak,
translate: {}, your_actor: str,
post_json_object: {},
translate: {}, post_json_object: {},
signing_priv_key_pem: str) -> {}:
"""Shows the profile of the actor for the given post
Returns the actor json
@ -901,13 +899,10 @@ def _desktop_show_profile(session, nickname: str, domain: str,
return actor_json
def _desktop_show_profile_from_handle(session, nickname: str, domain: str,
http_prefix: str, base_dir: str,
box_name: str, handle: str,
system_language: str,
def _desktop_show_profile_from_handle(session, domain: str, base_dir: str,
handle: str, system_language: str,
screenreader: str, espeak,
translate: {}, your_actor: str,
post_json_object: {},
translate: {},
signing_priv_key_pem: str) -> {}:
"""Shows the profile for a handle
Returns the actor json
@ -985,9 +980,7 @@ def _desktop_show_box(indent: str,
your_actor: str, box_name: str, box_json: {},
translate: {},
screenreader: str, system_language: str, espeak,
page_number: int,
new_replies: bool,
new_dms: bool) -> bool:
page_number: int) -> bool:
"""Shows online timeline
"""
number_width = 2
@ -1429,8 +1422,6 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
content = None
cached_webfingers = {}
person_cache = {}
new_replies_exist = False
new_dms_exist = False
pgp_key_upload = False
say_str = indent + 'Loading translations file'
@ -1502,12 +1493,9 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
signing_priv_key_pem)
else:
inbox_json = box_json
new_dms_exist = False
new_replies_exist = False
if inbox_json:
_new_desktop_notifications(your_actor, inbox_json, notify_json)
if notify_json.get('dmNotify'):
new_dms_exist = True
if notify_json.get('dmNotifyChanged'):
_desktop_notification(notification_type,
"Epicyon",
@ -1515,7 +1503,6 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
if notification_sounds:
_play_notification_sound(dm_sound_filename, player)
if notify_json.get('repliesNotify'):
new_replies_exist = True
if notify_json.get('repliesNotifyChanged'):
_desktop_notification(notification_type,
"Epicyon",
@ -1532,9 +1519,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
None, system_language, espeak,
page_number,
new_replies_exist,
new_dms_exist)
page_number)
desktop_shown = True
prev_timeline_first_id = timeline_first_id
else:
@ -1580,9 +1565,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
screenreader, system_language, espeak,
page_number,
new_replies_exist, new_dms_exist)
new_dms_exist = False
page_number)
elif command_str.startswith('show rep'):
page_number = 1
prev_timeline_first_id = ''
@ -1596,10 +1579,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
screenreader, system_language, espeak,
page_number,
new_replies_exist, new_dms_exist)
# Turn off the replies indicator
new_replies_exist = False
page_number)
elif command_str.startswith('show b'):
page_number = 1
prev_timeline_first_id = ''
@ -1613,10 +1593,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
screenreader, system_language, espeak,
page_number,
new_replies_exist, new_dms_exist)
# Turn off the replies indicator
new_replies_exist = False
page_number)
elif (command_str.startswith('show sen') or
command_str.startswith('show out')):
page_number = 1
@ -1631,8 +1608,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
screenreader, system_language, espeak,
page_number,
new_replies_exist, new_dms_exist)
page_number)
elif (command_str == 'show' or command_str.startswith('show in') or
command_str == 'clear'):
page_number = 1
@ -1656,8 +1632,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
screenreader, system_language, espeak,
page_number,
new_replies_exist, new_dms_exist)
page_number)
elif (command_str.startswith('read ') or
command_str.startswith('show ') or
command_str == 'read' or
@ -1699,14 +1674,11 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
if post_json_object:
actor_json = \
_desktop_show_profile(session, nickname, domain,
http_prefix, base_dir,
curr_timeline,
page_number, post_index,
base_dir, post_index,
box_json,
system_language,
screenreader,
espeak, translate,
your_actor,
post_json_object,
signing_priv_key_pem)
else:
@ -1718,16 +1690,12 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
profile_handle = post_index_str
_desktop_clear_screen()
_desktop_show_banner()
_desktop_show_profile_from_handle(session,
nickname, domain,
http_prefix, base_dir,
curr_timeline,
_desktop_show_profile_from_handle(session, domain,
base_dir,
profile_handle,
system_language,
screenreader,
espeak, translate,
your_actor,
None,
signing_priv_key_pem)
say_str = 'Press Enter to continue...'
say_str2 = _highlight_text(say_str)
@ -1742,12 +1710,10 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
post_index = int(post_index_str)
actor_json = \
_desktop_show_profile(session, nickname, domain,
http_prefix, base_dir,
curr_timeline,
page_number, post_index,
base_dir, post_index,
box_json,
system_language, screenreader,
espeak, translate, your_actor,
espeak, translate,
None, signing_priv_key_pem)
say_str = 'Press Enter to continue...'
say_str2 = _highlight_text(say_str)
@ -2581,5 +2547,4 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str,
your_actor, curr_timeline, box_json,
translate,
screenreader, system_language,
espeak, page_number,
new_replies_exist, new_dms_exist)
espeak, page_number)

View File

@ -353,8 +353,7 @@ def _dav_encode_token(year: int, month_number: int,
def _icalendar_day(base_dir: str, nickname: str, domain: str,
day_events: [], person_cache: {},
http_prefix: str) -> str:
day_events: [], person_cache: {}) -> str:
"""Returns a day's events in icalendar format
"""
ical_str = ''
@ -478,7 +477,6 @@ def _icalendar_day(base_dir: str, nickname: str, domain: str,
def get_todays_events_icalendar(base_dir: str, nickname: str, domain: str,
year: int, month_number: int,
day_number: int, person_cache: {},
http_prefix: str,
text_match: str, system_language: str) -> str:
"""Returns today's events in icalendar format
"""
@ -503,8 +501,7 @@ def get_todays_events_icalendar(base_dir: str, nickname: str, domain: str,
return ical_str
ical_str += \
_icalendar_day(base_dir, nickname, domain, day_events, person_cache,
http_prefix)
_icalendar_day(base_dir, nickname, domain, day_events, person_cache)
ical_str += 'END:VCALENDAR\n'
return ical_str
@ -514,7 +511,6 @@ def get_month_events_icalendar(base_dir: str, nickname: str, domain: str,
year: int,
month_number: int,
person_cache: {},
http_prefix: str,
text_match: str) -> str:
"""Returns today's events in icalendar format
"""
@ -537,8 +533,7 @@ def get_month_events_icalendar(base_dir: str, nickname: str, domain: str,
day_events = month_events[str(day_of_month)]
ical_str += \
_icalendar_day(base_dir, nickname, domain,
day_events, person_cache,
http_prefix)
day_events, person_cache)
ical_str += 'END:VCALENDAR\n'
return ical_str
@ -1098,7 +1093,7 @@ def dav_report_response(base_dir: str, nickname: str, domain: str,
search_date.year,
search_date.month,
search_date.day, person_cache,
http_prefix, text_match,
text_match,
system_language)
events_href = \
http_prefix + '://' + domain_full + '/users/' + \
@ -1132,7 +1127,6 @@ def dav_report_response(base_dir: str, nickname: str, domain: str,
query_start_year,
query_start_month,
person_cache,
http_prefix,
text_match)
events_href = \
http_prefix + '://' + domain_full + '/users/' + \
@ -1180,7 +1174,6 @@ def dav_report_response(base_dir: str, nickname: str, domain: str,
nickname, domain,
year, month,
person_cache,
http_prefix,
text_match)
events_href = \
http_prefix + '://' + domain_full + '/users/' + \
@ -1217,7 +1210,7 @@ def dav_report_response(base_dir: str, nickname: str, domain: str,
get_todays_events_icalendar(base_dir, nickname, domain,
search_date.year, search_date.month,
search_date.day, person_cache,
http_prefix, text_match,
text_match,
system_language)
events_href = \
http_prefix + '://' + domain_full + '/users/' + \

484
img/logo.svg 100644
View File

@ -0,0 +1,484 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="2048"
height="2048"
viewBox="0 0 2048 2048"
sodipodi:docname="logo.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs6" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.29248047"
inkscape:cx="871.85309"
inkscape:cy="1022.2905"
inkscape:window-width="1080"
inkscape:window-height="1836"
inkscape:window-x="0"
inkscape:window-y="29"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8">
<image
width="2048"
height="2048"
preserveAspectRatio="none"
style="image-rendering:optimizeQuality"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACAAAAAgAAQMAAACIaUFzAAADJ3pUWHRSYXcgcHJvZmlsZSB0eXBl
IGV4aWYAAHja7ZdLchwhDIb3nCJHQBJC4jg0NFW5QY6fH/phz9jluCpZZDFQDYwaJKFP0HbYf/0c
4QcKx+QhqXkuOUeUVFLhioHHo2yrpZhWexU/pQ/ycL9giAS9HC8Kn8t2yOd4nPLTCF3zb0XngCpG
+vaiXgu2R/l26md/VnR6IHRa7ueCU5HwIad0/G756HNxe9har++2cEXgfDIjensmY8NOs+SRO6rm
3Zba7TQ6PQ7PghV0Q9i7whFh3oUkohU5PZT5sFT0GS1JwjwK64dCOF/oCnoERo4Gr89tjIsiAvk+
Lu9IHh49ly+3VKB4n24/Kgz38DFX6LNcuUdPqQKH6VAkjyhjvvtP5aRPcrk8moDfWfZ8W36Qm9wm
4jPhMEb3sTaNXdSUwSufm7q2skaYh1xMspZlVMOjGNuqJSB4HmtsSLgeGxJ3w7gQg/mgRJ0qDdpX
36jBxcQ7G3rmxrJkLsYlcAN25MKsNNikSBdHnrSVO0n49oVgdNa2jDkMd8JMJihDHvG/qV8qGqPN
EFH0O1bwi+eJhBuT3GwxC0ACjTOougJ81ecyuQoI6gqzY4M1boeKTWll9pFcskALJir646ST9VMB
QgTbCmdIQCBmEqVM0ZiNCHF0CgU4ojNO3gYEpModTnISyYDjPG1jjZGDZWXlQ4ybFCAUJ9WApkgN
gJWSIn8sOXKoqmhS1aymrkUrTlrCKcvZ8rySq4klU8tm5lasunhy9Rzc3L14LVwEV7aWXKx4KaVW
GK3QXLG6YkKtG2+ypU23vNnmW9lqQ/a01LTl0Kx5K6127tJxCeGYW/deet1pRyrtadcdx373vex1
INWGjDR05GHDRxn1jdqJ9UP9PjW6qPEiNSfaTQ1Ss0sFzetEJzMQ40QgbpMAIbEns+iBUuJJbjLD
NwinQhlO6oTTaRIDwbQT66Cb3Ru5m1tAPP+WG09yYaL7F+TCRPcFuY/cPqE2P2kBl4IsQvMYzqBG
welrvbJX3nBf+Bx4nd/Wr/rwpwnf7V+KXopeil6KXopeil6K/lNF+OMB/wSG33A4w46juleIAAAB
hWlDQ1BJQ0MgcHJvZmlsZQAAeJx9kT1Iw0AcxV9TtUWqHewg4pChOlnwC3HUKhShQqkVWnUwufRD
aNKQpLg4Cq4FBz8Wqw4uzro6uAqC4AeIo5OToouU+L+k0CLGg+N+vLv3uHsHCPUyU82OUUDVLCOd
iIvZ3IoYeEUXehHGGIISM/XZVCoJz/F1Dx9f72I8y/vcn6NHyZsM8InEM0w3LOJ14qlNS+e8Txxh
JUkhPiceMeiCxI9cl11+41x0WOCZESOTniOOEIvFNpbbmJUMlXiSOKqoGuULWZcVzluc1XKVNe/J
XxjKa8tLXKc5iAQWsIgURMioYgNlWIjRqpFiIk37cQ//gONPkUsm1wYYOeZRgQrJ8YP/we9uzcLE
uJsUigOdL7b9MQQEdoFGzba/j227cQL4n4ErreWv1IHpT9JrLS16BIS3gYvrlibvAZc7QP+TLhmS
I/lpCoUC8H5G35QD+m6B7lW3t+Y+Th+ADHWVvAEODoHhImWvebw72N7bv2ea/f0AVTtymzJac7AA
AA7gaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1
TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1l
dGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9
Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVz
Y3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNv
bS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8x
LjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2Rj
L2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8i
CiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5z
OnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0i
Z2ltcDpkb2NpZDpnaW1wOjdmNTU4YTVkLTAyZTAtNGZiZi04NjJiLTc5M2Q2ZjZjN2M3NSIKICAg
eG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMDMwZWFkYy1kM2YyLTRmZWItYWVlZS0wYTQwYjVk
OGRjMWQiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpiNzhkZTUyYS03YzY0
LTRiZmMtYWVjYy0xMTVkY2M0MzVmYzQiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1Q
OkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE2
NTUyMjE4MDUyODg5OTciCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRh
dGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9y
eT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIK
ICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDph
ZmUxNjEyZS0yYmFiLTQ4NjgtYTNlMS1hMTQzMTQ1OThjNWEiCiAgICAgIHN0RXZ0OnNvZnR3YXJl
QWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDIxLTEyLTEyVDIx
OjI2OjA1KzAwOjAwIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgog
ICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjFj
ZjUxMzYxLTVlMDEtNGFlMi1hNmZiLWFhYjZiMjI2M2IyZCIKICAgICAgc3RFdnQ6c29mdHdhcmVB
Z2VudD0iR2ltcCAyLjEwIChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjItMDYtMTRUMTY6
NDg6MzgrMDE6MDAiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAg
ICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6OGY1
ZGQwZDUtOTBkNi00YWQxLWEyN2UtYWNiYTFjNTQzZWNmIgogICAgICBzdEV2dDpzb2Z0d2FyZUFn
ZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wNi0xNFQxNjo1
MDowNSswMTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6
RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAog
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz5sc3Io
AAAABlBMVEVWBQBlboYG6bSiAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAADsQA
AA7EAZUrDhsAAAAHdElNRQfmBg4PMgX1EDdvAAAAFnRFWHRDb21tZW50AGJpbmFyeSBjb21tZW50
xeSgegAAIABJREFUeNrt3buu5bySIGixCAy94gs0wEcod4wGeB6pzfEooB9sNCijH2NUaON4UzKO
oQHUYp/8M3NvXXhnBKmVijC66+S/99rSt6hg8CJpGCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
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
APMDAK4NXH4dm4IF+A/g1d7iWWFHPXhs4OILQAMsTkYAxv4A2g9gAHYpHgD+Z2cAaWOxnw55HCBy
VgRgeBTAdjpkVy9YBfB30E1vQ82hBHfiC3svEMqTtkggfwzA+Z6eTfxhADwKMJ0OeZcQvZZIaHOP
ARjPLUBB5CyR0OYaBYsCnKF2jQ8wPwpgi7aUHRqgZSEYuBv5fEFy0JwlEi66pwAsUYAVGKBpGRC4
G/l8QTYE2D4NYAFud2tbAJ1UBkA/vMM8pROIAmzxemEC/qttOwH/7djn9gj88A7zmE4gBrBEAXbg
dte4E4iNh6cowAace9dnAYxRgBUYoHEOjI2H4yXzDAwwPApgi/fcEyzA0hqAJw7Ngb8x85A+IDYc
nKNHvMMCbEPzSByZGtikbZ5RBUUHA/Geu/Ca1c8oAmKV0B4HmEHdlw4AMm1gpoCTln7KFRDsB5c4
AOwgrMP5B/vBOdpQNtCGt/UAYGkjUwlcuYsnlMGxfnCPp4oFFGDsApA2MBPAQxfxlCsg1A8u7wCQ
SeMcDly5iYd0gsF+cIwCbKB/tc/5+/vBPd5ZLJAAna4AfzewxQFmSPZuAGnjHOjSVTykEwxkwTkO
AJl6ujUAbxIYo+XCBgmwdAMYigEWSICpH4BOGehp4I5bPGAuJJwE9mjBWHXVis4LIvHhwBrtuBdI
gLknwJDQxzPowZt5SCfoLXPGWDPZIJvdPvQNHp+gVcDTF+YhVYBPYI/2W6CJZ+kNEO+WGHDlZh6U
A12d4RbLWjMowNgf4HKRR6eOQPvefRgeJrDFLpIVFGB7BAAPJyUGW7r/27Ny4BVginxn9W1WPCwH
XjJhbNC0gnI/IgeeBKZYPzGBtoB9eE4I//EI0CPmj8uB36e5R0cMENesfloO/P5u9tigEWTwrh+Y
AyMAGnQJQz8xB/4E2CKHPIFlm+flwL+u9TXcRawDMMA6fEhw0O9LPGFCuGTiaIIGWIaPCQN5uPyJ
RUA8ca+wH9dvVbywUF4HaID5kwD4Ct2gPqcHQLqi9uHdIceBgoKCgoKCgoKCgoKCgoKCgoKCgoKC
goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKC
goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKC
goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKC
goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKC
goKCgoLij4r/DTmR+19NqbnDAAAAAElFTkSuQmCC
"
id="image10" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 34 KiB

BIN
img/logo2048.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

110
inbox.py
View File

@ -186,7 +186,7 @@ def cache_svg_images(session, base_dir: str, http_prefix: str,
if not test_image_filename:
image_filename = \
base_dir + '/media/' + post_id + '_' + filename
if not download_image(session, base_dir, url,
if not download_image(session, url,
image_filename, debug):
continue
else:
@ -884,9 +884,7 @@ def _inbox_post_recipients(base_dir: str, post_json_object: {},
return recipients_dict, recipients_dict_followers
def _receive_undo_follow(session, base_dir: str, http_prefix: str,
port: int, message_json: {},
federation_list: [],
def _receive_undo_follow(base_dir: str, message_json: {},
debug: bool, domain: str,
onion_domain: str, i2p_domain: str) -> bool:
if not message_json['object'].get('actor'):
@ -947,12 +945,8 @@ def _receive_undo_follow(session, base_dir: str, http_prefix: str,
return False
def _receive_undo(session, base_dir: str, http_prefix: str,
port: int, send_threads: [], post_log: [],
cached_webfingers: {}, person_cache: {},
message_json: {}, federation_list: [],
debug: bool, domain: str,
onion_domain: str, i2p_domain: str) -> bool:
def _receive_undo(base_dir: str, message_json: {}, debug: bool,
domain: str, onion_domain: str, i2p_domain: str) -> bool:
"""Receives an undo request within the POST section of HTTPServer
"""
if not message_json['type'].startswith('Undo'):
@ -971,10 +965,8 @@ def _receive_undo(session, base_dir: str, http_prefix: str,
return False
if message_json['object']['type'] == 'Follow' or \
message_json['object']['type'] == 'Join':
return _receive_undo_follow(session, base_dir, http_prefix,
port, message_json,
federation_list, debug,
domain, onion_domain, i2p_domain)
return _receive_undo_follow(base_dir, message_json,
debug, domain, onion_domain, i2p_domain)
return False
@ -1242,10 +1234,8 @@ def _receive_edit_to_post(recent_posts_cache: {}, message_json: {},
def _receive_update_activity(recent_posts_cache: {}, session, base_dir: str,
http_prefix: str, domain: str, port: int,
send_threads: [], post_log: [],
cached_webfingers: {},
person_cache: {}, message_json: {},
federation_list: [],
nickname: str, debug: bool,
max_mentions: int, max_emoji: int,
allow_local_network_access: bool,
@ -1332,11 +1322,11 @@ def _receive_update_activity(recent_posts_cache: {}, session, base_dir: str,
def _receive_like(recent_posts_cache: {},
session, handle: str, is_group: bool, base_dir: str,
session, handle: str, base_dir: str,
http_prefix: str, domain: str, port: int,
onion_domain: str, i2p_domain: str,
send_threads: [], post_log: [], cached_webfingers: {},
person_cache: {}, message_json: {}, federation_list: [],
cached_webfingers: {},
person_cache: {}, message_json: {},
debug: bool,
signing_priv_key_pem: str,
max_recent_posts: int, translate: {},
@ -1394,7 +1384,7 @@ def _receive_like(recent_posts_cache: {},
handle_name, handle_dom,
post_liked_id,
like_actor):
_like_notify(base_dir, domain, onion_domain, handle,
_like_notify(base_dir, domain, onion_domain, i2p_domain, handle,
like_actor, post_liked_id)
update_likes_collection(recent_posts_cache, base_dir, post_filename,
post_liked_id, like_actor,
@ -1462,10 +1452,10 @@ def _receive_like(recent_posts_cache: {},
def _receive_undo_like(recent_posts_cache: {},
session, handle: str, is_group: bool, base_dir: str,
session, handle: str, base_dir: str,
http_prefix: str, domain: str, port: int,
send_threads: [], post_log: [], cached_webfingers: {},
person_cache: {}, message_json: {}, federation_list: [],
cached_webfingers: {},
person_cache: {}, message_json: {},
debug: bool,
signing_priv_key_pem: str,
max_recent_posts: int, translate: {},
@ -1581,11 +1571,11 @@ def _receive_undo_like(recent_posts_cache: {},
def _receive_reaction(recent_posts_cache: {},
session, handle: str, is_group: bool, base_dir: str,
session, handle: str, base_dir: str,
http_prefix: str, domain: str, port: int,
onion_domain: str,
send_threads: [], post_log: [], cached_webfingers: {},
person_cache: {}, message_json: {}, federation_list: [],
cached_webfingers: {},
person_cache: {}, message_json: {},
debug: bool,
signing_priv_key_pem: str,
max_recent_posts: int, translate: {},
@ -2686,7 +2676,7 @@ def _valid_post_content(base_dir: str, nickname: str, domain: str,
message_json['object']['tag'])
return False
# check that the post is in a language suitable for this account
if not understood_post_language(base_dir, nickname, domain,
if not understood_post_language(base_dir, nickname,
message_json, system_language,
http_prefix, domain_full,
person_cache):
@ -2850,7 +2840,8 @@ def _already_reacted(base_dir: str, nickname: str, domain: str,
return False
def _like_notify(base_dir: str, domain: str, onion_domain: str,
def _like_notify(base_dir: str, domain: str,
onion_domain: str, i2p_domain: str,
handle: str, actor: str, url: str) -> None:
"""Creates a notification that a like has arrived
"""
@ -2861,9 +2852,13 @@ def _like_notify(base_dir: str, domain: str, onion_domain: str,
# check that the liked post was by this handle
nickname = handle.split('@')[0]
if '/' + domain + '/users/' + nickname not in url:
if not onion_domain:
return
if '/' + onion_domain + '/users/' + nickname not in url:
if onion_domain:
if '/' + onion_domain + '/users/' + nickname not in url:
return
if i2p_domain:
if '/' + i2p_domain + '/users/' + nickname not in url:
return
if not i2p_domain and not onion_domain:
return
account_dir = base_dir + '/accounts/' + handle
@ -3012,8 +3007,7 @@ def _reply_notify(base_dir: str, handle: str, url: str) -> None:
print('EX: unable to write ' + reply_file)
def _git_patch_notify(base_dir: str, handle: str,
subject: str, content: str,
def _git_patch_notify(base_dir: str, handle: str, subject: str,
from_nickname: str, from_domain: str) -> None:
"""Creates a notification that a new git patch has arrived
"""
@ -3051,7 +3045,6 @@ def _send_to_group_members(server, session, session_onion, session_i2p,
send_threads: [], post_log: [],
cached_webfingers: {},
person_cache: {}, debug: bool,
system_language: str,
curr_domain: str,
onion_domain: str, i2p_domain: str,
signing_priv_key_pem: str) -> None:
@ -3238,7 +3231,7 @@ def _update_last_seen(base_dir: str, handle: str, actor: str) -> None:
print('EX: unable to write ' + last_seen_filename)
def _bounce_dm(senderPostId: str, session, http_prefix: str,
def _bounce_dm(sender_post_id: str, session, http_prefix: str,
base_dir: str, nickname: str, domain: str, port: int,
sending_handle: str, federation_list: [],
send_threads: [], post_log: [],
@ -3288,7 +3281,7 @@ def _bounce_dm(senderPostId: str, session, http_prefix: str,
media_type = None
image_description = ''
city = 'London, England'
in_reply_to = remove_id_ending(senderPostId)
in_reply_to = remove_id_ending(sender_post_id)
in_reply_to_atom_uri = None
schedule_post = False
event_date = None
@ -3646,8 +3639,7 @@ def _check_for_git_patches(base_dir: str, nickname: str, domain: str,
json_obj['type'], json_obj['summary'],
json_obj['content'],
from_nickname, from_domain_full):
_git_patch_notify(base_dir, handle,
json_obj['summary'], json_obj['content'],
_git_patch_notify(base_dir, handle, json_obj['summary'],
from_nickname, from_domain_full)
return 1
if '[PATCH]' in json_obj['content']:
@ -3662,10 +3654,8 @@ def _inbox_after_initial(server, inbox_start_time,
key_id: str, handle: str, message_json: {},
base_dir: str, http_prefix: str, send_threads: [],
post_log: [], cached_webfingers: {}, person_cache: {},
queue: [], domain: str,
onion_domain: str, i2p_domain: str,
port: int, proxy_type: str,
federation_list: [], debug: bool,
domain: str, onion_domain: str, i2p_domain: str,
port: int, federation_list: [], debug: bool,
queue_filename: str, destination_filename: str,
max_replies: int, allow_deletion: bool,
max_mentions: int, max_emoji: int, translate: {},
@ -3715,15 +3705,13 @@ def _inbox_after_initial(server, inbox_start_time,
handle_name = handle.split('@')[0]
if _receive_like(recent_posts_cache,
session, handle, is_group,
session, handle,
base_dir, http_prefix,
domain, port,
onion_domain, i2p_domain,
send_threads, post_log,
cached_webfingers,
person_cache,
message_json,
federation_list,
debug, signing_priv_key_pem,
max_recent_posts, translate,
allow_deletion,
@ -3743,14 +3731,12 @@ def _inbox_after_initial(server, inbox_start_time,
return False
if _receive_undo_like(recent_posts_cache,
session, handle, is_group,
session, handle,
base_dir, http_prefix,
domain, port,
send_threads, post_log,
cached_webfingers,
person_cache,
message_json,
federation_list,
debug, signing_priv_key_pem,
max_recent_posts, translate,
allow_deletion,
@ -3770,15 +3756,13 @@ def _inbox_after_initial(server, inbox_start_time,
return False
if _receive_reaction(recent_posts_cache,
session, handle, is_group,
session, handle,
base_dir, http_prefix,
domain, port,
onion_domain,
send_threads, post_log,
cached_webfingers,
person_cache,
message_json,
federation_list,
debug, signing_priv_key_pem,
max_recent_posts, translate,
allow_deletion,
@ -4346,8 +4330,7 @@ def _inbox_after_initial(server, inbox_start_time,
http_prefix, federation_list,
send_threads,
post_log, cached_webfingers,
person_cache,
debug, system_language,
person_cache, debug,
domain, onion_domain, i2p_domain,
signing_priv_key_pem)
fitness_performance(inbox_start_time,
@ -4422,7 +4405,7 @@ def _restore_queue_items(base_dir: str, queue: []) -> None:
def run_inbox_queue_watchdog(project_version: str, httpd) -> None:
"""This tries to keep the inbox thread running even if it dies
"""
print('THREAD: Starting inbox queue watchdog')
print('THREAD: Starting inbox queue watchdog ' + project_version)
inbox_queue_original = httpd.thrInboxQueue.clone(run_inbox_queue)
httpd.thrInboxQueue.start()
while True:
@ -5089,17 +5072,14 @@ def run_inbox_queue(server,
inbox_start_time = time.time()
curr_session = session
curr_proxy_type = proxy_type
if queue_json.get('actor'):
if isinstance(queue_json['actor'], str):
sender_domain, _ = get_domain_from_actor(queue_json['actor'])
if sender_domain.endswith('.onion') and \
session_onion and proxy_type != 'tor':
curr_proxy_type = 'tor'
curr_session = session_onion
elif (sender_domain.endswith('.i2p') and
session_i2p and proxy_type != 'i2p'):
curr_proxy_type = 'i2p'
curr_session = session_i2p
if debug and queue_json.get('actor'):
@ -5259,13 +5239,7 @@ def run_inbox_queue(server,
# if queue_json['post'].get('id'):
# queue_json['post']['id'] = queue_json['id']
if _receive_undo(curr_session,
base_dir, http_prefix, port,
send_threads, post_log,
cached_webfingers,
person_cache,
queue_json['post'],
federation_list,
if _receive_undo(base_dir, queue_json['post'],
debug, domain, onion_domain, i2p_domain):
print('Queue: Undo accepted from ' + key_id)
if os.path.isfile(queue_filename):
@ -5335,11 +5309,9 @@ def run_inbox_queue(server,
if _receive_update_activity(recent_posts_cache, curr_session,
base_dir, http_prefix,
domain, port,
send_threads, post_log,
cached_webfingers,
person_cache,
queue_json['post'],
federation_list,
queue_json['postNickname'],
debug,
max_mentions, max_emoji,
@ -5460,11 +5432,9 @@ def run_inbox_queue(server,
base_dir, http_prefix,
send_threads, post_log,
cached_webfingers,
person_cache, queue,
domain,
person_cache, domain,
onion_domain, i2p_domain,
port, curr_proxy_type,
federation_list,
port, federation_list,
debug,
queue_filename, destination,
max_replies, allow_deletion,

View File

@ -99,7 +99,7 @@ def set_actor_languages(actor_json: {}, languages_str: str) -> None:
actor_json['attachment'].append(new_languages)
def understood_post_language(base_dir: str, nickname: str, domain: str,
def understood_post_language(base_dir: str, nickname: str,
message_json: {}, system_language: str,
http_prefix: str, domain_full: str,
person_cache: {}) -> bool:

View File

@ -385,8 +385,7 @@ def outbox_like(recent_posts_cache: {},
def outbox_undo_like(recent_posts_cache: {},
base_dir: str, http_prefix: str,
nickname: str, domain: str, port: int,
base_dir: str, nickname: str, domain: str,
message_json: {}, debug: bool) -> None:
""" When an undo like request is received by the outbox from c2s
"""

View File

@ -580,8 +580,7 @@ def post_message_to_outbox(session, translate: {},
if debug:
print('DEBUG: handle any undo like requests')
outbox_undo_like(recent_posts_cache,
base_dir, http_prefix,
post_to_nickname, domain, port,
base_dir, post_to_nickname, domain,
message_json, debug)
if debug:

View File

@ -4998,7 +4998,7 @@ def download_announce(session, base_dir: str, http_prefix: str,
base_dir, nickname, domain, post_id,
recent_posts_cache)
return None
if not understood_post_language(base_dir, nickname, domain,
if not understood_post_language(base_dir, nickname,
announced_json, system_language,
http_prefix, domain_full,
person_cache):

View File

@ -136,20 +136,20 @@ def question_update_votes(base_dir: str, nickname: str, domain: str,
return question_json, question_post_filename
def is_question(postObjectJson: {}) -> bool:
def is_question(post_object_json: {}) -> bool:
""" is the given post a question?
"""
if postObjectJson['type'] != 'Create' and \
postObjectJson['type'] != 'Update':
if post_object_json['type'] != 'Create' and \
post_object_json['type'] != 'Update':
return False
if not has_object_dict(postObjectJson):
if not has_object_dict(post_object_json):
return False
if not postObjectJson['object'].get('type'):
if not post_object_json['object'].get('type'):
return False
if postObjectJson['object']['type'] != 'Question':
if post_object_json['object']['type'] != 'Question':
return False
if not postObjectJson['object'].get('oneOf'):
if not post_object_json['object'].get('oneOf'):
return False
if not isinstance(postObjectJson['object']['oneOf'], list):
if not isinstance(post_object_json['object']['oneOf'], list):
return False
return True

View File

@ -193,7 +193,7 @@ def run_post_schedule(base_dir: str, httpd, max_scheduled_posts: int):
def run_post_schedule_watchdog(project_version: str, httpd) -> None:
"""This tries to keep the scheduled post thread running even if it dies
"""
print('THREAD: Starting scheduled post watchdog')
print('THREAD: Starting scheduled post watchdog ' + project_version)
post_schedule_original = \
httpd.thrPostSchedule.clone(run_post_schedule)
httpd.thrPostSchedule.start()

View File

@ -465,7 +465,7 @@ def post_json(http_prefix: str, domain_full: str,
return None
def post_json_string(session, post_jsonStr: str,
def post_json_string(session, post_json_str: str,
federation_list: [],
inbox_url: str,
headers: {},
@ -489,7 +489,7 @@ def post_json_string(session, post_jsonStr: str,
try:
post_result = \
session.post(url=inbox_url, data=post_jsonStr,
session.post(url=inbox_url, data=post_json_str,
headers=headers, timeout=timeout_sec)
except requests.exceptions.RequestException as ex:
if not quiet:
@ -500,7 +500,7 @@ def post_json_string(session, post_jsonStr: str,
print('EX: connection was reset during post_json_string')
if not quiet:
print('EX: post_json_string failed ' + inbox_url + ' ' +
post_jsonStr + ' ' + str(headers))
post_json_str + ' ' + str(headers))
return None, None, 0
except ValueError as ex:
if not quiet:
@ -592,8 +592,7 @@ def _looks_like_url(url: str) -> bool:
return True
def download_image(session, base_dir: str, url: str,
image_filename: str, debug: bool,
def download_image(session, url: str, image_filename: str, debug: bool,
force: bool = False) -> bool:
"""Downloads an image with an expected mime type
"""

View File

@ -320,8 +320,7 @@ def _ssml_header(system_language: str, box_name: str, summary: str) -> str:
def _speaker_endpoint_ssml(display_name: str, summary: str,
content: str, image_description: str,
links: [], language: str,
content: str, language: str,
gender: str, box_name: str) -> str:
"""Returns an SSML endpoint for the TTS speaker
https://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language
@ -379,8 +378,6 @@ def get_ssml_box(base_dir: str, path: str,
return _speaker_endpoint_ssml(speaker_json['name'],
speaker_json['summary'],
speaker_json['say'],
speaker_json['imageDescription'],
speaker_json['detectedLinks'],
system_language,
gender, box_name)
@ -411,7 +408,7 @@ def speakable_text(base_dir: str, content: str, translate: {}) -> (str, []):
def _post_to_speaker_json(base_dir: str, http_prefix: str,
nickname: str, domain: str, domain_full: str,
nickname: str, domain_full: str,
post_json_object: {}, person_cache: {},
translate: {}, announcing_actor: str,
theme_name: str) -> {}:
@ -554,7 +551,7 @@ def update_speaker(base_dir: str, http_prefix: str,
"""
speaker_json = \
_post_to_speaker_json(base_dir, http_prefix,
nickname, domain, domain_full,
nickname, domain_full,
post_json_object, person_cache,
translate, announcing_actor,
theme_name)
@ -581,8 +578,6 @@ def update_speaker(base_dir: str, http_prefix: str,
_speaker_endpoint_ssml(speaker_json['name'],
speaker_json['summary'],
speaker_json['say'],
speaker_json['imageDescription'],
speaker_json['detectedLinks'],
system_language,
gender, box_name)
try:

View File

@ -3208,7 +3208,7 @@ def test_client_to_server(base_dir: str):
http_prefix,
cached_webfingers, person_cache,
True, __version__, signing_priv_key_pem)
for _ in range(10):
for _ in range(20):
if os.path.isfile(alice_dir + '/accounts/alice@' + alice_domain +
'/followers.txt'):
test_str = 'bob@' + bob_domain + ':' + str(bob_port)

View File

@ -383,7 +383,6 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {},
year, month_number,
day_number,
person_cache,
http_prefix,
text_match,
system_language)
day_events = None
@ -404,7 +403,7 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {},
if icalendar:
return get_month_events_icalendar(base_dir, nickname, domain,
year, month_number, person_cache,
http_prefix, text_match)
text_match)
events = \
get_calendar_events(base_dir, nickname, domain, year, month_number,