loader.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #
  2. # Metrix++, Copyright 2009-2013, Metrix++ Project
  3. # Link: http://metrixplusplus.sourceforge.net
  4. #
  5. # This file is a part of Metrix++ Tool.
  6. #
  7. # Metrix++ is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, version 3 of the License.
  10. #
  11. # Metrix++ is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Metrix++. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import core.api
  20. import core.db.loader
  21. import os
  22. import fnmatch
  23. class Loader(object):
  24. def __init__(self):
  25. self.plugins = []
  26. self.parsers = []
  27. self.hash = {}
  28. self.exit_code = 0
  29. self.db = core.db.loader.Loader()
  30. def get_database_loader(self):
  31. return self.db
  32. def get_plugin(self, name):
  33. return self.hash[name]['instance']
  34. def iterate_plugins(self, is_reversed = False):
  35. if is_reversed == False:
  36. for item in self.plugins:
  37. yield item['instance']
  38. else:
  39. for item in reversed(self.plugins):
  40. yield item['instance']
  41. def register_parser(self, fnmatch_exp_list, parser):
  42. self.parsers.append((fnmatch_exp_list, parser))
  43. def get_parser(self, file_path):
  44. for parser in self.parsers:
  45. for fnmatch_exp in parser[0]:
  46. if fnmatch.fnmatch(file_path, fnmatch_exp):
  47. return parser[1]
  48. return None
  49. def load(self, directory, optparser):
  50. import sys
  51. sys.path.append(directory)
  52. def load_recursively(manager, directory):
  53. import ConfigParser
  54. import re
  55. pattern = re.compile(r'.*[.]ini$', flags=re.IGNORECASE)
  56. dirList = os.listdir(directory)
  57. for fname in dirList:
  58. fname = os.path.join(directory, fname)
  59. if os.path.isdir(fname):
  60. load_recursively(manager, fname)
  61. elif re.match(pattern, fname):
  62. config = ConfigParser.ConfigParser()
  63. config.read(fname)
  64. item = {'package': config.get('Plugin', 'package'),
  65. 'module': config.get('Plugin', 'module'),
  66. 'class': config.get('Plugin', 'class'),
  67. 'version': config.get('Plugin', 'version'),
  68. 'depends': config.get('Plugin', 'depends'),
  69. 'enabled': config.getboolean('Plugin', 'enabled')}
  70. if item['enabled']:
  71. manager.plugins.append(item)
  72. manager.hash[item['package'] + '.' + item['module']] = item
  73. load_recursively(self, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ext-priority'))
  74. load_recursively(self, directory)
  75. # TODO check dependencies
  76. for item in self.plugins:
  77. plugin = __import__(item['package'], globals(), locals(), [item['module']], -1)
  78. module_attr = plugin.__getattribute__(item['module'])
  79. class_attr = module_attr.__getattribute__(item['class'])
  80. item['instance'] = class_attr.__new__(class_attr)
  81. item['instance'].__init__()
  82. item['instance'].set_name(item['package'] + "." + item['module'])
  83. item['instance'].set_version(item['version'])
  84. item['instance'].set_plugin_loader(self)
  85. for item in self.iterate_plugins():
  86. if (isinstance(item, core.api.IConfigurable)):
  87. item.declare_configuration(optparser)
  88. (options, args) = optparser.parse_args()
  89. for item in self.iterate_plugins():
  90. if (isinstance(item, core.api.IConfigurable)):
  91. item.configure(options)
  92. for item in self.iterate_plugins():
  93. item.initialize()
  94. return args
  95. def unload(self):
  96. for item in self.iterate_plugins(is_reversed = True):
  97. item.terminate()
  98. def run(self, args):
  99. for item in self.iterate_plugins():
  100. if (isinstance(item, core.api.IRunable)):
  101. item.run(args)
  102. return self.exit_code
  103. def inc_exit_code(self):
  104. self.exit_code += 1
  105. def __repr__(self):
  106. result = object.__repr__(self) + ' with loaded:'
  107. for item in self.iterate_plugins():
  108. result += '\n\t' + item.__repr__()
  109. if isinstance(item, core.api.Parent):
  110. result += ' with subscribed:'
  111. for child in item.iterate_children():
  112. result += '\n\t\t' + child.__repr__()
  113. return result