Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

90 linhas
3.4KB

  1. # encoding:utf-8
  2. import importlib
  3. import json
  4. import os
  5. from common.singleton import singleton
  6. from .event import *
  7. from .plugin import *
  8. from common.log import logger
  9. @singleton
  10. class PluginManager:
  11. def __init__(self):
  12. self.plugins = {}
  13. self.listening_plugins = {}
  14. self.instances = {}
  15. def register(self, name: str, desc: str, version: str, author: str):
  16. def wrapper(plugincls):
  17. self.plugins[name] = plugincls
  18. plugincls.name = name
  19. plugincls.desc = desc
  20. plugincls.version = version
  21. plugincls.author = author
  22. plugincls.enabled = True
  23. logger.info("Plugin %s_v%s registered" % (name, version))
  24. return plugincls
  25. return wrapper
  26. def save_config(self, pconf):
  27. with open("plugins/plugins.json", "w", encoding="utf-8") as f:
  28. json.dump(pconf, f, indent=4, ensure_ascii=False)
  29. def load_config(self):
  30. logger.info("Loading plugins config...")
  31. plugins_dir = "plugins"
  32. for plugin_name in os.listdir(plugins_dir):
  33. plugin_path = os.path.join(plugins_dir, plugin_name)
  34. if os.path.isdir(plugin_path):
  35. # 判断插件是否包含同名.py文件
  36. main_module_path = os.path.join(plugin_path, plugin_name+".py")
  37. if os.path.isfile(main_module_path):
  38. # 导入插件
  39. import_path = "{}.{}.{}".format(plugins_dir, plugin_name, plugin_name)
  40. main_module = importlib.import_module(import_path)
  41. modified = False
  42. if os.path.exists("plugins/plugins.json"):
  43. with open("plugins/plugins.json", "r", encoding="utf-8") as f:
  44. pconf = json.load(f)
  45. else:
  46. modified = True
  47. pconf = {"plugins": []}
  48. for name, plugincls in self.plugins.items():
  49. if name not in [plugin["name"] for plugin in pconf["plugins"]]:
  50. modified = True
  51. logger.info("Plugin %s not found in pconfig, adding to pconfig..." % name)
  52. pconf["plugins"].append({"name": name, "enabled": True})
  53. if modified:
  54. self.save_config(pconf)
  55. return pconf
  56. def load_plugins(self):
  57. pconf = self.load_config()
  58. logger.debug("plugins.json config={}".format(pconf))
  59. for plugin in pconf["plugins"]:
  60. name = plugin["name"]
  61. enabled = plugin["enabled"]
  62. self.plugins[name].enabled = enabled
  63. for name, plugincls in self.plugins.items():
  64. if plugincls.enabled:
  65. if name not in self.instances:
  66. instance = plugincls()
  67. self.instances[name] = instance
  68. for event in instance.handlers:
  69. if event not in self.listening_plugins:
  70. self.listening_plugins[event] = []
  71. self.listening_plugins[event].append(name)
  72. def emit_event(self, e_context: EventContext, *args, **kwargs):
  73. if e_context.event in self.listening_plugins:
  74. for name in self.listening_plugins[e_context.event]:
  75. if e_context.action == EventAction.CONTINUE:
  76. logger.debug("Plugin %s triggered by event %s" % (name,e_context.event))
  77. instance = self.instances[name]
  78. instance.handlers[e_context.event](e_context, *args, **kwargs)
  79. return e_context