PaiGram/utils/service/manager.py

99 lines
3.5 KiB
Python
Raw Normal View History

2022-07-26 10:07:31 +00:00
import inspect
import os
from glob import glob
from importlib import import_module
from typing import List, Union, Dict
from logger import Log
from models.types import Func
2022-07-26 10:07:31 +00:00
from utils.aiobrowser import AioBrowser
from utils.mysql import MySQL
from utils.redisdb import RedisDB
ServicesFunctions: List[Func] = []
ServicesDict: Dict[str, Func] = {}
2022-07-26 10:07:31 +00:00
def listener_service():
"""监听服务"""
def decorator(func: Func):
ServicesFunctions.append(
2022-07-26 10:07:31 +00:00
func
)
return func
return decorator
class ServicesManager:
2022-07-26 10:07:31 +00:00
def __init__(self, mysql: MySQL, redis: RedisDB, browser: AioBrowser):
self.browser = browser
self.redis = redis
self.mysql = mysql
self.services_list: List[str] = []
2022-07-26 10:07:31 +00:00
self.exclude_list: List[str] = []
def refresh_list(self, app_paths):
self.services_list.clear()
2022-07-26 10:07:31 +00:00
app_paths = glob(app_paths)
for app_path in app_paths:
if os.path.isdir(app_path):
app_path = os.path.basename(app_path)
self.services_list.append(app_path)
2022-07-26 10:07:31 +00:00
def add_exclude(self, exclude: Union[str, List[str]]):
if isinstance(exclude, str):
self.exclude_list.append(exclude)
elif isinstance(exclude, list):
self.exclude_list.extend(exclude)
else:
raise TypeError
def import_module(self):
for services_name in self.services_list:
if services_name not in self.exclude_list:
2022-07-26 10:07:31 +00:00
try:
import_module(f"apps.{services_name}")
2022-07-26 10:07:31 +00:00
except ImportError as exc:
Log.warning(f"Service模块 {services_name} 导入失败", exc)
2022-07-26 10:07:31 +00:00
except ImportWarning as exc:
Log.warning(f"Service模块 {services_name} 加载成功但有警告", exc)
2022-07-26 10:07:31 +00:00
except Exception as exc:
Log.warning(f"Service模块 {services_name} 加载失败", exc)
2022-07-26 10:07:31 +00:00
else:
Log.debug(f"Service模块 {services_name} 加载成功")
2022-07-26 10:07:31 +00:00
def add_service(self):
for func in ServicesFunctions:
2022-07-26 10:07:31 +00:00
if callable(func):
kwargs = {}
try:
signature = inspect.signature(func)
except ValueError as exception:
if "no signature found" in str(exception):
Log.warning("no signature found", exception)
break
elif "not supported by signature" in str(exception):
Log.warning("not supported by signature", exception)
break
else:
raise exception
else:
for parameter_name, parameter in signature.parameters.items():
annotation = parameter.annotation
if issubclass(annotation, MySQL):
kwargs[parameter_name] = self.mysql
if issubclass(annotation, RedisDB):
kwargs[parameter_name] = self.redis
if issubclass(annotation, AioBrowser):
kwargs[parameter_name] = self.browser
try:
handlers_list = func(**kwargs)
class_name = handlers_list.__class__.__name__
ServicesDict.setdefault(class_name, handlers_list)
except BaseException as exc:
2022-07-26 10:07:31 +00:00
Log.error("初始化Service失败", exc)
finally:
pass