fix plugins

This commit is contained in:
jxxghp 2023-07-24 18:04:44 +08:00
parent 2e4770264b
commit e50dbc4df6
4 changed files with 161 additions and 114 deletions

View File

@ -84,7 +84,10 @@ def set_plugin_config(plugin_id: str, conf: dict,
""" """
根据插件ID获取插件配置信息 根据插件ID获取插件配置信息
""" """
# 保存配置
PluginManager().save_plugin_config(plugin_id, conf) PluginManager().save_plugin_config(plugin_id, conf)
# 重新生效插件
PluginManager().reload_plugin(plugin_id, conf)
return schemas.Response(success=True) return schemas.Response(success=True)

View File

@ -66,6 +66,14 @@ class PluginManager(metaclass=Singleton):
except Exception as err: except Exception as err:
logger.error(f"加载插件 {plugin_id} 出错:{err} - {traceback.format_exc()}") logger.error(f"加载插件 {plugin_id} 出错:{err} - {traceback.format_exc()}")
def reload_plugin(self, plugin_id: str, conf: dict):
"""
重新加载插件
"""
if not self._running_plugins.get(plugin_id):
return
self._running_plugins[plugin_id].init_plugin(conf)
def stop(self): def stop(self):
""" """
停止 停止

View File

@ -7,6 +7,7 @@ from typing import Any, List, Dict, Tuple
from urllib.parse import urljoin from urllib.parse import urljoin
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from ruamel.yaml import CommentedMap from ruamel.yaml import CommentedMap
from app import schemas from app import schemas
@ -57,6 +58,13 @@ class AutoSignIn(_PluginBase):
# 加载的模块 # 加载的模块
_site_schema: list = [] _site_schema: list = []
# 配置属性
_enabled: bool = False
_cron: str = ""
_notify: bool = False
_queue_cnt: int = 5
_sign_sites: list = []
def init_plugin(self, config: dict = None): def init_plugin(self, config: dict = None):
self.sites = SitesHelper() self.sites = SitesHelper()
self.event = EventManager() self.event = EventManager()
@ -64,24 +72,44 @@ class AutoSignIn(_PluginBase):
# 停止现有任务 # 停止现有任务
self.stop_service() self.stop_service()
# 配置
if config:
self._enabled = config.get("enabled")
self._cron = config.get("cron")
self._notify = config.get("notify")
self._queue_cnt = config.get("queue_cnt")
self._sign_sites = config.get("sign_sites")
# 加载模块 # 加载模块
self._site_schema = ModuleHelper.load('app.plugins.autosignin.sites', if self._enabled:
filter_func=lambda _, obj: hasattr(obj, 'match'))
# 定时服务 self._site_schema = ModuleHelper.load('app.plugins.autosignin.sites',
self._scheduler = BackgroundScheduler(timezone=settings.TZ) filter_func=lambda _, obj: hasattr(obj, 'match'))
triggers = TimerUtils.random_scheduler(num_executions=2,
begin_hour=9,
end_hour=23,
max_interval=12 * 60,
min_interval=6 * 60)
for trigger in triggers:
self._scheduler.add_job(self.sign_in, "cron", hour=trigger.hour, minute=trigger.minute)
# 启动任务 # 定时服务
if self._scheduler.get_jobs(): self._scheduler = BackgroundScheduler(timezone=settings.TZ)
self._scheduler.print_jobs()
self._scheduler.start() if self._cron:
try:
self._scheduler.add_job(func=self.sign_in,
trigger=CronTrigger.from_crontab(self._cron))
except Exception as err:
logger.error(f"定时任务配置错误:{err}")
else:
# 随机时间
triggers = TimerUtils.random_scheduler(num_executions=2,
begin_hour=9,
end_hour=23,
max_interval=12 * 60,
min_interval=6 * 60)
for trigger in triggers:
self._scheduler.add_job(self.sign_in, "cron",
hour=trigger.hour, minute=trigger.minute)
# 启动任务
if self._scheduler.get_jobs():
self._scheduler.print_jobs()
self._scheduler.start()
@staticmethod @staticmethod
def get_command() -> List[Dict[str, Any]]: def get_command() -> List[Dict[str, Any]]:
@ -197,22 +225,6 @@ class AutoSignIn(_PluginBase):
} }
} }
] ]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 6
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'retry_keyword',
'label': '重试关键字'
}
}
]
} }
] ]
}, },
@ -235,26 +247,6 @@ class AutoSignIn(_PluginBase):
] ]
} }
] ]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'content': [
{
'component': 'VSelect',
'props': {
'chips': True,
'multiple': True,
'model': 'special_sites',
'label': '特殊站点',
'items': site_options
}
}
]
}
]
} }
] ]
} }
@ -263,9 +255,7 @@ class AutoSignIn(_PluginBase):
"notify": True, "notify": True,
"cron": "1 9,18 * * *", "cron": "1 9,18 * * *",
"queue_cnt": 5, "queue_cnt": 5,
"retry_keyword": "", "sign_sites": []
"sign_sites": [],
"special_sites": []
} }
def get_page(self) -> List[dict]: def get_page(self) -> List[dict]:
@ -283,13 +273,17 @@ class AutoSignIn(_PluginBase):
logger.info("收到远程签到命令,开始执行签到任务 ...") logger.info("收到远程签到命令,开始执行签到任务 ...")
# 查询签到站点 # 查询签到站点
sign_sites = [site for site in self.sites.get_indexers() if not site.get("public")] sign_sites = [site for site in self.sites.get_indexers() if not site.get("public")]
# 过滤掉没有选中的站点
if self._sign_sites:
sign_sites = [site for site in sign_sites if site.get("id") in self._sign_sites]
if not sign_sites: if not sign_sites:
logger.info("没有需要签到的站点") logger.info("没有需要签到的站点")
return return
# 执行签到 # 执行签到
logger.info("开始执行签到任务 ...") logger.info("开始执行签到任务 ...")
with ThreadPool(min(len(sign_sites), 5)) as p: with ThreadPool(min(len(sign_sites), self._queue_cnt)) as p:
status = p.map(self.signin_site, sign_sites) status = p.map(self.signin_site, sign_sites)
if status: if status:
@ -302,8 +296,9 @@ class AutoSignIn(_PluginBase):
"status": s[1] "status": s[1]
} for s in status]) } for s in status])
# 发送通知 # 发送通知
self.chain.post_message(Notification(title="站点自动签到", if self._notify:
text="\n".join([f'{s[0]}{s[1]}' for s in status if s]))) self.chain.post_message(Notification(title="站点自动签到",
text="\n".join([f'{s[0]}{s[1]}' for s in status if s])))
else: else:
logger.error("站点签到任务失败!") logger.error("站点签到任务失败!")

View File

@ -5,6 +5,7 @@ from typing import Optional, Any, List, Dict, Tuple
import requests import requests
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from ruamel.yaml import CommentedMap from ruamel.yaml import CommentedMap
from app import schemas from app import schemas
@ -55,37 +56,64 @@ class SiteStatistic(_PluginBase):
# 私有属性 # 私有属性
sites = None sites = None
_scheduler: BackgroundScheduler = None _scheduler = None
_MAX_CONCURRENCY: int = 10
_last_update_time: Optional[datetime] = None _last_update_time: Optional[datetime] = None
_sites_data: dict = {} _sites_data: dict = {}
_site_schema: List[ISiteUserInfo] = None _site_schema: List[ISiteUserInfo] = None
def init_plugin(self, config: dict = None): # 配置属性
# 加载模块 _enabled: bool = False
self._site_schema = ModuleHelper.load('app.plugins.sitestatistic.siteuserinfo', _cron: str = ""
filter_func=lambda _, obj: hasattr(obj, 'schema')) _notify: bool = False
self._site_schema.sort(key=lambda x: x.order) _queue_cnt: int = 5
# 站点管理 _statistic_sites: list = []
self.sites = SitesHelper()
# 站点上一次更新时间
self._last_update_time = None
# 站点数据
self._sites_data = {}
# 定时服务
self._scheduler = BackgroundScheduler(timezone=settings.TZ)
triggers = TimerUtils.random_scheduler(num_executions=1,
begin_hour=0,
end_hour=1,
min_interval=1,
max_interval=60)
for trigger in triggers:
self._scheduler.add_job(self.refresh_all_site_data, "cron", hour=trigger.hour, minute=trigger.minute)
# 启动任务 def init_plugin(self, config: dict = None):
if self._scheduler.get_jobs():
self._scheduler.print_jobs() # 停止现有任务
self._scheduler.start() self.stop_service()
# 配置
if config:
self._enabled = config.get("enabled")
self._cron = config.get("cron")
self._notify = config.get("notify")
self._queue_cnt = config.get("queue_cnt")
self._statistic_sites = config.get("statistic_sites")
if self._enabled:
# 加载模块
self._site_schema = ModuleHelper.load('app.plugins.sitestatistic.siteuserinfo',
filter_func=lambda _, obj: hasattr(obj, 'schema'))
self._site_schema.sort(key=lambda x: x.order)
# 站点管理
self.sites = SitesHelper()
# 站点上一次更新时间
self._last_update_time = None
# 站点数据
self._sites_data = {}
# 定时服务
self._scheduler = BackgroundScheduler(timezone=settings.TZ)
if self._cron:
try:
self._scheduler.add_job(func=self.refresh_all_site_data,
trigger=CronTrigger.from_crontab(self._cron))
except Exception as err:
logger.error(f"定时任务配置错误:{err}")
else:
triggers = TimerUtils.random_scheduler(num_executions=1,
begin_hour=0,
end_hour=1,
min_interval=1,
max_interval=60)
for trigger in triggers:
self._scheduler.add_job(self.refresh_all_site_data, "cron",
hour=trigger.hour, minute=trigger.minute)
# 启动任务
if self._scheduler.get_jobs():
self._scheduler.print_jobs()
self._scheduler.start()
@staticmethod @staticmethod
def get_command() -> List[Dict[str, Any]]: def get_command() -> List[Dict[str, Any]]:
@ -241,7 +269,17 @@ class SiteStatistic(_PluginBase):
pass pass
def stop_service(self): def stop_service(self):
pass """
退出插件
"""
try:
if self._scheduler:
self._scheduler.remove_all_jobs()
if self._scheduler.running:
self._scheduler.shutdown()
self._scheduler = None
except Exception as e:
logger.error("退出插件失败:%s" % str(e))
def __build_class(self, html_text: str) -> Any: def __build_class(self, html_text: str) -> Any:
for site_schema in self._site_schema: for site_schema in self._site_schema:
@ -471,12 +509,14 @@ class SiteStatistic(_PluginBase):
else: else:
refresh_sites = [site for site in self.sites.get_indexers() if refresh_sites = [site for site in self.sites.get_indexers() if
site.get("name") in specify_sites] site.get("name") in specify_sites]
# 过滤掉未选中的站点
refresh_sites = [site for site in refresh_sites if site.get("id") in self._statistic_sites]
if not refresh_sites: if not refresh_sites:
return return
# 并发刷新 # 并发刷新
with ThreadPool(min(len(refresh_sites), self._MAX_CONCURRENCY)) as p: with ThreadPool(min(len(refresh_sites), self._queue_cnt)) as p:
p.map(self.__refresh_site_data, refresh_sites) p.map(self.__refresh_site_data, refresh_sites)
# 获取今天的日期 # 获取今天的日期
@ -487,35 +527,36 @@ class SiteStatistic(_PluginBase):
self._last_update_time = datetime.now() self._last_update_time = datetime.now()
# 通知刷新完成 # 通知刷新完成
messages = [] if self._notify:
# 按照上传降序排序 messages = []
sites = self._sites_data.keys() # 按照上传降序排序
uploads = [self._sites_data[site].get("upload") or 0 for site in sites] sites = self._sites_data.keys()
downloads = [self._sites_data[site].get("download") or 0 for site in sites] uploads = [self._sites_data[site].get("upload") or 0 for site in sites]
data_list = sorted(list(zip(sites, uploads, downloads)), downloads = [self._sites_data[site].get("download") or 0 for site in sites]
key=lambda x: x[1], data_list = sorted(list(zip(sites, uploads, downloads)),
reverse=True) key=lambda x: x[1],
# 总上传 reverse=True)
incUploads = 0 # 总上传
# 总下载 incUploads = 0
incDownloads = 0 # 总下载
for data in data_list: incDownloads = 0
site = data[0] for data in data_list:
upload = int(data[1]) site = data[0]
download = int(data[2]) upload = int(data[1])
if upload > 0 or download > 0: download = int(data[2])
incUploads += int(upload) if upload > 0 or download > 0:
incDownloads += int(download) incUploads += int(upload)
messages.append(f"{site}\n" incDownloads += int(download)
f"上传量:{StringUtils.str_filesize(upload)}\n" messages.append(f"{site}\n"
f"下载量:{StringUtils.str_filesize(download)}\n" f"上传量:{StringUtils.str_filesize(upload)}\n"
f"————————————") f"下载量:{StringUtils.str_filesize(download)}\n"
f"————————————")
if incDownloads or incUploads: if incDownloads or incUploads:
messages.insert(0, f"【汇总】\n" messages.insert(0, f"【汇总】\n"
f"总上传:{StringUtils.str_filesize(incUploads)}\n" f"总上传:{StringUtils.str_filesize(incUploads)}\n"
f"总下载:{StringUtils.str_filesize(incDownloads)}\n" f"总下载:{StringUtils.str_filesize(incDownloads)}\n"
f"————————————") f"————————————")
self.chain.post_message(Notification(title="站点数据统计", text="\n".join(messages))) self.chain.post_message(Notification(title="站点数据统计", text="\n".join(messages)))
logger.info("站点数据刷新完成") logger.info("站点数据刷新完成")