diff --git a/speaker.py b/speaker.py
index eb71b6086..5bb896f90 100644
--- a/speaker.py
+++ b/speaker.py
@@ -28,55 +28,55 @@ from utils import acct_dir
from utils import local_actor_url
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
"""
- random.seed(displayName)
- rangeMin = 1
- rangeMax = 100
+ random.seed(display_name)
+ range_min = 1
+ range_max = 100
if 'She' in gender:
- rangeMin = 50
+ range_min = 50
elif 'Him' in gender:
- rangeMax = 50
+ range_max = 50
if screenreader == 'picospeaker':
- rangeMin = -6
- rangeMax = 3
+ range_min = -6
+ range_max = 3
if 'She' in gender:
- rangeMin = -1
+ range_min = -1
elif 'Him' in gender:
- rangeMax = -1
- return random.randint(rangeMin, rangeMax)
+ range_max = -1
+ 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
"""
- random.seed(displayName)
+ random.seed(display_name)
if screenreader == 'picospeaker':
return random.randint(-40, -20)
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
"""
- random.seed(displayName)
+ random.seed(display_name)
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
can have a file which specifies conversions. File should contain
line items such as:
Epicyon -> Epi-cyon
"""
- pronounceFilename = base_dir + '/accounts/speaker_pronounce.txt'
- convertDict = {}
+ pronounce_filename = base_dir + '/accounts/speaker_pronounce.txt'
+ convert_dict = {}
if translate:
- convertDict = {
+ convert_dict = {
"Epicyon": "Epi-cyon",
"espeak": "e-speak",
"emoji": "emowji",
@@ -139,10 +139,10 @@ def _speaker_pronounce(base_dir: str, sayText: str, translate: {}) -> str:
"(": ",",
")": ","
}
- if os.path.isfile(pronounceFilename):
- with open(pronounceFilename, 'r') as fp:
- pronounceList = fp.readlines()
- for conversion in pronounceList:
+ if os.path.isfile(pronounce_filename):
+ with open(pronounce_filename, 'r') as fp_pro:
+ pronounce_list = fp_pro.readlines()
+ for conversion in pronounce_list:
separator = None
if '->' in conversion:
separator = '->'
@@ -157,43 +157,43 @@ def _speaker_pronounce(base_dir: str, sayText: str, translate: {}) -> str:
text = conversion.split(separator)[0].strip()
converted = conversion.split(separator)[1].strip()
- convertDict[text] = converted
- for text, converted in convertDict.items():
- if text in sayText:
- sayText = sayText.replace(text, converted)
- return sayText
+ convert_dict[text] = converted
+ for text, converted in convert_dict.items():
+ if text in say_text:
+ say_text = say_text.replace(text, converted)
+ return say_text
-def speaker_replace_links(sayText: str, translate: {},
- detectedLinks: []) -> str:
+def speaker_replace_links(say_text: str, translate: {},
+ detected_links: []) -> str:
"""Replaces any links in the given text with "link to [domain]".
Instead of reading out potentially very long and meaningless links
"""
- text = sayText
+ text = say_text
text = text.replace('?v=', '__v=')
- for ch in speakerRemoveChars:
- text = text.replace(ch, ' ')
+ for char in SPEAKER_REMOVE_CHARS:
+ text = text.replace(char, ' ')
text = text.replace('__v=', '?v=')
replacements = {}
- wordsList = text.split(' ')
+ words_list = text.split(' ')
if translate.get('Linked'):
- linkedStr = translate['Linked']
+ linked_str = translate['Linked']
else:
- linkedStr = 'Linked'
- prevWord = ''
- for word in wordsList:
+ linked_str = 'Linked'
+ prev_word = ''
+ for word in words_list:
if word.startswith('v='):
replacements[word] = ''
if word.startswith(':'):
if word.endswith(':'):
replacements[word] = ', emowji ' + word.replace(':', '') + ','
continue
- if word.startswith('@') and not prevWord.endswith('RT'):
+ if word.startswith('@') and not prev_word.endswith('RT'):
# replace mentions, but not re-tweets
if translate.get('mentioning'):
replacements[word] = \
translate['mentioning'] + ' ' + word[1:] + ', '
- prevWord = word
+ prev_word = word
domain = None
domain_full = None
@@ -209,94 +209,94 @@ def speaker_replace_links(sayText: str, translate: {},
domain = domain.split('/')[0]
if domain.startswith('www.'):
domain = domain.replace('www.', '')
- replacements[domain_full] = '. ' + linkedStr + ' ' + domain + '.'
- detectedLinks.append(domain_full)
- for replaceStr, newStr in replacements.items():
- sayText = sayText.replace(replaceStr, newStr)
- return sayText.replace('..', '.')
+ replacements[domain_full] = '. ' + linked_str + ' ' + domain + '.'
+ detected_links.append(domain_full)
+ for replace_str, new_str in replacements.items():
+ say_text = say_text.replace(replace_str, new_str)
+ return say_text.replace('..', '.')
-def _add_ssm_lemphasis(sayText: str) -> str:
+def _add_ssm_lemphasis(say_text: str) -> str:
"""Adds emphasis to *emphasised* text
"""
- if '*' not in sayText:
- return sayText
- text = sayText
- for ch in speakerRemoveChars:
- text = text.replace(ch, ' ')
- wordsList = text.split(' ')
+ if '*' not in say_text:
+ return say_text
+ text = say_text
+ for char in SPEAKER_REMOVE_CHARS:
+ text = text.replace(char, ' ')
+ words_list = text.split(' ')
replacements = {}
- for word in wordsList:
+ for word in words_list:
if word.startswith('*'):
if word.endswith('*'):
replacements[word] = \
'
\n' + \
' \n' + \
- ' \n' + \
@@ -351,30 +351,30 @@ def _speaker_endpoint_ssml(displayName: str, summary: str,
def get_ssm_lbox(base_dir: str, path: str,
domain: str,
system_language: str,
- instanceTitle: str,
- boxName: str) -> str:
+ instance_title: str,
+ box_name: str) -> str:
"""Returns SSML for the given timeline
"""
nickname = path.split('/users/')[1]
if '/' in nickname:
nickname = nickname.split('/')[0]
- speakerFilename = \
+ speaker_filename = \
acct_dir(base_dir, nickname, domain) + '/speaker.json'
- if not os.path.isfile(speakerFilename):
+ if not os.path.isfile(speaker_filename):
return None
- speakerJson = load_json(speakerFilename)
- if not speakerJson:
+ speaker_json = load_json(speaker_filename)
+ if not speaker_json:
return None
gender = None
- if speakerJson.get('gender'):
- gender = speakerJson['gender']
- return _speaker_endpoint_ssml(speakerJson['name'],
- speakerJson['summary'],
- speakerJson['say'],
- speakerJson['imageDescription'],
- speakerJson['detectedLinks'],
+ if speaker_json.get('gender'):
+ gender = speaker_json['gender']
+ return _speaker_endpoint_ssml(speaker_json['name'],
+ speaker_json['summary'],
+ speaker_json['say'],
+ speaker_json['imageDescription'],
+ speaker_json['detectedLinks'],
system_language,
- instanceTitle, gender)
+ instance_title, gender)
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:
content = content.replace(' <3', ' ' + translate['heart'])
content = remove_html(html_replace_quote_marks(content))
- detectedLinks = []
- content = speaker_replace_links(content, translate, detectedLinks)
+ detected_links = []
+ content = speaker_replace_links(content, translate, detected_links)
# replace all double spaces
while ' ' in content:
content = content.replace(' ', ' ')
content = content.replace(' . ', '. ').strip()
- sayContent = _speaker_pronounce(base_dir, content, translate)
+ say_content = _speaker_pronounce(base_dir, content, translate)
# replace all double spaces
- while ' ' in sayContent:
- sayContent = sayContent.replace(' ', ' ')
- return sayContent.replace(' . ', '. ').strip(), detectedLinks
+ while ' ' in say_content:
+ say_content = say_content.replace(' ', ' ')
+ return say_content.replace(' . ', '. ').strip(), detected_links
def _post_to_speaker_json(base_dir: str, http_prefix: str,
nickname: str, domain: str, domain_full: str,
post_json_object: {}, person_cache: {},
- translate: {}, announcingActor: str,
+ translate: {}, announcing_actor: str,
theme_name: str) -> {}:
"""Converts an ActivityPub post into some Json containing
speech synthesis parameters.
@@ -418,7 +418,7 @@ def _post_to_speaker_json(base_dir: str, http_prefix: str,
return
if not isinstance(post_json_object['object']['content'], str):
return
- detectedLinks = []
+ detected_links = []
content = urllib.parse.unquote_plus(post_json_object['object']['content'])
content = html.unescape(content)
content = content.replace('
', '').replace('
', ' ') @@ -427,35 +427,35 @@ def _post_to_speaker_json(base_dir: str, http_prefix: str, if ' <3' in content: content = content.replace(' <3', ' ' + translate['heart']) 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 while ' ' in content: content = content.replace(' ', ' ') content = content.replace(' . ', '. ').strip() - sayContent = content - sayContent = _speaker_pronounce(base_dir, content, translate) + say_content = content + say_content = _speaker_pronounce(base_dir, content, translate) # replace all double spaces - while ' ' in sayContent: - sayContent = sayContent.replace(' ', ' ') - sayContent = sayContent.replace(' . ', '. ').strip() + while ' ' in say_content: + say_content = say_content.replace(' ', ' ') + say_content = say_content.replace(' . ', '. ').strip() else: - sayContent = content + say_content = content - imageDescription = '' + image_description = '' if post_json_object['object'].get('attachment'): - attachList = post_json_object['object']['attachment'] - if isinstance(attachList, list): - for img in attachList: + attach_list = post_json_object['object']['attachment'] + if isinstance(attach_list, list): + for img in attach_list: if not isinstance(img, dict): continue if img.get('name'): if isinstance(img['name'], str): - imageDescription += \ + image_description += \ img['name'] + '. ' - isDirect = is_dm(post_json_object) + is_direct = is_dm(post_json_object) 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 = '' 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) summary = html.unescape(summary) - speakerName = \ + speaker_name = \ get_display_name(base_dir, post_json_object['actor'], person_cache) - if not speakerName: + if not speaker_name: return - speakerName = _remove_emoji_from_text(speakerName) - speakerName = speakerName.replace('_', ' ') - speakerName = camel_case_split(speakerName) + speaker_name = _remove_emoji_from_text(speaker_name) + speaker_name = speaker_name.replace('_', ' ') + speaker_name = camel_case_split(speaker_name) gender = get_gender_from_bio(base_dir, post_json_object['actor'], person_cache, translate) - if announcingActor: - announcedNickname = get_nickname_from_actor(announcingActor) - announcedDomain, announcedport = get_domain_from_actor(announcingActor) - if announcedNickname and announcedDomain: - announcedHandle = announcedNickname + '@' + announcedDomain - sayContent = \ + if announcing_actor: + announced_nickname = get_nickname_from_actor(announcing_actor) + announced_domain, _ = \ + get_domain_from_actor(announcing_actor) + if announced_nickname and announced_domain: + announced_handle = announced_nickname + '@' + announced_domain + say_content = \ translate['announces'] + ' ' + \ - announcedHandle + '. ' + sayContent + announced_handle + '. ' + say_content content = \ translate['announces'] + ' ' + \ - announcedHandle + '. ' + content + announced_handle + '. ' + content post_id = None if post_json_object['object'].get('id'): post_id = remove_id_ending(post_json_object['object']['id']) - followRequestsExist = False - followRequestsList = [] - accountsDir = acct_dir(base_dir, nickname, domain_full) - approveFollowsFilename = accountsDir + '/followrequests.txt' - if os.path.isfile(approveFollowsFilename): - with open(approveFollowsFilename, 'r') as fp: - follows = fp.readlines() + follow_requests_exist = False + follow_requests_list = [] + accounts_dir = acct_dir(base_dir, nickname, domain_full) + approve_follows_filename = accounts_dir + '/followrequests.txt' + if os.path.isfile(approve_follows_filename): + with open(approve_follows_filename, 'r') as fp_foll: + follows = fp_foll.readlines() if len(follows) > 0: - followRequestsExist = True + follow_requests_exist = True for i in range(len(follows)): follows[i] = follows[i].strip() - followRequestsList = follows - postDM = False - dmFilename = accountsDir + '/.newDM' - if os.path.isfile(dmFilename): - postDM = True - postReply = False - replyFilename = accountsDir + '/.newReply' - if os.path.isfile(replyFilename): - postReply = True - likedBy = '' - likeFilename = accountsDir + '/.newLike' - if os.path.isfile(likeFilename): - with open(likeFilename, 'r') as fp: - likedBy = fp.read() - calendarFilename = accountsDir + '/.newCalendar' - postCal = os.path.isfile(calendarFilename) - shareFilename = accountsDir + '/.newShare' - postShare = os.path.isfile(shareFilename) + follow_requests_list = follows + post_dm = False + dm_filename = accounts_dir + '/.newDM' + if os.path.isfile(dm_filename): + post_dm = True + post_reply = False + reply_filename = accounts_dir + '/.newReply' + if os.path.isfile(reply_filename): + post_reply = True + liked_by = '' + like_filename = accounts_dir + '/.newLike' + if os.path.isfile(like_filename): + with open(like_filename, 'r') as fp_like: + liked_by = fp_like.read() + calendar_filename = accounts_dir + '/.newCalendar' + post_cal = os.path.isfile(calendar_filename) + share_filename = accounts_dir + '/.newShare' + post_share = os.path.isfile(share_filename) - return _speaker_endpoint_json(speakerName, summary, - content, sayContent, imageDescription, - detectedLinks, gender, post_id, - postDM, postReply, - followRequestsExist, - followRequestsList, - likedBy, published, - postCal, postShare, theme_name, - isDirect, replyToYou) + return _speaker_endpoint_json(speaker_name, summary, + content, say_content, image_description, + detected_links, gender, post_id, + post_dm, post_reply, + follow_requests_exist, + follow_requests_list, + liked_by, published, + post_cal, post_share, theme_name, + is_direct, reply_to_you) def update_speaker(base_dir: str, http_prefix: str, nickname: str, domain: str, domain_full: str, post_json_object: {}, person_cache: {}, - translate: {}, announcingActor: str, + translate: {}, announcing_actor: str, theme_name: str) -> None: """ Generates a json file which can be used for TTS announcement of incoming inbox posts """ - speakerJson = \ + speaker_json = \ _post_to_speaker_json(base_dir, http_prefix, nickname, domain, domain_full, post_json_object, person_cache, - translate, announcingActor, + translate, announcing_actor, theme_name) - speakerFilename = acct_dir(base_dir, nickname, domain) + '/speaker.json' - save_json(speakerJson, speakerFilename) + speaker_filename = acct_dir(base_dir, nickname, domain) + '/speaker.json' + save_json(speaker_json, speaker_filename)