2024-12-06 01:08:46 -05:00
|
|
|
#!/usr/bin/env python3
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from typing import List, Optional
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
@dataclass
|
|
|
|
class Dependency:
|
|
|
|
name: str
|
|
|
|
depType: str # screen, braille, input, sound, speech, core
|
|
|
|
moduleName: str
|
|
|
|
checkCommands: Optional[List[str]] = None # Command-line tools to check
|
|
|
|
pythonImports: Optional[List[str]] = None # Python packages to check
|
|
|
|
devicePaths: Optional[List[str]] = None # Device files to check
|
|
|
|
|
|
|
|
def check_dependency(dep: Dependency) -> bool:
|
|
|
|
"""Check if a single dependency is satisfied."""
|
|
|
|
isAvailable = True
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
if dep.pythonImports:
|
|
|
|
for package in dep.pythonImports:
|
|
|
|
try:
|
|
|
|
moduleName = package.split('.')[0]
|
|
|
|
__import__(moduleName)
|
|
|
|
print(f'{package}: OK')
|
|
|
|
except ImportError:
|
|
|
|
print(f'{package}: FAIL')
|
|
|
|
isAvailable = False
|
|
|
|
|
|
|
|
if dep.checkCommands:
|
|
|
|
for cmd in dep.checkCommands:
|
|
|
|
if os.path.exists(f'/usr/bin/{cmd}') or os.path.exists(f'/bin/{cmd}'):
|
|
|
|
print(f'{cmd}: OK')
|
|
|
|
else:
|
|
|
|
print(f'{cmd}: FAIL')
|
|
|
|
isAvailable = False
|
|
|
|
|
|
|
|
if dep.devicePaths:
|
|
|
|
for path in dep.devicePaths:
|
|
|
|
if os.path.exists(path):
|
|
|
|
print(f'{path}: OK')
|
|
|
|
else:
|
|
|
|
print(f'{path}: FAIL')
|
|
|
|
isAvailable = False
|
2020-03-03 15:56:44 -05:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
return isAvailable
|
|
|
|
|
|
|
|
# Define all dependencies
|
|
|
|
dependencyList = [
|
|
|
|
# Core dependencies
|
|
|
|
Dependency('FenrirCore', 'core', 'core',
|
|
|
|
pythonImports=['daemonize', 'enchant']),
|
2018-05-15 03:23:11 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
# Screen drivers
|
|
|
|
Dependency('DummyScreen', 'screen', 'dummyDriver'),
|
|
|
|
Dependency('VCSA', 'screen', 'vcsaDriver',
|
|
|
|
pythonImports=['dbus'],
|
|
|
|
devicePaths=['/dev/vcsa']),
|
|
|
|
Dependency('PTY', 'screen', 'ptyDriver',
|
|
|
|
pythonImports=['pyte']),
|
|
|
|
|
|
|
|
# Braille drivers
|
|
|
|
Dependency('DummyBraille', 'braille', 'dummyDriver'),
|
|
|
|
Dependency('DebugBraille', 'braille', 'debugDriver'),
|
|
|
|
Dependency('BRLAPI', 'braille', 'brlapiDriver',
|
|
|
|
pythonImports=['brlapi']),
|
|
|
|
|
|
|
|
# Input drivers
|
|
|
|
Dependency('DummyInput', 'input', 'dummyDriver'),
|
|
|
|
Dependency('DebugInput', 'input', 'debugDriver'),
|
|
|
|
Dependency('Evdev', 'input', 'evdevDriver',
|
|
|
|
pythonImports=['evdev', 'evdev.InputDevice', 'evdev.UInput', 'pyudev']),
|
|
|
|
Dependency('PTYInput', 'input', 'ptyDriver',
|
|
|
|
pythonImports=['pyte']),
|
|
|
|
|
|
|
|
# Sound drivers
|
|
|
|
Dependency('DummySound', 'sound', 'dummyDriver'),
|
|
|
|
Dependency('DebugSound', 'sound', 'debugDriver'),
|
|
|
|
Dependency('GenericSound', 'sound', 'genericDriver',
|
|
|
|
checkCommands=['play', 'sox']),
|
|
|
|
Dependency('GStreamer', 'sound', 'gstreamerDriver',
|
|
|
|
pythonImports=['gi', 'gi.repository.GLib', 'gi.repository.Gst']),
|
|
|
|
|
|
|
|
# Speech drivers
|
|
|
|
Dependency('DummySpeech', 'speech', 'dummyDriver'),
|
|
|
|
Dependency('DebugSpeech', 'speech', 'debugDriver'),
|
|
|
|
Dependency('Speechd', 'speech', 'speechdDriver',
|
|
|
|
pythonImports=['speechd']),
|
|
|
|
Dependency('GenericSpeech', 'speech', 'genericDriver',
|
|
|
|
checkCommands=['espeak-ng'])
|
|
|
|
]
|
|
|
|
|
|
|
|
defaultModules = {
|
|
|
|
'FenrirCore',
|
|
|
|
'VCSA',
|
|
|
|
'DummyBraille',
|
|
|
|
'Evdev',
|
|
|
|
'GenericSpeech',
|
|
|
|
'GenericSound'
|
|
|
|
}
|
|
|
|
|
|
|
|
def check_all_dependencies():
|
|
|
|
print('Checking dependencies...\n')
|
|
|
|
availableModules = []
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
# Group dependencies by type for organized output
|
|
|
|
for depType in ['core', 'screen', 'braille', 'input', 'sound', 'speech']:
|
|
|
|
print(f'{depType.upper()} DRIVERS')
|
|
|
|
print('-' * 20)
|
|
|
|
|
|
|
|
depsOfType = [d for d in dependencyList if d.depType == depType]
|
|
|
|
for dep in depsOfType:
|
|
|
|
print(f'\nChecking {dep.name}:')
|
|
|
|
if check_dependency(dep):
|
|
|
|
availableModules.append(dep.name)
|
|
|
|
print('')
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
print_summary(availableModules)
|
|
|
|
|
|
|
|
def print_summary(availableModules: List[str]):
|
|
|
|
print('=' * 20)
|
|
|
|
print('SUMMARY')
|
|
|
|
print('=' * 20)
|
|
|
|
|
|
|
|
missingModules = defaultModules - set(availableModules)
|
|
|
|
if missingModules:
|
|
|
|
print('Default Setup: FAIL')
|
|
|
|
print('\nUnavailable Default Modules:')
|
|
|
|
for module in missingModules:
|
|
|
|
print(f'- {module}')
|
|
|
|
print('\nYou may need to install the missing dependencies for the modules above or reconfigure fenrir to not use them.')
|
|
|
|
else:
|
|
|
|
print('Default Setup: OK')
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
print('\nAvailable Modules:')
|
|
|
|
for module in availableModules:
|
|
|
|
print(f'- {module}')
|
2017-05-03 12:15:05 -04:00
|
|
|
|
2024-12-07 19:46:47 -05:00
|
|
|
if __name__ == '__main__':
|
|
|
|
check_all_dependencies()
|