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 [X] = Done
Cleanups: 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 [] split it out
[] use it in vcsa driver [] 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 [] commandsData.py
[] eventData.py [] eventData.py
[] generalData.py [] generalData.py
@ -21,29 +27,22 @@ Cleanups:
General: General:
- commands - commands
[] place last spoken to clipboard [] place last spoken to clipboard (Easy for contribution)
- imporove attribute handling - imporove attribute handling
[] improve attributes_curr_char [] improve attributes_curr_char
[] add an attribute sound [] add an attribute sound (Easy for contribution)
[] beep on cursor/ review by char (capital wins) [] beep on cursor/ review by char (capital wins)
[] beep on review by word (once for multiple, capital wins) [] beep on review by word (once for multiple, capital wins)
[] configurable (by char, by word, none) [] configurable (by char, by word, none)
https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
- Improved Say all - Improved Say all
[] all the text of all pages [] speech callbacks
[] command to stop and place review cursor at this position [] speech process by word
[] command to slow down speech on keypress [] all the text of all pages
[] command to stop and place review cursor at this position
- generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution) [] command to slow down speech on keypress
[] next item
[] prev item
[] curr item
[] first item
[] last item
- make it runnable via pypy3 - 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: Braille Support:
[] brailleFocusMode: [] brailleFocusMode:
@ -77,11 +76,11 @@ Driver:
https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py
Settings: Settings:
[] write settings (Easy for contribution) [] write settings (Easy for contribution)
[] menue for settings configuration (Easy for contribution) [] menue for settings configuration (Easy for contribution)
Application Profiles (low priority): 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. - fenrir is not able to detect the current application inside of screen.
ps -e -H -o pid,pgrp,ppid,tty,cmd 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 http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process/24862213
@ -94,7 +93,14 @@ Application Profiles (low priority):
- per application shortcuts - per application shortcuts
-----------DONE---------------- -----------DONE----------------
General: Cleanups:
- inheritation for drivers
[Done] Speech (All)
[Done] Braille (All)
[Done] Sound (All)
[Done] Input (All)
[Done] Screen (All)
General:
Braille Support: Braille Support:
Driver: Driver:
Settings: Settings:

View File

@ -105,6 +105,7 @@ KEY_FENRIR,KEY_PAGEUP=prev_clipboard
KEY_FENRIR,KEY_PAGEDOWN=next_clipboard KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
KEY_FENRIR,KEY_C=copy_marked_to_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_V=paste_clipboard
KEY_FENRIR,KEY_F5=import_clipboard_from_file KEY_FENRIR,KEY_F5=import_clipboard_from_file
KEY_FENRIR,KEY_F6=export_clipboard_to_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_PAGEDOWN=next_clipboard
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
KEY_FENRIR,KEY_C=copy_marked_to_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_V=paste_clipboard
KEY_FENRIR,KEY_F5=import_clipboard_from_file KEY_FENRIR,KEY_F5=import_clipboard_from_file
KEY_FENRIR,KEY_F6=export_clipboard_to_file KEY_FENRIR,KEY_F6=export_clipboard_to_file

View File

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

View File

@ -5,10 +5,11 @@
# By Chrys, Storm Dragon, and contributers. # By Chrys, Storm Dragon, and contributers.
from core import debug from core import debug
from core.brailleDriver import brailleDriver
class driver(): class driver(brailleDriver):
def __init__(self): def __init__(self):
self._isInitialized = False brailleDriver.__init__(self)
self._brl = None self._brl = None
def initialize(self, environment): 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. # By Chrys, Storm Dragon, and contributers.
from core import debug from core import debug
from core.brailleDriver import brailleDriver
class driver(): class driver(brailleDriver):
def __init__(self): def __init__(self):
self.printMessages = False brailleDriver.__init__(self)
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')

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

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 import time
from core import debug from core import debug
from core.inputDriver import inputDriver
class driver(): class driver(inputDriver):
def __init__(self): def __init__(self):
self._initialized = False inputDriver.__init__(self)
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getInputEvent(self): def getInputEvent(self):
time.sleep(0.05) time.sleep(0.1)
if not self._initialized: if not self._initialized:
return None 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.eventData import fenrirEventType
from core import inputData from core import inputData
from core import debug from core import debug
from core.inputDriver import inputDriver
class driver(inputDriver):
class driver():
def __init__(self): def __init__(self):
inputDriver.__init__(self)
self._manager = multiprocessing.Manager() self._manager = multiprocessing.Manager()
self.iDevices = {} self.iDevices = {}
self.iDevicesFD = self._manager.list() self.iDevicesFD = self._manager.list()
self.uDevices = {} self.uDevices = {}
self.iDeviceNo = 0 self.iDeviceNo = 0
self._initialized = False
self.watchDog = Value(c_bool, True) self.watchDog = Value(c_bool, True)
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
@ -70,9 +70,6 @@ class driver():
def plugInputDeviceWatchdogTimer(self, active): def plugInputDeviceWatchdogTimer(self, active):
time.sleep(2.5) time.sleep(2.5)
return time.time() return time.time()
def shutdown(self):
if not self._initialized:
return
def inputWatchdog(self,active , params): def inputWatchdog(self,active , params):
try: try:
deviceFd = [] deviceFd = []
@ -323,10 +320,6 @@ class driver():
self.removeDevice(fd) self.removeDevice(fd)
self.iDevices.clear() self.iDevices.clear()
self.uDevices.clear() self.uDevices.clear()
self.iDeviceNo = 0 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 struct import unpack_from, unpack, pack
from core import debug from core import debug
from core.eventData import fenrirEventType from core.eventData import fenrirEventType
from core.screenDriver import screenDriver
class driver(screenDriver):
class driver():
def __init__(self): def __init__(self):
screenDriver.__init__(self)
self.vcsaDevicePath = '/dev/vcsa' self.vcsaDevicePath = '/dev/vcsa'
self.ListSessions = None self.ListSessions = None
self.charmap = {} self.charmap = {}
@ -41,8 +42,6 @@ class driver():
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog) self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog)
def shutdown(self):
pass
def getCurrScreen(self): def getCurrScreen(self):
self.env['screen']['oldTTY'] = self.env['screen']['newTTY'] self.env['screen']['oldTTY'] = self.env['screen']['newTTY']
try: 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. # By Chrys, Storm Dragon, and contributers.
from core import debug from core import debug
from core.soundDriver import soundDriver
class driver(): class driver(soundDriver):
def __init__(self): def __init__(self):
self.volume = None soundDriver.__init__(self)
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))

View File

@ -6,15 +6,15 @@
from core import debug from core import debug
import subprocess import subprocess
from core.soundDriver import soundDriver
class driver(): class driver(soundDriver):
def __init__(self): def __init__(self):
soundDriver.__init__(self)
self.proc = None self.proc = None
self.volume = 1.0
self.soundType = '' self.soundType = ''
self.soundFileCommand = '' self.soundFileCommand = ''
self.frequenceCommand = '' self.frequenceCommand = ''
self._initialized = False
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand') self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand')
@ -24,10 +24,7 @@ class driver():
if self.frequenceCommand == '': if self.frequenceCommand == '':
self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence' self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
self._initialized = True self._initialized = True
def shutdown(self):
if not self._initialized:
return
self.cancel()
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0): def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
if not self._initialized: if not self._initialized:
return return
@ -56,11 +53,4 @@ class driver():
self.proc.kill() self.proc.kill()
if self.soundType == 'frequence': if self.soundType == 'frequence':
self.proc.kill() self.proc.kill()
self.soundType = '' 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 from core import debug
import time, threading import time, threading
from core.soundDriver import soundDriver
_gstreamerAvailable = False _gstreamerAvailable = False
try: try:
@ -19,12 +19,11 @@ except Exception as e:
_gstreamerAvailable = False _gstreamerAvailable = False
_availableError = str(e) _availableError = str(e)
class driver: class driver(soundDriver):
def __init__(self): def __init__(self):
soundDriver.__init__(self)
self._source = None self._source = None
self._sink = None self._sink = None
self.volume = 1
self._initialized = False
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
@ -112,10 +111,3 @@ class driver:
return return
self._player.set_state(Gst.State.NULL) self._player.set_state(Gst.State.NULL)
self._pipeline.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 # generic driver
from core import debug from core import debug
from core.speechDriver import speechDriver
class driver(): class driver(speechDriver):
def __init__(self): def __init__(self):
pass speechDriver.__init__(self)
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))

View File

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

View File

@ -6,11 +6,12 @@
# Espeak driver # Espeak driver
from core import debug from core import debug
from core.speechDriver import speechDriver
class driver(): class driver(speechDriver):
def __init__(self): def __init__(self):
speechDriver.__init__(self)
self._es = None self._es = None
self._isInitialized = False
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
@ -21,15 +22,18 @@ class driver():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
self._initialized = False self._initialized = False
def shutdown(self):
pass
def speak(self,text, interrupt=True): def speak(self,text, interrupt=True):
if not self._isInitialized: if not self._isInitialized:
return return
if not interrupt: if not interrupt:
self.cancel() 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) self._es.synth(text)
def cancel(self): def cancel(self):
@ -38,20 +42,6 @@ class driver():
self._es.cancel() self._es.cancel()
return True 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): def setPitch(self, pitch):
if not self._isInitialized: if not self._isInitialized:
return return
@ -62,17 +52,6 @@ class driver():
return return
return self._es.set_parameter(self._es.Parameter().Rate, int(rate * 500 + 100)) 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): def setVolume(self, volume):
if not self._isInitialized: if not self._isInitialized:
return return

View File

@ -9,6 +9,7 @@ from core import debug
from threading import Thread, Lock from threading import Thread, Lock
from queue import Queue, Empty from queue import Queue, Empty
from subprocess import Popen from subprocess import Popen
from core.speechDriver import speechDriver
class speakQueue(Queue): class speakQueue(Queue):
def clear(self): def clear(self):
@ -18,18 +19,13 @@ class speakQueue(Queue):
except Empty: except Empty:
pass pass
class driver(): class driver(speechDriver):
def __init__(self): def __init__(self):
speechDriver.__init__(self)
self.proc = None self.proc = None
self.speechThread = Thread(target=self.worker) self.speechThread = Thread(target=self.worker)
self.lock = Lock() self.lock = Lock()
self.textQueue = speakQueue() self.textQueue = speakQueue()
self.volume = ''
self.rate = ''
self.pitch = ''
self.module = ''
self.language = ''
self.voice = ''
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
self.minVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinVolume') 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 # speech-dispatcher driver
from core import debug from core import debug
from core.speechDriver import speechDriver
class driver(): class driver(speechDriver):
def __init__(self): def __init__(self):
speechDriver.__init__(self)
self._sd = None self._sd = None
self._isInitialized = False
self._language = ''
def initialize(self, environment): def initialize(self, environment):
self.env = environment self.env = environment
@ -22,7 +22,6 @@ class driver():
self._isInitialized = True self._isInitialized = True
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR)
self._initialized = False
def shutdown(self): def shutdown(self):
if not self._isInitialized: if not self._isInitialized:
@ -42,7 +41,18 @@ class driver():
if not self._isInitialized: if not self._isInitialized:
return return
try: 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.set_punctuation(self._punct.NONE)
self._sd.speak(text) self._sd.speak(text)
except Exception as e: except Exception as e:
@ -57,23 +67,7 @@ class driver():
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR)
self._isInitialized = False 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): def setPitch(self, pitch):
if not self._isInitialized: if not self._isInitialized:
return return
@ -88,20 +82,7 @@ class driver():
try: try:
self._sd.set_rate(int(-100 + rate * 200)) self._sd.set_rate(int(-100 + rate * 200))
except Exception as e: except Exception as e:
self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR) 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): def setVolume(self, volume):
if not self._isInitialized: if not self._isInitialized: