sync with master

This commit is contained in:
chrys
2016-11-05 02:07:48 +01:00
27 changed files with 271 additions and 223 deletions

View File

@@ -0,0 +1,29 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return 'enables or disables tracking of highlighted'
def run(self):
currMode=self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight')
self.env['runtime']['settingsManager'].setSetting('focus', 'highlight', str(not currMode))
self.env['runtime']['settingsManager'].setSetting('focus', 'cursor', str(currMode))
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
self.env['runtime']['outputManager'].presentText("highlight tracking", soundIcon='', interrupt=True)
else:
self.env['runtime']['outputManager'].presentText("cursor tracking", soundIcon='', interrupt=True)
def setCallback(self, callback):
pass

View File

@@ -18,6 +18,8 @@ class command():
return ''
def run(self):
if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
return
if self.env['runtime']['screenManager'].isScreenChange():
return
if self.env['runtime']['inputManager'].noKeyPressed():

View File

@@ -18,6 +18,8 @@ class command():
return ''
def run(self):
if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
return
if self.env['runtime']['inputManager'].noKeyPressed():
return
if self.env['runtime']['screenManager'].isScreenChange():

View File

@@ -0,0 +1,24 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return 'enables or disables tracking of highlighted'
def run(self):
if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
return
self.env['runtime']['outputManager'].presentText(self.env['screenData']['newAttribDelta'], soundIcon='', interrupt=True)
def setCallback(self, callback):
pass

View File

@@ -18,7 +18,9 @@ class command():
def run(self):
if self.env['runtime']['inputManager'].noKeyPressed():
return
return
if self.env['screenData']['newAttribDelta'] != '':
return
if self.env['runtime']['screenManager'].isScreenChange():
return
if self.env['runtime']['cursorManager'].isCursorVerticalMove():
@@ -29,9 +31,7 @@ class command():
return
prevLine = self.env['screenData']['oldContentText'].split('\n')[self.env['screenData']['newCursor']['y']]
currLine = self.env['screenData']['newContentText'].split('\n')[self.env['screenData']['newCursor']['y']]
if currLine.isspace():
self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
else:
if not currLine.isspace():
currPrompt = currLine.find('$')
rootPrompt = currLine.find('#')
if currPrompt <= 0:

View File

@@ -63,7 +63,12 @@ class cursorManager():
self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
if not self.env['screenData']['newCursorReview']:
self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursor'].copy()
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') and \
self.env['screenData']['newCursorAttrib'] != None:
if self.env['screenData']['newCursorAttrib']['x'] != 0 and \
self.env['screenData']['newCursorAttrib']['y'] != 0:
self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursorAttrib'].copy()
def setReviewCursorPosition(self, x, y):
if not self.isReviewMode():
self.enterReviewModeCurrTextCursor()

View File

@@ -43,7 +43,7 @@ class inputManager():
if len(self.env['input']['currInput']) == 0:
self.env['input']['prevDeepestInput'] = []
self.env['input']['shortcutRepeat'] = 1
self.handleLedStates(mEvent)
self.setLedState = self.handleLedStates(mEvent)
self.env['input']['lastInputTime'] = time.time()
elif mEvent['EventState'] == 1:
if not mEvent['EventName'] in self.env['input']['currInput']:
@@ -57,7 +57,7 @@ class inputManager():
self.env['input']['shortcutRepeat'] += 1
else:
self.env['input']['shortcutRepeat'] = 1
self.handleLedStates(mEvent)
self.setLedState = self.handleLedStates(mEvent)
self.env['input']['lastInputTime'] = time.time()
elif mEvent['EventState'] == 2:
self.env['input']['lastInputTime'] = time.time()
@@ -77,34 +77,29 @@ class inputManager():
def handleLedStates(self, mEvent):
if not self.setLedState:
return
return self.setLedState
if mEvent['EventName'] == 'KEY_NUMLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newNumLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState()
self.setLedState = False
return
return False
if mEvent['EventState'] == 0 and not self.env['input']['newNumLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState()
self.setLedState = False
return
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)
self.setLedState = False
return
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)
self.setLedState = False
return
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)
self.setLedState = False
return
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)
self.setLedState = False
return
self.env['runtime']['inputDriver'].toggleLedState(2)
return False
return self.setLedState
def grabDevices(self):
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
@@ -168,10 +163,10 @@ class inputManager():
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def isFenrirKeyPressed(self):
return 'KEY_FENRIR' in self.env['input']['currInput']
return 'KEY_FENRIR' in self.env['input']['prevDeepestInput']
def isScriptKeyPressed(self):
return 'KEY_SCRIPT' in self.env['input']['currInput']
return 'KEY_SCRIPT' in self.env['input']['prevDeepestInput']
def noKeyPressed(self):
return self.env['input']['currInput'] == []

View File

@@ -11,8 +11,10 @@ screenData = {
'columns': 0,
'lines': 0,
'oldDelta': '',
'oldAttribDelta': '',
'oldNegativeDelta': '',
'oldCursorReview':None,
'oldCursorAttrib':None,
'oldCursor':{'x':0,'y':0},
'oldContentBytes': b'',
'oldContentText': '',
@@ -21,7 +23,9 @@ screenData = {
'oldTTY':None,
'newDelta': '',
'newNegativeDelta': '',
'newAttribDelta': '',
'newCursorReview':None,
'newCursorAttrib':None,
'newCursor':{'x':0,'y':0},
'newContentBytes': b'',
'newContentText': '',

View File

@@ -55,6 +55,10 @@ settings = {
'spellCheckLanguage': 'en_US',
'scriptPath':'/etc/fenrir/scripts',
},
'focus':{
'cursor': True,
'highlight': False,
},
'promote':{
'enabled': True,
'inactiveTimeoutSec': 120,

View File

@@ -43,8 +43,6 @@ class driver():
return currMapEvent
if currMapEvent['EventState'] in [0,1,2]:
return currMapEvent
event = self.iDevices[fd].read_one()
return None
@@ -77,7 +75,7 @@ class driver():
if self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() == 'ALL':
self.iDevices = {dev.fd: dev for dev in self.iDevices if 1 in dev.capabilities()}
self.ledDevices = {dev.fd: dev for dev in self.ledDevices if 1 in dev.capabilities() and 17 in dev.capabilities()}
elif self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() == 'AUTO':
elif self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() == 'NOMICE':
self.iDevices = {dev.fd: dev for dev in self.iDevices if 1 in dev.capabilities() and not 3 in dev.capabilities() and not 2 in dev.capabilities()}
self.ledDevices = {dev.fd: dev for dev in self.ledDevices if 1 in dev.capabilities() and 17 in dev.capabilities() and not 3 in dev.capabilities() and not 2 in dev.capabilities()}
else:
@@ -102,10 +100,10 @@ class driver():
# 0 = Numlock
# 1 = Capslock
# 2 = Rollen
if self.ledDevices == {}:
return False
if self.ledDevices == None:
return False
return False
if self.ledDevices == {}:
return False
for fd, dev in self.ledDevices.items():
return led in dev.leds()
return False

View File

@@ -8,6 +8,7 @@ import difflib
import re
import subprocess
from core import debug
from utils import screen_utils
class driver():
def __init__(self):
@@ -16,9 +17,6 @@ class driver():
self.env = environment
def shutdown(self):
pass
def insert_newlines(self, string, every=64):
return '\n'.join(string[i:i+every] for i in range(0, len(string), every))
def getCurrScreen(self):
self.env['screenData']['oldTTY'] = self.env['screenData']['newTTY']
try:
@@ -85,10 +83,12 @@ class driver():
# set new "old" values
self.env['screenData']['oldContentBytes'] = self.env['screenData']['newContentBytes']
self.env['screenData']['oldContentText'] = self.env['screenData']['newContentText']
self.env['screenData']['oldContentTextAttrib'] = self.env['screenData']['newContentAttrib']
self.env['screenData']['oldCursor']['x'] = self.env['screenData']['newCursor']['x']
self.env['screenData']['oldCursor']['y'] = self.env['screenData']['newCursor']['y']
self.env['screenData']['oldContentAttrib'] = self.env['screenData']['newContentAttrib']
self.env['screenData']['oldCursor'] = self.env['screenData']['newCursor'].copy()
if self.env['screenData']['newCursorAttrib']:
self.env['screenData']['oldCursorAttrib'] = self.env['screenData']['newCursorAttrib'].copy()
self.env['screenData']['oldDelta'] = self.env['screenData']['newDelta']
self.env['screenData']['oldAttribDelta'] = self.env['screenData']['newAttribDelta']
self.env['screenData']['oldNegativeDelta'] = self.env['screenData']['newNegativeDelta']
self.env['screenData']['newContentBytes'] = newContentBytes
# get metadata like cursor or screensize
@@ -98,8 +98,9 @@ class driver():
self.env['screenData']['newCursor']['y'] = int( self.env['screenData']['newContentBytes'][3])
# analyze content
self.env['screenData']['newContentText'] = self.env['screenData']['newContentBytes'][4:][::2].decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
self.env['screenData']['newContentText'] = screen_utils.removeNonprintable(self.env['screenData']['newContentText'])
self.env['screenData']['newContentAttrib'] = self.env['screenData']['newContentBytes'][5:][::2]
self.env['screenData']['newContentText'] = self.insert_newlines(self.env['screenData']['newContentText'], self.env['screenData']['columns'])
self.env['screenData']['newContentText'] = screen_utils.insertNewlines(self.env['screenData']['newContentText'], self.env['screenData']['columns'])
if self.env['screenData']['newTTY'] != self.env['screenData']['oldTTY']:
self.env['screenData']['oldContentBytes'] = b''
@@ -108,10 +109,15 @@ class driver():
self.env['screenData']['oldCursor']['x'] = 0
self.env['screenData']['oldCursor']['y'] = 0
self.env['screenData']['oldDelta'] = ''
self.env['screenData']['oldAttribDelta'] = ''
self.env['screenData']['oldCursorAttrib'] = None
self.env['screenData']['newCursorAttrib'] = None
self.env['screenData']['oldNegativeDelta'] = ''
# always clear current deltas
# initialize current deltas
self.env['screenData']['newNegativeDelta'] = ''
self.env['screenData']['newDelta'] = ''
self.env['screenData']['newDelta'] = ''
self.env['screenData']['newAttribDelta'] = ''
# changes on the screen
oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screenData']['oldContentText']))
newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screenData']['newContentText']))
@@ -145,4 +151,9 @@ class driver():
else:
self.env['screenData']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
self.env['screenData']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
# track highlighted
if self.env['screenData']['oldContentAttrib'] != self.env['screenData']['newContentAttrib']:
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
self.env['screenData']['newAttribDelta'], self.env['screenData']['newCursorAttrib'] = screen_utils.trackHighlights(self.env['screenData']['oldContentAttrib'], self.env['screenData']['newContentAttrib'], self.env['screenData']['newContentText'], self.env['screenData']['columns'])

View File

@@ -21,12 +21,10 @@ class driver():
if self.soundFileCommand == '':
self.soundFileCommand = 'play -q -v fenrirVolume fenrirSoundFile'
if self.frequenceCommand == '':
self.frequenceCommand = '=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
return
self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
def shutdown(self):
self.cancel()
return
def playFrequence(self, frequence, duration, adjustVolume):
def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
if interrupt:
self.cancel()
popenFrequenceCommand = self.frequenceCommand.replace('fenrirVolume', str(self.volume + adjustVolume ))

View File

@@ -34,13 +34,15 @@ class driver():
def speak(self,text, queueable=True):
if not self._isInitialized:
return False
self.initialize(self.env)
if not self._isInitialized:
return False
if queueable == False: self.cancel()
try:
self._sd.set_synthesis_voice(self._language)
self._sd.set_punctuation(self._punct.NONE)
except Exception as e:
pass
self._isInitialized = False
self._sd.speak(text)
return True

View File

@@ -5,6 +5,7 @@
# By Chrys, Storm Dragon, and contributers.
from core import debug
from collections import Counter
def getPrevLine(currX,currY, currText):
endOfScreen = False

View File

@@ -0,0 +1,54 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
from collections import Counter
import string
def removeNonprintable(text):
# Get the difference of all ASCII characters from the set of printable characters
nonprintable = set([chr(i) for i in range(128)]).difference(string.printable)
# Use translate to remove all non-printable characters
return text.translate({ord(character):None for character in nonprintable})
def insertNewlines(string, every=64):
return '\n'.join(string[i:i+every] for i in range(0, len(string), every))
def splitEvery(string, every=64):
return list(string[i:i+every] for i in range(0, len(string), every))
def trackHighlights(oldAttr, newAttr, text, lenght):
result = ''
currCursor = None
if oldAttr == newAttr:
return result, currCursor
if len(newAttr) == 0:
return result, currCursor
if len(oldAttr) != len(newAttr):
return result, currCursor
old = splitEvery(oldAttr,lenght)
new = splitEvery(newAttr,lenght)
textLines = text.split('\n')
if len(textLines) != len(new):
return result, currCursor
try:
background = Counter(newAttr).most_common(1)
background = background[0][0]
except Exception as e:
background = chr(7)
for line in range(len(new)):
if old[line] != new[line]:
for column in range(len(new[line])):
if old[line][column] != new[line][column]:
if new[line][column] != background:
if not currCursor:
currCursor = {}
currCursor['x'] = column
currCursor['y'] = line
result += textLines[line][column]
result += ' '
return result, currCursor

View File

@@ -1,112 +0,0 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from core import debug
def getPrevWord(currX,currY, currText):
if currText == '':
return -1, -1, ''
x, y, currWord = getCurrentWord(currX,currY,currText)
wrappedLines = currText.split('\n')
if (currWord == ''):
return currX, currY, ''
while True:
if x < 2:
if y != 0:
y -= 1
else:
return currX, currY, ''
x = len(wrappedLines[y]) - 1
else:
x -= 1
if wrappedLines[y] != '':
break
x, y, currWord = getCurrentWord(x, y, currText)
if currWord == '':
return currX, currY, ''
return x, y, currWord
def getCurrentWord(currX,currY, currText):
if currText == '':
return -1, -1, ''
x = currX
y = currY
wrappedLines = currText.split('\n')
wordFound = False
currWord = ''
currLine = wrappedLines[y].replace("\t"," ")
if currLine[x] == ' ' and x > 1:
x = x - 2
while not wordFound:
x = currLine[:x].rfind(" ")
if x == -1:
x = 0
else:
x += 1
wordEnd = currLine[x + 1:].find(" ")
if wordEnd == -1:
wordEnd = len(currLine)
else:
wordEnd += x + 1
currWord = currLine[x:wordEnd]
wordFound = currWord.strip(" \t\n") != ''
if wordFound:
break
if x == 0:
if y != 0:
y -= 1
currLine = wrappedLines[y].replace("\t"," ")
else:
return currX, currY, ''
x = len(wrappedLines[y]) - 1
else:
x -= 1
return x, y, currWord
def getNextWord(currX,currY, currText):
if currText == '':
return -1, -1, ''
x = currX
y = currY
wrappedLines = currText.split('\n')
wordFound = False
currWord = ''
currLine = wrappedLines[y].replace("\t"," ")
while not wordFound:
xtmp = 0
if x + 1 >= len(currLine):
if y < len(wrappedLines):
y += 1
currLine = wrappedLines[y].replace("\t"," ")
else:
return currX, currY, ''
x = 0
else:
x += 1
xtmp = x
x = currLine[x:].find(" ")
if x == -1:
x = len(currLine)
continue
else:
if xtmp != 0:
xtmp += 1
x += xtmp
if x + 1 < len(currLine):
wordEnd = currLine[x + 1:].find(" ")
else:
wordEnd = -1
if wordEnd == -1:
wordEnd = len(currLine)
else:
wordEnd += x + 1
if wordEnd >= len(currLine) and y + 1 >= len(wrappedLines):
return currX, currY, ''
currWord = currLine[x:wordEnd]
wordFound = currWord.strip(" \t\n") != ''
if not wordFound:
x = wordEnd
return x, y, currWord