mirror of https://gitlab.com/bashrc2/epicyon
Snake case
parent
586267b5c9
commit
5b2d54daf6
385
speaker.py
385
speaker.py
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue