plugin_registry.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. # coding=utf-8
  2. """
  3. 插件注册服务
  4. 提供插件的注册、查询、更新等核心功能
  5. """
  6. from typing import List, Optional
  7. from django.db import models
  8. from django.db.models import QuerySet
  9. from django.utils import timezone
  10. from plugin.models.plugin import Plugin, PluginStatus, PluginType
  11. from plugin.models.plugin_version import PluginVersion, PluginVersionStatus
  12. from common.utils.logger import maxkb_logger
  13. class PluginRegistryService:
  14. """插件注册服务"""
  15. @staticmethod
  16. def get_plugins(workspace_id: str = 'default', plugin_type: str = None,
  17. status: str = None, is_installed: bool = None) -> QuerySet:
  18. """获取插件列表"""
  19. queryset = Plugin.objects.filter(workspace_id=workspace_id)
  20. if plugin_type:
  21. queryset = queryset.filter(plugin_type=plugin_type)
  22. if status:
  23. queryset = queryset.filter(status=status)
  24. if is_installed is not None:
  25. queryset = queryset.filter(is_installed=is_installed)
  26. return queryset.order_by('-create_time')
  27. @staticmethod
  28. def get_plugin(plugin_id: str) -> Optional[Plugin]:
  29. """获取单个插件"""
  30. try:
  31. return Plugin.objects.get(id=plugin_id)
  32. except Plugin.DoesNotExist:
  33. return None
  34. @staticmethod
  35. def get_plugin_by_code(code: str) -> Optional[Plugin]:
  36. """通过编码获取插件"""
  37. try:
  38. return Plugin.objects.get(code=code)
  39. except Plugin.DoesNotExist:
  40. return None
  41. @staticmethod
  42. def register_plugin(workspace_id: str, name: str, code: str,
  43. plugin_type: str = PluginType.CUSTOM,
  44. desc: str = '', version: str = '1.0.0',
  45. author: str = '', icon: str = '',
  46. schema: dict = None, config: dict = None,
  47. entry_point: str = '', user_id: str = None) -> Plugin:
  48. """注册插件"""
  49. # 检查编码是否已存在
  50. if Plugin.objects.filter(code=code).exists():
  51. raise ValueError(f'插件编码 {code} 已存在')
  52. plugin = Plugin.objects.create(
  53. workspace_id=workspace_id,
  54. name=name,
  55. code=code,
  56. plugin_type=plugin_type,
  57. desc=desc,
  58. version=version,
  59. author=author,
  60. icon=icon,
  61. schema=schema or {},
  62. config=config or {},
  63. entry_point=entry_point,
  64. user_id=user_id
  65. )
  66. # 创建初始版本
  67. PluginVersion.objects.create(
  68. plugin=plugin,
  69. version=version,
  70. status=PluginVersionStatus.ACTIVE,
  71. schema=schema or {},
  72. config=config or {}
  73. )
  74. return plugin
  75. @staticmethod
  76. def update_plugin(plugin_id: str, **kwargs) -> Optional[Plugin]:
  77. """更新插件"""
  78. plugin = PluginRegistryService.get_plugin(plugin_id)
  79. if not plugin:
  80. return None
  81. for key, value in kwargs.items():
  82. if hasattr(plugin, key):
  83. setattr(plugin, key, value)
  84. plugin.save()
  85. return plugin
  86. @staticmethod
  87. def install_plugin(plugin_id: str) -> Optional[Plugin]:
  88. """安装插件"""
  89. plugin = PluginRegistryService.get_plugin(plugin_id)
  90. if not plugin:
  91. return None
  92. plugin.is_installed = True
  93. plugin.install_time = timezone.now()
  94. plugin.status = PluginStatus.ACTIVE
  95. plugin.save()
  96. return plugin
  97. @staticmethod
  98. def uninstall_plugin(plugin_id: str) -> Optional[Plugin]:
  99. """卸载插件"""
  100. plugin = PluginRegistryService.get_plugin(plugin_id)
  101. if not plugin:
  102. return None
  103. plugin.is_installed = False
  104. plugin.status = PluginStatus.INACTIVE
  105. plugin.save()
  106. return plugin
  107. @staticmethod
  108. def enable_plugin(plugin_id: str) -> Optional[Plugin]:
  109. """启用插件"""
  110. plugin = PluginRegistryService.get_plugin(plugin_id)
  111. if not plugin:
  112. return None
  113. plugin.status = PluginStatus.ACTIVE
  114. plugin.save()
  115. return plugin
  116. @staticmethod
  117. def disable_plugin(plugin_id: str) -> Optional[Plugin]:
  118. """禁用插件"""
  119. plugin = PluginRegistryService.get_plugin(plugin_id)
  120. if not plugin:
  121. return None
  122. plugin.status = PluginStatus.INACTIVE
  123. plugin.save()
  124. return plugin
  125. @staticmethod
  126. def delete_plugin(plugin_id: str) -> bool:
  127. """删除插件"""
  128. plugin = PluginRegistryService.get_plugin(plugin_id)
  129. if not plugin:
  130. return False
  131. # 删除关联的版本
  132. PluginVersion.objects.filter(plugin=plugin).delete()
  133. plugin.delete()
  134. return True
  135. @staticmethod
  136. def get_plugin_versions(plugin_id: str) -> QuerySet:
  137. """获取插件版本列表"""
  138. return PluginVersion.objects.filter(plugin_id=plugin_id).order_by('-create_time')
  139. @staticmethod
  140. def create_plugin_version(plugin_id: str, version: str,
  141. changelog: str = '', schema: dict = None,
  142. config: dict = None, file_path: str = '',
  143. file_hash: str = '') -> Optional[PluginVersion]:
  144. """创建插件版本"""
  145. plugin = PluginRegistryService.get_plugin(plugin_id)
  146. if not plugin:
  147. return None
  148. plugin_version = PluginVersion.objects.create(
  149. plugin=plugin,
  150. version=version,
  151. changelog=changelog,
  152. schema=schema or plugin.schema,
  153. config=config or plugin.config,
  154. file_path=file_path,
  155. file_hash=file_hash
  156. )
  157. # 更新插件当前版本
  158. plugin.version = version
  159. plugin.save()
  160. return plugin_version
  161. @staticmethod
  162. def rollback_plugin_version(plugin_id: str, version_id: str) -> Optional[Plugin]:
  163. """回滚插件版本"""
  164. plugin = PluginRegistryService.get_plugin(plugin_id)
  165. if not plugin:
  166. return None
  167. try:
  168. target_version = PluginVersion.objects.get(id=version_id, plugin=plugin)
  169. except PluginVersion.DoesNotExist:
  170. return None
  171. # 更新插件配置为目标版本
  172. plugin.version = target_version.version
  173. plugin.schema = target_version.schema
  174. plugin.config = target_version.config
  175. plugin.save()
  176. # 标记回滚
  177. target_version.is_rollback = True
  178. target_version.save()
  179. return plugin
  180. @staticmethod
  181. def search_plugins(workspace_id: str, query: str) -> QuerySet:
  182. """搜索插件"""
  183. return Plugin.objects.filter(
  184. workspace_id=workspace_id
  185. ).filter(
  186. models.Q(name__icontains=query) | models.Q(code__icontains=query)
  187. ).order_by('-create_time')