| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #!/usr/bin/env python
- # -- coding: utf-8 --
- # @Time : 2024/09/18
- import os.path
- from importlib import import_module
- from pathlib import Path
- import sys
- from types import ModuleType
- from flask import Blueprint, Flask
- from ..base.signal import module_initailize
- from .config import CONFIG_CACHE
- def path_to_module(file_path:str, root_path:str) -> str:
- """
- 文件路径转为模块名称
-
- Args:
- file_path (str): 文件路径
- root_path (str): 根路径
-
- Returns:
- str: 模块名称
- """
- file_path = Path(file_path)
- root_path = Path(root_path).resolve()
- file_relative = file_path.relative_to(root_path)
- module_path = str(file_relative.with_suffix('')).replace(os.sep, '.').replace('\\', '.')
- return module_path
- class RuoYiModuleRegistry(object):
-
- module_prefix = "ruoyi_"
- controller_name = "controller"
- exclude_modules = ["ruoyi_ui"]
-
- def __init__(self, app:Flask=None, proot:str=None):
- self.app = app
- self.proot = proot
- url_prefix = CONFIG_CACHE["ruoyi.api.version"]
- if not url_prefix.startswith("/"):
- raise ValueError("url_prefix must start with /")
- self.api = Blueprint(
- "api",
- __name__,
- url_prefix=url_prefix
- )
-
- def register_modules(self):
- '''
- 注册所有模块
- '''
- self.import_modules()
- self.register_controllers()
-
- def import_modules(self):
- '''
- 导入所有模块
- '''
- for modname in os.listdir(self.proot):
- if not modname.startswith(self.module_prefix):
- continue
- if modname in self.exclude_modules:
- continue
- if not os.path.exists(
- os.path.join(self.proot,modname,"__init__.py")
- ):
- self.app.logger.warning(f"模块路径不存在__init__.py文件: {modname}")
- continue
- self.import_module(modname)
-
- def import_module(self, modname:str):
- '''
- 导入模块
-
- Args:
- modname (str): 模块名称
- '''
- modpath = os.path.join(self.proot,modname)
- mod = import_module(path_to_module(modpath,self.proot))
- module_initailize.send(mod,registry=self)
-
- def is_registered_module(self, modname:str) -> bool:
- '''
- 检查模块是否已经注册
-
- Args:
- modname (str): 模块名称
- Returns:
- bool: 是否已经注册
- '''
- flag = modname in sys.modules
- return flag
-
- def unregister_module(self, mod:ModuleType):
- '''
- 注销模块
-
- Args:
- mod (ModuleType): 模块对象
- '''
- if mod in self.default_modules:
- return
- # todo
- def register_controllers(self):
- '''
- 注册所有控制层路由
- '''
- for modname in os.listdir(self.proot):
-
- if not modname.startswith(self.module_prefix):
- continue
- if modname in self.exclude_modules:
- continue
- if not self.is_registered_module(modname):
- continue
- self.register_controller(modname)
- self.app.register_blueprint(self.api)
-
- def register_controller(self, modname:str):
- '''
- 注册控制层路由
-
- Args:
- mod (str): 模块名称
- '''
- modpath = os.path.join(self.proot,modname)
- mod_con_path = os.path.join(modpath,self.controller_name)
- if not os.path.exists(mod_con_path):
- return
- try:
- self._register_rules(mod_con_path)
- except Exception as e:
- raise Exception(
- "在模块中的路由,注册失败: {},原因: {}".format(modname,str(e))
- )
-
- def unregister_controller(self, modname:str):
- '''
- 注销控制层路由
-
- Args:
- modname (str): 模块名称
- '''
- # todo
-
-
- def _register_rules(self,path:str):
- '''
- 注册路由规则
-
- Args:
- path (str): 路由路径
- '''
- for rule_name in os.listdir(path):
- con_path = os.path.join(path,rule_name)
- if os.path.isfile(con_path) and rule_name.endswith(".py") \
- and rule_name != "__init__.py":
- rule_path = path_to_module(con_path,self.proot)
- import_module(rule_path)
- elif os.path.isdir(con_path) and \
- os.path.exists(os.path.join(con_path,"__init__.py")):
- for sub_rule_name in os.listdir(con_path):
- sub_path = os.path.join(con_path,sub_rule_name)
- if os.path.isfile(sub_path) and sub_rule_name.endswith(".py") \
- and sub_rule_name != "__init__.py":
- rule_path = path_to_module(sub_path,self.proot)
- import_module(path_to_module(sub_path,self.proot))
- else:
- continue
|