Updated configure_pipewire script. A bit more code refactor. Preparing to start moving everything over to pep8 compliance.
This commit is contained in:
@ -76,18 +76,21 @@ class command():
|
||||
# Note: Auto-disable on 100% completion removed to respect user settings
|
||||
|
||||
# Pattern 1: Percentage (50%, 25.5%, etc.)
|
||||
# Filter out common non-progress percentages (weather, system stats, etc.)
|
||||
percentMatch = re.search(r'(\d+(?:\.\d+)?)\s*%', text)
|
||||
if percentMatch:
|
||||
percentage = float(percentMatch.group(1))
|
||||
# Only trigger on realistic progress percentages (0-100%)
|
||||
if 0 <= percentage <= 100:
|
||||
self.env['runtime']['debug'].writeDebugOut("Found percentage: " + str(percentage), debug.debugLevel.INFO)
|
||||
if percentage != self.env['commandBuffer']['lastProgressValue']:
|
||||
self.env['runtime']['debug'].writeDebugOut("Playing tone for: " + str(percentage), debug.debugLevel.INFO)
|
||||
self.playProgressTone(percentage)
|
||||
self.env['commandBuffer']['lastProgressValue'] = percentage
|
||||
self.env['commandBuffer']['lastProgressTime'] = currentTime
|
||||
return
|
||||
# Filter out weather/system stats that contain percentages
|
||||
if not re.search(r'\b(?:humidity|cpu|memory|disk|usage|temp|weather|forecast)\b', text, re.IGNORECASE):
|
||||
self.env['runtime']['debug'].writeDebugOut("Found percentage: " + str(percentage), debug.debugLevel.INFO)
|
||||
if percentage != self.env['commandBuffer']['lastProgressValue']:
|
||||
self.env['runtime']['debug'].writeDebugOut("Playing tone for: " + str(percentage), debug.debugLevel.INFO)
|
||||
self.playProgressTone(percentage)
|
||||
self.env['commandBuffer']['lastProgressValue'] = percentage
|
||||
self.env['commandBuffer']['lastProgressTime'] = currentTime
|
||||
return
|
||||
|
||||
# Pattern 1b: Time/token activity (not percentage-based, so use single beep)
|
||||
timeMatch = re.search(r'(\d+)s\s', text)
|
||||
|
@ -17,6 +17,8 @@ class screenManager():
|
||||
self.currScreenText = ''
|
||||
self.colums = None
|
||||
self.rows = None
|
||||
# Compile regex once for better performance
|
||||
self._space_normalize_regex = re.compile(' +')
|
||||
def getRows(self):
|
||||
return self.rows
|
||||
def getColumns(self):
|
||||
@ -124,11 +126,6 @@ class screenManager():
|
||||
# This code detects and categorizes screen content changes to provide appropriate
|
||||
# speech feedback (typing echo vs incoming text vs screen updates)
|
||||
|
||||
# Pre-process screen text for comparison - collapse multiple spaces to single space
|
||||
# This normalization prevents spurious diffs from spacing inconsistencies
|
||||
oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
|
||||
newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
|
||||
|
||||
# Track whether this appears to be typing (user input) vs other screen changes
|
||||
typing = False
|
||||
diffList = []
|
||||
@ -137,6 +134,10 @@ class screenManager():
|
||||
# Special case: Initial screen content (going from empty to populated)
|
||||
# This handles first screen load or TTY switch scenarios
|
||||
if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '':
|
||||
# Pre-process screen text for comparison - collapse multiple spaces to single space
|
||||
# This normalization prevents spurious diffs from spacing inconsistencies
|
||||
oldScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
|
||||
newScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
|
||||
if oldScreenText == '' and\
|
||||
newScreenText != '':
|
||||
self.env['screen']['newDelta'] = newScreenText
|
||||
@ -194,6 +195,12 @@ class screenManager():
|
||||
# GENERAL SCREEN CHANGE DETECTION
|
||||
# Not typing - handle as line-by-line content change
|
||||
# This catches: incoming messages, screen updates, application output, etc.
|
||||
|
||||
# Pre-process screen text for comparison - collapse multiple spaces to single space
|
||||
# This normalization prevents spurious diffs from spacing inconsistencies
|
||||
oldScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
|
||||
newScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
|
||||
|
||||
diff = self.differ.compare(oldScreenText.split('\n'),\
|
||||
newScreenText.split('\n'))
|
||||
diffList = list(diff)
|
||||
|
@ -234,15 +234,71 @@ class settingsManager():
|
||||
elif isinstance(self.settings[section][setting], bool):
|
||||
if not value in ['True','False']:
|
||||
raise ValueError('could not convert string to bool: '+ value)
|
||||
v = value == 'True'
|
||||
elif isinstance(self.settings[section][setting], int):
|
||||
v = int(value)
|
||||
elif isinstance(self.settings[section][setting], float):
|
||||
v = float(value)
|
||||
|
||||
# Content validation for critical settings
|
||||
self._validateSettingValue(section, setting, v)
|
||||
|
||||
self.settingArgDict[section][setting] = str(value)
|
||||
except Exception as e:
|
||||
print('settingsManager:setOptionArgDict:Datatype missmatch: '+ section + '#' + setting + '=' + value + ' Error:' + str(e))
|
||||
#self.env['runtime']['debug'].writeDebugOut('settingsManager:setOptionArgDict:Datatype missmatch: '+ section + '#' + setting + '=' + value + ' Error:' + str(e), debug.debugLevel.ERROR)
|
||||
return
|
||||
|
||||
def _validateSettingValue(self, section, setting, value):
|
||||
"""Validate setting values for critical screen reader functionality.
|
||||
Only validates settings that could cause crashes or accessibility issues.
|
||||
Invalid values raise ValueError which is caught by the calling method."""
|
||||
|
||||
# Speech settings validation - critical for accessibility
|
||||
if section == 'speech':
|
||||
if setting == 'rate':
|
||||
if not (0.0 <= value <= 3.0):
|
||||
raise ValueError(f'Speech rate must be between 0.0 and 3.0, got {value}')
|
||||
elif setting == 'pitch':
|
||||
if not (0.0 <= value <= 2.0):
|
||||
raise ValueError(f'Speech pitch must be between 0.0 and 2.0, got {value}')
|
||||
elif setting == 'volume':
|
||||
if not (0.0 <= value <= 1.5):
|
||||
raise ValueError(f'Speech volume must be between 0.0 and 1.5, got {value}')
|
||||
elif setting == 'driver':
|
||||
valid_drivers = ['speechdDriver', 'genericDriver', 'dummyDriver']
|
||||
if value not in valid_drivers:
|
||||
raise ValueError(f'Invalid speech driver: {value}. Valid options: {valid_drivers}')
|
||||
|
||||
# Sound settings validation
|
||||
elif section == 'sound':
|
||||
if setting == 'volume':
|
||||
if not (0.0 <= value <= 1.5):
|
||||
raise ValueError(f'Sound volume must be between 0.0 and 1.5, got {value}')
|
||||
elif setting == 'driver':
|
||||
valid_drivers = ['genericDriver', 'gstreamerDriver', 'dummyDriver']
|
||||
if value not in valid_drivers:
|
||||
raise ValueError(f'Invalid sound driver: {value}. Valid options: {valid_drivers}')
|
||||
|
||||
# Screen settings validation
|
||||
elif section == 'screen':
|
||||
if setting == 'driver':
|
||||
valid_drivers = ['vcsaDriver', 'ptyDriver', 'dummyDriver']
|
||||
if value not in valid_drivers:
|
||||
raise ValueError(f'Invalid screen driver: {value}. Valid options: {valid_drivers}')
|
||||
|
||||
# Input settings validation
|
||||
elif section == 'keyboard':
|
||||
if setting == 'driver':
|
||||
valid_drivers = ['evdevDriver', 'ptyDriver', 'atspiDriver', 'dummyDriver']
|
||||
if value not in valid_drivers:
|
||||
raise ValueError(f'Invalid input driver: {value}. Valid options: {valid_drivers}')
|
||||
|
||||
# General settings validation
|
||||
elif section == 'general':
|
||||
if setting == 'debugLevel':
|
||||
if not (0 <= value <= 3):
|
||||
raise ValueError(f'Debug level must be between 0 and 3, got {value}')
|
||||
|
||||
def parseSettingArgs(self, settingArgs):
|
||||
for optionElem in settingArgs.split(';'):
|
||||
|
Reference in New Issue
Block a user