Add speakable text for desktop client

merge-requests/30/head
Bob Mottram 2021-03-18 17:27:46 +00:00
parent b677ff544a
commit c9e36e8577
5 changed files with 74 additions and 31 deletions

View File

@ -10,7 +10,6 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer, HTTPServer
import sys import sys
import json import json
import time import time
import locale
import urllib.parse import urllib.parse
import datetime import datetime
from socket import error as SocketError from socket import error as SocketError
@ -192,6 +191,7 @@ from shares import addShare
from shares import removeShare from shares import removeShare
from shares import expireShares from shares import expireShares
from categories import setHashtagCategory from categories import setHashtagCategory
from utils import loadTranslationsFromFile
from utils import getLocalNetworkAddresses from utils import getLocalNetworkAddresses
from utils import decodedHost from utils import decodedHost
from utils import isPublicPost from utils import isPublicPost
@ -14443,32 +14443,11 @@ def runDaemon(brochMode: bool,
httpd.translate = {} httpd.translate = {}
httpd.systemLanguage = 'en' httpd.systemLanguage = 'en'
if not unitTest: if not unitTest:
if not os.path.isdir(baseDir + '/translations'): httpd.translate, httpd.systemLanguage = \
print('ERROR: translations directory not found') loadTranslationsFromFile(baseDir, language)
return print('System language: ' + httpd.systemLanguage)
if not language:
systemLanguage = locale.getdefaultlocale()[0]
else:
systemLanguage = language
if not systemLanguage:
systemLanguage = 'en'
if '_' in systemLanguage:
systemLanguage = systemLanguage.split('_')[0]
while '/' in systemLanguage:
systemLanguage = systemLanguage.split('/')[1]
if '.' in systemLanguage:
systemLanguage = systemLanguage.split('.')[0]
translationsFile = baseDir + '/translations/' + \
systemLanguage + '.json'
if not os.path.isfile(translationsFile):
systemLanguage = 'en'
translationsFile = baseDir + '/translations/' + \
systemLanguage + '.json'
print('System language: ' + systemLanguage)
httpd.systemLanguage = systemLanguage
httpd.translate = loadJson(translationsFile)
if not httpd.translate: if not httpd.translate:
print('ERROR: no translations loaded from ' + translationsFile) print('ERROR: no translations were loaded')
sys.exit() sys.exit()
# For moderated newswire feeds this is the amount of time allowed # For moderated newswire feeds this is the amount of time allowed

View File

@ -15,6 +15,7 @@ import webbrowser
import urllib.parse import urllib.parse
from pathlib import Path from pathlib import Path
from random import randint from random import randint
from utils import loadTranslationsFromFile
from utils import removeHtml from utils import removeHtml
from utils import getStatusNumber from utils import getStatusNumber
from utils import loadJson from utils import loadJson
@ -24,6 +25,7 @@ from utils import getDomainFromActor
from utils import getFullDomain from utils import getFullDomain
from utils import isPGPEncrypted from utils import isPGPEncrypted
from session import createSession from session import createSession
from speaker import speakableText
from speaker import getSpeakerPitch from speaker import getSpeakerPitch
from speaker import getSpeakerRate from speaker import getSpeakerRate
from speaker import getSpeakerRange from speaker import getSpeakerRange
@ -425,10 +427,11 @@ def _textOnlyContent(content: str) -> str:
return removeHtml(content) return removeHtml(content)
def _readLocalBoxPost(boxName: str, def _readLocalBoxPost(baseDir: str, boxName: str,
pageNumber: int, index: int, boxJson: {}, pageNumber: int, index: int, boxJson: {},
systemLanguage: str, systemLanguage: str,
screenreader: str, espeak) -> {}: screenreader: str, espeak,
translate: {}) -> {}:
"""Reads a post from the given timeline """Reads a post from the given timeline
Returns the speaker json Returns the speaker json
""" """
@ -458,7 +461,7 @@ def _readLocalBoxPost(boxName: str,
return return
content = _safeMessage(content) content = _safeMessage(content)
messageStr = content messageStr = speakableText(baseDir, content, translate)
if screenreader: if screenreader:
time.sleep(2) time.sleep(2)
@ -911,6 +914,7 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str,
noKeyPress: bool, noKeyPress: bool,
storeInboxPosts: bool, storeInboxPosts: bool,
showNewPosts: bool, showNewPosts: bool,
language: str,
debug: bool) -> None: debug: bool) -> None:
"""Runs the desktop and screen reader client, """Runs the desktop and screen reader client,
which announces new inbox items which announces new inbox items
@ -977,6 +981,12 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str,
newDMsExist = False newDMsExist = False
pgpKeyUpload = False pgpKeyUpload = False
sayStr = indent + 'Loading translations file...'
_sayCommand(sayStr, sayStr, screenreader,
systemLanguage, espeak)
translate, systemLanguage = \
loadTranslationsFromFile(baseDir, language)
sayStr = indent + 'Connecting...' sayStr = indent + 'Connecting...'
_sayCommand(sayStr, sayStr, screenreader, _sayCommand(sayStr, sayStr, screenreader,
systemLanguage, espeak) systemLanguage, espeak)
@ -1124,10 +1134,10 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str,
if boxJson and postIndexStr.isdigit(): if boxJson and postIndexStr.isdigit():
postIndex = int(postIndexStr) postIndex = int(postIndexStr)
postJsonObject = \ postJsonObject = \
_readLocalBoxPost(currTimeline, _readLocalBoxPost(baseDir, currTimeline,
pageNumber, postIndex, boxJson, pageNumber, postIndex, boxJson,
systemLanguage, screenreader, systemLanguage, screenreader,
espeak) espeak, translate)
print('') print('')
elif commandStr == 'reply' or commandStr == 'r': elif commandStr == 'reply' or commandStr == 'r':
if postJsonObject: if postJsonObject:

View File

@ -1926,6 +1926,7 @@ if args.desktop:
args.noKeyPress, args.noKeyPress,
storeInboxPosts, storeInboxPosts,
args.notifyShowNewPosts, args.notifyShowNewPosts,
args.language,
args.debug) args.debug)
sys.exit() sys.exit()

View File

@ -405,6 +405,30 @@ def getSSMLbox(baseDir: str, path: str,
instanceTitle, gender) instanceTitle, gender)
def speakableText(baseDir: str, content: str, translate: {}) -> str:
"""Convert the given text to a speakable version
which includes changes for prononciation
"""
if isPGPEncrypted(content):
return
# replace some emoji before removing html
if ' <3' in content:
content = content.replace(' <3', ' ' + translate['heart'])
content = removeHtml(htmlReplaceQuoteMarks(content))
detectedLinks = []
content = speakerReplaceLinks(content, translate, detectedLinks)
# replace all double spaces
while ' ' in content:
content = content.replace(' ', ' ')
content = content.replace(' . ', '. ').strip()
sayContent = _speakerPronounce(baseDir, content, translate)
# replace all double spaces
while ' ' in sayContent:
sayContent = sayContent.replace(' ', ' ')
return sayContent.replace(' . ', '. ').strip()
def _postToSpeakerJson(baseDir: str, httpPrefix: str, def _postToSpeakerJson(baseDir: str, httpPrefix: str,
nickname: str, domain: str, domainFull: str, nickname: str, domain: str, domainFull: str,
postJsonObject: {}, personCache: {}, postJsonObject: {}, personCache: {},

View File

@ -13,6 +13,7 @@ import shutil
import datetime import datetime
import json import json
import idna import idna
import locale
from pprint import pprint from pprint import pprint
from calendar import monthrange from calendar import monthrange
from followingCalendar import addPersonToCalendar from followingCalendar import addPersonToCalendar
@ -2150,3 +2151,31 @@ def isPGPEncrypted(content: str) -> bool:
if '--END PGP MESSAGE--' in content: if '--END PGP MESSAGE--' in content:
return True return True
return False return False
def loadTranslationsFromFile(baseDir: str, language: str) -> ({}, str):
"""Returns the translations dictionary
"""
if not os.path.isdir(baseDir + '/translations'):
print('ERROR: translations directory not found')
return
if not language:
systemLanguage = locale.getdefaultlocale()[0]
else:
systemLanguage = language
if not systemLanguage:
systemLanguage = 'en'
if '_' in systemLanguage:
systemLanguage = systemLanguage.split('_')[0]
while '/' in systemLanguage:
systemLanguage = systemLanguage.split('/')[1]
if '.' in systemLanguage:
systemLanguage = systemLanguage.split('.')[0]
translationsFile = baseDir + '/translations/' + \
systemLanguage + '.json'
if not os.path.isfile(translationsFile):
systemLanguage = 'en'
translationsFile = baseDir + '/translations/' + \
systemLanguage + '.json'
print('System language: ' + systemLanguage)
return loadJson(translationsFile), systemLanguage