fix merge

This commit is contained in:
chrys
2018-03-22 00:45:17 +01:00
251 changed files with 424 additions and 423 deletions

View File

View File

@ -0,0 +1,31 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
class applicationManager():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getCurrentApplication(self):
currApp = self.env['screen']['newApplication'].upper()
if not currApp:
currApp == 'DEFAULT'
if currApp == '':
currApp == 'DEFAULT'
return currApp
def getPrevApplication(self):
prevApp = self.env['screen']['oldApplication'].upper()
if not prevApp:
prevApp == 'DEFAULT'
if prevApp == '':
prevApp == 'DEFAULT'
return prevApp
def isApplicationChange(self):
return self.env['screen']['oldApplication'] != self.env['screen']['newApplication']

View File

@ -0,0 +1,41 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.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,24 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import time
# used as shared memory between commands
# use this in your own commands
commandBuffer = {
'enableSpeechOnKeypress': False,
'Marks':{'1':None, '2':None},
'bookMarks':{},
'windowArea':{},
}
# used by the commandManager
commandInfo = {
#'currCommand': '',
'lastCommandExecutionTime': time.time(),
'lastCommandRequestTime': time.time(),
}

View File

@ -0,0 +1,223 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import glob, os, time, inspect
currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
fenrirPath = os.path.dirname(currentdir)
from fenrirscreenreader.core import debug
from fenrirscreenreader.utils import module_utils
class commandManager():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
# commands
self.env['commands'] = {}
self.env['commandsIgnore'] = {}
for commandFolder in self.env['general']['commandFolderList']:
self.env['runtime']['commandManager'].loadCommands(commandFolder)
if self.env['runtime']['settingsManager'].getSetting('general', 'commandPath') != '':
self.env['runtime']['commandManager'].loadCommands(commandFolder,
self.env['runtime']['settingsManager'].getSetting('general', 'commandPath'))
# scripts for scriptKey
self.env['runtime']['commandManager'].loadScriptCommands()
def shutdown(self):
for commandFolder in self.env['general']['commandFolderList']:
self.env['runtime']['commandManager'].shutdownCommands(commandFolder)
def loadCommands(self, section='commands',commandPath=''):
if commandPath =='':
commandPath = fenrirPath+ "/commands/"
if not commandPath.endswith('/'):
commandPath += '/'
commandFolder = commandPath + section +"/"
if not os.path.exists(commandFolder):
self.env['runtime']['debug'].writeDebugOut("commandFolder not exists:" + commandFolder ,debug.debugLevel.WARNING)
return
if not os.path.isdir(commandFolder):
self.env['runtime']['debug'].writeDebugOut("commandFolder not a directory:" + commandFolder ,debug.debugLevel.ERROR)
return
if not os.access(commandFolder, os.R_OK):
self.env['runtime']['debug'].writeDebugOut("commandFolder not readable:" + commandFolder ,debug.debugLevel.ERROR)
return
self.env['commands'][section] = {}
self.env['commandsIgnore'][section] = {}
commandList = glob.glob(commandFolder+'*')
for command in commandList:
try:
fileName, fileExtension = os.path.splitext(command)
fileName = fileName.split('/')[-1]
if fileName.startswith('__'):
continue
try:
if self.env['commands'][section][fileName.upper()] != None:
continue
except:
pass
if fileExtension.lower() == '.py':
command_mod = module_utils.importModule(fileName, command)
self.env['commands'][section][fileName.upper()] = command_mod.command()
self.env['commandsIgnore'][section][fileName.upper()[fileName.upper().find('-')+1:]+'_IGNORE'] = False
self.env['commands'][section][fileName.upper()].initialize(self.env)
self.env['runtime']['debug'].writeDebugOut("Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Loading command:" + command ,debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
continue
def loadScriptCommands(self, section='commands', scriptPath=''):
if scriptPath =='':
scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath')
if not scriptPath.endswith('/'):
scriptPath += '/'
if not os.path.exists(scriptPath):
if os.path.exists(fenrirPath +'/../../config/scripts/'):
scriptPath = fenrirPath +'/../../config/scripts/'
else:
self.env['runtime']['debug'].writeDebugOut("scriptpath not exists:" + scriptPath ,debug.debugLevel.WARNING)
return
if not os.path.isdir(scriptPath):
self.env['runtime']['debug'].writeDebugOut("scriptpath not a directory:" + scriptPath ,debug.debugLevel.ERROR)
return
if not os.access(scriptPath, os.R_OK):
self.env['runtime']['debug'].writeDebugOut("scriptpath not readable:" + scriptPath ,debug.debugLevel.ERROR)
return
commandList = glob.glob(scriptPath+'*')
subCommand = fenrirPath + '/commands/commands/subprocess.py'
for command in commandList:
invalid = False
try:
fileName, fileExtension = os.path.splitext(command)
fileName = fileName.split('/')[-1]
if fileName.startswith('__'):
continue
if fileName.upper() in self.env['commands'][section]:
continue
command_mod = module_utils.importModule(fileName ,subCommand)
self.env['commands'][section][fileName.upper()] = command_mod.command()
self.env['commands'][section][fileName.upper()].initialize(self.env,command)
self.env['runtime']['debug'].writeDebugOut("Load script:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True)
commSettings = fileName.upper().split('__-__')
if len(commSettings) == 1:
keys = commSettings[0]
elif len(commSettings) == 2:
keys = commSettings[1]
elif len(commSettings) > 2:
continue
keys = keys.split('__+__')
shortcutKeys = []
shortcut = []
for key in keys:
if not self.env['runtime']['settingsManager'].isValidKey(key.upper()):
self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING)
invalid = True
break
shortcutKeys.append(key.upper())
if invalid:
continue
if not 'KEY_SCRIPT' in shortcutKeys:
shortcutKeys.append('KEY_SCRIPT')
shortcut.append(1)
shortcut.append(sorted(shortcutKeys))
self.env['bindings'][str(shortcut)] = fileName.upper()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Loading script:" + command ,debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
continue
def shutdownCommands(self, section):
for command in sorted(self.env['commands'][section]):
try:
self.env['commands'][section][command].shutdown()
del self.env['commands'][section][command]
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Shutdown command:" + section + "." + command ,debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
continue
def executeSwitchTrigger(self, trigger, unLoadScript, loadScript):
if self.env['runtime']['screenManager'].isSuspendingScreen():
return
#unload
oldScript = unLoadScript
if self.commandExists(oldScript, trigger):
try:
self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.unload:" + trigger + "." + oldScript ,debug.debugLevel.INFO)
self.env['commands'][trigger][oldScript].unload()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + oldScript ,debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
#load
newScript = loadScript
if self.commandExists(newScript, trigger):
try:
self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.load:" + trigger + "." + newScript ,debug.debugLevel.INFO)
self.env['commands'][trigger][newScript].load()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + newScript ,debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def executeDefaultTrigger(self, trigger, force=False):
if not force:
if self.env['runtime']['screenManager'].isSuspendingScreen():
return
for command in sorted(self.env['commands'][trigger]):
if self.commandExists(command, trigger):
try:
if self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE']:
self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE'] = False
self.env['runtime']['debug'].writeDebugOut("Ignore trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)
else:
self.env['runtime']['debug'].writeDebugOut("Executing trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)
self.env['commands'][trigger][command].run()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + command + str(e) ,debug.debugLevel.ERROR)
def executeCommand(self, command, section = 'commands'):
if self.env['runtime']['screenManager'].isSuspendingScreen():
return
if self.commandExists(command, section):
try:
if self.env['runtime']['helpManager'].isTutorialMode() and section != 'help':
self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO)
description = self.getCommandDescription(command, section)
self.env['runtime']['outputManager'].presentText(description, interrupt=True)
else:
self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO)
self.runCommand(command, section)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
def runCommand(self, command, section = 'commands'):
if self.commandExists(command, section):
try:
self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command ,debug.debugLevel.INFO)
self.env['commands'][section][command].run()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
def getCommandDescription(self, command, section = 'commands'):
if self.commandExists(command, section):
try:
return self.env['commands'][section][command].getDescription()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR)
self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
def commandExists(self, command, section = 'commands'):
return( command in self.env['commands'][section])
def getShortcutForCommand(self, command):
shortcut = ''
try:
shortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)]
except:
pass
return shortcut

View File

@ -0,0 +1,109 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
class cursorManager():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def clearMarks(self):
self.env['commandBuffer']['Marks']['1'] = None
self.env['commandBuffer']['Marks']['2'] = None
def isMarkSet(self):
return self.env['commandBuffer']['Marks']['1'] != None
def isSingleMark(self):
return self.env['commandBuffer']['Marks']['1'] != None and \
self.env['commandBuffer']['Marks']['2'] == None
def isMultibleMark(self):
return self.env['commandBuffer']['Marks']['1'] != None and \
self.env['commandBuffer']['Marks']['2'] != None
def setMark(self):
currCursor = None
if self.env['screen']['newCursorReview']:
currCursor = self.env['screen']['newCursorReview'].copy()
else:
currCursor = self.env['screen']['newCursor'].copy()
if not self.env['commandBuffer']['Marks']['1']:
self.env['commandBuffer']['Marks']['1'] = currCursor.copy()
return 1
else:
self.env['commandBuffer']['Marks']['2'] = currCursor.copy()
return 2
return 0
def getReviewOrTextCursor(self):
if self.env['screen']['newCursorReview']:
return self.env['screen']['newCursorReview'].copy()
else:
return self.env['screen']['newCursor'].copy()
def clearReviewCursor(self):
if not self.isReviewMode():
return
self.env['screen']['oldCursorReview'] = None
self.env['screen']['newCursorReview'] = None
def isCursorHorizontalMove(self):
return self.env['screen']['newCursor']['x'] != self.env['screen']['oldCursor']['x']
def isCursorVerticalMove(self):
return self.env['screen']['newCursor']['y'] != self.env['screen']['oldCursor']['y']
def isReviewMode(self):
return self.env['screen']['newCursorReview'] != None
def enterReviewModeCurrTextCursor(self, overwrite=False):
if self.isReviewMode() and not overwrite:
return
self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
if not self.env['screen']['newCursorReview']:
self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy()
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') and \
self.env['screen']['newCursorAttrib'] != None:
if self.env['screen']['newCursorAttrib']['x'] != 0 and \
self.env['screen']['newCursorAttrib']['y'] != 0:
self.env['screen']['newCursorReview'] = self.env['screen']['newCursorAttrib'].copy()
def setReviewCursorPosition(self, x, y):
if not self.isReviewMode():
self.enterReviewModeCurrTextCursor()
self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
self.env['screen']['newCursorReview']['x'] = x
self.env['screen']['newCursorReview']['y'] = y
def isApplicationWindowSet(self):
try:
currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
if self.env['commandBuffer']['windowArea'][currApp]['1'] != None:
return True
except:
pass
return False
def setWindowForApplication(self):
if not self.env['commandBuffer']['Marks']['1']:
return False
if not self.env['commandBuffer']['Marks']['2']:
return False
currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
self.env['commandBuffer']['windowArea'][currApp] = {}
if self.env['commandBuffer']['Marks']['1']['x'] * self.env['commandBuffer']['Marks']['1']['y'] <= \
self.env['commandBuffer']['Marks']['2']['x'] * self.env['commandBuffer']['Marks']['2']['y']:
self.env['commandBuffer']['windowArea'][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy()
self.env['commandBuffer']['windowArea'][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
else:
self.env['commandBuffer']['windowArea'][currApp]['1'] = self.env['commandBuffer']['Marks']['2'].copy()
self.env['commandBuffer']['windowArea'][currApp]['2'] = self.env['commandBuffer']['Marks']['1'].copy()
return True
def clearWindowForApplication(self):
currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
try:
del self.env['commandBuffer']['windowArea'][currApp]
except:
return False
return True

View File

@ -0,0 +1,13 @@
#!/usr/bin/python
from enum import Enum
class debugLevel(Enum):
DEACTIVE = 0
ERROR = 1
WARNING = 2
INFO = 3
def __int__(self):
return self.value
def __str__(self):
return self.name

View File

@ -0,0 +1,71 @@
#!/usr/bin/python
# Debugger module for the Fenrir screen reader.
from fenrirscreenreader.core import debug
from datetime import datetime
class debugManager():
def __init__(self, fileName='/var/log/fenrir.log'):
self._fileName = fileName
self._file = None
self._fileOpened = False
def initialize(self, environment):
self.env = environment
def shutdown(self):
self.closeDebugFile()
def __del__(self):
try:
self.shutdown()
except:
pass
def openDebugFile(self, fileName = ''):
self._fileOpened = False
if fileName != '':
self._fileName = fileName
if self._fileName != '':
self._file = open(self._fileName,'a')
self._fileOpened = True
def writeDebugOut(self, text, level = debug.debugLevel.DEACTIVE, onAnyLevel=False):
mode = self.env['runtime']['settingsManager'].getSetting('general','debugMode')
if mode == '':
mode = 'FILE'
mode = mode.upper().split(',')
fileMode = 'FILE' in mode
printMode = 'PRINT' in mode
if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \
not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debug.debugLevel.DEACTIVE)) :
if self._fileOpened:
self.closeDebugFile()
return
else:
if not self._fileOpened and fileMode:
self.openDebugFile()
if onAnyLevel:
msg = 'ANY '+ str(level) + ' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f'))
else:
msg = str(level) +' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
)
msg += ': ' + text
if printMode:
print(msg)
if fileMode:
self._file.write(msg + '\n')
def closeDebugFile(self):
if not self._fileOpened:
return False
if self._file != None:
self._file.close()
self._fileOpened = False
return True
def getDebugFile(self):
return self._fileName
def setDebugFile(self, fileName):
self.closeDebugFile()
self._fileName = fileName

View File

@ -0,0 +1,29 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
from fenrirscreenreader.core.settingsData import settingsData
from fenrirscreenreader.core.runtimeData import runtimeData
from fenrirscreenreader.core.screenData import screenData
from fenrirscreenreader.core.outputData import outputData
from fenrirscreenreader.core.generalData import generalData
from fenrirscreenreader.core import commandData
from fenrirscreenreader.core.inputData import inputData
from fenrirscreenreader.core.punctuationData import punctuationData
environment = {
'screen': screenData,
'runtime': runtimeData,
'general': generalData,
'settings': settingsData,
'commandInfo': commandData.commandInfo,
'commandBuffer': commandData.commandBuffer,
'input': inputData,
'punctuation': punctuationData,
'output': outputData,
'soundIcons': {},
'bindings': {},
}

View File

@ -0,0 +1,24 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
from enum import Enum
class fenrirEventType(Enum):
Ignore = 0
StopMainLoop = 1
ScreenUpdate = 2
KeyboardInput = 3
BrailleInput = 4
PlugInputDevice = 5
BrailleFlush = 6
ScreenChanged = 7
HeartBeat = 8 # for time based scheduling
ExecuteCommand = 9
def __int__(self):
return self.value
def __str__(self):
return self.name

View File

@ -0,0 +1,85 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
from fenrirscreenreader.core.eventData import fenrirEventType
from queue import Empty
import time
from multiprocessing import Queue
from multiprocessing.sharedctypes import Value
from ctypes import c_bool
class eventManager():
def __init__(self):
self.running = Value(c_bool, True)
self._eventQueue = Queue() # multiprocessing.Queue()
self.cleanEventQueue()
def initialize(self, environment):
self.env = environment
def shutdown(self):
self.cleanEventQueue()
def proceedEventLoop(self):
event = self._eventQueue.get()
st = time.time()
self.eventDispatcher(event)
#print('NET loop ' + str(time.time() - st))
def eventDispatcher(self, event):
self.env['runtime']['debug'].writeDebugOut('eventManager:eventDispatcher:start: event:' + str(event['Type']) + ' QueueSize:' + str( self._eventQueue.qsize()),debug.debugLevel.INFO)
if not event:
return
if not event['Type']:
return
if event['Type'] == fenrirEventType.Ignore:
return
elif event['Type'] == fenrirEventType.StopMainLoop:
self.handleStopMainLoop(event)
elif event['Type'] == fenrirEventType.ScreenUpdate:
self.env['runtime']['fenrirManager'].handleScreenUpdate(event)
elif event['Type'] == fenrirEventType.KeyboardInput:
self.env['runtime']['fenrirManager'].handleInput(event)
elif event['Type'] == fenrirEventType.BrailleInput:
pass
elif event['Type'] == fenrirEventType.PlugInputDevice:
self.env['runtime']['fenrirManager'].handlePlugInputDevice(event)
pass
elif event['Type'] == fenrirEventType.BrailleFlush:
pass
elif event['Type'] == fenrirEventType.ScreenChanged:
self.env['runtime']['fenrirManager'].handleScreenChange(event)
elif event['Type'] == fenrirEventType.HeartBeat:
self.env['runtime']['fenrirManager'].handleHeartBeat(event)
elif event['Type'] == fenrirEventType.ExecuteCommand:
self.env['runtime']['fenrirManager'].handleExecuteCommand(event)
def isMainEventLoopRunning(self):
return self.running.value == 1
def startMainEventLoop(self):
self.running.value = 1
while( self.isMainEventLoopRunning()):
self.proceedEventLoop()
def handleStopMainLoop(self, event):
self.running.value = 0
time.sleep(0.1)
def stopMainEventLoop(self):
self._eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None})
def cleanEventQueue(self):
if self._eventQueue.empty():
return
try:
while True:
self._eventQueue.get_nowait()
except Empty:
pass
def getEventQueue(self):
return self._eventQueue
def getRunning(self):
return self.running
def putToEventQueue(self,event, data):
if not isinstance(event, fenrirEventType):
return False
self._eventQueue.put({"Type":event,"Data":data})
return True

View File

@ -0,0 +1,185 @@
#!/bin/env python3
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import os, sys, signal, time
from fenrirscreenreader.core import i18n
from fenrirscreenreader.core import settingsManager
from fenrirscreenreader.core import debug
from fenrirscreenreader.core.eventData import fenrirEventType
import argparse
class fenrirManager():
def __init__(self):
self.initialized = False
cliArgs = self.handleArgs()
if not cliArgs:
return
try:
self.environment = settingsManager.settingsManager().initFenrirConfig(cliArgs, self)
if not self.environment:
raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable')
except RuntimeError:
raise
self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True)
signal.signal(signal.SIGINT, self.captureSignal)
signal.signal(signal.SIGTERM, self.captureSignal)
self.initialized = True
self.modifierInput = False
self.singleKeyCommand = False
self.command = ''
def handleArgs(self):
args = None
parser = argparse.ArgumentParser(description="Fenrir Help")
parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile')
parser.add_argument('-o', '--options', metavar='SECTION#SETTING=VALUE,..', default='', help='Overwrite options in given settings file')
parser.add_argument('-d', '--debug', action='store_true', help='Turns on Debugmode')
parser.add_argument('-p', '--print', action='store_true', help='Print debug messages on screen')
try:
args = parser.parse_args()
except Exception as e:
parser.print_help()
return args
def proceed(self):
if not self.initialized:
return
self.environment['runtime']['eventManager'].startMainEventLoop()
self.shutdown()
def handleInput(self, event):
#startTime = time.time
self.environment['runtime']['debug'].writeDebugOut('DEBUG INPUT fenrirMan:' + str(event),debug.debugLevel.INFO)
if not event['Data']:
event['Data'] = self.environment['runtime']['inputManager'].getInputEvent()
if event['Data']:
event['Data']['EventName'] = self.environment['runtime']['inputManager'].convertEventName(event['Data']['EventName'])
self.environment['runtime']['inputManager'].handleInputEvent(event['Data'])
else:
return
if self.environment['runtime']['inputManager'].noKeyPressed():
self.environment['runtime']['inputManager'].clearLastDeepInput()
if self.environment['runtime']['screenManager'].isSuspendingScreen():
self.environment['runtime']['inputManager'].writeEventBuffer()
else:
if self.environment['runtime']['helpManager'].isTutorialMode():
self.environment['runtime']['inputManager'].clearEventBuffer()
self.detectCommand()
if self.modifierInput:
self.environment['runtime']['inputManager'].clearEventBuffer()
if self.singleKeyCommand:
if self.environment['runtime']['inputManager'].noKeyPressed():
self.environment['runtime']['inputManager'].clearEventBuffer()
else:
self.environment['runtime']['inputManager'].writeEventBuffer()
if self.environment['runtime']['inputManager'].noKeyPressed():
self.modifierInput = False
self.singleKeyCommand = False
if self.environment['input']['keyForeward'] > 0:
self.environment['input']['keyForeward'] -=1
self.environment['runtime']['commandManager'].executeDefaultTrigger('onInput')
#print('handleInput:',time.time() - startTime)
def handleExecuteCommand(self, event):
if event['Data'] == '':
return
command = event['Data']
if self.environment['runtime']['helpManager'].isTutorialMode():
if self.environment['runtime']['commandManager'].commandExists( command, 'help'):
self.environment['runtime']['commandManager'].executeCommand( command, 'help')
return
self.environment['runtime']['commandManager'].executeCommand( command, 'commands')
def handleScreenChange(self, event):
self.environment['runtime']['screenManager'].hanldeScreenChange(event['Data'])
'''
if self.environment['runtime']['applicationManager'].isApplicationChange():
self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
self.environment['runtime']['applicationManager'].getPrevApplication(), \
self.environment['runtime']['applicationManager'].getCurrentApplication())
'''
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')
self.environment['runtime']['screenDriver'].getCurrScreen()
def handleScreenUpdate(self, event):
#startTime = time.time()
self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data'])
'''
if self.environment['runtime']['applicationManager'].isApplicationChange():
self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
self.environment['runtime']['applicationManager'].getPrevApplication(), \
self.environment['runtime']['applicationManager'].getCurrentApplication())
'''
# timout for the last keypress
if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3:
self.environment['runtime']['inputManager'].clearLastDeepInput()
# has cursor changed?
if self.environment['runtime']['cursorManager'].isCursorVerticalMove() or \
self.environment['runtime']['cursorManager'].isCursorHorizontalMove():
self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange')
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
self.environment['runtime']['inputManager'].clearLastDeepInput()
#print('handleScreenUpdate:',time.time() - startTime)
def handlePlugInputDevice(self, event):
self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True)
def handleHeartBeat(self, event):
self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat',force=True)
#self.environment['runtime']['outputManager'].brailleText(flush=False)
def detectCommand(self):
if self.environment['input']['keyForeward'] > 0:
return
if self.environment['runtime']['inputManager'].isKeyPress():
self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier()
else:
if not self.environment['runtime']['inputManager'].noKeyPressed():
if self.singleKeyCommand:
self.singleKeyCommand = len( self.environment['runtime']['inputManager'].getLastDeepestInput() ) == 1
# key is already released. we need the old one
if not( self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()):
shortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut)
if not self.modifierInput:
if self.environment['runtime']['inputManager'].isKeyPress():
if self.command != '':
self.singleKeyCommand = True
if not (self.singleKeyCommand or self.modifierInput):
return
# fire event
if self.command != '':
if self.modifierInput:
self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
self.command = ''
else:
if self.singleKeyCommand:
if self.environment['runtime']['inputManager'].noKeyPressed():
self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
self.command = ''
def shutdownRequest(self):
try:
self.environment['runtime']['eventManager'].stopMainEventLoop()
except:
pass
def captureSignal(self, siginit, frame):
self.shutdownRequest()
def shutdown(self):
self.environment['runtime']['eventManager'].stopMainEventLoop()
self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)
self.environment['runtime']['eventManager'].cleanEventQueue()
time.sleep(1)
for currManager in self.environment['general']['managerList']:
if self.environment['runtime'][currManager]:
self.environment['runtime'][currManager].shutdown()
del self.environment['runtime'][currManager]
self.environment = None

View File

@ -0,0 +1,18 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
generalData = {
'args': None,
'tutorialMode': False,
'currUser':'',
'prevUser':'',
'managerList':['processManager', 'punctuationManager', 'cursorManager', 'applicationManager', 'commandManager'
, 'screenManager', 'inputManager','outputManager', 'helpManager', 'memoryManager', 'eventManager', 'debug'],
'commandFolderList':['commands','onInput', 'onCursorChange', 'onScreenUpdate','onScreenChanged','onHeartBeat', 'onPlugInputDevice'
,'onApplicationChange','onSwitchApplicationProfile','help',],
}

View File

@ -0,0 +1,55 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import re, string
class headLineManager():
def __init__(self):
self.regExSingle = re.compile(r'(([^\w\s])\2{5,})')
self.regExDouble = re.compile(r'([^\w\s]{2,}){5,}')
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def replaceHeadLines(self, text):
# fast len check for bigger typing echo
if len(text) < 5:
return text
# more strong check, to not match if not needed:
if len(text.strip(string.ascii_letters+string.digits+string.whitespace)) < 5:
return text
result = ''
newText = ''
lastPos = 0
for match in self.regExDouble.finditer(text):
span = match.span()
newText += text[lastPos:span[0]]
numberOfChars = len(text[span[0]:span[1]])
name = text[span[0]:span[1]][:2]
if name[0] == name[1]:
newText += ' ' + str(numberOfChars) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[0], True) + ' '
else:
newText += ' ' + str(int(numberOfChars / 2)) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name, True) + ' '
lastPos = span[1]
if lastPos != 0:
newText += ' '
newText += text[lastPos:]
lastPos = 0
for match in self.regExSingle.finditer(newText):
span = match.span()
result += text[lastPos:span[0]]
numberOfChars = len(newText[span[0]:span[1]])
name = newText[span[0]:span[1]][:2]
if name[0] == name[1]:
result += ' ' + str(numberOfChars) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[0], True) + ' '
else:
result += ' ' + str(int(numberOfChars / 2)) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name, True) + ' '
lastPos = span[1]
if lastPos != 0:
result += ' '
result += newText[lastPos:]
return result

View File

@ -0,0 +1,81 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
class helpManager():
def __init__(self):
self.helpDict = {}
self.tutorialListIndex = None
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def toggleTutorialMode(self):
self.setTutorialMode(not self.env['general']['tutorialMode'])
def setTutorialMode(self, newTutorialMode):
self.env['general']['tutorialMode'] = newTutorialMode
if newTutorialMode:
self.createHelpDict()
self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_TUTORIAL_MODE'
self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_HELP'
self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_HELP'
self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_HELP'
else:
try:
del(self.env['bindings'][str([1, ['KEY_ESC']])])
del(self.env['bindings'][str([1, ['KEY_UP']])])
del(self.env['bindings'][str([1, ['KEY_DOWN']])])
del(self.env['bindings'][str([1, ['KEY_SPACE']])])
except:
pass
def isTutorialMode(self):
return self.env['general']['tutorialMode']
def getCommandHelpText(self, command, section = 'commands'):
commandName = command.lower()
commandName = commandName.split('__-__')[0]
commandName = commandName.replace('_',' ')
commandName = commandName.replace('_',' ')
if command == 'TOGGLE_TUTORIAL_MODE':
commandDescription = _('toggles the tutorial mode')
else:
commandDescription = self.env['runtime']['commandManager'].getCommandDescription( command, section = 'commands')
if commandDescription == '':
commandDescription = 'no Description available'
commandShortcut = self.env['runtime']['commandManager'].getShortcutForCommand( command)
commandShortcut = commandShortcut.replace('KEY_',' ')
commandShortcut = commandShortcut.replace('[','')
commandShortcut = commandShortcut.replace(']','')
commandShortcut = commandShortcut.replace("'",'')
if commandShortcut == '':
commandShortcut = 'unbound'
helptext = commandName + ', Shortcut ' + commandShortcut + ', Description ' + commandDescription
return helptext
def createHelpDict(self, section = 'commands'):
self.helpDict = {}
for command in sorted(self.env['commands'][section].keys()):
self.helpDict[len(self.helpDict)] = self.getCommandHelpText(command, section)
if len(self.helpDict) > 0:
self.tutorialListIndex = 0
else:
self.tutorialListIndex = None
def getHelpForCurrentIndex(self):
if self.tutorialListIndex == None:
return ''
return self.helpDict[self.tutorialListIndex]
def nextIndex(self):
if self.tutorialListIndex == None:
return
self.tutorialListIndex += 1
if self.tutorialListIndex >= len(self.helpDict):
self.tutorialListIndex = 0
def prevIndex(self):
if self.tutorialListIndex == None:
return
self.tutorialListIndex -= 1
if self.tutorialListIndex < 0:
self.tutorialListIndex = len(self.helpDict) - 1

View File

@ -0,0 +1,11 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import gettext
import locale
# the only function we really need to call here is gettext.install. Python3 has simplified this.
gettext.install("fenrir")

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,52 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.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)
return None
def handleInputEvent(self, event):
time.sleep(0.05)
if not self._initialized:
return
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

@ -0,0 +1,212 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import time
from fenrirscreenreader.core import debug
class inputManager():
def __init__(self):
self.setLedState = True
def initialize(self, environment):
self.env = environment
self.env['runtime']['settingsManager'].loadDriver(\
self.env['runtime']['settingsManager'].getSetting('keyboard', 'driver'), 'inputDriver')
self.updateInputDevices()
# init LEDs with current state
self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState()
self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1)
self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2)
self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
self.lastDeepestInput = []
self.lastInputTime = time.time()
def shutdown(self):
self.removeAllDevices()
self.env['runtime']['settingsManager'].shutdownDriver('inputDriver')
def getInputEvent(self):
return self.env['runtime']['inputDriver'].getInputEvent()
def handleInputEvent(self, eventData):
self.env['runtime']['debug'].writeDebugOut('DEBUG INPUT inputMan:' + str(eventData),debug.debugLevel.INFO)
if not eventData:
return
self.env['input']['prevInput'] = self.env['input']['currInput'].copy()
if eventData['EventState'] == 0:
if eventData['EventName'] in self.env['input']['currInput']:
self.env['input']['currInput'].remove(eventData['EventName'])
if len(self.env['input']['currInput']) > 1:
self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
elif len(self.env['input']['currInput']) == 0:
self.env['input']['shortcutRepeat'] = 1
self.setLedState = self.handleLedStates(eventData)
self.lastInputTime = time.time()
elif eventData['EventState'] == 1:
if not eventData['EventName'] in self.env['input']['currInput']:
self.env['input']['currInput'].append(eventData['EventName'])
if len(self.env['input']['currInput']) > 1:
self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
if len(self.lastDeepestInput) < len(self.env['input']['currInput']):
self.setLastDeepestInput( self.env['input']['currInput'].copy())
elif self.lastDeepestInput == self.env['input']['currInput']:
if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'):
self.env['input']['shortcutRepeat'] += 1
else:
self.env['input']['shortcutRepeat'] = 1
self.setLedState = self.handleLedStates(eventData)
self.lastInputTime = time.time()
elif eventData['EventState'] == 2:
self.lastInputTime = time.time()
self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState()
self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1)
self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2)
self.env['runtime']['debug'].writeDebugOut("currInput " + str(self.env['input']['currInput'] ) ,debug.debugLevel.INFO)
if self.noKeyPressed():
self.env['input']['prevInput'] = []
self.setLedState = True
def handleLedStates(self, mEvent):
if not self.setLedState:
return self.setLedState
if mEvent['EventName'] == 'KEY_NUMLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newNumLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState()
return False
if mEvent['EventState'] == 0 and not self.env['input']['newNumLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState()
return False
if mEvent['EventName'] == 'KEY_CAPSLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newCapsLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState(1)
return False
if mEvent['EventState'] == 0 and not self.env['input']['newCapsLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState(1)
return False
if mEvent['EventName'] == 'KEY_SCROLLLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newScrollLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState(2)
return False
if mEvent['EventState'] == 0 and not self.env['input']['newScrollLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState(2)
return False
return self.setLedState
def grabAllDevices(self):
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
self.env['runtime']['inputDriver'].grabAllDevices()
def updateInputDevices(self):
try:
self.env['runtime']['inputDriver'].updateInputDevices()
except:
pass
def removeAllDevices(self):
try:
self.env['runtime']['inputDriver'].removeAllDevices()
except:
pass
def convertEventName(self, eventName):
if not eventName:
return ''
if eventName == '':
return ''
eventName = eventName.upper()
if eventName == 'KEY_LEFTCTRL':
eventName = 'KEY_CTRL'
elif eventName == 'KEY_RIGHTCTRL':
eventName = 'KEY_CTRL'
elif eventName == 'KEY_LEFTSHIFT':
eventName = 'KEY_SHIFT'
elif eventName == 'KEY_RIGHTSHIFT':
eventName = 'KEY_SHIFT'
elif eventName == 'KEY_LEFTALT':
eventName = 'KEY_ALT'
elif eventName == 'KEY_RIGHTALT':
eventName = 'KEY_ALT'
elif eventName == 'KEY_LEFTMETA':
eventName = 'KEY_META'
elif eventName == 'KEY_RIGHTMETA':
eventName = 'KEY_META'
if self.isFenrirKey(eventName):
eventName = 'KEY_FENRIR'
if self.isScriptKey(eventName):
eventName = 'KEY_SCRIPT'
return eventName
def clearEventBuffer(self):
self.env['runtime']['inputDriver'].clearEventBuffer()
def setLastDeepestInput(self, currentDeepestInput):
self.lastDeepestInput = currentDeepestInput
def clearLastDeepInput(self):
self.lastDeepestInput = []
def getLastInputTime(self):
return self.lastInputTime
def getLastDeepestInput(self):
return self.lastDeepestInput
def writeEventBuffer(self):
try:
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
self.env['runtime']['inputDriver'].writeEventBuffer()
self.clearEventBuffer()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Error while writeUInput",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def noKeyPressed(self):
return self.env['input']['currInput'] == []
def isKeyPress(self):
return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != [])
def getPrevDeepestShortcut(self):
shortcut = []
shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.getLastDeepestInput())
return str(shortcut)
def getPrevShortcut(self):
shortcut = []
shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.env['input']['prevInput'])
return str(shortcut)
def getCurrShortcut(self, inputSequence = None):
shortcut = []
shortcut.append(self.env['input']['shortcutRepeat'])
if inputSequence:
shortcut.append(inputSequence)
else:
shortcut.append(self.env['input']['currInput'])
if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']):
if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)):
shortcut = []
self.env['input']['shortcutRepeat'] = 1
shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.env['input']['currInput'])
self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO)
return str(shortcut)
def currKeyIsModifier(self):
if len(self.getLastDeepestInput()) != 1:
return False
return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT')
def isFenrirKey(self, eventName):
return eventName in self.env['input']['fenrirKey']
def isScriptKey(self, eventName):
return eventName in self.env['input']['scriptKey']
def getCommandForShortcut(self, shortcut):
if not self.shortcutExists(shortcut):
return ''
return self.env['bindings'][shortcut]
def shortcutExists(self, shortcut):
return(shortcut in self.env['bindings'])

View File

@ -0,0 +1,123 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import time
from fenrirscreenreader.core import debug
class memoryManager():
def __init__(self):
self.listStorage = {}
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def listStorageValid(self,name, checkIndex = False):
try:
if checkIndex:
index = self.listStorage[name]['index']
if index == -1:
return self.listStorage[name]['list'] == []
return self.listStorage[name]['list'][index] != None
else:
return isinstance(self.listStorage[name]['list'],list)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("listStorageValid " + str(e),debug.debugLevel.ERROR)
return False
def addValueToFirstIndex(self, name, value):
if not self.listStorageValid(name):
return
if self.listStorage[name]['maxLength'] == None:
self.listStorage[name]['list'] = [value] + self.listStorage[name]['list']
else:
self.listStorage[name]['list'] = [value] + self.listStorage[name]['list'][:self.listStorage[name]['maxLength'] -1]
self.listStorage[name]['index'] = 0
def addIndexList(self, name, maxLength = None, currList = [], currIndex = -1):
if len(currList) != 0 and (currIndex == -1):
currIndex = 0
self.listStorage[name] = {'list': currList, 'index': currIndex, 'maxLength': maxLength}
def isLastIndex(self, name):
if not self.listStorageValid(name):
return False
return self.listStorage[name]['index'] == len(self.listStorage[name]['list']) - 1
def isFirstIndex(self, name):
if not self.listStorageValid(name):
return False
return self.listStorage[name]['index'] == 0
def getNextIndex(self, name):
if not self.listStorageValid(name):
return False
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return False
self.listStorage[name]['index'] += 1
if self.listStorage[name]['index'] > len(self.listStorage[name]['list']) -1:
self.listStorage[name]['index'] = 0
return True
def setPrefIndex(self, name):
if not self.listStorageValid(name):
return False
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return False
self.listStorage[name]['index'] -= 1
if self.listStorage[name]['index'] < 0:
self.listStorage[name]['index'] = len(self.listStorage[name]['list']) -1
return True
def setFirstIndex(self, name):
if not self.listStorageValid(name):
return False
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return False
self.listStorage[name]['index'] = 0
return True
def getIndexListLen(self, name):
if not self.listStorageValid(name):
return 0
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return 0
return len(self.listStorage[name])
def setLastIndex(self, name):
if not self.listStorageValid(name):
return False
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return False
self.listStorage[name]['index'] = len(self.listStorage[name]['list']) -1
return True
def clearCurrentIndexList(self, name):
if not self.listStorageValid(name):
return False
self.listStorage[name]['index'] = []
self.listStorage[name]['index'] = -1
def getCurrentIndex(self,name):
if not self.listStorageValid(name):
return False
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return False
try:
return self.listStorage[name]['index']
except:
retrun -1
def isIndexListEmpty(self, name):
if not self.listStorageValid(name):
return False
return len(self.listStorage[name]['list']) == 0
def getIndexListElement(self, name):
if not self.listStorageValid(name):
return None
if self.isIndexListEmpty(name):
self.listStorage[name]['index'] = -1
return None
currIndex = self.getCurrentIndex(name)
if currIndex == -1:
return None
try:
return self.listStorage[name]['list'][currIndex]
except:
return None

View File

@ -0,0 +1,15 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import time
from fenrirscreenreader.core import debug
outputData = {
'nextFlush': time.time(),
'messageText': '',
'messageOffset': None,
'cursorOffset': None,
}

View File

@ -0,0 +1,272 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
from fenrirscreenreader.utils import line_utils
import string, time, re
class outputManager():
def __init__(self):
self.lastEcho = ''
def initialize(self, environment):
self.env = environment
self.env['runtime']['settingsManager'].loadDriver(\
self.env['runtime']['settingsManager'].getSetting('speech', 'driver'), 'speechDriver')
self.env['runtime']['settingsManager'].loadDriver(\
self.env['runtime']['settingsManager'].getSetting('sound', 'driver'), 'soundDriver')
self.env['runtime']['settingsManager'].loadDriver(\
self.env['runtime']['settingsManager'].getSetting('braille', 'driver'), 'brailleDriver')
def shutdown(self):
self.env['runtime']['settingsManager'].shutdownDriver('soundDriver')
self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
self.env['runtime']['settingsManager'].shutdownDriver('brailleDriver')
def presentText(self, text, interrupt=True, soundIcon = '', ignorePunctuation=False, announceCapital=False, flush=True):
if text == '':
return
self.env['runtime']['debug'].writeDebugOut("presentText:\nsoundIcon:'"+soundIcon+"'\nText:\n" + text ,debug.debugLevel.INFO)
if self.playSoundIcon(soundIcon, interrupt):
self.env['runtime']['debug'].writeDebugOut("soundIcon found" ,debug.debugLevel.INFO)
return
if (len(text) > 1) and (text.strip(string.whitespace) == ''):
return
toAnnounceCapital = announceCapital and text[0].isupper()
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)
return
if self.env['runtime']['speechDriver'] == None:
self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText",debug.debugLevel.ERROR)
return
if interrupt:
self.interruptOutput()
try:
self.env['runtime']['speechDriver'].setLanguage(self.env['runtime']['settingsManager'].getSetting('speech', 'language'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech language in outputManager.speakText",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setVoice(self.env['runtime']['settingsManager'].getSetting('speech', 'voice'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Error while setting speech voice in outputManager.speakText",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
try:
if announceCapital:
self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'capitalPitch'))
else:
self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech pitch in outputManager.speakText",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setRate(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech rate in outputManager.speakText",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setModule(self.env['runtime']['settingsManager'].getSetting('speech', 'module'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech module in outputManager.speakText",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
try:
self.env['runtime']['speechDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume'))
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("setting speech volume in outputManager.speakText ",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
try:
cleanText = text.replace('\n',' , ')
cleanText = self.env['runtime']['headLineManager'].replaceHeadLines(cleanText)
cleanText = self.env['runtime']['punctuationManager'].proceedPunctuation(cleanText, ignorePunctuation)
cleanText = re.sub(' +$',' ', cleanText)
self.env['runtime']['speechDriver'].speak(cleanText)
self.env['runtime']['debug'].writeDebugOut("Speak: "+ cleanText,debug.debugLevel.INFO)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def brailleText(self, text='', flush=True):
if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
return
if self.env['runtime']['brailleDriver'] == None:
return
if flush:
self.env['output']['nextFlush'] = time.time() + self.getFlushTime(text)
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)
else:
if self.env['output']['nextFlush'] < time.time():
if self.env['output']['messageText'] != '':
self.env['output']['messageText'] = ''
if self.env['output']['messageOffset'] != None:
self.env['output']['messageOffset'] = None
cursor = self.getBrailleCursor()
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)
else:
displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
self.env['runtime']['brailleDriver'].writeText('flush'+displayText)
def getBrailleCursor(self):
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'REVIEW':
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'MANUAL':
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'LAST':
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
def getFixCursorCell(self):
size = self.env['runtime']['brailleDriver'].getDeviceSize()[0]
fixCell = self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'fixCursorOnCell')
if fixCell <= -1:
return size[0]
if fixCell >= size[0]:
return size[0]
return fixCell
def getActiveOffsetAndText(self):
if self.env['output']['messageOffset']:
return self.env['output']['messageOffset'], self.env['output']['messageText']
if not self.env['output']['cursorOffset']:
return self.getBrailleCursor(), self.env['screen']['newContentText']
return self.env['output']['cursorOffset'], self.env['screen']['newContentText']
def getHorizontalPanSize(self):
size = self.env['runtime']['brailleDriver'].getDeviceSize()
if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') <= 0:
return size[0]
if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') >= size[0]:
return size[0]
return self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal')
def getHorizontalPanLevel(self,offsetChange = 0):
panned = True
panSize = self.getHorizontalPanSize()
offset, text = self.getActiveOffsetAndText()
currline = text.split('\n')[offset['y']]
newOffsetStart = (int(offset['x'] / panSize) + offsetChange) * panSize
if newOffsetStart < 0:
newOffsetStart = 0
panned = False
if newOffsetStart >= len(text):
newOffsetStart = int((len(text) - panSize - 1) / panSize)
panned = False
return newOffsetStart, panned
def setPanLeft(self):
newPan, panned = self.getHorizontalPanLevel(-1)
if self.env['output']['messageOffset']:
self.env['output']['messageOffset'] = newPan.copy()
else:
self.env['output']['cursorOffset'] = newPan.copy()
return panned
def setPanRight(self):
newPan, panned = self.getHorizontalPanLevel(1)
if self.env['output']['messageOffset']:
self.env['output']['messageOffset'] = newPan.copy()
else:
self.env['output']['cursorOffset'] = newPan.copy()
return panned
def removePanning(self):
if self.env['output']['messageOffset']:
self.env['output']['messageOffset'] = None
else:
self.env['output']['cursorOffset'] = None
def getBrailleTextWithOffset(self, text, offset = None, cursor = None):
if text == '':
return ''
size = self.env['runtime']['brailleDriver'].getDeviceSize()
offsetText = text
if cursor and not offset:
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'FIXCELL':
#fix cell
cursorCell = self.getFixCursorCell()
offsetStart = cursor['x']
if offsetStart < size[0]:
if offsetStart <= cursorCell:
return offsetText[0: size[0]]
offsetStart -= cursorCell
if offsetStart >= len(offsetText):
offsetStart = len(offsetText) - 1
else:
# page and fallback
offsetStart = int(cursor['x'] / size[0]) * size[0]
else:
if not offset:
offset = {'x':0,'y':0}
offsetStart = offset['x']
if offsetStart >= len(offsetText):
offsetStart = len(offsetText) - size[0]
if offsetStart < 0:
offsetStart = 0
offsetEnd = offsetStart + size[0]
offsetText = offsetText[offsetStart: offsetEnd]
return offsetText
def interruptOutput(self):
self.env['runtime']['speechDriver'].cancel()
self.env['runtime']['debug'].writeDebugOut("Interrupt speech",debug.debugLevel.INFO)
def clearFlushTime(self):
self.setFlushTime(0.0)
def setFlushTime(self,newTime):
self.env['output']['nextFlush'] = newTime
def getFlushTime(self,text=''):
if self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') < 0 or \
self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'NONE':
return 999999999999
if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'FIX':
return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout')
if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'CHAR':
return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len(text)
if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'WORD':
wordsList = text.split(' ')
return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len( list( filter(None, wordsList) ) )
def playSoundIcon(self, soundIcon = '', interrupt=True):
if soundIcon == '':
return False
soundIcon = soundIcon.upper()
if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.speakText",debug.debugLevel.INFO)
return False
if self.env['runtime']['soundDriver'] == None:
self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText",debug.debugLevel.ERROR)
return False
try:
self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume'))
self.env['runtime']['soundDriver'].playSoundFile(self.env['soundIcons'][soundIcon], interrupt)
return True
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("\"playSoundIcon\" in outputManager.speakText ",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
return False
def announceActiveCursor(self, interrupt_p=False):
if self.env['runtime']['cursorManager'].isReviewMode():
self.presentText(' review cursor ', interrupt=interrupt_p)
else:
self.presentText(' text cursor ', interrupt=interrupt_p)

View File

@ -0,0 +1,87 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
from fenrirscreenreader.core.eventData import fenrirEventType
import time
from threading import Thread
from multiprocessing import Process
class processManager():
def __init__(self):
self._Processes = []
self._Threads = []
def initialize(self, environment):
self.env = environment
self.running = self.env['runtime']['eventManager'].getRunning()
self.addSimpleEventThread(fenrirEventType.HeartBeat, self.heartBeatTimer, multiprocess=True)
def shutdown(self):
self.terminateAllProcesses()
def terminateAllProcesses(self):
for proc in self._Processes:
try:
proc.terminate()
except Exception as e:
print(e)
def heartBeatTimer(self, active):
try:
time.sleep(0.5)
except:
pass
return time.time()
def addCustomEventThread(self, function, pargs = None, multiprocess = False, runOnce = False):
eventQueue = self.env['runtime']['eventManager'].getEventQueue()
if multiprocess:
t = Process(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce))
self._Processes.append(t)
else:# thread not implemented yet
t = Thread(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce))
self._Threads.append(t)
t.start()
def addSimpleEventThread(self, event, function, pargs = None, multiprocess = False, runOnce = False):
if multiprocess:
t = Process(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce))
self._Processes.append(t)
else:
t = Thread(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce))
self._Threads.append(t)
t.start()
def customEventWorkerThread(self, eventQueue, function, pargs = None, runOnce = False):
#if not isinstance(eventQueue, Queue):
# return
if not callable(function):
return
while self.running.value:
try:
if pargs:
function(self.running, eventQueue, pargs)
else:
function(self.running, eventQueue)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('processManager:customEventWorkerThread:function():' + str(e),debug.debugLevel.ERROR)
if runOnce:
break
def simpleEventWorkerThread(self, event, function, pargs = None, runOnce = False):
if not isinstance(event, fenrirEventType):
return
if not callable(function):
return
while self.running.value:
Data = None
try:
if pargs:
Data = function(self.running, pargs)
else:
Data = function(self.running)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('processManager:simpleEventWorkerThread:function():' + str(e),debug.debugLevel.ERROR)
self.env['runtime']['eventManager'].putToEventQueue(event, Data)
if runOnce:
break

View File

@ -0,0 +1,61 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import string
punctuationData = {
'LEVELDICT':{
'none': '',
'some': '#-$~+*-/\\@',
'most': '.,:-$~ +*-/\\@!#%^&*()[]}{<>;',
'all': string.punctuation + ' §',
},
'PUNCTDICT':{
' ':'space',
'&':'and',
"'":"apostrophe",
'@':'at',
'\\':'backslash',
'|':'bar',
'!':'bang',
'^':'carrot',
':':'colon',
',':'comma',
'-':'dash',
'$':'dollar',
'.':'dot',
'>':'greater',
'`':'grave',
'#':'hash',
'{':'left brace',
'[':'left bracket',
'(':'left paren',
'<':'less',
'%':'percent',
'+':'plus',
'?':'question',
'"':'quote',
')':'right paren',
'}':'right brace',
']':'right bracket',
';':'semicolon',
'/':'slash',
'*':'star',
'~':'tilde',
'_':'line',
'=':'equals',
},
'CUSTOMDICT':{
},
'EMOTICONDICT':{
':)':'smiley',
';)':'winking face',
'XD':'loool',
':@':'angry face',
':D':'lought'
},
}

View File

@ -0,0 +1,83 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import string
from fenrirscreenreader.core import debug
class punctuationManager():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
self.allPunctNone = dict.fromkeys(map(ord, string.punctuation +"§ "), ' ')
# replace with None:
# dot, comma, grave, apostrophe
#for char in [ord('`'),ord("'")]:
# self.allPunctNone[char] = None
# dont restore the following (for announce correct pause)
for char in [ord("'"),ord('.'), ord(','), ord(';'), ord(':'), ord('?'), ord('!'), ord('-')]:
self.allPunctNone[char] = chr(char)
def shutdown(self):
pass
def removeUnused(self, text, currLevel = ''):
# dont translate dot and comma because they create a pause
currAllPunctNone = self.allPunctNone.copy()
for char in currLevel:
try:
del currAllPunctNone[ord(char)]
except:
pass
return text.translate(currAllPunctNone)
def useCustomDict(self, text, customDict, seperator=''):
resultText = str(text)
if customDict:
for key,item in customDict.items():
resultText = resultText.replace(str(key),seperator + str(item) + seperator)
return resultText
def usePunctuationDict(self, text, punctuationDict, punctuation):
resultText = str(text)
if punctuationDict and punctuation and punctuation != '':
if ' ' in punctuation:
resultText = resultText.replace(' ',' ' + punctuationDict[' '] + ' ')
for key,item in punctuationDict.items():
if key in punctuation and key not in ' ':
if self.env['runtime']['settingsManager'].getSetting('general', 'respectPunctuationPause') and \
len(key) == 1 and \
key in "',.;:?!":
resultText = resultText.replace(str(key),' ' +str(item) + str(key) + ' ')
else:
resultText = resultText.replace(str(key),' ' +str(item) + ' ')
return resultText
def proceedPunctuation(self, text, ignorePunctuation=False):
resultText = text
resultText = self.useCustomDict(resultText, self.env['punctuation']['CUSTOMDICT'])
if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'):
resultText = self.useCustomDict(resultText, self.env['punctuation']['EMOTICONDICT'], ' ')
currPunctLevel = ''
if not ignorePunctuation and self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower() in self.env['punctuation']['LEVELDICT']:
currPunctLevel = self.env['punctuation']['LEVELDICT'][self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()]
else:
currPunctLevel = string.punctuation +' §'
resultText = self.usePunctuationDict(resultText, self.env['punctuation']['PUNCTDICT'], currPunctLevel)
resultText = self.removeUnused(resultText, currPunctLevel)
return resultText
def cyclePunctuation(self):
punctList = list(self.env['punctuation']['LEVELDICT'].keys())
try:
currIndex = punctList.index(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()) # curr punctuation
except:
return False
currIndex += 1
if currIndex >= len(punctList):
currIndex = 0
currLevel = punctList[currIndex]
self.env['runtime']['settingsManager'].setSetting('general', 'punctuationLevel', currLevel.lower())
return True

View File

@ -0,0 +1,20 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
runtimeData = {
'speechDriver': None,
'screenDriver': None,
'soundDriver': None,
'inputDriver': None,
'brailleDriver': None,
'inputManager': None,
'commandManager': None,
'screenManager': None,
'outputManager': None,
'debug':None,
}

View File

@ -0,0 +1,55 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import time
screenData = {
'columns': 0,
'lines': 0,
'oldDelta': '',
'oldAttribDelta': '',
'oldNegativeDelta': '',
'oldCursorReview':None,
'oldCursorAttrib':None,
'oldCursor':{'x':0,'y':0},
'oldContentBytes': b'',
'oldContentText': '',
'oldContentAttrib': None,
'oldApplication': '',
'oldTTY':None,
'newDelta': '',
'newNegativeDelta': '',
'newAttribDelta': '',
'newCursorReview':None,
'newCursorAttrib':None,
'newCursor':{'x':0,'y':0},
'newContentBytes': b'',
'newContentText': '',
'newContentAttrib': None,
'newTTY':'0',
'newApplication': '',
'lastScreenUpdate': time.time(),
'autoIgnoreScreens':[],
}
'''
screenData = {
'columns': 0,
'lines': 0,
'textDelta': '',
'negativeDelta': '',
'attribDelta': '',
'reviewCursor':None, #{'x':0,'y':0}
'attribCursor':None, #{'x':0,'y':0}
'textCursor':None, #{'x':0,'y':0}
'content': None, #{'x':0,'y':0}
'Text': '',
'Attrib': None,
'screen': None,
'application': '',
'timestamp': time.time(),
}
'''

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 fenrirscreenreader.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,117 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import time, os
class screenManager():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
self.env['runtime']['settingsManager'].loadDriver(\
self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver')
self.env['runtime']['screenDriver'].getCurrScreen()
self.env['runtime']['screenDriver'].getCurrScreen()
self.env['runtime']['screenDriver'].getSessionInformation()
def shutdown(self):
self.env['runtime']['settingsManager'].shutdownDriver('screenDriver')
def hanldeScreenChange(self, eventData):
self.env['runtime']['screenDriver'].getCurrScreen()
self.env['runtime']['screenDriver'].getSessionInformation()
if self.isScreenChange():
self.changeBrailleScreen()
if not self.isSuspendingScreen(self.env['screen']['newTTY']):
self.env['runtime']['screenDriver'].update(eventData, 'onScreenChange')
self.env['screen']['lastScreenUpdate'] = time.time()
def handleScreenUpdate(self, eventData):
self.env['screen']['oldApplication'] = self.env['screen']['newApplication']
if not self.isSuspendingScreen(self.env['screen']['newTTY']):
self.env['runtime']['screenDriver'].update(eventData, 'onScreenUpdate')
#if trigger == 'onUpdate' or self.isScreenChange() \
# or len(self.env['screen']['newDelta']) > 6:
# self.env['runtime']['screenDriver'].getCurrApplication()
self.env['screen']['lastScreenUpdate'] = time.time()
def formatAttributes(self, attribute, attributeFormatString = None):
if not attributeFormatString:
attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString')
if not attributeFormatString:
return ''
if attributeFormatString == '':
return ''
attributeFormatString = attributeFormatString.replace('fenrirBGColor', self.env['runtime']['screenDriver'].getFenrirBGColor(attribute))
attributeFormatString = attributeFormatString.replace('fenrirFGColor', self.env['runtime']['screenDriver'].getFenrirFGColor(attribute))
attributeFormatString = attributeFormatString.replace('fenrirUnderline', self.env['runtime']['screenDriver'].getFenrirUnderline(attribute))
attributeFormatString = attributeFormatString.replace('fenrirBold', self.env['runtime']['screenDriver'].getFenrirBold(attribute))
attributeFormatString = attributeFormatString.replace('fenrirBlink', self.env['runtime']['screenDriver'].getFenrirBlink(attribute))
attributeFormatString = attributeFormatString.replace('fenrirFontSize', self.env['runtime']['screenDriver'].getFenrirFontSize(attribute))
attributeFormatString = attributeFormatString.replace('fenrirFont', self.env['runtime']['screenDriver'].getFenrirFont(attribute))
return attributeFormatString
def isSuspendingScreen(self, screen = None):
if screen == None:
screen = self.env['screen']['newTTY']
ignoreScreens = []
fixIgnoreScreens = self.env['runtime']['settingsManager'].getSetting('screen', 'suspendingScreen')
if fixIgnoreScreens != '':
ignoreScreens.extend(fixIgnoreScreens.split(','))
if self.env['runtime']['settingsManager'].getSettingAsBool('screen', 'autodetectSuspendingScreen'):
ignoreScreens.extend(self.env['screen']['autoIgnoreScreens'])
self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ' + str(ignoreScreens) + ' '+ str(self.env['screen']['newTTY']),debug.debugLevel.INFO)
try:
ignoreFileName = self.env['runtime']['settingsManager'].getSetting('screen', 'suspendingScreenFile')
if ignoreFileName != '':
if os.access(ignoreFileName, os.R_OK):
with open(ignoreFileName) as fp:
ignoreScreens.extend(fp.read().replace('\n','').split(','))
except:
pass
return (screen in ignoreScreens)
def isScreenChange(self):
if not self.env['screen']['oldTTY']:
return False
return self.env['screen']['newTTY'] != self.env['screen']['oldTTY']
def isDelta(self, ignoreSpace=False):
newDelta = self.env['screen']['newDelta']
if ignoreSpace:
newDelta = newDelta.strip()
return newDelta != ''
def isNegativeDelta(self):
return self.env['screen']['newNegativeDelta'] != ''
def getWindowAreaInText(self, text):
if not self.env['runtime']['cursorManager'].isApplicationWindowSet():
return text
windowText = ''
windowList = text.split('\n')
currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
windowList = windowList[self.env['commandBuffer']['windowArea'][currApp]['1']['y']:self.env['commandBuffer']['windowArea'][currApp]['2']['y'] + 1]
for line in windowList:
windowText += line[self.env['commandBuffer']['windowArea'][currApp]['1']['x']:self.env['commandBuffer']['windowArea'][currApp]['2']['x'] + 1] + '\n'
return windowText
def injectTextToScreen(self, text, screen = None):
try:
self.env['runtime']['screenDriver'].injectTextToScreen(text, screen)
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR)
def changeBrailleScreen(self):
if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
return
if not self.env['runtime']['brailleDriver']:
return
if self.env['screen']['oldTTY']:
if not self.isSuspendingScreen(self.env['screen']['oldTTY']):
try:
self.env['runtime']['brailleDriver'].leveScreen()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:leveScreen ' + str(e),debug.debugLevel.ERROR)
if not self.isSuspendingScreen():
try:
self.env['runtime']['brailleDriver'].enterScreen(self.env['screen']['newTTY'])
except Exception as e:
self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:enterScreen ' + str(e),debug.debugLevel.ERROR)

View File

@ -0,0 +1,113 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
settingsData = {
'sound': {
'enabled': True,
'driver': 'genericDriver',
'theme': 'default',
'volume': 1.0,
'genericPlayFileCommand': 'play -q -v fenrirVolume fenrirSoundFile',
'genericFrequencyCommand': 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
},
'speech':{
'enabled': True,
'driver': 'genericDriver',
'serverPath': '',
'rate': 0.75,
'pitch': 0.5,
'capitalPitch':0.8,
'volume': 1.0,
'module': '',
'voice': 'en-us',
'language': '',
'autoReadIncoming': True,
'genericSpeechCommand':'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"',
'fenrirMinVolume':0,
'fenrirMaxVolume':200,
'fenrirMinPitch':0,
'fenrirMaxPitch':99,
'fenrirMinRate':80,
'fenrirMaxRate':450,
},
'braille':{
'enabled': False,
'driver':'brlapiDriver',
'layout': 'en',
'flushMode': 'word', #NONE,FIX,CHAR,WORD
'flushTimeout': 3,
'cursorFocusMode':'page', # page,fixCell
'fixCursorOnCell': -1,
'cursorFollowMode': 'review', # none, review, last, text
'panSizeHorizontal': 0 # 0 = display size
},
'screen':{
'driver': 'vcsaDriver',
'encoding': 'auto',
'screenUpdateDelay': 0.1,
'suspendingScreen': '',
'suspendingScreenFile': '/tmp/fenrirSuspend',
'autodetectSuspendingScreen': False,
},
'general':{
'debugLevel': debug.debugLevel.DEACTIVE,
'debugMode': 'FILE',
'punctuationProfile':'default',
'punctuationLevel': 'some',
'respectPunctuationPause':True,
'newLinePause':True,
'numberOfClipboards': 10,
'emoticons': True,
'fenrirKeys': 'KEY_KP0,KEY_META',
'scriptKeys': 'KEY_COMPOSE',
'timeFormat': '%I:%M%P',
'dateFormat': '%A, %B %d, %Y',
'autoSpellCheck': False,
'spellCheckLanguage': 'en_US',
'scriptPath': '/usr/share/fenrir/scripts',
'commandPath': '/usr/share/fenrir/commands',
'attributeFormatString': 'Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize'
},
'focus':{
'cursor': True,
'highlight': False,
},
'review':{
'lineBreak': True,
'endOfScreen': True,
'leaveReviewOnCursorChange': True,
'leaveReviewOnScreenChange': True,
},
'promote':{
'enabled': True,
'inactiveTimeoutSec': 120,
'list': '',
},
'time':{
'enabled': False,
'presentTime': True,
'presentDate': True,
'delaySec': 0,
'onMinutes': '00,30',
'announce': True,
'interrupt': False,
},
'keyboard':{
'driver': 'evdev',
'device': 'all',
'grabDevices': True,
'ignoreShortcuts': False,
'keyboardLayout': "desktop",
'charEcho': False,
'charDeleteEcho': True,
'wordEcho': True,
'interruptOnKeyPress': True,
'interruptOnKeyPressFilter': '',
'doubleTapTimeout': 0.2,
}
}

View File

@ -0,0 +1,364 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
import os, inspect
currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
fenrirPath = os.path.dirname(currentdir)
from configparser import ConfigParser
from fenrirscreenreader.core import debugManager
from fenrirscreenreader.core import memoryManager
from fenrirscreenreader.core import processManager
from fenrirscreenreader.core import eventManager
from fenrirscreenreader.core import inputManager
from fenrirscreenreader.core import outputManager
from fenrirscreenreader.core import commandManager
from fenrirscreenreader.core import screenManager
from fenrirscreenreader.core import punctuationManager
from fenrirscreenreader.core import cursorManager
from fenrirscreenreader.core import applicationManager
from fenrirscreenreader.core import helpManager
from fenrirscreenreader.core import headLineManager
from fenrirscreenreader.core import tableManager
from fenrirscreenreader.core import environment
from fenrirscreenreader.core import inputData
from fenrirscreenreader.core.settingsData import settingsData
from fenrirscreenreader.core import debug
from fenrirscreenreader.utils import module_utils
class settingsManager():
def __init__(self):
self.settings = settingsData
self.settingArgDict = {}
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def loadShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/desktop.conf'):
kbConfig = open(kbConfigPath,"r")
while(True):
invalid = False
line = kbConfig.readline()
if not line:
break
line = line.replace('\n','')
if line.replace(" ","") == '':
continue
if line.replace(" ","").startswith("#"):
continue
if line.count("=") != 1:
continue
sepLine = line.split('=')
commandName = sepLine[1].upper()
sepLine[0] = sepLine[0].replace(" ","")
sepLine[0] = sepLine[0].replace("'","")
sepLine[0] = sepLine[0].replace('"',"")
keys = sepLine[0].split(',')
shortcutKeys = []
shortcutRepeat = 1
shortcut = []
for key in keys:
try:
shortcutRepeat = int(key)
except:
if not self.isValidKey(key.upper()):
self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING)
invalid = True
break
shortcutKeys.append(key.upper())
if invalid:
continue
shortcut.append(shortcutRepeat)
shortcut.append(sorted(shortcutKeys))
if len(shortcutKeys) != 1 and not 'KEY_FENRIR' in shortcutKeys:
self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR)
continue
self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True)
self.env['bindings'][str(shortcut)] = commandName
kbConfig.close()
# fix bindings
self.env['bindings'][str([1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE'
def loadSoundIcons(self, soundIconPath):
siConfig = open(soundIconPath + '/soundicons.conf',"r")
while(True):
line = siConfig.readline()
if not line:
break
line = line.replace('\n','')
if line.replace(" ","") == '':
continue
if line.replace(" ","").startswith("#"):
continue
if line.count("=") != 1:
continue
Values = line.split('=')
soundIcon = Values[0].upper()
Values[1] = Values[1].replace("'","")
Values[1] = Values[1].replace('"',"")
soundIconFile = ''
if os.path.exists(Values[1]):
soundIconFile = Values[1]
else:
if not soundIconPath.endswith("/"):
soundIconPath += '/'
if os.path.exists(soundIconPath + Values[1]):
soundIconFile = soundIconPath + Values[1]
self.env['soundIcons'][soundIcon] = soundIconFile
self.env['runtime']['debug'].writeDebugOut("SoundIcon: " + soundIcon + '.' + soundIconFile, debug.debugLevel.INFO, onAnyLevel=True)
siConfig.close()
def isValidKey(self, key):
return key in inputData.keyNames
def loadDicts(self, dictConfigPath=fenrirPath + '/../../config/punctuation/default.conf'):
dictConfig = open(dictConfigPath,"r")
currDictName = ''
while(True):
line = dictConfig.readline()
if not line:
break
line = line.replace('\n','')
if line.replace(" ","") == '':
continue
if line.replace(" ","").startswith("#"):
continue
if line.replace(" ","").upper().startswith("[") and \
line.replace(" ","").upper().endswith("DICT]"):
currDictName = line[line.find('[') + 1 :line.upper().find('DICT]') + 4].upper()
else:
if currDictName == '':
continue
if not ":===:" in line:
continue
sepLine = line.split(':===:')
if len(sepLine) == 1:
sepLine.append('')
elif len(sepLine) < 1:
continue
elif len(sepLine) > 2:
sepLine[1] = ':===:'
self.env['punctuation'][currDictName][sepLine[0]] = sepLine[1]
self.env['runtime']['debug'].writeDebugOut("Punctuation: " + currDictName + '.' + str(sepLine[0]) + ' :' + sepLine[1] ,debug.debugLevel.INFO, onAnyLevel=True)
dictConfig.close()
def loadSettings(self, settingConfigPath):
if not os.path.exists(settingConfigPath):
return False
self.env['settings'] = ConfigParser()
self.env['settings'].read(settingConfigPath)
return True
def setSetting(self, section, setting, value):
self.env['settings'].set(section, setting, value)
def getSetting(self, section, setting):
value = ''
try:
value = self.settingArgDict[section.lower()][setting.lower()]
return value
except:
pass
try:
value = self.env['settings'].get(section, setting)
except:
value = str(self.settings[section][setting])
return value
def getSettingAsInt(self, section, setting):
value = 0
try:
value = int(self.settingArgDict[section.lower()][setting.lower()])
return value
except Exception as e:
pass
try:
value = self.env['settings'].getint(section, setting)
except:
value = self.settings[section][setting]
return value
def getSettingAsFloat(self, section, setting):
value = 0.0
try:
value = float(self.settingArgDict[section.lower()][setting.lower()])
return value
except Exception as e:
pass
try:
value = self.env['settings'].getfloat(section, setting)
except:
value = self.settings[section][setting]
return value
def getSettingAsBool(self, section, setting):
value = False
try:
value = self.settingArgDict[section.lower()][setting.lower()].upper() in ['1','YES','JA','TRUE']
return value
except Exception as e:
pass
try:
value = self.env['settings'].getboolean(section, setting)
except:
value = self.settings[section][setting]
return value
def loadDriver(self, driverName, driverType):
try:
if self.env['runtime'][driverType] != None:
self.env['runtime'][driverType].shutdown(self.env)
driver_mod = module_utils.importModule(driverName,
fenrirPath + "/" + driverType + '/' + driverName + '.py')
self.env['runtime'][driverType] = driver_mod.driver()
self.env['runtime'][driverType].initialize(self.env)
self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") OK",debug.debugLevel.INFO, onAnyLevel=True)
except Exception as e:
self.env['runtime'][driverType] = None
self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") FAILED:"+ str(e), debug.debugLevel.ERROR)
def shutdownDriver(self, driverType):
if self.env['runtime'][driverType] == None:
return
self.env['runtime'][driverType].shutdown()
del self.env['runtime'][driverType]
def setFenrirKeys(self, keys):
keys = keys.upper()
keyList = keys.split(',')
for key in keyList:
if not key in self.env['input']['fenrirKey']:
self.env['input']['fenrirKey'].append(key)
def setScriptKeys(self, keys):
keys = keys.upper()
keyList = keys.split(',')
for key in keyList:
if not key in self.env['input']['scriptKey']:
self.env['input']['scriptKey'].append(key)
def setOptionArgDict(self, section, option, value):
section = section.lower()
option = option.lower()
try:
e = self.settingArgDict[section]
except KeyError:
self.settingArgDict[section] = {}
self.settingArgDict[section][option] = str(value)
def parseSettingArgs(self, settingArgs):
for optionElem in settingArgs.split(';'):
if len(optionElem.split('#',1)) != 2:
continue
if len(optionElem.split('#',1)[1].split('=',1)) != 2:
continue
section = str(optionElem.split('#',1)[0]).lower()
option = str(optionElem.split('#',1)[1].split('=',1)[0]).lower()
value = optionElem.split('#',1)[1].split('=',1)[1]
self.setOptionArgDict(section, option, value)
def initFenrirConfig(self, cliArgs, fenrirManager = None, environment = environment.environment):
settingsRoot = '/etc/fenrirscreenreader/'
settingsFile = cliArgs.setting
soundRoot = '/usr/share/sounds/fenrirscreenreader/'
environment['runtime']['debug'] = debugManager.debugManager()
environment['runtime']['debug'].initialize(environment)
# get fenrir settings root
if not os.path.exists(settingsRoot):
if os.path.exists(fenrirPath +'/../../config/'):
settingsRoot = fenrirPath +'/../../config/'
else:
return None
# get settings file
if not os.path.exists(settingsFile):
if os.path.exists(settingsRoot + '/settings/settings.conf'):
settingsFile = settingsRoot + '/settings/settings.conf'
else:
return None
# get sound themes root
if not os.path.exists(soundRoot):
if os.path.exists(fenrirPath + '/../../config/sound/'):
soundRoot = fenrirPath + '/../../config/sound/'
environment['runtime']['settingsManager'] = self
environment['runtime']['settingsManager'].initialize(environment)
validConfig = environment['runtime']['settingsManager'].loadSettings(settingsFile)
if not validConfig:
return None
if cliArgs.options != '':
self.parseSettingArgs(cliArgs.options)
if cliArgs.debug:
self.setOptionArgDict('general', 'debugLevel', 3)
if cliArgs.print:
self.setOptionArgDict('general', 'debugLevel', 3)
self.setOptionArgDict('general', 'debugMode', 'PRINT')
self.setFenrirKeys(self.getSetting('general','fenrirKeys'))
self.setScriptKeys(self.getSetting('general','scriptKeys'))
if not os.path.exists(self.getSetting('keyboard','keyboardLayout')):
if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')):
self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout'))
environment['runtime']['settingsManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout'))
if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf'):
self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf')
environment['runtime']['settingsManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout'))
else:
environment['runtime']['settingsManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout'))
if not os.path.exists(self.getSetting('sound','theme') + '/soundicons.conf'):
if os.path.exists(soundRoot + self.getSetting('sound','theme')):
self.setSetting('sound', 'theme', soundRoot + self.getSetting('sound','theme'))
if os.path.exists(self.getSetting('sound','theme') + '/soundicons.conf'):
environment['runtime']['settingsManager'].loadSoundIcons(self.getSetting('sound','theme'))
else:
environment['runtime']['settingsManager'].loadSoundIcons(self.getSetting('sound','theme'))
if not os.path.exists(self.getSetting('general','punctuationProfile')):
if os.path.exists(settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile')):
self.setSetting('general', 'punctuationProfile', settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile'))
environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile'))
if os.path.exists(settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile') + '.conf'):
self.setSetting('general', 'punctuationProfile', settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile') + '.conf')
environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile'))
else:
environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile'))
if fenrirManager:
environment['runtime']['fenrirManager'] = fenrirManager
environment['runtime']['memoryManager'] = memoryManager.memoryManager()
environment['runtime']['memoryManager'].initialize(environment)
environment['runtime']['eventManager'] = eventManager.eventManager()
environment['runtime']['eventManager'].initialize(environment)
environment['runtime']['processManager'] = processManager.processManager()
environment['runtime']['processManager'].initialize(environment)
environment['runtime']['outputManager'] = outputManager.outputManager()
environment['runtime']['outputManager'].initialize(environment)
environment['runtime']['commandManager'] = commandManager.commandManager()
environment['runtime']['commandManager'].initialize(environment)
environment['runtime']['inputManager'] = inputManager.inputManager()
environment['runtime']['inputManager'].initialize(environment)
environment['runtime']['punctuationManager'] = punctuationManager.punctuationManager()
environment['runtime']['punctuationManager'].initialize(environment)
environment['runtime']['cursorManager'] = cursorManager.cursorManager()
environment['runtime']['cursorManager'].initialize(environment)
environment['runtime']['applicationManager'] = applicationManager.applicationManager()
environment['runtime']['applicationManager'].initialize(environment)
environment['runtime']['helpManager'] = helpManager.helpManager()
environment['runtime']['helpManager'].initialize(environment)
environment['runtime']['headLineManager'] = headLineManager.headLineManager()
environment['runtime']['headLineManager'].initialize(environment)
environment['runtime']['tableManager'] = tableManager.tableManager()
environment['runtime']['tableManager'].initialize(environment)
if environment['runtime']['screenManager'] == None:
environment['runtime']['screenManager'] = screenManager.screenManager()
environment['runtime']['screenManager'].initialize(environment)
environment['runtime']['debug'].writeDebugOut('\/-------environment-------\/',debug.debugLevel.INFO, onAnyLevel=True)
environment['runtime']['debug'].writeDebugOut(str(environment), debug.debugLevel.INFO, onAnyLevel=True)
environment['runtime']['debug'].writeDebugOut('\/-------settings.conf-------\/', debug.debugLevel.INFO, onAnyLevel=True)
environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections) , debug.debugLevel.INFO, onAnyLevel=True)
environment['runtime']['debug'].writeDebugOut('\/-------self.settingArgDict-------\/',debug.debugLevel.INFO, onAnyLevel=True)
environment['runtime']['debug'].writeDebugOut(str( self.settingArgDict) ,debug.debugLevel.INFO, onAnyLevel=True)
return environment

View File

@ -0,0 +1,47 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.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,100 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.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 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,46 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import re
class tableManager():
def __init__(self):
self.headLine = ''
self.defaultSeparators = ['+',';','|',' ']
self.noOfHeadLineColumns = 0
self.headColumnSep = ''
self.rowColumnSep = ''
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def resetTableMode(self):
self.setHeadLine()
def setHeadColumnSep(self, columnSep = ''):
self.headColumnSep = columnSep
if columnSep == '':
self.noOfHeadLineColumns = 0
else:
self.counNoOfHeadColumns()
def counNoOfHeadColumns(self):
pass
def searchForHeadColumnSep(self, headLine):
if ' ' in headLine:
return ' '
return ''
def setRowColumnSep(self, columnSep = ''):
self.rowColumnSep = columnSep
def setHeadLine(self, headLine = ''):
self.setHeadColumnSep()
self.setRowColumnSep()
if headLine != '':
sep = self.searchForHeadColumnSep(headLine)
if sep != '':
self.headLine = headLine
self.setHeadColumnSep(sep)