Refactor the dependency checker.
This commit is contained in:
		| @@ -1,232 +1,141 @@ | |||||||
| #!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||||
| import os, sys |  | ||||||
|  |  | ||||||
| # default installation | import os | ||||||
| # core | import sys | ||||||
| # speech: speech-dispatcher | from dataclasses import dataclass | ||||||
| # sound: sox | from typing import List, Optional | ||||||
| # braille: brltty: |  | ||||||
| defaultInstallation = ['FenrirCore','vcsaDriver','dummyDriver (braille)','evdevDriver','genericDriver (speech)', 'genericDriver (sound)'] |  | ||||||
| currentInstallation = [] |  | ||||||
|  |  | ||||||
| print('checking dependencys...') | @dataclass | ||||||
| # CORE | class Dependency: | ||||||
| print('') |     name: str | ||||||
| print('fenrir core:') |     depType: str  # screen, braille, input, sound, speech, core | ||||||
| available = True |     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 | ||||||
|  |      | ||||||
|  |     if dep.pythonImports: | ||||||
|  |         for package in dep.pythonImports: | ||||||
|             try: |             try: | ||||||
|     from daemonize import Daemonize |                 moduleName = package.split('.')[0] | ||||||
|     print('python3-daemonize: OK') |                 __import__(moduleName) | ||||||
| except: |                 print(f'{package}: OK') | ||||||
|     print('python3-daemonize: FAIL') |             except ImportError: | ||||||
|     available = available and False |                 print(f'{package}: FAIL') | ||||||
|  |                 isAvailable = False | ||||||
|  |  | ||||||
| try: |     if dep.checkCommands: | ||||||
|     import enchant |         for cmd in dep.checkCommands: | ||||||
|     print('pyenchant: OK') |             if os.path.exists(f'/usr/bin/{cmd}') or os.path.exists(f'/bin/{cmd}'): | ||||||
| except: |                 print(f'{cmd}: OK') | ||||||
|     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)') |  | ||||||
|  |  | ||||||
| # 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: |             else: | ||||||
|     print('VCSA Device: FAIL') |                 print(f'{cmd}: FAIL') | ||||||
|     available = available and False     |                 isAvailable = 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)')  |  | ||||||
|  |  | ||||||
| # BRAILLE |     if dep.devicePaths: | ||||||
| print('--------------------') |         for path in dep.devicePaths: | ||||||
| print('braille driver') |             if os.path.exists(path): | ||||||
| # dummy and debug |                 print(f'{path}: OK') | ||||||
| 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 |  | ||||||
|      |  | ||||||
| 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: |             else: | ||||||
|     print('sox: FAIL') |                 print(f'{path}: FAIL') | ||||||
|     available = available and False |                 isAvailable = 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') |  | ||||||
|  |  | ||||||
| # SPEECH |     return isAvailable | ||||||
| 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)') |  | ||||||
|  |  | ||||||
| # SUMMERY | # Define all dependencies | ||||||
| print('====================') | dependencyList = [ | ||||||
| available = True |     # Core dependencies | ||||||
| missing = [] |     Dependency('FenrirCore', 'core', 'core',  | ||||||
| for element in  defaultInstallation: |               pythonImports=['daemonize', 'enchant']), | ||||||
|     if not element in currentInstallation: |      | ||||||
|         available = False |     # Screen drivers | ||||||
|         missing.append(element) |     Dependency('DummyScreen', 'screen', 'dummyDriver'), | ||||||
| if available: |     Dependency('VCSA', 'screen', 'vcsaDriver', | ||||||
|     print('Default Setup: OK') |               pythonImports=['dbus'], | ||||||
| else: |               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 = [] | ||||||
|  |      | ||||||
|  |     # 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('') | ||||||
|  |  | ||||||
|  |     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('Default Setup: FAIL') | ||||||
|     print('Unavailable Default Modules:') |         print('\nUnavailable Default Modules:') | ||||||
|     for e in missing: |         for module in missingModules: | ||||||
|         print(e) |             print(f'- {module}') | ||||||
|     print('you may need to install the missing dependencys for the modules above or reconfigure fenrir to not use them') |         print('\nYou may need to install the missing dependencies for the modules above or reconfigure fenrir to not use them.') | ||||||
| print('') |     else: | ||||||
| print('Available Modules:')    |         print('Default Setup: OK') | ||||||
| for element in  currentInstallation: |  | ||||||
|     print(element) |  | ||||||
|  |  | ||||||
|  |     print('\nAvailable Modules:') | ||||||
|  |     for module in availableModules: | ||||||
|  |         print(f'- {module}') | ||||||
|  |  | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     check_all_dependencies() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user