__init__.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #!/usr/bin/python2 -O
  2. '''Qubes extensions
  3. Extensions provide additional features (like application menus) found only on
  4. some systems. They may be OS- or architecture-dependent or custom-developed for
  5. particular customer.
  6. .. autoclass:: Extension
  7. :members:
  8. :show-inheritance:
  9. .. autoclass:: ExtensionPlugin
  10. :members:
  11. :show-inheritance:
  12. '''
  13. import inspect
  14. import qubes.events
  15. import qubes.plugins
  16. class ExtensionPlugin(qubes.plugins.Plugin):
  17. '''Metaclass for :py:class:`Extension`'''
  18. def __init__(cls, name, bases, dict_):
  19. super(ExtensionPlugin, cls).__init__(name, bases, dict_)
  20. cls._instance = None
  21. def __call__(cls, *args, **kwargs):
  22. if cls._instance is None:
  23. cls._instance = super(ExtensionPlugin, cls).__call__(
  24. *args, **kwargs)
  25. return cls._instance
  26. class Extension(object):
  27. '''Base class for all extensions
  28. :param qubes.Qubes app: application object
  29. '''
  30. __metaclass__ = ExtensionPlugin
  31. def __init__(self, app):
  32. self.app = app
  33. for name in dir(self):
  34. attr = getattr(self, name)
  35. if not qubes.events.ishandler(attr):
  36. continue
  37. if attr.ha_vm is not None:
  38. attr.ha_vm.add_hook(attr.ha_event, attr)
  39. else:
  40. # global hook
  41. self.app.add_hook(attr.ha_event, attr)
  42. def handler(*events, **kwargs):
  43. '''Event handler decorator factory.
  44. To hook an event, decorate a method in your plugin class with this
  45. decorator. You may hook both per-vm-class and global events.
  46. .. note::
  47. This decorator is intended only for extensions! For regular use in the
  48. core, see py:func:`qubes.events.handler`.
  49. :param str event: event type
  50. :param type vm: VM to hook (leave as None to hook all VMs)
  51. :param bool system: when :py:obj:`True`, hook is system-wide (not attached \
  52. to any VM)
  53. '''
  54. def decorator(f):
  55. f.ha_events = events
  56. if kwargs.get('system', False):
  57. f.ha_vm = None
  58. elif 'vm' in kwargs:
  59. f.ha_vm = kwargs['vm']
  60. else:
  61. f.ha_vm = qubes.vm.BaseVM
  62. return f
  63. return decorator
  64. __all__ = qubes.plugins.load(__file__)