home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''Define some common abstract basic handler types.
-
- These provide the common functionality for concrete handlers of different
- classes, like handlers for a kernel module, a driver package, a handler group,
- etc.
-
- Custom concrete handlers need to fulfill the following requirements:
- - __init__(self, backend) must take exactly one argument (a reference to a
- Backend instance). All othe properties must be detected by the
- constructor or changed with methods. These classes are instantiated
- automatically, which is not possible with constructors which need more
- arguments.
-
- - All handler types in this module have some abstract functions which need to
- be implemented (see the documentation of the particular classes).
- '''
- import subprocess
- import os.path as os
- import sys
- import logging
- from gettext import gettext as _
- import detection
- from oslib import OSLib
-
- class Handler:
- '''Abstract basic handler.'''
-
- def __init__(self, backend, name, description = None, rationale = None):
- '''Create a handler with given (human readable) name.
-
- Every handler should have a human readable name. A custom rationale and
- a multi-line description can be given, too. Every handler gets a
- reference to the currently used Backend so that it can request
- installation of packages and other system changes.
-
- By default, available handlers are announced in
- AbstractUI.check(). If you want to have a handler which is
- available, but not announced that way, set self.annonuce to False.
- '''
- self._hwids = []
- self._changed = False
- self.backend = backend
- self._name = name
- self._description = description
- self._rationale = rationale
- self.license = None
- self.announce = True
- if not hasattr(self, '_free'):
- self._free = None
-
- if hasattr(self, 'package') and self.package:
- self._package_defaults()
- else:
- self.package = None
- self.driver_vendor = None
- self.version = None
- self.repository = None
- self._recommended = False
-
-
- def _package_defaults(self):
- '''Set fallback name/description/freeness from package.'''
- if self.package:
- if not (self._name) or self._description is None:
- (distro_name, distro_desc) = OSLib.inst.package_description(self.package)
- if not self._name:
- self._name = distro_name
-
- if self._description is None:
- self._description = distro_desc
-
-
- if self.package and self._free is None:
-
- try:
- self._free = OSLib.inst.is_package_free(self.package)
- except (KeyError, ValueError):
- pass
- except:
- None<EXCEPTION MATCH>(KeyError, ValueError)
-
-
- None<EXCEPTION MATCH>(KeyError, ValueError)
-
-
- def name(self):
- '''Return one-line name of the handler (for human consumption).'''
- self._package_defaults()
- return self._name
-
-
- def description(self):
- '''Return multi-line description of the handler.'''
- self._package_defaults()
- return self._description
-
-
- def id(self):
- '''Return an unique identifier of the handler.
-
- This is used for specifying a handler with --enable/--disable on the
- command line, and is mentioned in the --list output.
- '''
- if self.package:
- i = 'pkg:' + self.package
- else:
- i = '%s:%s' % (str(self.__class__).split('.')[-1], self.name())
- if self.driver_vendor:
- i += ':' + self.driver_vendor.replace(' ', '_')
-
- return i
-
-
- def rationale(self):
- '''Return rationale as to why this driver might be enabled.
-
- Might return None if no rationale is available.
- '''
- return self._rationale
-
-
- def changed(self):
- '''Return if the module has been enabled/disabled at least once.'''
- return self._changed
-
-
- def can_change(self):
- '''Check whether we can actually modify settings of this handler.
-
- This might not be the case if e. g. the user manually modified a
- configuration file. Return an explanatory text if settings can not be
- changed, or None if changing is ok.
- '''
- pass
-
-
- def __str__(self):
- if not self.free() or 'free':
- pass
- if not self.enabled() or 'enabled':
- pass
- return '%s([%s, %s, %s] %s)' % (self.id(), str(self.__class__).split('.')[-1], 'nonfree', 'disabled', self.name())
-
-
- def free(self):
- '''Return if the handler represents a free software driver.'''
- if self._free is not None:
- return self._free
- raise NotImplementedError, 'subclasses need to implement this'
-
-
- def enabled(self):
- """Return if the handler is enabled.
-
- 'Enabled' means that the user agreed to use this driver if it is
- applicable.
- """
- if self.package:
- return OSLib.inst.package_installed(self.package)
- return True
-
-
- def used(self):
- '''Return if the handler is currently in use.'''
- raise NotImplementedError, 'subclasses need to implement this'
-
-
- def recommended(self):
- '''Return if the version of a certain driver is recommended over others
- when more than one driver flavour supports the same device.
-
- This method should return True only for the recommended version while
- it will return False for any other compatible version. If only one
- version of a driver is provided, then it should return False.
- '''
- return self._recommended
-
-
- def available(self):
- '''Return if the conditions to use this handler on the system are met.
-
- This usually means that the hardware for this driver is available, but
- there might be hardware independent drivers, too.
-
- If this returns True or False, the answer is definitive and no further
- detection, db querying, etc is performed. If this returns None, then
- the handler cannot decide availability on its own; in that case it is
- merely available in the handler pool, and an external driver database
- (detection.DriverDB) is queried.
- '''
- if self.package:
- if not (self.repository) or OSLib.inst.repository_enabled(self.repository):
-
- try:
- OSLib.inst.package_description(self.package)
- return None
- except ValueError:
- return False
-
-
- None<EXCEPTION MATCH>ValueError
- return None
- self.package
- raise NotImplementedError, 'subclasses need to implement this'
-
-
- def enable(self):
- '''Allow the OS to use it if the hardware is available.
-
- If possible, the handler should be loaded, too. Return True if
- immediately successful, or False if the system needs to be rebooted for
- the changes to become effective.
- '''
- if self.repository:
- OSLib.inst.add_repository(self.repository)
-
- if self.package:
- self.backend.install_package(self.package)
- if not OSLib.inst.package_installed(self.package):
- return True
-
- self._changed = True
- return True
-
-
- def disable(self):
- '''Prevent the OS from using it even if the hardware is available.
-
- If possible, the handler should be unloaded, too. Return True if
- immediately successful, or False if the system needs to be rebooted for
- the changes to become effective.
-
- '''
- if self.repository:
- OSLib.inst.remove_repository(self.repository)
-
- if self.package:
- self.backend.remove_package(self.package)
- if OSLib.inst.package_installed(self.package):
- return None
-
- self._changed = True
- return True
-
-
-
- class HandlerGroup(Handler):
- '''Perform operations on a group of handlers.
-
- A group should be provided if it makes little sense to present several very
- similar handlers in the UI. For example, the three VMWare or the dozens of
- commercial OSS drivers should be grouped.
- '''
-
- def __init__(self, backend, name, id, description = None, rationale = None):
- Handler.__init__(self, backend, name, description, rationale)
- self._id = id
- self.subhandlers = []
-
-
- def id(self):
- '''Return an unique identifier of the handler.'''
- return self._id
-
-
- def add(self, handler):
- '''Add a subhandler.'''
- self.subhandlers.append(handler)
-
-
- def free(self):
- '''Return if all subhandlers represent free software drivers.'''
- for h in self.subhandlers:
- if not h.free():
- return False
-
- return True
-
-
- def enabled(self):
- '''Return if all subhandlers are enabled.'''
- for h in self.subhandlers:
- if not h.enabled():
- return False
-
- return True
-
-
- def used(self):
- '''Return if any subhandler is used.'''
- for h in self.subhandlers:
- if h.used():
- return True
-
- return False
-
-
- def available(self):
- '''Return if the hardware for any subhandler is available.
-
- If all subhandlers return False, this returns False. If any subhandler
- returns True, this returns True. Otherwise this returns None.
- '''
- all_false = True
- for h in self.subhandlers:
- a = h.available()
- if a:
- return True
- if a == None:
- all_false = False
- continue
- a
- if not a == False:
- raise AssertionError
-
- if all_false:
- return False
- return None
-
-
- def enable(self):
- '''Enable all subhandlers.'''
- result = True
- for h in self.subhandlers:
- if h.enable():
- pass
- result = result
-
- return result
-
-
- def disable(self):
- '''Disable all subhandlers.'''
- result = True
- for h in self.subhandlers:
- if h.disable():
- pass
- result = result
-
- return result
-
-
- def changed(self):
- '''Return if at least one subhandler has been enabled/disabled at
- least once.'''
- for h in self.subhandlers:
- if h.changed():
- return True
-
- return False
-
-
- def can_change(self):
- '''Check whether we can actually modify settings of this handler.'''
- if not self.subhandlers:
- raise AssertionError
- for h in self.subhandlers:
- c = h.can_change()
- if c:
- return c
-
-
-
-
- class KernelModuleHandler(Handler):
- '''Handler for a kernel module.
-
- This class can be used as a standard handler for kernel modules (and in
- fact detection.get_handlers() uses this as a default handler if there is no
- custom one). Subclasses have to implement __init__() at least.
- '''
- _loaded_modules = None
-
- def __init__(self, backend, kernel_module, name = None, description = None, rationale = None):
- """Create handler for a kernel module.
-
- If not given explicitly, the name is read from modinfo's 'description'
- field.
- """
- self.module = kernel_module
- self._modinfo = detection.get_modinfo(self.module)
- if not name:
- if not self._modinfo:
- raise AssertionError, 'kernel module %s exists' % self.module
- name = '\n'.join(self._modinfo.get('description', [
- self.module]))
-
- Handler.__init__(self, backend, name, description, rationale)
- self._do_rebind = True
-
-
- def id(self):
- '''Return an unique identifier of the handler.'''
- i = 'kmod:' + self.module
- if self.driver_vendor:
- i += ':' + self.driver_vendor.replace(' ', '_')
-
- return i
-
-
- def free(self):
- '''Return if the handler represents a free software driver.'''
- if self._free is not None:
- return self._free
- if not self._modinfo:
- raise AssertionError, 'kernel module %s exists' % self.module
- for l in self._modinfo.get('license', [
- 'unknown']):
- if l in ('GPL', 'GPL v2', 'GPL and additional rights', 'Dual BSD/GPL', 'Dual MIT/GPL', 'Dual MPL/GPL', 'BSD'):
- return True
-
- return False
-
-
- def enabled(self):
- """Return if the handler is enabled.
-
- 'Enabled' means that the user agreed to use this driver if it is
- applicable.
- """
- if not OSLib.inst.module_blacklisted(self.module) and self._modinfo is not None:
- pass
- return Handler.enabled(self)
-
-
- def used(self):
- '''Return if the handler is currently in use.'''
- if not self.module_loaded(self.module) and self.package is None:
- pass
- return OSLib.inst.package_installed(self.package)
-
-
- def available(self):
- '''Return if the conditions to use this handler on the system are met
- (e. g. hardware for this driver is available).
-
- This defaults to None, because we usually want to delegate this to the
- driver db. Subclasses are welcome to override this, of course.
- '''
-
- try:
- if Handler.available(self) == False:
- return False
- except NotImplementedError:
- pass
-
-
-
- def enable(self):
- '''Allow the OS to use it if the hardware is available.
-
- This removes the module from the modprobe blacklist.
- '''
- Handler.enable(self)
- OSLib.inst.blacklist_module(self.module, False)
- subprocess.call([
- OSLib.inst.modprobe_path,
- self.module])
- self._modinfo = detection.get_modinfo(self.module)
- self.read_loaded_modules()
- if self._do_rebind:
- return self.rebind(self.module)
-
-
- def disable(self):
- '''Prevent the OS from using it even if the hardware is available.
-
- This adds the module to the modprobe blacklist.
- '''
- Handler.disable(self)
- OSLib.inst.blacklist_module(self.module, True)
- self._modinfo = detection.get_modinfo(self.module)
- return False
-
-
- def rebind(klass, module):
- '''Re-bind all devices using the module.
-
- This is necessary for example to reload firmware. Return True on
- success, or False if rebind failed for any device.
- '''
- drivers_dir = os.path.join(OSLib.inst.sys_dir, 'module', module, 'drivers')
- if not os.path.isdir(drivers_dir):
- logging.warning('%s does not exist, cannot rebind %s driver' % (drivers_dir, module))
- return None
- succeeded = True
- for driver in os.listdir(drivers_dir):
- driver_path = os.path.join(drivers_dir, driver)
- for device in os.listdir(driver_path):
- if device == 'module' or not os.path.isdir(os.path.join(driver_path, device)):
- continue
-
-
- try:
- logging.debug('unbind/rebind on driver %s: device %s', driver_path, device)
- f = open(os.path.join(driver_path, 'unbind'), 'w')
- f.write(device)
- f.close()
- f = open(os.path.join(driver_path, 'bind'), 'w')
- f.write(device)
- f.close()
- continue
- except IOError:
- logging.warning('unbind/rebind for device %s on driver %s failed', device, driver_path, exc_info = True)
- succeeded = False
- continue
-
-
-
-
- return succeeded
-
- rebind = classmethod(rebind)
-
- def read_loaded_modules(klass):
- '''Get the list of loaded kernel modules.'''
- klass._loaded_modules = []
- proc_modules = open(OSLib.inst.proc_modules)
-
- try:
- for line in proc_modules:
-
- try:
- line = line[:line.index(' ')]
- except ValueError:
- pass
-
- klass._loaded_modules.append(line.strip())
- finally:
- proc_modules.close()
-
-
- read_loaded_modules = classmethod(read_loaded_modules)
-
- def module_loaded(klass, module):
- '''Return if a module is currently loaded.'''
- if klass._loaded_modules == None:
- klass.read_loaded_modules()
-
- return module in klass._loaded_modules
-
- module_loaded = classmethod(module_loaded)
-
-
- class FirmwareHandler(KernelModuleHandler):
- """Handler for an already available kernel module needing firmware.
-
- Subclasses need to extend enable() and implement disable() to do something
- with the downloaded file (unpack it, put into the right directory, etc.).
- This class' enable() function will deal with downloading it and the UI
- progress reporting of the download.
- """
-
- def __init__(self, backend, kernel_module, testfile, name = None, description = None, rationale = None, url = None, sha1sum = None, free = False):
- """Create handler for a piece of firmware for a kernel module.
-
- The required argument 'url' specifies where the firmware can be
- downloaded from. The optional 'sha1sum' argument provides a checksum of
- the downloaded file. The file will not be installed if it does not
- match.
-
- enabled() will return True iff the path in testfile exists.
-
- By default this handler assumes that the firmware is not free (since
- otherwise the distribution could ship it together with the driver). You
- can set 'free' to True for free firmware or to None to use the kernel
- module's freeness.
-
- If not given explicitly, the name is read from modinfo's 'description'
- field.
- """
- self.url = url
- self.sha1sum = sha1sum
- self._free = free
- self.testfile = testfile
- KernelModuleHandler.__init__(self, backend, kernel_module, name, description, rationale)
-
-
- def id(self):
- '''Return an unique identifier of the handler.'''
- i = 'firmware:' + self.module
- if self.driver_vendor:
- i += ':' + self.driver_vendor.replace(' ', '_')
-
- return i
-
-
- def free(self):
- '''Return if the handler represents a free software driver.'''
- if self._free is None:
- return KernelModuleHandler.free(self)
- return self._free
-
-
- def enabled(self):
- """Return if the handler is enabled.
-
- 'Enabled' means that the user agreed to use this driver if it is
- applicable.
- """
- if os.path.exists(self.testfile):
- pass
- return KernelModuleHandler.enabled(self)
-
-
- def used(self):
- '''Return if the handler is currently in use.'''
- if self.enabled():
- pass
- return KernelModuleHandler.used(self)
-
-
- def enable(self):
- '''Allow the OS to use it if the hardware is available.
-
- This downloads the url and puts it into self.firmware_file. Subclasses
- need to provide an actual implementation what to do with the file.
- '''
- raise NotImplementedError, 'FirmwareHandler is currently not implemented'
- KernelModuleHandler.enable(self)
-
-
- def disable(self):
- '''Prevent the OS from using it even if the hardware is available.
-
- Implementation in subclasses need to remove the firmware files and call
- KernelModuleHandler.disable().
- '''
- raise NotImplementedError, 'subclasses need to implement this'
-
-
-
- class PrinterDriverHandler(Handler):
- '''Handler for a printer driver.'''
-
- def id(self):
- '''Return an unique identifier of the handler.
-
- This is used for specifying a handler with --enable/--disable on the
- command line, and is mentioned in the --list output.
- '''
- if self.package:
- i = 'printer:' + self.package
- else:
- i = 'printer:%s' % self.name()
- if self.version:
- i += ':' + str(self.version)
- elif self.driver_vendor:
- i += ':' + self.driver_vendor.replace(' ', '_')
-
- return i
-
-
- def used(self):
- '''Return if the handler is currently in use.'''
- return self.enabled()
-
-
-