diff --git a/check-dependencies.py b/check-dependencies.py index 060c4a85..66ba282c 100755 --- a/check-dependencies.py +++ b/check-dependencies.py @@ -1,232 +1,141 @@ #!/usr/bin/env python3 -import os, sys -# default installation -# core -# speech: speech-dispatcher -# sound: sox -# braille: brltty: -defaultInstallation = ['FenrirCore','vcsaDriver','dummyDriver (braille)','evdevDriver','genericDriver (speech)', 'genericDriver (sound)'] -currentInstallation = [] +import os +import sys +from dataclasses import dataclass +from typing import List, Optional -print('checking dependencys...') -# CORE -print('') -print('fenrir core:') -available = True -try: - from daemonize import Daemonize - print('python3-daemonize: OK') -except: - print('python3-daemonize: FAIL') - available = available and False +@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 -try: - import enchant - print('pyenchant: OK') -except: - print('pyenchant: FAIL') - available = available and False - -if available: - currentInstallation.append('FenrirCore') - -# SCREEN -print('--------------------') -print('screen driver') -# dummy and debug -print('dummyDriver (screen): OK') -currentInstallation.append('dummyDriver (screen)') + 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 -# VCSA (screen driver) -print('vcsaDriver') -available = True -try: - import dbus - print('python3-dbus: OK') -except: - print('python3-dbus: FAIL') - available = available and False -if os.path.exists('/dev/vcsa'): - print('VCSA Device: OK') -else: - print('VCSA Device: FAIL') - available = available and False -if available: - currentInstallation.append('vcsaDriver') -print('') -# pty emulation (screen driver) -print('ptyDriver') -available = True -try: - import pyte - print('pyte: OK') -except: - print('pyte: FAIL') - available = available and False -if available: - currentInstallation.append('ptyDriver (screen)') + 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 + + return isAvailable + +# Define all dependencies +dependencyList = [ + # Core dependencies + Dependency('FenrirCore', 'core', 'core', + pythonImports=['daemonize', 'enchant']), -# BRAILLE -print('--------------------') -print('braille driver') -# dummy and debug -print('dummyDriver (braille): OK') -currentInstallation.append('dummyDriver (braille)') -print('debugDriver (braille): OK') -currentInstallation.append('debugDriver (braille)') -# brltty (braille driver) -print('brlapiDriver') -available = True -try: - import brlapi - print('python3-brlapi: OK') -except: - print('python3-brlapi: FAIL') - available = available and False + # 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 = [] -if available: - currentInstallation.append('brlapiDriver') -# INPUT -print('--------------------') -print('input driver') -# dummy and debug -print('dummyDriver (input): OK') -currentInstallation.append('dummyDriver (input)') -print('debugDriver (input): OK') -currentInstallation.append('debugDriver (input)') -# evdev (input driver) -print('evdevDriver') -available = True -try: - import evdev - from evdev import InputDevice, UInput - print('python3-evdev: OK') -except: - print('python3-evdev: FAIL') - available = available and False -try: - import pyudev - print('python3-pyudev: OK') -except: - print('python3-pyudev: FAIL') - available = available and False -if available: - currentInstallation.append('evdevDriver') -# pty emulation (input driver) -print('') -print('ptyDriver') -available = True -try: - import pyte - print('pyte: OK') -except: - print('pyte: FAIL') - available = available and False -if available: - currentInstallation.append('ptyDriver (Input)') -# SOUND -print('--------------------') -print('sound driver') -# dummy and debug -print('dummyDriver (sound): OK') -currentInstallation.append('dummyDriver (sound)') -print('debugDriver (sound): OK') -currentInstallation.append('debugDriver (sound)') -print('genericDriver (uses sox by default)') -available = True -if os.path.exists('/usr/bin/play') and os.path.exists('/usr/bin/sox'): - print('sox: OK') -else: - print('sox: FAIL') - available = available and False -if available: - currentInstallation.append('genericDriver (sound)') -print('') -# gstreamer (sound driver) -print('gstreamerDriver') -available = True -try: - import gi - print('gi: OK') -except: - print('gi: FAIL') - available = available and False -try: - from gi.repository import GLib - print('gi GLib: OK') -except: - print('gi GLib: FAIL') - available = available and False -try: - gi.require_version('Gst', '1.0') - from gi.repository import Gst - print('gi Gst: OK') -except: - print('gi Gst: FAIL') - available = available and False -if available: - currentInstallation.append('gstreamerDriver') + # 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('') -# SPEECH -print('--------------------') -print('speech driver') -# dummy and debug -print('dummyDriver (speech): OK') -currentInstallation.append('dummyDriver (speech)') -print('debugDriver (speech): OK') -currentInstallation.append('debugDriver (speech)') -# speechd (speech driver) -print('speechdDriver') -available = True -try: - import speechd - print('python3-speechd: OK') -except: - print('python3-speechd: FAIL') - available = available and False -if available: - currentInstallation.append('speechdDriver') -print('') -# espeak (speech driver) -print('espeakDriver') -available = True -try: - from espeak import espeak - print('python3-espeak: OK') -except: - print('python3-espeak: FAIL') - available = available and False -if available: - currentInstallation.append('espeakDriver') -print('genericDriver (uses espeak-ng by default)') -available = True -if os.path.exists('/usr/bin/espeak-ng') or os.path.exists('/bin/espeak-ng'): - print('espeak-ng: OK') -else: - print('espeak-ng: FAIL') - available = available and False -if available: - currentInstallation.append('genericDriver (speech)') + print_summary(availableModules) -# SUMMERY -print('====================') -available = True -missing = [] -for element in defaultInstallation: - if not element in currentInstallation: - available = False - missing.append(element) -if available: - print('Default Setup: OK') -else: - print('Default Setup: FAIL') - print('Unavailable Default Modules:') - for e in missing: - print(e) - print('you may need to install the missing dependencys for the modules above or reconfigure fenrir to not use them') -print('') -print('Available Modules:') -for element in currentInstallation: - print(element) +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') + print('\nAvailable Modules:') + for module in availableModules: + print(f'- {module}') + +if __name__ == '__main__': + check_all_dependencies()