Merge branch 'bleed'

This commit is contained in:
chrys 2017-10-26 00:22:33 +02:00
commit 2230a45fac
31 changed files with 1136 additions and 368 deletions

View File

@ -5,10 +5,16 @@ Things needing little knowledge are marked with "(Easy for contribution)". so ju
[X] = Done
Cleanups:
- split oldValues := newValues out to helper function (Easy for contribution)
- generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution)
[] next item
[] prev item
[] curr item
[] first item
[] last item
- split oldValues := newValues out to helper function
[] split it out
[] use it in vcsa driver
[] Migrate *Data.py to classes and use getter/setter (Easy for contribution)
- Migrate *Data.py to classes and use getter/setter (Easy for contribution)
[] commandsData.py
[] eventData.py
[] generalData.py
@ -21,29 +27,22 @@ Cleanups:
General:
- commands
[] place last spoken to clipboard
[] place last spoken to clipboard (Easy for contribution)
- imporove attribute handling
[] improve attributes_curr_char
[] add an attribute sound
[] beep on cursor/ review by char (capital wins)
[] beep on review by word (once for multiple, capital wins)
[] configurable (by char, by word, none)
https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
[] improve attributes_curr_char
[] add an attribute sound (Easy for contribution)
[] beep on cursor/ review by char (capital wins)
[] beep on review by word (once for multiple, capital wins)
[] configurable (by char, by word, none)
https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
- Improved Say all
[] all the text of all pages
[] command to stop and place review cursor at this position
[] command to slow down speech on keypress
- generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution)
[] next item
[] prev item
[] curr item
[] first item
[] last item
[] speech callbacks
[] speech process by word
[] all the text of all pages
[] command to stop and place review cursor at this position
[] command to slow down speech on keypress
- make it runnable via pypy3
[] wrapper script for running Fenrir to check if pypy exists, use python3 as fallback.
[] wrapper script for running Fenrir to check if pypy exists, use python3 as fallback.
Braille Support:
[] brailleFocusMode:
@ -77,11 +76,11 @@ Driver:
https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py
Settings:
[] write settings (Easy for contribution)
[] menue for settings configuration (Easy for contribution)
[] write settings (Easy for contribution)
[] menue for settings configuration (Easy for contribution)
Application Profiles (low priority):
- reimplement process detection without subprocessing // this is started by chrys
- reimplement process detection without subprocessing
- fenrir is not able to detect the current application inside of screen.
ps -e -H -o pid,pgrp,ppid,tty,cmd
http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process/24862213
@ -94,6 +93,13 @@ Application Profiles (low priority):
- per application shortcuts
-----------DONE----------------
Cleanups:
- inheritation for drivers
[Done] Speech (All)
[Done] Braille (All)
[Done] Sound (All)
[Done] Input (All)
[Done] Screen (All)
General:
Braille Support:
Driver:

View File

@ -105,6 +105,7 @@ KEY_FENRIR,KEY_PAGEUP=prev_clipboard
KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
KEY_FENRIR,KEY_C=copy_marked_to_clipboard
KEY_FENRIR,KEY_CTRL,KEY_U=copy_last_echo_to_clipboard
KEY_FENRIR,KEY_V=paste_clipboard
KEY_FENRIR,KEY_F5=import_clipboard_from_file
KEY_FENRIR,KEY_F6=export_clipboard_to_file

View File

@ -105,6 +105,7 @@ KEY_FENRIR,KEY_PAGEUP=prev_clipboard
KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
KEY_FENRIR,KEY_C=copy_marked_to_clipboard
KEY_FENRIR,KEY_CTRL,KEY_U=copy_last_echo_to_clipboard
KEY_FENRIR,KEY_V=paste_clipboard
KEY_FENRIR,KEY_F5=import_clipboard_from_file
KEY_FENRIR,KEY_F6=export_clipboard_to_file

View File

@ -7,7 +7,7 @@ from setuptools import find_packages
from setuptools import setup
fenrirVersion = '1.5'
packageVersion = 'post10'
packageVersion = 'post11'
# handle flags for package manager like yaourt and pacaur.
forceSettings = False
@ -97,6 +97,7 @@ setup(
"pyudev",
"setuptools",
"pexpect",
"pyttsx3",
],
)

View File

@ -5,10 +5,11 @@
# By Chrys, Storm Dragon, and contributers.
from core import debug
from core.brailleDriver import brailleDriver
class driver():
class driver(brailleDriver):
def __init__(self):
self._isInitialized = False
brailleDriver.__init__(self)
self._brl = None
def initialize(self, environment):

View File

@ -0,0 +1,49 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
from core.brailleDriver import brailleDriver
class driver(brailleDriver):
def __init__(self):
brailleDriver.__init__(self)
def initialize(self, environment):
self.env = environment
self._isInitialized = True
self.deviceSize = (40,0)
print('Braille Debug Driver: Initialized')
def getDeviceSize(self):
if not self._isInitialized:
return (0,0)
print('Braille Debug Driver: getDeviceSize ' + str(self.deviceSize))
return self.deviceSize
def writeText(self,text):
if not self._isInitialized:
return
print('Braille Debug Driver: writeText:' + str(text))
print('Braille Debug Driver: -----------------------------------')
def connectDevice(self):
print('Braille Debug Driver: connectDevice')
def enterScreen(self, screen):
if not self._isInitialized:
return
print('Braille Debug Driver: enterScreen')
def leveScreen(self):
if not self._isInitialized:
return
print('Braille Debug Driver: leveScreen')
def shutdown(self):
if self._isInitialized:
self.leveScreen()
self._isInitialized = False
print('Braille Debug Driver: Shutdown')

View File

@ -5,51 +5,8 @@
# By Chrys, Storm Dragon, and contributers.
from core import debug
from core.brailleDriver import brailleDriver
class driver():
class driver(brailleDriver):
def __init__(self):
self.printMessages = False
def initialize(self, environment):
self.env = environment
self._isInitialized = True
self.deviceSize = (40,0)
if self.printMessages:
print('BrailleDummyDriver: Initialize')
def getDeviceSize(self):
if not self._isInitialized:
return (0,0)
if self.printMessages:
print('BrailleDummyDriver: getDeviceSize ' + str(self.deviceSize))
return self.deviceSize
def writeText(self,text):
if not self._isInitialized:
return
if self.printMessages:
print('BrailleDummyDriver: writeText:' + str(text))
print('BrailleDummyDriver: -----------------------------------')
def connectDevice(self):
if self.printMessages:
print('BrailleDummyDriver: connectDevice')
def enterScreen(self, screen):
if not self._isInitialized:
return
if self.printMessages:
print('BrailleDummyDriver: enterScreen')
def leveScreen(self):
if not self._isInitialized:
return
if self.printMessages:
print('BrailleDummyDriver: leveScreen')
def shutdown(self):
if not self._isInitialized:
return
if self.printMessages:
print('BrailleDummyDriver: Shutdown')
brailleDriver.__init__(self)

View File

@ -0,0 +1,28 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
from utils import mark_utils
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return _('copies last presented text to the currently selected clipboard')
def run(self):
lastEcho = self.env['runtime']['outputManager'].getLastEcho()
self.env['commandBuffer']['clipboard'] = [lastEcho] + self.env['commandBuffer']['clipboard'][:self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards') -1]
self.env['commandBuffer']['currClipboard'] = 0
self.env['runtime']['outputManager'].presentText(lastEcho, soundIcon='CopyToClipboard', interrupt=True)
def setCallback(self, callback):
pass

View File

@ -0,0 +1,41 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
class brailleDriver():
def __init__(self):
self._isInitialized = False
self.deviceSize = None
def initialize(self, environment):
self.env = environment
self._isInitialized = True
def getDeviceSize(self):
if not self._isInitialized:
return (0,0)
return (0,0)
def writeText(self,text):
if not self._isInitialized:
return
def connectDevice(self):
pass
def enterScreen(self, screen):
if not self._isInitialized:
return
def leveScreen(self):
if not self._isInitialized:
return
def shutdown(self):
if not self._isInitialized:
return
self.leveScreen()
self._isInitialized = False

View File

@ -0,0 +1,49 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
class inputDriver():
def __init__(self):
self._initialized = False
def initialize(self, environment):
self.env = environment
self._isInitialized = True
def shutdown(self):
if self._initialized:
self.releaseDevices()
self._isInitialized = False
def getInputEvent(self):
time.sleep(0.05)
if not self._initialized:
return None
def writeEventBuffer(self):
if not self._initialized:
return
def clearEventBuffer(self):
if not self._initialized:
return
del self.env['input']['eventBuffer'][:]
def updateInputDevices(self, force = False, init = False):
if not self._initialized:
return
def getLedState(self, led = 0):
if not self._initialized:
return False
return False
def toggleLedState(self, led = 0):
if not self._initialized:
return None
def grabDevices(self):
if not self._initialized:
return None
def releaseDevices(self):
if not self._initialized:
return None
def __del__(self):
if not self._initialized:
return None
self.releaseDevices()

View File

@ -10,7 +10,7 @@ import string, time
class outputManager():
def __init__(self):
pass
self.lastEcho = ''
def initialize(self, environment):
self.env = environment
self.env['runtime']['settingsManager'].loadDriver(\
@ -37,11 +37,12 @@ class outputManager():
if toAnnounceCapital:
if self.playSoundIcon('capital', False):
toAnnounceCapital = False
self.lastEcho = text
self.speakText(text, interrupt, ignorePunctuation,toAnnounceCapital)
if flush:
self.brailleText(text, flush)
def getLastEcho(self):
return self.lastEcho
def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False):
if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
self.env['runtime']['debug'].writeDebugOut("Speech disabled in outputManager.speakText",debug.debugLevel.INFO)
@ -110,7 +111,7 @@ class outputManager():
self.env['output']['messageOffset'] = {'x':0,'y':0}
self.env['output']['messageText'] = text
displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
self.env['runtime']['brailleDriver'].writeText('flush'+displayText)
self.env['runtime']['brailleDriver'].writeText('flush '+ displayText)
else:
if self.env['output']['nextFlush'] < time.time():
if self.env['output']['messageText'] != '':
@ -121,7 +122,7 @@ class outputManager():
x, y, self.env['output']['brlText'] = \
line_utils.getCurrentLine(cursor['x'], cursor['y'], self.env['screen']['newContentText'])
displayText = self.getBrailleTextWithOffset(self.env['screen']['newContentText'], self.env['output']['cursorOffset'], cursor)
self.env['runtime']['brailleDriver'].writeText('notflush'+displayText)
self.env['runtime']['brailleDriver'].writeText('notflush ' + displayText)
else:
displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
self.env['runtime']['brailleDriver'].writeText('flush'+displayText)

View File

@ -0,0 +1,48 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
#attrib:
#http://rampex.ihep.su/Linux/linux_howto/html/tutorials/mini/Colour-ls-6.html
#0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = purple, 6 = brown/yellow, 7 = white.
#https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
#blink = 5 if attr & 1 else 0
#bold = 1 if attr & 16 else 0
from core import debug
class screenDriver():
def __init__(self):
self._isInitialized = False
self.bgColorNames = {0: _('black'), 1: _('blue'), 2: _('green'), 3: _('cyan'), 4: _('red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('white')}
self.fgColorNames = {0: _('Black'), 1: _('Blue'), 2: _('Green'), 3: _('Cyan'), 4: _('Red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('Light gray'), 8: _('Dark gray'), 9: _('Light blue'), 10: ('Light green'), 11: _('Light cyan'), 12: _('Light red'), 13: _('Light magenta'), 14: _('Light yellow'), 15: _('White')}
def initialize(self, environment):
self.env = environment
self._isInitialized = True
def shutdown(self):
self._isInitialized = False
def getCurrScreen(self):
pass
def getCurrApplication(self):
pass
def getSessionInformation(self):
pass
def getFenrirBGColor(self, attribute):
return ''
def getFenrirFGColor(self, attribute):
return ''
def getFenrirUnderline(self, attribute):
return ''
def getFenrirBold(self, attribute):
return ''
def getFenrirBlink(self, attribute):
return ''
def getFenrirFont(self, attribute):
return ''
def getFenrirFontSize(self, attribute):
return ''
def update(self, trigger='onUpdate'):
pass

View File

@ -0,0 +1,47 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
class soundDriver():
def __init__(self):
self.volume = None
self._initialized = False
def initialize(self, environment):
self.env = environment
self._initialized = True
def shutdown(self):
if not self._initialized:
return
self.cancel()
self._isInitialized = False
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
if not self._initialized:
return
if interrupt:
self.cancel()
def playSoundFile(self, filePath, interrupt = True):
if not self._initialized:
return
if interrupt:
self.cancel()
def cancel(self):
if not self._initialized:
return
def setCallback(self, callback):
if not self._initialized:
return
def setVolume(self, volume):
if not self._initialized:
return
self.volume = volume

View File

@ -0,0 +1,102 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
class speechDriver():
def __init__(self):
self._isInitialized = False
self.language = None
self.voice = None
self.module = None
self.pitch = None
self.rate = None
self.volume = None
def initialize(self, environment):
self.env = environment
self._isInitialized = True
def shutdown(self):
if self._isInitialized:
self.cancel()
self._isInitialized = False
def speak(self,text, queueable=True):
if not self._isInitialized:
return
if not queueable:
self.cancel()
def cancel(self):
if not self._isInitialized:
return
def setCallback(self, callback):
if not self._isInitialized:
return
if not callback:
return
def clear_buffer(self):
if not self._isInitialized:
return
def setVoice(self, voice):
if not self._isInitialized:
return
if not isinstance(voice, float):
return
if voice == '':
return
self.voice = voice
def setPitch(self, pitch):
if not self._isInitialized:
return
if not isinstance(pitch, float):
return
if pitch < 0.0:
retrun
if pitch > 1.0:
return
self.pitch = pitch
def setRate(self, rate):
if not self._isInitialized:
return
if not isinstance(rate, float):
return
if rate < 0.0:
retrun
if rate > 1.0:
return
self.rate = rate
def setModule(self, module):
if not self._isInitialized:
return
if not isinstance(module, str):
return
if module == '':
return
self.module = module
def setLanguage(self, language):
if not self._isInitialized:
return
if not isinstance(language, str):
return
if language == '':
return
self.language = language
def setVolume(self, volume):
if not self._isInitialized:
return
if not isinstance(volume,float):
return
if volume < 0.0:
retrun
if volume > 1.0:
return
self.volume = volume

View File

@ -0,0 +1,66 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import time
from core import debug
from core.inputDriver import inputDriver
class driver(inputDriver):
def __init__(self):
inputDriver.__init__(self)
def initialize(self, environment):
self.env = environment
self._initialized = True
print('Input Debug Driver: Initialized')
def shutdown(self):
if self._initialized:
self.releaseDevices()
self._initialized = False
print('Input Debug Driver: Shutdown')
def getInputEvent(self):
time.sleep(0.05)
if not self._initialized:
return None
print('Input Debug Driver: getInputEvent')
return None
def writeEventBuffer(self):
if not self._initialized:
return
print('Input Debug Driver: writeEventBuffer')
def clearEventBuffer(self):
if not self._initialized:
return
del self.env['input']['eventBuffer'][:]
print('Input Debug Driver: clearEventBuffer')
def updateInputDevices(self, force = False, init = False):
if not self._initialized:
return
print('Input Debug Driver: updateInputDevices')
def getLedState(self, led = 0):
if not self._initialized:
return False
return False
def toggleLedState(self, led = 0):
if not self._initialized:
return
print('Input Debug Driver: toggleLedState')
def grabDevices(self):
if not self._initialized:
return
print('Input Debug Driver: grabDevices')
def releaseDevices(self):
if not self._initialized:
return
print('Input Debug Driver: releaseDevices')
def __del__(self):
if self._initialized:
self.releaseDevices()
print('Input Debug Driver: __del__')

View File

@ -6,55 +6,13 @@
import time
from core import debug
from core.inputDriver import inputDriver
class driver():
class driver(inputDriver):
def __init__(self):
self._initialized = False
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
inputDriver.__init__(self)
def getInputEvent(self):
time.sleep(0.05)
time.sleep(0.1)
if not self._initialized:
return None
def writeEventBuffer(self):
if not self._initialized:
return
def clearEventBuffer(self):
if not self._initialized:
return
del self.env['input']['eventBuffer'][:]
def updateInputDevices(self, force = False, init = False):
if not self._initialized:
return
def getLedState(self, led = 0):
if not self._initialized:
return False
return False
def toggleLedState(self, led = 0):
if not self._initialized:
return None
def grabDevices(self):
if not self._initialized:
return None
def releaseDevices(self):
if not self._initialized:
return None
def __del__(self):
if not self._initialized:
return None
self.releaseDevices()

View File

@ -30,16 +30,16 @@ from ctypes import c_bool
from core.eventData import fenrirEventType
from core import inputData
from core import debug
from core.inputDriver import inputDriver
class driver():
class driver(inputDriver):
def __init__(self):
inputDriver.__init__(self)
self._manager = multiprocessing.Manager()
self.iDevices = {}
self.iDevicesFD = self._manager.list()
self.uDevices = {}
self.iDeviceNo = 0
self._initialized = False
self.watchDog = Value(c_bool, True)
def initialize(self, environment):
self.env = environment
@ -70,9 +70,6 @@ class driver():
def plugInputDeviceWatchdogTimer(self, active):
time.sleep(2.5)
return time.time()
def shutdown(self):
if not self._initialized:
return
def inputWatchdog(self,active , params):
try:
deviceFd = []
@ -325,8 +322,4 @@ class driver():
self.uDevices.clear()
self.iDeviceNo = 0
def __del__(self):
if not self._initialized:
return

View File

@ -0,0 +1,12 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
from core.screenDriver import screenDriver
class driver(screenDriver):
def __init__(self):
screenDriver.__init__(self)

View File

@ -0,0 +1,372 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
#attrib:
#http://rampex.ihep.su/Linux/linux_howto/html/tutorials/mini/Colour-ls-6.html
#0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = purple, 6 = brown/yellow, 7 = white.
#https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
#blink = 5 if attr & 1 else 0
#bold = 1 if attr & 16 else 0
import difflib
import re
import subprocess
import glob, os
import termios
import time
import select
import dbus
import fcntl
from array import array
import errno
import sys
from utils import screen_utils
from fcntl import ioctl
from struct import unpack_from, unpack, pack
from core import debug
from core.eventData import fenrirEventType
from core.screenDriver import screenDriver
class driver(screenDriver):
def __init__(self):
screenDriver.__init__(self)
self.vcsaDevicePath = '/dev/vcsa'
self.ListSessions = None
self.charmap = {}
self.bgColorNames = {0: _('black'), 1: _('blue'), 2: _('green'), 3: _('cyan'), 4: _('red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('white')}
self.fgColorNames = {0: _('Black'), 1: _('Blue'), 2: _('Green'), 3: _('Cyan'), 4: _('Red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('Light gray'), 8: _('Dark gray'), 9: _('Light blue'), 10: ('Light green'), 11: _('Light cyan'), 12: _('Light red'), 13: _('Light magenta'), 14: _('Light yellow'), 15: _('White')}
self.hichar = None
def initialize(self, environment):
self.env = environment
self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog)
def getCurrScreen(self):
self.env['screen']['oldTTY'] = self.env['screen']['newTTY']
try:
currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r')
self.env['screen']['newTTY'] = str(currScreenFile.read()[3:-1])
currScreenFile.close()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def injectTextToScreen(self, text, screen = None):
useScreen = "/dev/tty" + self.env['screen']['newTTY']
if screen != None:
useScreen = screen
with open(useScreen, 'w') as fd:
for c in text:
fcntl.ioctl(fd, termios.TIOCSTI, c)
def getCurrApplication(self):
apps = []
try:
currScreen = self.env['screen']['newTTY']
apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
return
try:
for i in apps:
i = i.upper()
i = i.split()
i[0] = i[0]
i[1] = i[1]
if '+' in i[2]:
if i[0] != '':
if not "GREP" == i[0] and \
not "SH" == i[0] and \
not "PS" == i[0]:
if "TTY"+currScreen in i[1]:
if self.env['screen']['newApplication'] != i[0]:
self.env['screen']['newApplication'] = i[0]
return
except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def getSessionInformation(self):
try:
bus = dbus.SystemBus()
if not self.ListSessions:
obj = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1')
inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager')
self.ListSessions = inf.get_dbus_method('ListSessions')
sessions = self.ListSessions()
self.env['screen']['autoIgnoreScreens'] = []
for session in sessions:
obj = bus.get_object('org.freedesktop.login1', session[4])
inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
sessionType = inf.Get('org.freedesktop.login1.Session', 'Type')
screen = str(inf.Get('org.freedesktop.login1.Session', 'VTNr'))
if screen == '':
screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY'))
screen = screen[screen.upper().find('TTY') + 3:]
if screen == '':
self.env['runtime']['debug'].writeDebugOut('No TTY found for session:' + session[4],debug.debugLevel.ERROR)
return
if sessionType.upper() == 'X11':
self.env['screen']['autoIgnoreScreens'].append(screen)
if screen == self.env['screen']['newTTY'] :
if self.env['general']['currUser'] != session[2]:
self.env['general']['prevUser'] = self.env['general']['currUser']
self.env['general']['currUser'] = session[2]
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR)
self.env['screen']['autoIgnoreScreens'] = []
self.env['runtime']['debug'].writeDebugOut('getSessionInformation:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.debugLevel.INFO)
def updateWatchdog(self,active , eventQueue):
try:
vcsa = {}
vcsaDevices = glob.glob('/dev/vcsa*')
for vcsaDev in vcsaDevices:
index = vcsaDev[9:]
vcsa[str(index)] = open(vcsaDev,'rb')
tty = open('/sys/devices/virtual/tty/tty0/active','r')
currScreen = str(tty.read()[3:-1])
oldScreen = currScreen
watchdog = select.epoll()
watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR)
watchdog.register(tty, select.POLLPRI | select.POLLERR)
while active.value == 1:
changes = watchdog.poll(2)
for change in changes:
fileno = change[0]
event = change[1]
if fileno == tty.fileno():
self.env['runtime']['debug'].writeDebugOut('ScreenChange',debug.debugLevel.INFO)
tty.seek(0)
currScreen = str(tty.read()[3:-1])
if currScreen != oldScreen:
try:
watchdog.unregister(vcsa[ oldScreen ])
except:
pass
try:
watchdog.register(vcsa[ currScreen ], select.POLLPRI | select.POLLERR)
except:
pass
oldScreen = currScreen
eventQueue.put({"Type":fenrirEventType.ScreenChanged,"Data":''})
try:
vcsa[currScreen].seek(0)
lastScreenContent = vcsa[currScreen].read()
except:
pass
else:
self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO)
vcsa[currScreen].seek(0)
dirtyContent = vcsa[currScreen].read()
screenContent = b''
timeout = time.time()
while screenContent != dirtyContent:
screenContent = dirtyContent
if time.time() - timeout >= 0.4:
break
time.sleep(0.007)
vcsa[currScreen].seek(0)
dirtyContent = vcsa[currScreen].read()
eventQueue.put({"Type":fenrirEventType.ScreenUpdate,"Data":None})
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR)
def updateCharMap(self, screen):
self.charmap = {}
try:
tty = open('/dev/tty' + screen, 'rb')
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:' + str(e),debug.debugLevel.ERROR)
return
GIO_UNIMAP = 0x4B66
VT_GETHIFONTMASK = 0x560D
himask = array("H", (0,))
ioctl(tty, VT_GETHIFONTMASK, himask)
self.hichar, = unpack_from("@H", himask)
sz = 512
line = ''
while True:
try:
unipairs = array("H", [0]*(2*sz))
unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0]))
ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc)
break
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:scaling up sz=' + str(sz) + ' ' + str(e),debug.debugLevel.WARNING)
sz *= 2
tty.close()
ncodes, = unpack_from("@H", unimapdesc)
utable = unpack_from("@%dH" % (2*ncodes), unipairs)
for u, b in zip(utable[::2], utable[1::2]):
if self.charmap.get(b) is None:
self.charmap[b] = chr(u)
def autoDecodeVCSA(self, allData, rows, cols):
allText = ''
allAttrib = []
i = 0
for y in range(rows):
lineText = ''
lineAttrib = []
for x in range(cols):
data = allData[i: i + 2]
i += 2
if data == b' \x07':
#attr = 7
#ink = 7
#paper = 0
#ch = ' '
lineAttrib.append((7,15,0,0,0,0)) # attribute, ink, paper, blink, bold, underline
lineText += ' '
continue
(sh,) = unpack("=H", data)
attr = (sh >> 8) & 0xFF
ch = sh & 0xFF
if self.hichar == 0x100:
attr >>= 1
ink = attr & 0x0F
paper = (attr>>4) & 0x0F
blink = 0
#if attr & 1:
# blink = 1
bold = 0
#if attr & 16:
# bold = 1
#if (ink != 7) or (paper != 0):
# print(ink,paper)
if sh & self.hichar:
ch |= 0x100
try:
lineText += self.charmap[ch]
except KeyError:
lineText += '?'
lineAttrib.append((attr,ink, paper,blink,bold,0)) # attribute, ink, paper, blink, bold, underline
allText += lineText + '\n'
allAttrib += lineAttrib
return str(allText), allAttrib
def getFenrirBGColor(self, attribute):
try:
return self.bgColorNames[attribute[2]]
except Exception as e:
print(e)
return ''
def getFenrirFGColor(self, attribute):
try:
return self.fgColorNames[attribute[1]]
except Exception as e:
print(e)
return ''
def getFenrirUnderline(self, attribute):
if attribute[5] == 1:
return _('underlined')
return ''
def getFenrirBold(self, attribute):
if attribute[4] == 1:
return _('bold')
return ''
def getFenrirBlink(self, attribute):
if attribute[3] == 1:
return _('blink')
return ''
def getFenrirFont(self, attribute):
return _('Default')
def getFenrirFontSize(self, attribute):
return _('Default')
def update(self, trigger='onUpdate'):
if trigger == 'onInput': # no need for an update on input for VCSA
return
newContentBytes = b''
try:
# read screen
vcsa = open(self.vcsaDevicePath + self.env['screen']['newTTY'],'rb',0)
newContentBytes = vcsa.read()
vcsa.close()
if len(newContentBytes) < 5:
return
except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
return
# set new "old" values
self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes']
self.env['screen']['oldContentText'] = self.env['screen']['newContentText']
self.env['screen']['oldContentAttrib'] = self.env['screen']['newContentAttrib']
self.env['screen']['oldCursor'] = self.env['screen']['newCursor'].copy()
if self.env['screen']['newCursorAttrib']:
self.env['screen']['oldCursorAttrib'] = self.env['screen']['newCursorAttrib'].copy()
self.env['screen']['oldDelta'] = self.env['screen']['newDelta']
self.env['screen']['oldAttribDelta'] = self.env['screen']['newAttribDelta']
self.env['screen']['oldNegativeDelta'] = self.env['screen']['newNegativeDelta']
self.env['screen']['newContentBytes'] = newContentBytes
# get metadata like cursor or screensize
self.env['screen']['lines'] = int( self.env['screen']['newContentBytes'][0])
self.env['screen']['columns'] = int( self.env['screen']['newContentBytes'][1])
self.env['screen']['newCursor']['x'] = int( self.env['screen']['newContentBytes'][2])
self.env['screen']['newCursor']['y'] = int( self.env['screen']['newContentBytes'][3])
# analyze content
self.updateCharMap(str(self.env['screen']['newTTY']))
self.env['screen']['newContentText'], \
self.env['screen']['newContentAttrib'] =\
self.autoDecodeVCSA(self.env['screen']['newContentBytes'][4:], self.env['screen']['lines'], self.env['screen']['columns'])
if self.env['screen']['newTTY'] != self.env['screen']['oldTTY']:
self.env['screen']['oldContentBytes'] = b''
self.env['screen']['oldContentAttrib'] = None
self.env['screen']['oldContentText'] = ''
self.env['screen']['oldCursor']['x'] = 0
self.env['screen']['oldCursor']['y'] = 0
self.env['screen']['oldDelta'] = ''
self.env['screen']['oldAttribDelta'] = ''
self.env['screen']['oldCursorAttrib'] = None
self.env['screen']['newCursorAttrib'] = None
self.env['screen']['oldNegativeDelta'] = ''
# initialize current deltas
self.env['screen']['newNegativeDelta'] = ''
self.env['screen']['newDelta'] = ''
self.env['screen']['newAttribDelta'] = ''
# changes on the screen
oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
typing = False
if (self.env['screen']['oldContentText'] != self.env['screen']['newContentText']):
if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '':
if oldScreenText == '' and\
newScreenText != '':
self.env['screen']['newDelta'] = newScreenText
else:
cursorLineStart = self.env['screen']['newCursor']['y'] * self.env['screen']['columns'] + self.env['screen']['newCursor']['y']
cursorLineEnd = cursorLineStart + self.env['screen']['columns']
if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) == 1 and \
self.env['screen']['oldCursor']['y'] == self.env['screen']['newCursor']['y'] and \
self.env['screen']['newContentText'][:cursorLineStart] == self.env['screen']['oldContentText'][:cursorLineStart] and \
self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]:
cursorLineStartOffset = cursorLineStart
cursorLineEndOffset = cursorLineEnd
#if cursorLineStart < cursorLineStart + self.env['screen']['newCursor']['x'] - 4:
# cursorLineStartOffset = cursorLineStart + self.env['screen']['newCursor']['x'] - 4
if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3:
cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset]
oldScreenText = re.sub(' +',' ',oldScreenText)
newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
newScreenText = re.sub(' +',' ',newScreenText)
diff = difflib.ndiff(oldScreenText, newScreenText)
typing = True
else:
diff = difflib.ndiff( oldScreenText.split('\n'),\
newScreenText.split('\n'))
diffList = list(diff)
if self.env['runtime']['settingsManager'].getSetting('general', 'newLinePause') and not typing:
self.env['screen']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+')
else:
self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
self.env['screen']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
# track highlighted
if self.env['screen']['oldContentAttrib'] != self.env['screen']['newContentAttrib']:
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
self.env['screen']['newAttribDelta'], self.env['screen']['newCursorAttrib'] = screen_utils.trackHighlights(self.env['screen']['oldContentAttrib'], self.env['screen']['newContentAttrib'], self.env['screen']['newContentText'], self.env['screen']['columns'])

View File

@ -28,10 +28,11 @@ from fcntl import ioctl
from struct import unpack_from, unpack, pack
from core import debug
from core.eventData import fenrirEventType
from core.screenDriver import screenDriver
class driver():
class driver(screenDriver):
def __init__(self):
screenDriver.__init__(self)
self.vcsaDevicePath = '/dev/vcsa'
self.ListSessions = None
self.charmap = {}
@ -41,8 +42,6 @@ class driver():
def initialize(self, environment):
self.env = environment
self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog)
def shutdown(self):
pass
def getCurrScreen(self):
self.env['screen']['oldTTY'] = self.env['screen']['newTTY']
try:

View File

@ -0,0 +1,56 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
from core.soundDriver import soundDriver
class driver(soundDriver):
def __init__(self):
soundDriver.__init__(self)
def initialize(self, environment):
self.env = environment
self._initialized = True
print('Sound Debug Driver: Initialized')
def shutdown(self):
if not self._initialized:
return
self.cancel()
self._initialized = False
print('Sound Debug Driver: Shutdown')
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
if not self._initialized:
return
if interrupt:
self.cancel()
print('Sound Debug Driver: playFrequence:' + ' freq:' + str(frequence) + ' duration:' + str(duration) + ' adjustVolume:' + str(adjustVolume) )
print('Sound Debug Driver: -----------------------------------')
def playSoundFile(self, filePath, interrupt = True):
if not self._initialized:
return
if interrupt:
self.cancel()
print('Sound Debug Driver: playSoundFile:' + str(filePath))
print('Sound Debug Driver: -----------------------------------')
def cancel(self):
if not self._initialized:
return
print('Sound Debug Driver: Cancel')
def setCallback(self, callback):
if not self._initialized:
return
print('Sound Debug Driver: setCallback')
def setVolume(self, volume):
if not self._initialized:
return
self.volume = volume
print('Sound Debug Driver: setVolume:' + str(self.volume))

View File

@ -5,51 +5,8 @@
# By Chrys, Storm Dragon, and contributers.
from core import debug
from core.soundDriver import soundDriver
class driver():
class driver(soundDriver):
def __init__(self):
self.volume = None
self._initialized = False
def initialize(self, environment):
self.env = environment
self._initialized = True
print('SoundDummyDriver: Initialize')
def shutdown(self):
if not self._initialized:
return
self.cancel()
print('SoundDummyDriver: Shutdown')
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
if not self._initialized:
return
if interrupt:
self.cancel()
print('SoundDummyDriver: playFrequence:' + ' freq:' + str(frequence) + ' duration:' + str(duration) + ' adjustVolume:' + str(adjustVolume) )
print('SoundDummyDriver: -----------------------------------')
def playSoundFile(self, filePath, interrupt = True):
if not self._initialized:
return
if interrupt:
self.cancel()
print('SoundDummyDriver: playSoundFile:' + str(filePath))
print('SoundDummyDriver: -----------------------------------')
def cancel(self):
if not self._initialized:
return
print('SoundDummyDriver: Cancel')
def setCallback(self, callback):
if not self._initialized:
return
print('SoundDummyDriver: setCallback')
def setVolume(self, volume):
if not self._initialized:
return
self.volume = volume
print('SoundDummyDriver: setVolume:' + str(self.volume))
soundDriver.__init__(self)

View File

@ -6,15 +6,15 @@
from core import debug
import subprocess
from core.soundDriver import soundDriver
class driver():
class driver(soundDriver):
def __init__(self):
soundDriver.__init__(self)
self.proc = None
self.volume = 1.0
self.soundType = ''
self.soundFileCommand = ''
self.frequenceCommand = ''
self._initialized = False
def initialize(self, environment):
self.env = environment
self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand')
@ -24,10 +24,7 @@ class driver():
if self.frequenceCommand == '':
self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
self._initialized = True
def shutdown(self):
if not self._initialized:
return
self.cancel()
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
if not self._initialized:
return
@ -57,10 +54,3 @@ class driver():
if self.soundType == 'frequence':
self.proc.kill()
self.soundType = ''
def setCallback(self, callback):
if not self._initialized:
return
def setVolume(self, volume):
if not self._initialized:
return
self.volume = volume

View File

@ -6,7 +6,7 @@
from core import debug
import time, threading
from core.soundDriver import soundDriver
_gstreamerAvailable = False
try:
@ -19,12 +19,11 @@ except Exception as e:
_gstreamerAvailable = False
_availableError = str(e)
class driver:
class driver(soundDriver):
def __init__(self):
soundDriver.__init__(self)
self._source = None
self._sink = None
self.volume = 1
self._initialized = False
def initialize(self, environment):
self.env = environment
@ -112,10 +111,3 @@ class driver:
return
self._player.set_state(Gst.State.NULL)
self._pipeline.set_state(Gst.State.NULL)
def setVolume(self, volume):
if not self._initialized:
return
self.volume = volume

View File

@ -0,0 +1,74 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
# generic driver
from core import debug
from core.speechDriver import speechDriver
class driver(speechDriver):
def __init__(self):
speechDriver.__init__(self
def initialize(self, environment):
self._isInitialized = True
self.env = environment
print('Speech Debug Driver: Iitialized')
def shutdown(self):
if self._isInitialized:
self.cancel()
self._isInitialized = False
print('Speech Debug Driver: Shutdown')
def speak(self,text, queueable=True):
if not self._isInitialized:
return
if not queueable:
self.cancel()
print('Speech Debug Driver: Speak:'+text)
print('Speech Debug Driver: -----------------------------------')
def cancel(self):
if not self._isInitialized:
return
print('Speech Debug Driver: Cancel')
def setCallback(self, callback):
print('Speech Debug Driver: setCallback')
def clear_buffer(self):
if not self._isInitialized:
return
print('Speech Debug Driver: clear_buffer')
def setVoice(self, voice):
if not self._isInitialized:
return
print('Speech Debug Driver: setVoice:' + str(voice))
def setPitch(self, pitch):
if not self._isInitialized:
return
print('Speech Debug Driver: setPitch:' + str(pitch))
def setRate(self, rate):
if not self._isInitialized:
return
print('Speech Debug Driver: setRate:' + str(rate))
def setModule(self, module):
if not self._isInitialized:
return
print('Speech Debug Driver: setModule:' + str(module))
def setLanguage(self, language):
if not self._isInitialized:
return
print('Speech Debug Driver: setLanguage:' + str(language))
def setVolume(self, volume):
if not self._isInitialized:
return
print('Speech Debug Driver: setVolume:' + str(volume))

View File

@ -6,65 +6,8 @@
# generic driver
from core import debug
from core.speechDriver import speechDriver
class driver():
class driver(speechDriver):
def __init__(self):
pass
def initialize(self, environment):
self._isInitialized = True
self.env = environment
print('SpeechDummyDriver: Iitialize')
def shutdown(self):
print('SpeechDummyDriver: Shutdown')
def speak(self,text, queueable=True):
if not self._isInitialized:
return
if not queueable:
self.cancel()
print('SpeechDummyDriver: Speak:'+text)
print('SpeechDummyDriver: -----------------------------------')
def cancel(self):
if not self._isInitialized:
return
print('SpeechDummyDriver: Cancel')
def setCallback(self, callback):
print('SpeechDummyDriver: setCallback')
def clear_buffer(self):
if not self._isInitialized:
return
print('SpeechDummyDriver: clear_buffer')
def setVoice(self, voice):
if not self._isInitialized:
return
print('SpeechDummyDriver: setVoice:' + str(voice))
def setPitch(self, pitch):
if not self._isInitialized:
return
print('SpeechDummyDriver: setPitch:' + str(pitch))
def setRate(self, rate):
if not self._isInitialized:
return
print('SpeechDummyDriver: setRate:' + str(rate))
def setModule(self, module):
if not self._isInitialized:
return
print('SpeechDummyDriver: setModule:' + str(module))
def setLanguage(self, language):
if not self._isInitialized:
return
print('SpeechDummyDriver: setLanguage:' + str(language))
def setVolume(self, volume):
if not self._isInitialized:
return
print('SpeechDummyDriver: setVolume:' + str(volume))
speechDriver.__init__(self)

View File

@ -10,12 +10,12 @@ from subprocess import Popen, PIPE
import pexpect
import sys
import time
from core.speechDriver import speechDriver
class driver():
class driver(speechDriver):
def __init__(self):
pass
speechDriver.__init__(self)
def initialize(self, environment):
self._isInitialized = False
self.env = environment
try:
self.server = pexpect.spawnu('tclsh ' + self.env['runtime']['settingsManager'].getSetting('speech', 'serverPath'))
@ -55,20 +55,6 @@ class driver():
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:cancel:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
def setCallback(self, callback):
pass
def clear_buffer(self):
if not self._isInitialized:
return
def setVoice(self, voice):
if not self._isInitialized:
return
def setPitch(self, pitch):
pass
def setRate(self, rate):
if not self._isInitialized:
return
@ -77,11 +63,7 @@ class driver():
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver:setRate:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
def setModule(self, module):
pass
def setLanguage(self, language):
if not self._isInitialized:
return
self.server.sendline('set_lang ' + language + '')
def setVolume(self, volume):
pass

View File

@ -6,11 +6,12 @@
# Espeak driver
from core import debug
from core.speechDriver import speechDriver
class driver():
class driver(speechDriver):
def __init__(self):
speechDriver.__init__(self)
self._es = None
self._isInitialized = False
def initialize(self, environment):
self.env = environment
@ -22,14 +23,17 @@ class driver():
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
self._initialized = False
def shutdown(self):
pass
def speak(self,text, interrupt=True):
if not self._isInitialized:
return
if not interrupt:
self.cancel()
if self.language != None:
if self.language != '':
self._es.set_voice(self.language)
elif self.voice != None:
if self.voice != '':
self._es.set_voice(self.voice)
self._es.synth(text)
def cancel(self):
@ -38,20 +42,6 @@ class driver():
self._es.cancel()
return True
def setCallback(self, callback):
pass
def clear_buffer(self):
if not self._isInitialized:
return
def setVoice(self, voice):
if not self._isInitialized:
return
if voice =='':
return
return self._es.set_voice(voice)
def setPitch(self, pitch):
if not self._isInitialized:
return
@ -62,17 +52,6 @@ class driver():
return
return self._es.set_parameter(self._es.Parameter().Rate, int(rate * 500 + 100))
def setModule(self, module):
if not self._isInitialized:
return
def setLanguage(self, language):
if not self._isInitialized:
return
if language =='':
return
return self._es.set_voice(language)
def setVolume(self, volume):
if not self._isInitialized:
return

View File

@ -9,6 +9,7 @@ from core import debug
from threading import Thread, Lock
from queue import Queue, Empty
from subprocess import Popen
from core.speechDriver import speechDriver
class speakQueue(Queue):
def clear(self):
@ -18,18 +19,13 @@ class speakQueue(Queue):
except Empty:
pass
class driver():
class driver(speechDriver):
def __init__(self):
speechDriver.__init__(self)
self.proc = None
self.speechThread = Thread(target=self.worker)
self.lock = Lock()
self.textQueue = speakQueue()
self.volume = ''
self.rate = ''
self.pitch = ''
self.module = ''
self.language = ''
self.voice = ''
def initialize(self, environment):
self.env = environment
self.minVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinVolume')

View File

@ -0,0 +1,86 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
# Espeak driver
from threading import Thread, Lock
from core import debug
from core.speechDriver import speechDriver
class driver(speechDriver):
def __init__(self):
speechDriver.__init__(self)
self._engine = None
def initialize(self, environment):
self.env = environment
def shutdown(self):
if self._isInitialized:
self.cancel()
self._engine.endLoop()
self._initialized = False
def eventLoop(self):
self._engine.startLoop()
def startEngine(self):
try:
import pyttsx3
if self.module != '':
self._engine = pyttsx3.init(self.module)
else:
self._engine = pyttsx3.init()
self.eventLoopThread = Thread(target=self.eventLoop)
self._isInitialized = True
self.eventLoopThread.start()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('SpeechDriver:initialize:' + str(e),debug.debugLevel.ERROR)
def speak(self,text, interrupt=True):
if not self._isInitialized:
self.startEngine()
if not self._isInitialized:
return
if not interrupt:
self.cancel()
try:
self._engine.setProperty('volume', self.volume)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:volume:' + str(e),debug.debugLevel.ERROR)
try:
self._engine.setProperty('rate', self.rate)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:rate:' + str(e),debug.debugLevel.ERROR)
try:
self._engine.setProperty('pitch', self.pitch)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:pitch:' + str(e),debug.debugLevel.ERROR)
if self.language != None:
if self.language != '':
try:
self._engine.setProperty('voice', self.language)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:language:' + str(e),debug.debugLevel.ERROR)
elif self.voice != None:
if self.voice != '':
try:
self._engine.setProperty('voice', self.voice)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:voice:' + str(e),debug.debugLevel.ERROR)
self._engine.say(text)
def cancel(self):
if not self._isInitialized:
return
self._engine.stop()
self._engine.proxy.stop()
def setPitch(self, pitch):
if not self._isInitialized:
return
self.pitch = pitch
def setRate(self, rate):
if not self._isInitialized:
return
self.rate = rate

View File

@ -6,12 +6,12 @@
# speech-dispatcher driver
from core import debug
from core.speechDriver import speechDriver
class driver():
class driver(speechDriver):
def __init__(self):
speechDriver.__init__(self)
self._sd = None
self._isInitialized = False
self._language = ''
def initialize(self, environment):
self.env = environment
@ -22,7 +22,6 @@ class driver():
self._isInitialized = True
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR)
self._initialized = False
def shutdown(self):
if not self._isInitialized:
@ -42,7 +41,18 @@ class driver():
if not self._isInitialized:
return
try:
self._sd.set_synthesis_voice(self._language)
self._sd.set_output_module(self.module)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver setModule:' + str(e),debug.debugLevel.ERROR)
try:
if self.voice != '':
self._sd.set_voice(self.voice)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR)
try:
if self.language != '':
self._sd.set_synthesis_voice(self.language)
self._sd.set_punctuation(self._punct.NONE)
self._sd.speak(text)
except Exception as e:
@ -58,22 +68,6 @@ class driver():
self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR)
self._isInitialized = False
def setCallback(self, callback):
pass
def clear_buffer(self):
if not self._isInitialized:
return
def setVoice(self, voice):
if not self._isInitialized:
return
try:
if voice != '':
self._sd.set_voice(voice)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR)
def setPitch(self, pitch):
if not self._isInitialized:
return
@ -90,19 +84,6 @@ class driver():
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR)
def setModule(self, module):
if not self._isInitialized:
return
try:
self._sd.set_output_module(module)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver setModule:' + str(e),debug.debugLevel.ERROR)
def setLanguage(self, language):
if not self._isInitialized:
return
self._language = language
def setVolume(self, volume):
if not self._isInitialized:
return