Snake case

merge-requests/30/head
Bob Mottram 2022-01-03 18:06:04 +00:00
parent 586267b5c9
commit 5b2d54daf6
1 changed files with 193 additions and 192 deletions

View File

@ -28,55 +28,55 @@ from utils import acct_dir
from utils import local_actor_url from utils import local_actor_url
from content import html_replace_quote_marks from content import html_replace_quote_marks
speakerRemoveChars = ('.\n', '. ', ',', ';', '?', '!') SPEAKER_REMOVE_CHARS = ('.\n', '. ', ',', ';', '?', '!')
def get_speaker_pitch(displayName: str, screenreader: str, gender) -> int: def get_speaker_pitch(display_name: str, screenreader: str, gender) -> int:
"""Returns the speech synthesis pitch for the given name """Returns the speech synthesis pitch for the given name
""" """
random.seed(displayName) random.seed(display_name)
rangeMin = 1 range_min = 1
rangeMax = 100 range_max = 100
if 'She' in gender: if 'She' in gender:
rangeMin = 50 range_min = 50
elif 'Him' in gender: elif 'Him' in gender:
rangeMax = 50 range_max = 50
if screenreader == 'picospeaker': if screenreader == 'picospeaker':
rangeMin = -6 range_min = -6
rangeMax = 3 range_max = 3
if 'She' in gender: if 'She' in gender:
rangeMin = -1 range_min = -1
elif 'Him' in gender: elif 'Him' in gender:
rangeMax = -1 range_max = -1
return random.randint(rangeMin, rangeMax) return random.randint(range_min, range_max)
def get_speaker_rate(displayName: str, screenreader: str) -> int: def get_speaker_rate(display_name: str, screenreader: str) -> int:
"""Returns the speech synthesis rate for the given name """Returns the speech synthesis rate for the given name
""" """
random.seed(displayName) random.seed(display_name)
if screenreader == 'picospeaker': if screenreader == 'picospeaker':
return random.randint(-40, -20) return random.randint(-40, -20)
return random.randint(50, 120) return random.randint(50, 120)
def get_speaker_range(displayName: str) -> int: def get_speaker_range(display_name: str) -> int:
"""Returns the speech synthesis range for the given name """Returns the speech synthesis range for the given name
""" """
random.seed(displayName) random.seed(display_name)
return random.randint(300, 800) return random.randint(300, 800)
def _speaker_pronounce(base_dir: str, sayText: str, translate: {}) -> str: def _speaker_pronounce(base_dir: str, say_text: str, translate: {}) -> str:
"""Screen readers may not always pronounce correctly, so you """Screen readers may not always pronounce correctly, so you
can have a file which specifies conversions. File should contain can have a file which specifies conversions. File should contain
line items such as: line items such as:
Epicyon -> Epi-cyon Epicyon -> Epi-cyon
""" """
pronounceFilename = base_dir + '/accounts/speaker_pronounce.txt' pronounce_filename = base_dir + '/accounts/speaker_pronounce.txt'
convertDict = {} convert_dict = {}
if translate: if translate:
convertDict = { convert_dict = {
"Epicyon": "Epi-cyon", "Epicyon": "Epi-cyon",
"espeak": "e-speak", "espeak": "e-speak",
"emoji": "emowji", "emoji": "emowji",
@ -139,10 +139,10 @@ def _speaker_pronounce(base_dir: str, sayText: str, translate: {}) -> str:
"(": ",", "(": ",",
")": "," ")": ","
} }
if os.path.isfile(pronounceFilename): if os.path.isfile(pronounce_filename):
with open(pronounceFilename, 'r') as fp: with open(pronounce_filename, 'r') as fp_pro:
pronounceList = fp.readlines() pronounce_list = fp_pro.readlines()
for conversion in pronounceList: for conversion in pronounce_list:
separator = None separator = None
if '->' in conversion: if '->' in conversion:
separator = '->' separator = '->'
@ -157,43 +157,43 @@ def _speaker_pronounce(base_dir: str, sayText: str, translate: {}) -> str:
text = conversion.split(separator)[0].strip() text = conversion.split(separator)[0].strip()
converted = conversion.split(separator)[1].strip() converted = conversion.split(separator)[1].strip()
convertDict[text] = converted convert_dict[text] = converted
for text, converted in convertDict.items(): for text, converted in convert_dict.items():
if text in sayText: if text in say_text:
sayText = sayText.replace(text, converted) say_text = say_text.replace(text, converted)
return sayText return say_text
def speaker_replace_links(sayText: str, translate: {}, def speaker_replace_links(say_text: str, translate: {},
detectedLinks: []) -> str: detected_links: []) -> str:
"""Replaces any links in the given text with "link to [domain]". """Replaces any links in the given text with "link to [domain]".
Instead of reading out potentially very long and meaningless links Instead of reading out potentially very long and meaningless links
""" """
text = sayText text = say_text
text = text.replace('?v=', '__v=') text = text.replace('?v=', '__v=')
for ch in speakerRemoveChars: for char in SPEAKER_REMOVE_CHARS:
text = text.replace(ch, ' ') text = text.replace(char, ' ')
text = text.replace('__v=', '?v=') text = text.replace('__v=', '?v=')
replacements = {} replacements = {}
wordsList = text.split(' ') words_list = text.split(' ')
if translate.get('Linked'): if translate.get('Linked'):
linkedStr = translate['Linked'] linked_str = translate['Linked']
else: else:
linkedStr = 'Linked' linked_str = 'Linked'
prevWord = '' prev_word = ''
for word in wordsList: for word in words_list:
if word.startswith('v='): if word.startswith('v='):
replacements[word] = '' replacements[word] = ''
if word.startswith(':'): if word.startswith(':'):
if word.endswith(':'): if word.endswith(':'):
replacements[word] = ', emowji ' + word.replace(':', '') + ',' replacements[word] = ', emowji ' + word.replace(':', '') + ','
continue continue
if word.startswith('@') and not prevWord.endswith('RT'): if word.startswith('@') and not prev_word.endswith('RT'):
# replace mentions, but not re-tweets # replace mentions, but not re-tweets
if translate.get('mentioning'): if translate.get('mentioning'):
replacements[word] = \ replacements[word] = \
translate['mentioning'] + ' ' + word[1:] + ', ' translate['mentioning'] + ' ' + word[1:] + ', '
prevWord = word prev_word = word
domain = None domain = None
domain_full = None domain_full = None
@ -209,94 +209,94 @@ def speaker_replace_links(sayText: str, translate: {},
domain = domain.split('/')[0] domain = domain.split('/')[0]
if domain.startswith('www.'): if domain.startswith('www.'):
domain = domain.replace('www.', '') domain = domain.replace('www.', '')
replacements[domain_full] = '. ' + linkedStr + ' ' + domain + '.' replacements[domain_full] = '. ' + linked_str + ' ' + domain + '.'
detectedLinks.append(domain_full) detected_links.append(domain_full)
for replaceStr, newStr in replacements.items(): for replace_str, new_str in replacements.items():
sayText = sayText.replace(replaceStr, newStr) say_text = say_text.replace(replace_str, new_str)
return sayText.replace('..', '.') return say_text.replace('..', '.')
def _add_ssm_lemphasis(sayText: str) -> str: def _add_ssm_lemphasis(say_text: str) -> str:
"""Adds emphasis to *emphasised* text """Adds emphasis to *emphasised* text
""" """
if '*' not in sayText: if '*' not in say_text:
return sayText return say_text
text = sayText text = say_text
for ch in speakerRemoveChars: for char in SPEAKER_REMOVE_CHARS:
text = text.replace(ch, ' ') text = text.replace(char, ' ')
wordsList = text.split(' ') words_list = text.split(' ')
replacements = {} replacements = {}
for word in wordsList: for word in words_list:
if word.startswith('*'): if word.startswith('*'):
if word.endswith('*'): if word.endswith('*'):
replacements[word] = \ replacements[word] = \
'<emphasis level="strong">' + \ '<emphasis level="strong">' + \
word.replace('*', '') + \ word.replace('*', '') + \
'</emphasis>' '</emphasis>'
for replaceStr, newStr in replacements.items(): for replace_str, new_str in replacements.items():
sayText = sayText.replace(replaceStr, newStr) say_text = say_text.replace(replace_str, new_str)
return sayText return say_text
def _remove_emoji_from_text(sayText: str) -> str: def _remove_emoji_from_text(say_text: str) -> str:
"""Removes :emoji: from the given text """Removes :emoji: from the given text
""" """
if ':' not in sayText: if ':' not in say_text:
return sayText return say_text
text = sayText text = say_text
for ch in speakerRemoveChars: for char in SPEAKER_REMOVE_CHARS:
text = text.replace(ch, ' ') text = text.replace(char, ' ')
wordsList = text.split(' ') words_list = text.split(' ')
replacements = {} replacements = {}
for word in wordsList: for word in words_list:
if word.startswith(':'): if word.startswith(':'):
if word.endswith(':'): if word.endswith(':'):
replacements[word] = '' replacements[word] = ''
for replaceStr, newStr in replacements.items(): for replace_str, new_str in replacements.items():
sayText = sayText.replace(replaceStr, newStr) say_text = say_text.replace(replace_str, new_str)
return sayText.replace(' ', ' ').strip() return say_text.replace(' ', ' ').strip()
def _speaker_endpoint_json(displayName: str, summary: str, def _speaker_endpoint_json(display_name: str, summary: str,
content: str, sayContent: str, content: str, say_content: str,
imageDescription: str, image_description: str,
links: [], gender: str, post_id: str, links: [], gender: str, post_id: str,
postDM: bool, postReply: bool, post_dm: bool, post_reply: bool,
followRequestsExist: bool, follow_requests_exist: bool,
followRequestsList: [], follow_requests_list: [],
likedBy: str, published: str, postCal: bool, liked_by: str, published: str, post_cal: bool,
postShare: bool, theme_name: str, post_share: bool, theme_name: str,
isDirect: bool, replyToYou: bool) -> {}: is_direct: bool, reply_to_you: bool) -> {}:
"""Returns a json endpoint for the TTS speaker """Returns a json endpoint for the TTS speaker
""" """
speakerJson = { speaker_json = {
"name": displayName, "name": display_name,
"summary": summary, "summary": summary,
"content": content, "content": content,
"say": sayContent, "say": say_content,
"published": published, "published": published,
"imageDescription": imageDescription, "imageDescription": image_description,
"detectedLinks": links, "detectedLinks": links,
"id": post_id, "id": post_id,
"direct": isDirect, "direct": is_direct,
"replyToYou": replyToYou, "replyToYou": reply_to_you,
"notify": { "notify": {
"theme": theme_name, "theme": theme_name,
"dm": postDM, "dm": post_dm,
"reply": postReply, "reply": post_reply,
"followRequests": followRequestsExist, "followRequests": follow_requests_exist,
"followRequestsList": followRequestsList, "followRequestsList": follow_requests_list,
"likedBy": likedBy, "likedBy": liked_by,
"calendar": postCal, "calendar": post_cal,
"share": postShare "share": post_share
} }
} }
if gender: if gender:
speakerJson['gender'] = gender speaker_json['gender'] = gender
return speakerJson return speaker_json
def _ssm_lheader(system_language: str, instanceTitle: str) -> str: def _ssm_lheader(system_language: str, instance_title: str) -> str:
"""Returns a header for an SSML document """Returns a header for an SSML document
""" """
return '<?xml version="1.0"?>\n' + \ return '<?xml version="1.0"?>\n' + \
@ -307,26 +307,26 @@ def _ssm_lheader(system_language: str, instanceTitle: str) -> str:
' version="1.1">\n' + \ ' version="1.1">\n' + \
' <metadata>\n' + \ ' <metadata>\n' + \
' <dc:title xml:lang="' + system_language + '">' + \ ' <dc:title xml:lang="' + system_language + '">' + \
instanceTitle + ' inbox</dc:title>\n' + \ instance_title + ' inbox</dc:title>\n' + \
' </metadata>\n' ' </metadata>\n'
def _speaker_endpoint_ssml(displayName: str, summary: str, def _speaker_endpoint_ssml(display_name: str, summary: str,
content: str, imageDescription: str, content: str, image_description: str,
links: [], language: str, links: [], language: str,
instanceTitle: str, instance_title: str,
gender: str) -> str: gender: str) -> str:
"""Returns an SSML endpoint for the TTS speaker """Returns an SSML endpoint for the TTS speaker
https://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language https://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language
https://www.w3.org/TR/speech-synthesis/ https://www.w3.org/TR/speech-synthesis/
""" """
langShort = 'en' lang_short = 'en'
if language: if language:
langShort = language[:2] lang_short = language[:2]
if not gender: if not gender:
gender = 'neutral' gender = 'neutral'
else: else:
if langShort == 'en': if lang_short == 'en':
gender = gender.lower() gender = gender.lower()
if 'he/him' in gender: if 'he/him' in gender:
gender = 'male' gender = 'male'
@ -336,11 +336,11 @@ def _speaker_endpoint_ssml(displayName: str, summary: str,
gender = 'neutral' gender = 'neutral'
content = _add_ssm_lemphasis(content) content = _add_ssm_lemphasis(content)
voiceParams = 'name="' + displayName + '" gender="' + gender + '"' voice_params = 'name="' + display_name + '" gender="' + gender + '"'
return _ssm_lheader(langShort, instanceTitle) + \ return _ssm_lheader(lang_short, instance_title) + \
' <p>\n' + \ ' <p>\n' + \
' <s xml:lang="' + language + '">\n' + \ ' <s xml:lang="' + language + '">\n' + \
' <voice ' + voiceParams + '>\n' + \ ' <voice ' + voice_params + '>\n' + \
' ' + content + '\n' + \ ' ' + content + '\n' + \
' </voice>\n' + \ ' </voice>\n' + \
' </s>\n' + \ ' </s>\n' + \
@ -351,30 +351,30 @@ def _speaker_endpoint_ssml(displayName: str, summary: str,
def get_ssm_lbox(base_dir: str, path: str, def get_ssm_lbox(base_dir: str, path: str,
domain: str, domain: str,
system_language: str, system_language: str,
instanceTitle: str, instance_title: str,
boxName: str) -> str: box_name: str) -> str:
"""Returns SSML for the given timeline """Returns SSML for the given timeline
""" """
nickname = path.split('/users/')[1] nickname = path.split('/users/')[1]
if '/' in nickname: if '/' in nickname:
nickname = nickname.split('/')[0] nickname = nickname.split('/')[0]
speakerFilename = \ speaker_filename = \
acct_dir(base_dir, nickname, domain) + '/speaker.json' acct_dir(base_dir, nickname, domain) + '/speaker.json'
if not os.path.isfile(speakerFilename): if not os.path.isfile(speaker_filename):
return None return None
speakerJson = load_json(speakerFilename) speaker_json = load_json(speaker_filename)
if not speakerJson: if not speaker_json:
return None return None
gender = None gender = None
if speakerJson.get('gender'): if speaker_json.get('gender'):
gender = speakerJson['gender'] gender = speaker_json['gender']
return _speaker_endpoint_ssml(speakerJson['name'], return _speaker_endpoint_ssml(speaker_json['name'],
speakerJson['summary'], speaker_json['summary'],
speakerJson['say'], speaker_json['say'],
speakerJson['imageDescription'], speaker_json['imageDescription'],
speakerJson['detectedLinks'], speaker_json['detectedLinks'],
system_language, system_language,
instanceTitle, gender) instance_title, gender)
def speakable_text(base_dir: str, content: str, translate: {}) -> (str, []): def speakable_text(base_dir: str, content: str, translate: {}) -> (str, []):
@ -389,23 +389,23 @@ def speakable_text(base_dir: str, content: str, translate: {}) -> (str, []):
if ' <3' in content: if ' <3' in content:
content = content.replace(' <3', ' ' + translate['heart']) content = content.replace(' <3', ' ' + translate['heart'])
content = remove_html(html_replace_quote_marks(content)) content = remove_html(html_replace_quote_marks(content))
detectedLinks = [] detected_links = []
content = speaker_replace_links(content, translate, detectedLinks) content = speaker_replace_links(content, translate, detected_links)
# replace all double spaces # replace all double spaces
while ' ' in content: while ' ' in content:
content = content.replace(' ', ' ') content = content.replace(' ', ' ')
content = content.replace(' . ', '. ').strip() content = content.replace(' . ', '. ').strip()
sayContent = _speaker_pronounce(base_dir, content, translate) say_content = _speaker_pronounce(base_dir, content, translate)
# replace all double spaces # replace all double spaces
while ' ' in sayContent: while ' ' in say_content:
sayContent = sayContent.replace(' ', ' ') say_content = say_content.replace(' ', ' ')
return sayContent.replace(' . ', '. ').strip(), detectedLinks return say_content.replace(' . ', '. ').strip(), detected_links
def _post_to_speaker_json(base_dir: str, http_prefix: str, def _post_to_speaker_json(base_dir: str, http_prefix: str,
nickname: str, domain: str, domain_full: str, nickname: str, domain: str, domain_full: str,
post_json_object: {}, person_cache: {}, post_json_object: {}, person_cache: {},
translate: {}, announcingActor: str, translate: {}, announcing_actor: str,
theme_name: str) -> {}: theme_name: str) -> {}:
"""Converts an ActivityPub post into some Json containing """Converts an ActivityPub post into some Json containing
speech synthesis parameters. speech synthesis parameters.
@ -418,7 +418,7 @@ def _post_to_speaker_json(base_dir: str, http_prefix: str,
return return
if not isinstance(post_json_object['object']['content'], str): if not isinstance(post_json_object['object']['content'], str):
return return
detectedLinks = [] detected_links = []
content = urllib.parse.unquote_plus(post_json_object['object']['content']) content = urllib.parse.unquote_plus(post_json_object['object']['content'])
content = html.unescape(content) content = html.unescape(content)
content = content.replace('<p>', '').replace('</p>', ' ') content = content.replace('<p>', '').replace('</p>', ' ')
@ -427,35 +427,35 @@ def _post_to_speaker_json(base_dir: str, http_prefix: str,
if ' <3' in content: if ' <3' in content:
content = content.replace(' <3', ' ' + translate['heart']) content = content.replace(' <3', ' ' + translate['heart'])
content = remove_html(html_replace_quote_marks(content)) content = remove_html(html_replace_quote_marks(content))
content = speaker_replace_links(content, translate, detectedLinks) content = speaker_replace_links(content, translate, detected_links)
# replace all double spaces # replace all double spaces
while ' ' in content: while ' ' in content:
content = content.replace(' ', ' ') content = content.replace(' ', ' ')
content = content.replace(' . ', '. ').strip() content = content.replace(' . ', '. ').strip()
sayContent = content say_content = content
sayContent = _speaker_pronounce(base_dir, content, translate) say_content = _speaker_pronounce(base_dir, content, translate)
# replace all double spaces # replace all double spaces
while ' ' in sayContent: while ' ' in say_content:
sayContent = sayContent.replace(' ', ' ') say_content = say_content.replace(' ', ' ')
sayContent = sayContent.replace(' . ', '. ').strip() say_content = say_content.replace(' . ', '. ').strip()
else: else:
sayContent = content say_content = content
imageDescription = '' image_description = ''
if post_json_object['object'].get('attachment'): if post_json_object['object'].get('attachment'):
attachList = post_json_object['object']['attachment'] attach_list = post_json_object['object']['attachment']
if isinstance(attachList, list): if isinstance(attach_list, list):
for img in attachList: for img in attach_list:
if not isinstance(img, dict): if not isinstance(img, dict):
continue continue
if img.get('name'): if img.get('name'):
if isinstance(img['name'], str): if isinstance(img['name'], str):
imageDescription += \ image_description += \
img['name'] + '. ' img['name'] + '. '
isDirect = is_dm(post_json_object) is_direct = is_dm(post_json_object)
actor = local_actor_url(http_prefix, nickname, domain_full) actor = local_actor_url(http_prefix, nickname, domain_full)
replyToYou = is_reply(post_json_object, actor) reply_to_you = is_reply(post_json_object, actor)
published = '' published = ''
if post_json_object['object'].get('published'): if post_json_object['object'].get('published'):
@ -469,84 +469,85 @@ def _post_to_speaker_json(base_dir: str, http_prefix: str,
urllib.parse.unquote_plus(post_json_object_summary) urllib.parse.unquote_plus(post_json_object_summary)
summary = html.unescape(summary) summary = html.unescape(summary)
speakerName = \ speaker_name = \
get_display_name(base_dir, post_json_object['actor'], person_cache) get_display_name(base_dir, post_json_object['actor'], person_cache)
if not speakerName: if not speaker_name:
return return
speakerName = _remove_emoji_from_text(speakerName) speaker_name = _remove_emoji_from_text(speaker_name)
speakerName = speakerName.replace('_', ' ') speaker_name = speaker_name.replace('_', ' ')
speakerName = camel_case_split(speakerName) speaker_name = camel_case_split(speaker_name)
gender = get_gender_from_bio(base_dir, post_json_object['actor'], gender = get_gender_from_bio(base_dir, post_json_object['actor'],
person_cache, translate) person_cache, translate)
if announcingActor: if announcing_actor:
announcedNickname = get_nickname_from_actor(announcingActor) announced_nickname = get_nickname_from_actor(announcing_actor)
announcedDomain, announcedport = get_domain_from_actor(announcingActor) announced_domain, _ = \
if announcedNickname and announcedDomain: get_domain_from_actor(announcing_actor)
announcedHandle = announcedNickname + '@' + announcedDomain if announced_nickname and announced_domain:
sayContent = \ announced_handle = announced_nickname + '@' + announced_domain
say_content = \
translate['announces'] + ' ' + \ translate['announces'] + ' ' + \
announcedHandle + '. ' + sayContent announced_handle + '. ' + say_content
content = \ content = \
translate['announces'] + ' ' + \ translate['announces'] + ' ' + \
announcedHandle + '. ' + content announced_handle + '. ' + content
post_id = None post_id = None
if post_json_object['object'].get('id'): if post_json_object['object'].get('id'):
post_id = remove_id_ending(post_json_object['object']['id']) post_id = remove_id_ending(post_json_object['object']['id'])
followRequestsExist = False follow_requests_exist = False
followRequestsList = [] follow_requests_list = []
accountsDir = acct_dir(base_dir, nickname, domain_full) accounts_dir = acct_dir(base_dir, nickname, domain_full)
approveFollowsFilename = accountsDir + '/followrequests.txt' approve_follows_filename = accounts_dir + '/followrequests.txt'
if os.path.isfile(approveFollowsFilename): if os.path.isfile(approve_follows_filename):
with open(approveFollowsFilename, 'r') as fp: with open(approve_follows_filename, 'r') as fp_foll:
follows = fp.readlines() follows = fp_foll.readlines()
if len(follows) > 0: if len(follows) > 0:
followRequestsExist = True follow_requests_exist = True
for i in range(len(follows)): for i in range(len(follows)):
follows[i] = follows[i].strip() follows[i] = follows[i].strip()
followRequestsList = follows follow_requests_list = follows
postDM = False post_dm = False
dmFilename = accountsDir + '/.newDM' dm_filename = accounts_dir + '/.newDM'
if os.path.isfile(dmFilename): if os.path.isfile(dm_filename):
postDM = True post_dm = True
postReply = False post_reply = False
replyFilename = accountsDir + '/.newReply' reply_filename = accounts_dir + '/.newReply'
if os.path.isfile(replyFilename): if os.path.isfile(reply_filename):
postReply = True post_reply = True
likedBy = '' liked_by = ''
likeFilename = accountsDir + '/.newLike' like_filename = accounts_dir + '/.newLike'
if os.path.isfile(likeFilename): if os.path.isfile(like_filename):
with open(likeFilename, 'r') as fp: with open(like_filename, 'r') as fp_like:
likedBy = fp.read() liked_by = fp_like.read()
calendarFilename = accountsDir + '/.newCalendar' calendar_filename = accounts_dir + '/.newCalendar'
postCal = os.path.isfile(calendarFilename) post_cal = os.path.isfile(calendar_filename)
shareFilename = accountsDir + '/.newShare' share_filename = accounts_dir + '/.newShare'
postShare = os.path.isfile(shareFilename) post_share = os.path.isfile(share_filename)
return _speaker_endpoint_json(speakerName, summary, return _speaker_endpoint_json(speaker_name, summary,
content, sayContent, imageDescription, content, say_content, image_description,
detectedLinks, gender, post_id, detected_links, gender, post_id,
postDM, postReply, post_dm, post_reply,
followRequestsExist, follow_requests_exist,
followRequestsList, follow_requests_list,
likedBy, published, liked_by, published,
postCal, postShare, theme_name, post_cal, post_share, theme_name,
isDirect, replyToYou) is_direct, reply_to_you)
def update_speaker(base_dir: str, http_prefix: str, def update_speaker(base_dir: str, http_prefix: str,
nickname: str, domain: str, domain_full: str, nickname: str, domain: str, domain_full: str,
post_json_object: {}, person_cache: {}, post_json_object: {}, person_cache: {},
translate: {}, announcingActor: str, translate: {}, announcing_actor: str,
theme_name: str) -> None: theme_name: str) -> None:
""" Generates a json file which can be used for TTS announcement """ Generates a json file which can be used for TTS announcement
of incoming inbox posts of incoming inbox posts
""" """
speakerJson = \ speaker_json = \
_post_to_speaker_json(base_dir, http_prefix, _post_to_speaker_json(base_dir, http_prefix,
nickname, domain, domain_full, nickname, domain, domain_full,
post_json_object, person_cache, post_json_object, person_cache,
translate, announcingActor, translate, announcing_actor,
theme_name) theme_name)
speakerFilename = acct_dir(base_dir, nickname, domain) + '/speaker.json' speaker_filename = acct_dir(base_dir, nickname, domain) + '/speaker.json'
save_json(speakerJson, speakerFilename) save_json(speaker_json, speaker_filename)