140 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| from dataclasses import dataclass
 | |
| from typing import List, Optional
 | |
| 
 | |
| @dataclass
 | |
| class Dependency:
 | |
|     name: str
 | |
|     depType: str  # screen, 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
 | |
|     
 | |
|     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
 | |
| 
 | |
|     return isAvailable
 | |
| 
 | |
| # Define all dependencies
 | |
| dependencyList = [
 | |
|     # Core dependencies
 | |
|     Dependency('FenrirCore', 'core', 'core', 
 | |
|               pythonImports=['daemonize', 'enchant', 'pyperclip', 'setproctitle']),
 | |
|     
 | |
|     # Screen drivers
 | |
|     Dependency('DummyScreen', 'screen', 'dummyDriver'),
 | |
|     Dependency('VCSA', 'screen', 'vcsaDriver',
 | |
|               pythonImports=['dbus'],
 | |
|               devicePaths=['/dev/vcsa']),
 | |
|     Dependency('PTY', 'screen', 'ptyDriver',
 | |
|               pythonImports=['pyte', 'xdg']),
 | |
|               
 | |
|     # 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']),
 | |
|               
 | |
|     # Additional dependencies
 | |
|     Dependency('Pexpect', 'core', 'pexpectDriver',
 | |
|               pythonImports=['pexpect'])
 | |
| ]
 | |
| 
 | |
| defaultModules = {
 | |
|     'FenrirCore',
 | |
|     'VCSA',
 | |
|     'Evdev',
 | |
|     'GenericSpeech',
 | |
|     'GenericSound',
 | |
|     'Pexpect'
 | |
| }
 | |
| 
 | |
| def check_all_dependencies():
 | |
|     print('Checking dependencies...\n')
 | |
|     availableModules = []
 | |
|     
 | |
|     # Group dependencies by type for organized output
 | |
|     for depType in ['core', 'screen', '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('\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()
 |