Renamed fenrir-package to fenrir to satisfy packaging deps.
This commit is contained in:
0
src/fenrir/core/__init__.py
Executable file
0
src/fenrir/core/__init__.py
Executable file
31
src/fenrir/core/applicationManager.py
Normal file
31
src/fenrir/core/applicationManager.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from 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['screenData']['newApplication'].upper()
|
||||
if not currApp:
|
||||
currApp == 'DEFAULT'
|
||||
if currApp == '':
|
||||
currApp == 'DEFAULT'
|
||||
return currApp
|
||||
def getPrevApplication(self):
|
||||
prevApp = self.env['screenData']['oldApplication'].upper()
|
||||
if not prevApp:
|
||||
prevApp == 'DEFAULT'
|
||||
if prevApp == '':
|
||||
prevApp == 'DEFAULT'
|
||||
return prevApp
|
||||
def isApplicationChange(self):
|
||||
return self.env['screenData']['oldApplication'] != self.env['screenData']['newApplication']
|
127
src/fenrir/core/commandManager.py
Normal file
127
src/fenrir/core/commandManager.py
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
import importlib.util
|
||||
import glob, os, time
|
||||
from core import debug
|
||||
|
||||
class commandManager():
|
||||
def __init__(self):
|
||||
pass
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.env['runtime']['commandManager'].loadCommands('commands')
|
||||
self.env['runtime']['commandManager'].loadCommands('onInput')
|
||||
self.env['runtime']['commandManager'].loadCommands('onScreenUpdate')
|
||||
self.env['runtime']['commandManager'].loadCommands('onScreenChanged')
|
||||
self.env['runtime']['commandManager'].loadCommands('onApplicationChange')
|
||||
self.env['runtime']['commandManager'].loadCommands('onSwitchApplicationProfile')
|
||||
|
||||
def shutdown(self):
|
||||
self.env['runtime']['commandManager'].shutdownCommands('commands')
|
||||
self.env['runtime']['commandManager'].shutdownCommands('onInput')
|
||||
self.env['runtime']['commandManager'].shutdownCommands('onScreenUpdate')
|
||||
self.env['runtime']['commandManager'].shutdownCommands('onScreenChanged')
|
||||
self.env['runtime']['commandManager'].shutdownCommands('onApplicationChange')
|
||||
self.env['runtime']['commandManager'].shutdownCommands('onSwitchApplicationProfile')
|
||||
|
||||
def loadCommands(self, section='commands'):
|
||||
commandFolder = "commands/" + section +"/"
|
||||
commandList = glob.glob(commandFolder+'*')
|
||||
for command in commandList:
|
||||
try:
|
||||
fileName, fileExtension = os.path.splitext(command)
|
||||
fileName = fileName.split('/')[-1]
|
||||
if fileName in ['__init__','__pycache__']:
|
||||
continue
|
||||
if fileExtension.lower() == '.py':
|
||||
spec = importlib.util.spec_from_file_location(fileName, command)
|
||||
command_mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(command_mod)
|
||||
self.env['commands'][section][fileName.upper()] = command_mod.command()
|
||||
self.env['commands'][section][fileName.upper()].initialize(self.env)
|
||||
self.env['runtime']['debug'].writeDebugOut("Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO)
|
||||
|
||||
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 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):
|
||||
if self.env['runtime']['screenManager'].isSuspendingScreen():
|
||||
return
|
||||
for command in sorted(self.env['commands'][trigger]):
|
||||
if self.commandExists(command, trigger):
|
||||
try:
|
||||
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 ,debug.debugLevel.ERROR)
|
||||
self.env['runtime']['debug'].writeDebugOut(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['generalInformation']['tutorialMode']:
|
||||
self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO)
|
||||
description = self.env['commands'][section][command].getDescription()
|
||||
self.env['runtime']['outputManager'].presentText(description, interrupt=True)
|
||||
else:
|
||||
self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO)
|
||||
self.env['commands'][section][command].run()
|
||||
except Exception as e:
|
||||
self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.ERROR)
|
||||
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
|
||||
self.clearCommandQueued()
|
||||
self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
|
||||
|
||||
def isCommandQueued(self):
|
||||
return self.env['commandInfo']['currCommand'] != ''
|
||||
|
||||
def clearCommandQueued(self):
|
||||
self.env['commandInfo']['currCommand'] = ''
|
||||
|
||||
def queueCommand(self, command):
|
||||
if command == '':
|
||||
return
|
||||
self.env['commandInfo']['currCommand'] = command
|
||||
|
||||
def commandExists(self, command, section = 'commands'):
|
||||
return( command in self.env['commands'][section])
|
45
src/fenrir/core/commands.py
Normal file
45
src/fenrir/core/commands.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
import time
|
||||
|
||||
|
||||
# used as shared memory between commands
|
||||
# use this in your own commands
|
||||
commandBuffer = {
|
||||
'genericList':[],
|
||||
'genericListSource':'',
|
||||
'genericListSelection': 0,
|
||||
'clipboard':[],
|
||||
'currClipboard': 0,
|
||||
'Marks':{'1':None, '2':None},
|
||||
'bookMarks':{},
|
||||
'windowArea':{},
|
||||
}
|
||||
|
||||
# used by the commandManager
|
||||
commandInfo = {
|
||||
'currCommand': '',
|
||||
'lastCommandExecutionTime': time.time(),
|
||||
'lastCommandRequestTime': time.time(),
|
||||
}
|
||||
|
||||
# used by the commandManager
|
||||
commands = {
|
||||
'onInput':{
|
||||
},
|
||||
'onScreenChanged':{
|
||||
},
|
||||
'onScreenUpdate':{
|
||||
},
|
||||
'onApplicationChange':{
|
||||
},
|
||||
'commands':{
|
||||
},
|
||||
'onSwitchApplicationProfile':{
|
||||
},
|
||||
}
|
87
src/fenrir/core/cursorManager.py
Normal file
87
src/fenrir/core/cursorManager.py
Normal file
@@ -0,0 +1,87 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from 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):
|
||||
if not self.env['commandBuffer']['Marks']['1']:
|
||||
self.env['commandBuffer']['Marks']['1'] = self.env['screenData']['newCursorReview'].copy()
|
||||
else:
|
||||
self.env['commandBuffer']['Marks']['2'] = self.env['screenData']['newCursorReview'].copy()
|
||||
def getReviewOrTextCursor(self):
|
||||
if self.env['screenData']['newCursorReview']:
|
||||
return self.env['screenData']['newCursorReview'].copy()
|
||||
else:
|
||||
return self.env['screenData']['newCursor'].copy()
|
||||
def clearReviewCursor(self):
|
||||
if not self.isReviewMode():
|
||||
return
|
||||
self.env['screenData']['oldCursorReview'] = None
|
||||
self.env['screenData']['newCursorReview'] = None
|
||||
|
||||
def isReviewMode(self):
|
||||
return self.env['screenData']['newCursorReview'] != None
|
||||
def enterReviewModeCurrTextCursor(self, overwrite=False):
|
||||
if self.isReviewMode() and not overwrite:
|
||||
return
|
||||
self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
|
||||
if not self.env['screenData']['newCursorReview']:
|
||||
self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursor'].copy()
|
||||
def setReviewCursorPosition(self, x, y):
|
||||
if not self.isReviewMode():
|
||||
self.enterReviewModeCurrTextCursor()
|
||||
self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
|
||||
self.env['screenData']['newCursorReview']['x'] = x
|
||||
self.env['screenData']['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
|
67
src/fenrir/core/debug.py
Normal file
67
src/fenrir/core/debug.py
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/python
|
||||
# Debugger module for the Fenrir screen reader.
|
||||
|
||||
from enum import Enum
|
||||
from datetime import datetime
|
||||
|
||||
class debugLevel(Enum):
|
||||
DEACTIVE = 0
|
||||
ERROR = 1
|
||||
WARNING = 2
|
||||
INFO = 3
|
||||
def __int__(self):
|
||||
return self.value
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class debug():
|
||||
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 = debugLevel.DEACTIVE):
|
||||
if self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level):
|
||||
if self._fileOpened:
|
||||
self.closeDebugFile()
|
||||
return
|
||||
else:
|
||||
if not self._fileOpened:
|
||||
self.openDebugFile()
|
||||
msg = str(level) +' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
) + ': ' + text
|
||||
print(msg)
|
||||
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
|
26
src/fenrir/core/environment.py
Normal file
26
src/fenrir/core/environment.py
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
from core import settings
|
||||
from core import runtime
|
||||
from core import screenData
|
||||
from core import generalInformation
|
||||
from core import commands
|
||||
from core import inputEvent
|
||||
|
||||
environment = {
|
||||
'screenData': screenData.screenData,
|
||||
'runtime': runtime.runtime,
|
||||
'generalInformation': generalInformation.generalInformation,
|
||||
'settings': settings.settings,
|
||||
'commands': commands.commands,
|
||||
'commandInfo': commands.commandInfo,
|
||||
'commandBuffer': commands.commandBuffer,
|
||||
'input': inputEvent.input,
|
||||
'soundIcons': {},
|
||||
'bindings': {},
|
||||
}
|
12
src/fenrir/core/generalInformation.py
Normal file
12
src/fenrir/core/generalInformation.py
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
|
||||
generalInformation = {
|
||||
'running': True,
|
||||
'tutorialMode': False,
|
||||
}
|
32
src/fenrir/core/inputEvent.py
Normal file
32
src/fenrir/core/inputEvent.py
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
import time
|
||||
|
||||
input = {
|
||||
'currInput': [],
|
||||
'prevDeepestInput': [],
|
||||
'eventBuffer': [],
|
||||
'shortcutRepeat': 0,
|
||||
'fenrirKey': ['KEY_KP0'],
|
||||
'keyForeward': 0,
|
||||
'lastInputTime':time.time(),
|
||||
'oldNumLock': True,
|
||||
'newNumLock':True,
|
||||
'oldScrollLock': True,
|
||||
'newScrollLock':True,
|
||||
'oldCapsLock':False,
|
||||
'newCapsLock':False
|
||||
}
|
||||
|
||||
inputEvent = {
|
||||
'EventName': '',
|
||||
'EventValue': '',
|
||||
'EventSec': 0,
|
||||
'EventUsec': 0,
|
||||
'EventState': 0,
|
||||
}
|
156
src/fenrir/core/inputManager.py
Normal file
156
src/fenrir/core/inputManager.py
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
import time
|
||||
from core import debug
|
||||
from core import inputEvent
|
||||
|
||||
class inputManager():
|
||||
def __init__(self):
|
||||
pass
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.env['runtime']['settingsManager'].loadDriver(\
|
||||
self.env['runtime']['settingsManager'].getSetting('keyboard', 'driver'), 'inputDriver')
|
||||
# init LEDs with current state
|
||||
self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getNumlock()
|
||||
self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
|
||||
self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getCapslock()
|
||||
self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
|
||||
self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getScrollLock()
|
||||
self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
|
||||
self.grabDevices()
|
||||
|
||||
def shutdown(self):
|
||||
self.env['runtime']['inputManager'].releaseDevices()
|
||||
self.env['runtime']['settingsManager'].shutdownDriver('inputDriver')
|
||||
|
||||
def getInputEvent(self):
|
||||
eventReceived = False
|
||||
mEvent = self.env['runtime']['inputDriver'].getInputEvent()
|
||||
if mEvent:
|
||||
mEvent['EventName'] = self.convertEventName(mEvent['EventName'])
|
||||
eventReceived = True
|
||||
if mEvent['EventState'] == 0:
|
||||
if mEvent['EventName'] in self.env['input']['currInput']:
|
||||
self.env['input']['currInput'].remove(mEvent['EventName'])
|
||||
if len(self.env['input']['currInput']) > 1:
|
||||
self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
|
||||
if len(self.env['input']['currInput']) == 0:
|
||||
self.env['input']['prevDeepestInput'] = []
|
||||
self.env['input']['shortcutRepeat'] = 1
|
||||
elif mEvent['EventState'] == 1:
|
||||
if not mEvent['EventName'] in self.env['input']['currInput']:
|
||||
self.env['input']['currInput'].append(mEvent['EventName'])
|
||||
if len(self.env['input']['currInput']) > 1:
|
||||
self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
|
||||
if len(self.env['input']['prevDeepestInput']) < len(self.env['input']['currInput']):
|
||||
self.env['input']['prevDeepestInput'] = self.env['input']['currInput'].copy()
|
||||
elif self.env['input']['prevDeepestInput'] == self.env['input']['currInput']:
|
||||
self.env['input']['shortcutRepeat'] += 1
|
||||
|
||||
elif mEvent['EventState'] == 2:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
|
||||
self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getNumlock()
|
||||
self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
|
||||
self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getCapslock()
|
||||
self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
|
||||
self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getScrollLock()
|
||||
self.env['input']['lastInputTime'] = time.time()
|
||||
return eventReceived
|
||||
|
||||
def grabDevices(self):
|
||||
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
|
||||
self.env['runtime']['inputDriver'].grabDevices()
|
||||
|
||||
def releaseDevices(self):
|
||||
try:
|
||||
self.env['runtime']['inputDriver'].releaseDevices()
|
||||
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'
|
||||
return eventName
|
||||
|
||||
def isConsumeInput(self):
|
||||
return self.env['runtime']['commandManager'].isCommandQueued() and \
|
||||
not self.env['input']['keyForeward']
|
||||
#and
|
||||
# not (self.env['input']['keyForeward'] or \
|
||||
# self.env['runtime']['settingsManager'].getSettingAsBool(, 'keyboard', 'grabDevices'))
|
||||
|
||||
def clearEventBuffer(self):
|
||||
self.env['runtime']['inputDriver'].clearEventBuffer()
|
||||
|
||||
def writeEventBuffer(self):
|
||||
try:
|
||||
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
|
||||
self.env['runtime']['inputDriver'].writeEventBuffer()
|
||||
time.sleep(0.005)
|
||||
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 isFenrirKeyPressed(self):
|
||||
return 'KEY_FENRIR' in self.env['input']['currInput']
|
||||
|
||||
def noKeyPressed(self):
|
||||
return self.env['input']['currInput'] == []
|
||||
|
||||
def getPrevDeepestInput(self):
|
||||
shortcut = []
|
||||
shortcut.append(self.env['input']['shortcutRepeat'])
|
||||
shortcut.append(self.env['input']['prevDeepestInput'])
|
||||
|
||||
def getPrevShortcut(self):
|
||||
shortcut = []
|
||||
shortcut.append(self.env['input']['shortcutRepeat'])
|
||||
shortcut.append(self.env['input']['prevInput'])
|
||||
return str(shortcut)
|
||||
|
||||
def getCurrShortcut(self):
|
||||
shortcut = []
|
||||
shortcut.append(self.env['input']['shortcutRepeat'])
|
||||
shortcut.append(self.env['input']['currInput'])
|
||||
return str(shortcut)
|
||||
|
||||
def isFenrirKey(self, eventName):
|
||||
return eventName in self.env['input']['fenrirKey']
|
||||
|
||||
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'])
|
123
src/fenrir/core/outputManager.py
Normal file
123
src/fenrir/core/outputManager.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
import string
|
||||
|
||||
class outputManager():
|
||||
def __init__(self):
|
||||
pass
|
||||
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')
|
||||
|
||||
def shutdown(self):
|
||||
self.env['runtime']['settingsManager'].shutdownDriver('soundDriver')
|
||||
self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
|
||||
|
||||
def presentText(self, text, interrupt=True, soundIcon = '', ignorePunctuation=False, announceCapital=False):
|
||||
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
|
||||
toAnnounceCapital = announceCapital and len(text.strip(' \n\t')) == 1 and text.strip(' \n\t').isupper()
|
||||
if toAnnounceCapital:
|
||||
if self.playSoundIcon('capital', False):
|
||||
toAnnounceCapital = False
|
||||
|
||||
self.speakText(text, interrupt, ignorePunctuation,toAnnounceCapital)
|
||||
self.brailleText(text, interrupt)
|
||||
|
||||
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:
|
||||
text = self.env['runtime']['punctuationManager'].proceedPunctuation(text,ignorePunctuation)
|
||||
self.env['runtime']['speechDriver'].speak(text)
|
||||
self.env['runtime']['debug'].writeDebugOut("Speak: "+ text,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, interrupt=True):
|
||||
if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
|
||||
return
|
||||
if self.env['runtime']['brailleDriver'] == None:
|
||||
return
|
||||
print('braille:'+text)
|
||||
|
||||
def interruptOutput(self):
|
||||
self.env['runtime']['speechDriver'].cancel()
|
||||
self.env['runtime']['debug'].writeDebugOut("Interrupt speech",debug.debugLevel.INFO)
|
||||
|
||||
|
||||
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
|
110
src/fenrir/core/punctuationManager.py
Normal file
110
src/fenrir/core/punctuationManager.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
import string
|
||||
from 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 space:
|
||||
# dot, comma, grave, apostrophe
|
||||
for char in [ord('.'),ord(','),ord('`'),ord("'")]:
|
||||
self.allPunctNone[char] = None
|
||||
self.punctuation = {
|
||||
'levels':{
|
||||
'none': '',
|
||||
'some': '#-$~+*-/\\@',
|
||||
'most': '.,:-$~+*-/\\@!#%^&*()[]}{<>;',
|
||||
'all': string.punctuation,
|
||||
},
|
||||
'punctuationDict':{
|
||||
'&':'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':{
|
||||
':)':'smiley',
|
||||
';)':'winking face',
|
||||
'XD':'loool',
|
||||
':@':'angry face',
|
||||
':D':'lought'
|
||||
}
|
||||
}
|
||||
def shutdown(self):
|
||||
pass
|
||||
def removeUnused(self, text):
|
||||
return text.translate(self.allPunctNone)
|
||||
|
||||
def useCustomDict(self, text, customDict):
|
||||
resultText = str(text)
|
||||
if customDict:
|
||||
for key,item in customDict.items():
|
||||
resultText = resultText.replace(str(key),str(item))
|
||||
return resultText
|
||||
def usePunctuationDict(self, text, punctuationDict, punctuation):
|
||||
resultText = str(text)
|
||||
|
||||
if punctuationDict and punctuation and punctuation != '':
|
||||
for key,item in punctuationDict.items():
|
||||
if key in punctuation:
|
||||
resultText = resultText.replace(str(key),' ' +str(item) +' ')
|
||||
return resultText
|
||||
|
||||
def proceedPunctuation(self, text, ignorePunctuation=False):
|
||||
resultText = self.useCustomDict(text, self.punctuation['customDict'])
|
||||
currPunctLevel = ''
|
||||
if not ignorePunctuation and self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower() in self.punctuation['levels']:
|
||||
currPunctLevel = self.punctuation['levels'][self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()]
|
||||
else:
|
||||
currPunctLevel = string.punctuation
|
||||
resultText = self.usePunctuationDict(resultText, self.punctuation['punctuationDict'], currPunctLevel)
|
||||
resultText = self.removeUnused(resultText)
|
||||
return resultText
|
||||
|
||||
def cyclePunctuation(self):
|
||||
punctList = list(self.punctuation['levels'].keys())
|
||||
try:
|
||||
currIndex = punctList.index(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()) # curr punctuation
|
||||
except:
|
||||
return
|
||||
currIndex += 1
|
||||
if currIndex >= len(punctList):
|
||||
currIndex = 0
|
||||
currLevel = punctList[currIndex]
|
||||
self.env['runtime']['settingsManager'].setSetting('general', currLevel.lower())
|
20
src/fenrir/core/runtime.py
Normal file
20
src/fenrir/core/runtime.py
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
|
||||
runtime = {
|
||||
'speechDriver': None,
|
||||
'screenDriver': None,
|
||||
'soundDriver': None,
|
||||
'inputDriver': None,
|
||||
'brailleDriver': None,
|
||||
'inputManager': None,
|
||||
'commandManager': None,
|
||||
'screenManager': None,
|
||||
'outputManager': None,
|
||||
'debug':None,
|
||||
}
|
32
src/fenrir/core/screenData.py
Normal file
32
src/fenrir/core/screenData.py
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
import time
|
||||
|
||||
screenData = {
|
||||
'columns': 0,
|
||||
'lines': 0,
|
||||
'oldDelta': '',
|
||||
'oldNegativeDelta': '',
|
||||
'oldCursorReview':None,
|
||||
'oldCursor':{'x':0,'y':0},
|
||||
'oldContentBytes': b'',
|
||||
'oldContentText': '',
|
||||
'oldContentAttrib': b'',
|
||||
'oldApplication': '',
|
||||
'oldTTY':'-1',
|
||||
'newDelta': '',
|
||||
'newNegativeDelta': '',
|
||||
'newCursorReview':None,
|
||||
'newCursor':{'x':0,'y':0},
|
||||
'newContentBytes': b'',
|
||||
'newContentText': '',
|
||||
'newContentAttrib': b'',
|
||||
'newTTY':'0',
|
||||
'newApplication': '',
|
||||
'lastScreenUpdate': time.time()
|
||||
}
|
51
src/fenrir/core/screenManager.py
Normal file
51
src/fenrir/core/screenManager.py
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
import time
|
||||
|
||||
class screenManager():
|
||||
def __init__(self):
|
||||
self.autoIgnoreScreens = []
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
self.env['runtime']['settingsManager'].loadDriver(\
|
||||
self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver')
|
||||
if self.env['runtime']['settingsManager'].getSettingAsBool('screen', 'autodetectSuspendingScreen'):
|
||||
self.autoIgnoreScreens = self.env['runtime']['screenDriver'].getIgnoreScreens()
|
||||
|
||||
def shutdown(self):
|
||||
self.env['runtime']['settingsManager'].shutdownDriver('screenDriver')
|
||||
|
||||
def update(self, trigger='onUpdate'):
|
||||
self.env['runtime']['screenDriver'].getCurrScreen()
|
||||
self.env['screenData']['oldApplication'] = self.env['screenData']['newApplication']
|
||||
if not self.isSuspendingScreen():
|
||||
self.env['runtime']['screenDriver'].update(trigger)
|
||||
if trigger == 'onUpdate' or self.isScreenChange() or len(self.env['screenData']['newDelta']) > 6:
|
||||
self.env['runtime']['screenDriver'].getCurrApplication()
|
||||
self.env['screenData']['lastScreenUpdate'] = time.time()
|
||||
|
||||
def isSuspendingScreen(self):
|
||||
return ((self.env['screenData']['newTTY'] in \
|
||||
self.env['runtime']['settingsManager'].getSetting('screen', 'suspendingScreen').split(',')) or
|
||||
(self.env['screenData']['newTTY'] in self.autoIgnoreScreens))
|
||||
|
||||
def isScreenChange(self):
|
||||
return self.env['screenData']['newTTY'] != self.env['screenData']['oldTTY']
|
||||
|
||||
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
|
||||
|
68
src/fenrir/core/settings.py
Normal file
68
src/fenrir/core/settings.py
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
from core import debug
|
||||
|
||||
settings = {
|
||||
'sound': {
|
||||
'enabled': True,
|
||||
'driver': 'generic',
|
||||
'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': 'speechd',
|
||||
'rate': 0.75,
|
||||
'pitch': 0.5,
|
||||
'capitalPitch':0.8,
|
||||
'volume': 1.0,
|
||||
'module': '',
|
||||
'voice': 'de',
|
||||
'language': 'de',
|
||||
'autoReadIncoming': True,
|
||||
},
|
||||
'braille':{
|
||||
'enabled': False,
|
||||
'layout': 'en',
|
||||
},
|
||||
'screen':{
|
||||
'driver': 'linux',
|
||||
'encoding': 'cp850',
|
||||
'screenUpdateDelay': 0.4,
|
||||
'suspendingScreen': '',
|
||||
'autodetectSuspendingScreen': False,
|
||||
},
|
||||
'general':{
|
||||
'debugLevel': debug.debugLevel.DEACTIVE,
|
||||
'punctuationLevel': 1,
|
||||
'numberOfClipboards': 10,
|
||||
'fenrirKeys': ['KEY_KP0'],
|
||||
'timeFormat': '%I:%M%P',
|
||||
'dateFormat': '%A, %B %d, %Y',
|
||||
'autoSpellCheck': False,
|
||||
'spellCheckLanguage': 'en_US',
|
||||
},
|
||||
'promote':{
|
||||
'enabled': True,
|
||||
'inactiveTimeoutSec': 120,
|
||||
'list': '',
|
||||
},
|
||||
'keyboard':{
|
||||
'driver': 'evdev',
|
||||
'device': 'all',
|
||||
'grabDevices': True,
|
||||
'ignoreShortcuts': False,
|
||||
'keyboardLayout': "desktop",
|
||||
'charEcho': False,
|
||||
'charDeleteEcho': True,
|
||||
'wordEcho': True,
|
||||
'interruptOnKeyPress': True,
|
||||
'doubleTapDelay': 0.2,
|
||||
}
|
||||
}
|
214
src/fenrir/core/settingsManager.py
Normal file
214
src/fenrir/core/settingsManager.py
Normal file
@@ -0,0 +1,214 @@
|
||||
#!/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributers.
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
from configparser import ConfigParser
|
||||
from core import inputManager
|
||||
from core import outputManager
|
||||
from core import commandManager
|
||||
from core import screenManager
|
||||
from core import punctuationManager
|
||||
from core import cursorManager
|
||||
from core import applicationManager
|
||||
from core import environment
|
||||
from core.settings import settings
|
||||
from core import debug
|
||||
|
||||
class settingsManager():
|
||||
def __init__(self):
|
||||
self.settings = settings
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
def shutdown(self):
|
||||
pass
|
||||
def loadShortcuts(self, kbConfigPath='../../config/keyboard/desktop.conf'):
|
||||
kbConfig = open(kbConfigPath,"r")
|
||||
while(True):
|
||||
line = kbConfig.readline()
|
||||
if not line:
|
||||
break
|
||||
line = line.replace('\n','')
|
||||
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:
|
||||
shortcutKeys.append(key.upper())
|
||||
shortcut.append(shortcutRepeat)
|
||||
shortcut.append(sorted(shortcutKeys))
|
||||
self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO)
|
||||
self.env['bindings'][str(shortcut)] = commandName
|
||||
kbConfig.close()
|
||||
|
||||
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(" ","").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
|
||||
siConfig.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.env['settings'].get(section, setting)
|
||||
except:
|
||||
value = str(self.settings[section][setting])
|
||||
return value
|
||||
|
||||
def getSettingAsInt(self, section, setting):
|
||||
value = 0
|
||||
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 = self.env['settings'].getfloat(section, setting)
|
||||
except:
|
||||
value = self.settings[section][setting]
|
||||
return value
|
||||
|
||||
def getSettingAsBool(self, section, setting):
|
||||
value = False
|
||||
try:
|
||||
value = self.env['settings'].getboolean(section, setting)
|
||||
except:
|
||||
value = self.settings[section][setting]
|
||||
return value
|
||||
|
||||
def loadDriver(self, driverName, driverType):
|
||||
if self.env['runtime'][driverType] != None:
|
||||
print('shutdown %s',driverType)
|
||||
self.env['runtime'][driverType].shutdown(self.env)
|
||||
spec = importlib.util.spec_from_file_location(driverName, driverType + '/' + driverName + '.py')
|
||||
driver_mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(driver_mod)
|
||||
self.env['runtime'][driverType] = driver_mod.driver()
|
||||
self.env['runtime'][driverType].initialize(self.env)
|
||||
|
||||
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 keyIDasString(self, key):
|
||||
try:
|
||||
KeyID = self.getCodeForKeyID(key)
|
||||
return str(KeyID)
|
||||
except:
|
||||
return ''
|
||||
|
||||
def initFenrirConfig(self, environment = environment.environment, settingsRoot = '/etc/fenrir/', settingsFile='settings.conf'):
|
||||
environment['runtime']['debug'] = debug.debug()
|
||||
environment['runtime']['debug'].initialize(environment)
|
||||
if not os.path.exists(settingsRoot):
|
||||
if os.path.exists('../../config/'):
|
||||
settingsRoot = '../../config/'
|
||||
else:
|
||||
return None
|
||||
|
||||
environment['runtime']['settingsManager'] = self
|
||||
environment['runtime']['settingsManager'].initialize(environment)
|
||||
|
||||
validConfig = environment['runtime']['settingsManager'].loadSettings(settingsRoot + '/settings/' + settingsFile)
|
||||
if not validConfig:
|
||||
return None
|
||||
self.setFenrirKeys(self.getSetting('general','fenrirKeys'))
|
||||
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(settingsRoot + 'sound/'+ self.getSetting('sound','theme')):
|
||||
self.setSetting('sound', 'theme', settingsRoot + 'sound/'+ 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'))
|
||||
|
||||
environment['runtime']['inputManager'] = inputManager.inputManager()
|
||||
environment['runtime']['inputManager'].initialize(environment)
|
||||
environment['runtime']['outputManager'] = outputManager.outputManager()
|
||||
environment['runtime']['outputManager'].initialize(environment)
|
||||
environment['runtime']['commandManager'] = commandManager.commandManager()
|
||||
environment['runtime']['commandManager'].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)
|
||||
|
||||
if environment['runtime']['screenManager'] == None:
|
||||
environment['runtime']['screenManager'] = screenManager.screenManager()
|
||||
environment['runtime']['screenManager'].initialize(environment)
|
||||
|
||||
environment['runtime']['debug'].writeDebugOut('\/-------environment-------\/',debug.debugLevel.ERROR)
|
||||
environment['runtime']['debug'].writeDebugOut(str(environment),debug.debugLevel.ERROR)
|
||||
environment['runtime']['debug'].writeDebugOut('\/-------settings.conf-------\/',debug.debugLevel.ERROR)
|
||||
environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections
|
||||
),debug.debugLevel.ERROR)
|
||||
return environment
|
||||
|
Reference in New Issue
Block a user