Speaker option

merge-requests/21/head
Bob Mottram 2021-03-01 19:16:33 +00:00
parent 8f8c70ed6a
commit 6a33bce7c1
2 changed files with 132 additions and 0 deletions

View File

@ -75,6 +75,10 @@ from theme import setTheme
from announce import sendAnnounceViaServer
from socnet import instancesGraph
from migrate import migrateAccounts
from speaker import getSpeakerFromServer
from speaker import getSpeakerPitch
from speaker import getSpeakerRate
from speaker import getSpeakerRange
import argparse
@ -429,6 +433,10 @@ parser.add_argument('--level', dest='skillLevelPercent', type=int,
parser.add_argument('--status', '--availability', dest='availability',
type=str, default=None,
help='Set an availability status')
parser.add_argument('--speaker', '--tts', dest='speaker',
type=str, default=None,
help='Announce posts as they arrive at your ' +
'inbox using TTS. --speaker [handle]')
parser.add_argument('--block', dest='block', type=str, default=None,
help='Block a particular address')
parser.add_argument('--unblock', dest='unblock', type=str, default=None,
@ -1887,6 +1895,65 @@ if args.availability:
time.sleep(1)
sys.exit()
if args.speaker:
# Announce posts as they arrive in your inbox using text-to-speech
if args.speaker.startswith('@'):
args.speaker = args.speaker[1:]
if '@' not in args.speaker:
print('Specify the handle of the speaker nickname@domain')
sys.exit()
nickname = args.speaker.split('@')[0]
domain = args.speaker.split('@')[1]
if not nickname:
print('Specify a nickname with the --nickname option')
sys.exit()
if not args.password:
print('Specify a password with the --password option')
sys.exit()
proxyType = None
if args.tor or domain.endswith('.onion'):
proxyType = 'tor'
if domain.endswith('.onion'):
args.port = 80
elif args.i2p or domain.endswith('.i2p'):
proxyType = 'i2p'
if domain.endswith('.i2p'):
args.port = 80
elif args.gnunet:
proxyType = 'gnunet'
print('Setting up espeak')
from espeak import espeak
session = createSession(proxyType)
print('Running speaker for ' + nickname + '@' + domain)
prevSay = ''
while (1):
speakerJson = \
getSpeakerFromServer(baseDir, session, nickname, args.password,
domain, port,
httpPrefix,
True, __version__)
if speakerJson:
if speakerJson['say'] != prevSay:
print(speakerJson['name'] + ': ' + speakerJson['say'] + '\n')
pitch = getSpeakerPitch(speakerJson['name'])
espeak.set_parameter(espeak.Parameter.Pitch, pitch)
rate = getSpeakerRate(speakerJson['name'])
espeak.set_parameter(espeak.Parameter.Rate, 110)
srange = getSpeakerRange(speakerJson['name'])
espeak.set_parameter(espeak.Parameter.Range, srange)
espeak.synth(speakerJson['name'])
time.sleep(3)
espeak.synth(speakerJson['say'])
prevSay = speakerJson['say']
time.sleep(20)
sys.exit()
if federationList:
print('Federating with: ' + str(federationList))

65
speaker.py 100644
View File

@ -0,0 +1,65 @@
__filename__ = "speaker.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.2.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import random
from auth import createBasicAuthHeader
from session import getJson
from utils import getFullDomain
def getSpeakerPitch(displayName: str) -> int:
"""Returns the speech synthesis pitch for the given name
"""
random.seed(displayName)
return random.randint(1, 100)
def getSpeakerRate(displayName: str) -> int:
"""Returns the speech synthesis rate for the given name
"""
random.seed(displayName)
return random.randint(50, 120)
def getSpeakerRange(displayName: str) -> int:
"""Returns the speech synthesis range for the given name
"""
random.seed(displayName)
return random.randint(300, 800)
def getSpeakerFromServer(baseDir: str, session,
nickname: str, password: str,
domain: str, port: int,
httpPrefix: str,
debug: bool, projectVersion: str) -> {}:
"""Returns some json which contains the latest inbox
entry in a minimal format suitable for a text-to-speech reader
"""
if not session:
print('WARN: No session for getSpeakerFromServer')
return 6
domainFull = getFullDomain(domain, port)
authHeader = createBasicAuthHeader(nickname, password)
headers = {
'host': domain,
'Content-type': 'application/json',
'Authorization': authHeader
}
url = \
httpPrefix + '://' + \
domainFull + '/users/' + nickname + '/speaker'
speakerJson = \
getJson(session, url, headers, None,
__version__, httpPrefix, domain)
return speakerJson