You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.6 KiB

4 years ago
  1. # Copyright 2010 Google Inc.
  2. #
  3. # Permission is hereby granted, free of charge, to any person obtaining a
  4. # copy of this software and associated documentation files (the
  5. # "Software"), to deal in the Software without restriction, including
  6. # without limitation the rights to use, copy, modify, merge, publish, dis-
  7. # tribute, sublicense, and/or sell copies of the Software, and to permit
  8. # persons to whom the Software is furnished to do so, subject to the fol-
  9. # lowing conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included
  12. # in all copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  16. # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  17. # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  18. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. # IN THE SOFTWARE.
  21. """
  22. Implements plugin related api.
  23. To define a new plugin just subclass Plugin, like this.
  24. class AuthPlugin(Plugin):
  25. pass
  26. Then start creating subclasses of your new plugin.
  27. class MyFancyAuth(AuthPlugin):
  28. capability = ['sign', 'vmac']
  29. The actual interface is duck typed.
  30. """
  31. import glob
  32. import imp
  33. import os.path
  34. class Plugin(object):
  35. """Base class for all plugins."""
  36. capability = []
  37. @classmethod
  38. def is_capable(cls, requested_capability):
  39. """Returns true if the requested capability is supported by this plugin
  40. """
  41. for c in requested_capability:
  42. if c not in cls.capability:
  43. return False
  44. return True
  45. def get_plugin(cls, requested_capability=None):
  46. if not requested_capability:
  47. requested_capability = []
  48. result = []
  49. for handler in cls.__subclasses__():
  50. if handler.is_capable(requested_capability):
  51. result.append(handler)
  52. return result
  53. def _import_module(filename):
  54. (path, name) = os.path.split(filename)
  55. (name, ext) = os.path.splitext(name)
  56. (file, filename, data) = imp.find_module(name, [path])
  57. try:
  58. return imp.load_module(name, file, filename, data)
  59. finally:
  60. if file:
  61. file.close()
  62. _plugin_loaded = False
  63. def load_plugins(config):
  64. global _plugin_loaded
  65. if _plugin_loaded:
  66. return
  67. _plugin_loaded = True
  68. if not config.has_option('Plugin', 'plugin_directory'):
  69. return
  70. directory = config.get('Plugin', 'plugin_directory')
  71. for file in glob.glob(os.path.join(directory, '*.py')):
  72. _import_module(file)