Merge remote-tracking branch 'origin/v2' into v2

This commit is contained in:
jxxghp
2025-03-09 16:33:01 +08:00
4 changed files with 293 additions and 287 deletions
-5
View File
@@ -312,11 +312,6 @@ class SearchChain(ChainBase):
for indexer in self.siteshelper.get_indexers(): for indexer in self.siteshelper.get_indexers():
# 检查站点索引开关 # 检查站点索引开关
if not sites or indexer.get("id") in sites: if not sites or indexer.get("id") in sites:
# 站点流控
state, msg = self.siteshelper.check(indexer.get("domain"))
if state:
logger.warn(msg)
continue
indexer_sites.append(indexer) indexer_sites.append(indexer)
if not indexer_sites: if not indexer_sites:
logger.warn('未开启任何有效站点,无法搜索资源') logger.warn('未开启任何有效站点,无法搜索资源')
+1 -1
View File
@@ -52,7 +52,7 @@ class FilterModule(_ModuleBase):
}, },
# 官种 # 官种
"GZ": { "GZ": {
"include": [r'官方', r'官种'], "include": [r'官方', r'官种', r'官组'],
"match": ["labels"] "match": ["labels"]
}, },
# 特效字幕 # 特效字幕
+6
View File
@@ -122,6 +122,12 @@ class IndexerModule(_ModuleBase):
logger.warn(f"{site.get('name')} 不支持中文搜索") logger.warn(f"{site.get('name')} 不支持中文搜索")
continue continue
# 站点流控
state, msg = SitesHelper().check(StringUtils.get_url_domain(site.get("domain")))
if state:
logger.warn(msg)
continue
# 去除搜索关键字中的特殊字符 # 去除搜索关键字中的特殊字符
if search_word: if search_word:
search_word = StringUtils.clear(search_word, replace_word=" ", allow_space=True) search_word = StringUtils.clear(search_word, replace_word=" ", allow_space=True)
+286 -281
View File
@@ -30,6 +30,9 @@ from app.utils.singleton import Singleton
from app.utils.timer import TimerUtils from app.utils.timer import TimerUtils
lock = threading.Lock()
class SchedulerChain(ChainBase): class SchedulerChain(ChainBase):
pass pass
@@ -56,85 +59,6 @@ class Scheduler(metaclass=Singleton):
""" """
初始化定时服务 初始化定时服务
""" """
# 各服务的运行状态
self._jobs = {
"cookiecloud": {
"name": "同步CookieCloud站点",
"func": SiteChain().sync_cookies,
"running": False,
},
"mediaserver_sync": {
"name": "同步媒体服务器",
"func": MediaServerChain().sync,
"running": False,
},
"subscribe_tmdb": {
"name": "订阅元数据更新",
"func": SubscribeChain().check,
"running": False,
},
"subscribe_search": {
"name": "订阅搜索补全",
"func": SubscribeChain().search,
"running": False,
"kwargs": {
"state": "R"
}
},
"new_subscribe_search": {
"name": "新增订阅搜索",
"func": SubscribeChain().search,
"running": False,
"kwargs": {
"state": "N"
}
},
"subscribe_refresh": {
"name": "订阅刷新",
"func": SubscribeChain().refresh,
"running": False,
},
"subscribe_follow": {
"name": "关注的订阅分享",
"func": SubscribeChain().follow,
"running": False,
},
"transfer": {
"name": "下载文件整理",
"func": TransferChain().process,
"running": False,
},
"clear_cache": {
"name": "缓存清理",
"func": self.clear_cache,
"running": False,
},
"user_auth": {
"name": "用户认证检查",
"func": self.user_auth,
"running": False,
},
"scheduler_job": {
"name": "公共定时服务",
"func": SchedulerChain().scheduler_job,
"running": False,
},
"random_wallpager": {
"name": "壁纸缓存",
"func": TmdbChain().get_trending_wallpapers,
"running": False,
},
"sitedata_refresh": {
"name": "站点数据刷新",
"func": SiteChain().refresh_userdatas,
"running": False,
},
"recommend_refresh": {
"name": "推荐缓存",
"func": RecommendChain().refresh_recommend,
"running": False,
}
}
# 停止定时服务 # 停止定时服务
self.stop() self.stop()
@@ -143,221 +67,302 @@ class Scheduler(metaclass=Singleton):
if settings.DEV: if settings.DEV:
return return
# 创建定时服务 with lock:
self._scheduler = BackgroundScheduler(timezone=settings.TZ, # 各服务的运行状态
executors={ self._jobs = {
'default': ThreadPoolExecutor(100) "cookiecloud": {
}) "name": "同步CookieCloud站点",
"func": SiteChain().sync_cookies,
# CookieCloud定时同步 "running": False,
if settings.COOKIECLOUD_INTERVAL \ },
and str(settings.COOKIECLOUD_INTERVAL).isdigit(): "mediaserver_sync": {
self._scheduler.add_job( "name": "同步媒体服务器",
self.start, "func": MediaServerChain().sync,
"interval", "running": False,
id="cookiecloud", },
name="同步CookieCloud站点", "subscribe_tmdb": {
minutes=int(settings.COOKIECLOUD_INTERVAL), "name": "订阅元数据更新",
next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(minutes=1), "func": SubscribeChain().check,
kwargs={ "running": False,
'job_id': 'cookiecloud' },
"subscribe_search": {
"name": "订阅搜索补全",
"func": SubscribeChain().search,
"running": False,
"kwargs": {
"state": "R"
}
},
"new_subscribe_search": {
"name": "新增订阅搜索",
"func": SubscribeChain().search,
"running": False,
"kwargs": {
"state": "N"
}
},
"subscribe_refresh": {
"name": "订阅刷新",
"func": SubscribeChain().refresh,
"running": False,
},
"subscribe_follow": {
"name": "关注的订阅分享",
"func": SubscribeChain().follow,
"running": False,
},
"transfer": {
"name": "下载文件整理",
"func": TransferChain().process,
"running": False,
},
"clear_cache": {
"name": "缓存清理",
"func": self.clear_cache,
"running": False,
},
"user_auth": {
"name": "用户认证检查",
"func": self.user_auth,
"running": False,
},
"scheduler_job": {
"name": "公共定时服务",
"func": SchedulerChain().scheduler_job,
"running": False,
},
"random_wallpager": {
"name": "壁纸缓存",
"func": TmdbChain().get_trending_wallpapers,
"running": False,
},
"sitedata_refresh": {
"name": "站点数据刷新",
"func": SiteChain().refresh_userdatas,
"running": False,
},
"recommend_refresh": {
"name": "推荐缓存",
"func": RecommendChain().refresh_recommend,
"running": False,
} }
)
# 媒体服务器同步
if settings.MEDIASERVER_SYNC_INTERVAL \
and str(settings.MEDIASERVER_SYNC_INTERVAL).isdigit():
self._scheduler.add_job(
self.start,
"interval",
id="mediaserver_sync",
name="同步媒体服务器",
hours=int(settings.MEDIASERVER_SYNC_INTERVAL),
next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(minutes=5),
kwargs={
'job_id': 'mediaserver_sync'
}
)
# 新增订阅时搜索(5分钟检查一次)
self._scheduler.add_job(
self.start,
"interval",
id="new_subscribe_search",
name="新增订阅搜索",
minutes=5,
kwargs={
'job_id': 'new_subscribe_search'
} }
)
# 检查更新订阅TMDB数据(每隔6小时) # 创建定时服务
self._scheduler.add_job( self._scheduler = BackgroundScheduler(timezone=settings.TZ,
self.start, executors={
"interval", 'default': ThreadPoolExecutor(100)
id="subscribe_tmdb", })
name="订阅元数据更新",
hours=6,
kwargs={
'job_id': 'subscribe_tmdb'
}
)
# 订阅状态每隔24小时搜索一次 # CookieCloud定时同步
if settings.SUBSCRIBE_SEARCH: if settings.COOKIECLOUD_INTERVAL \
self._scheduler.add_job( and str(settings.COOKIECLOUD_INTERVAL).isdigit():
self.start,
"interval",
id="subscribe_search",
name="订阅搜索补全",
hours=24,
kwargs={
'job_id': 'subscribe_search'
}
)
if settings.SUBSCRIBE_MODE == "spider":
# 站点首页种子定时刷新模式
triggers = TimerUtils.random_scheduler(num_executions=32)
for trigger in triggers:
self._scheduler.add_job( self._scheduler.add_job(
self.start, self.start,
"cron", "interval",
id=f"subscribe_refresh|{trigger.hour}:{trigger.minute}", id="cookiecloud",
name="订阅刷新", name="同步CookieCloud站点",
hour=trigger.hour, minutes=int(settings.COOKIECLOUD_INTERVAL),
minute=trigger.minute, next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(minutes=1),
kwargs={
'job_id': 'cookiecloud'
}
)
# 媒体服务器同步
if settings.MEDIASERVER_SYNC_INTERVAL \
and str(settings.MEDIASERVER_SYNC_INTERVAL).isdigit():
self._scheduler.add_job(
self.start,
"interval",
id="mediaserver_sync",
name="同步媒体服务器",
hours=int(settings.MEDIASERVER_SYNC_INTERVAL),
next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(minutes=5),
kwargs={
'job_id': 'mediaserver_sync'
}
)
# 新增订阅时搜索(5分钟检查一次)
self._scheduler.add_job(
self.start,
"interval",
id="new_subscribe_search",
name="新增订阅搜索",
minutes=5,
kwargs={
'job_id': 'new_subscribe_search'
}
)
# 检查更新订阅TMDB数据(每隔6小时)
self._scheduler.add_job(
self.start,
"interval",
id="subscribe_tmdb",
name="订阅元数据更新",
hours=6,
kwargs={
'job_id': 'subscribe_tmdb'
}
)
# 订阅状态每隔24小时搜索一次
if settings.SUBSCRIBE_SEARCH:
self._scheduler.add_job(
self.start,
"interval",
id="subscribe_search",
name="订阅搜索补全",
hours=24,
kwargs={
'job_id': 'subscribe_search'
}
)
if settings.SUBSCRIBE_MODE == "spider":
# 站点首页种子定时刷新模式
triggers = TimerUtils.random_scheduler(num_executions=32)
for trigger in triggers:
self._scheduler.add_job(
self.start,
"cron",
id=f"subscribe_refresh|{trigger.hour}:{trigger.minute}",
name="订阅刷新",
hour=trigger.hour,
minute=trigger.minute,
kwargs={
'job_id': 'subscribe_refresh'
})
else:
# RSS订阅模式
if not settings.SUBSCRIBE_RSS_INTERVAL \
or not str(settings.SUBSCRIBE_RSS_INTERVAL).isdigit():
settings.SUBSCRIBE_RSS_INTERVAL = 30
elif int(settings.SUBSCRIBE_RSS_INTERVAL) < 5:
settings.SUBSCRIBE_RSS_INTERVAL = 5
self._scheduler.add_job(
self.start,
"interval",
id="subscribe_refresh",
name="RSS订阅刷新",
minutes=int(settings.SUBSCRIBE_RSS_INTERVAL),
kwargs={ kwargs={
'job_id': 'subscribe_refresh' 'job_id': 'subscribe_refresh'
}) }
else: )
# RSS订阅模式
if not settings.SUBSCRIBE_RSS_INTERVAL \ # 关注订阅分享(每1小时)
or not str(settings.SUBSCRIBE_RSS_INTERVAL).isdigit():
settings.SUBSCRIBE_RSS_INTERVAL = 30
elif int(settings.SUBSCRIBE_RSS_INTERVAL) < 5:
settings.SUBSCRIBE_RSS_INTERVAL = 5
self._scheduler.add_job( self._scheduler.add_job(
self.start, self.start,
"interval", "interval",
id="subscribe_refresh", id="subscribe_follow",
name="RSS订阅刷新", name="关注的订阅分享",
minutes=int(settings.SUBSCRIBE_RSS_INTERVAL), hours=1,
kwargs={ kwargs={
'job_id': 'subscribe_refresh' 'job_id': 'subscribe_follow'
} }
) )
# 关注订阅分享(每1小时 # 下载器文件转移(每5分钟
self._scheduler.add_job(
self.start,
"interval",
id="subscribe_follow",
name="关注的订阅分享",
hours=1,
kwargs={
'job_id': 'subscribe_follow'
}
)
# 下载器文件转移(每5分钟)
self._scheduler.add_job(
self.start,
"interval",
id="transfer",
name="下载文件整理",
minutes=5,
kwargs={
'job_id': 'transfer'
}
)
# 后台刷新TMDB壁纸
self._scheduler.add_job(
self.start,
"interval",
id="random_wallpager",
name="壁纸缓存",
minutes=30,
next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(seconds=3),
kwargs={
'job_id': 'random_wallpager'
}
)
# 公共定时服务
self._scheduler.add_job(
self.start,
"interval",
id="scheduler_job",
name="公共定时服务",
minutes=10,
kwargs={
'job_id': 'scheduler_job'
}
)
# 缓存清理服务,每隔24小时
self._scheduler.add_job(
self.start,
"interval",
id="clear_cache",
name="缓存清理",
hours=settings.CACHE_CONF["meta"] / 3600,
kwargs={
'job_id': 'clear_cache'
}
)
# 定时检查用户认证,每隔10分钟
self._scheduler.add_job(
self.start,
"interval",
id="user_auth",
name="用户认证检查",
minutes=10,
kwargs={
'job_id': 'user_auth'
}
)
# 站点数据刷新
if settings.SITEDATA_REFRESH_INTERVAL:
self._scheduler.add_job( self._scheduler.add_job(
self.start, self.start,
"interval", "interval",
id="sitedata_refresh", id="transfer",
name="站点数据刷新", name="下载文件整理",
minutes=settings.SITEDATA_REFRESH_INTERVAL * 60, minutes=5,
kwargs={ kwargs={
'job_id': 'sitedata_refresh' 'job_id': 'transfer'
} }
) )
# 推荐缓存 # 后台刷新TMDB壁纸
self._scheduler.add_job( self._scheduler.add_job(
self.start, self.start,
"interval", "interval",
id="recommend_refresh", id="random_wallpager",
name="推荐缓存", name="壁纸缓存",
hours=24, minutes=30,
next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(seconds=3), next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(seconds=3),
kwargs={ kwargs={
'job_id': 'recommend_refresh' 'job_id': 'random_wallpager'
} }
) )
# 初始化工作流服务 # 公共定时服务
self.init_workflow_jobs() self._scheduler.add_job(
self.start,
# 初始化插件服务 "interval",
self.init_plugin_jobs() id="scheduler_job",
name="公共定时服务",
minutes=10,
kwargs={
'job_id': 'scheduler_job'
}
)
# 打印服务 # 缓存清理服务,每隔24小时
logger.debug(self._scheduler.print_jobs()) self._scheduler.add_job(
self.start,
"interval",
id="clear_cache",
name="缓存清理",
hours=settings.CACHE_CONF["meta"] / 3600,
kwargs={
'job_id': 'clear_cache'
}
)
# 启动定时服务 # 定时检查用户认证,每隔10分钟
self._scheduler.start() self._scheduler.add_job(
self.start,
"interval",
id="user_auth",
name="用户认证检查",
minutes=10,
kwargs={
'job_id': 'user_auth'
}
)
# 站点数据刷新
if settings.SITEDATA_REFRESH_INTERVAL:
self._scheduler.add_job(
self.start,
"interval",
id="sitedata_refresh",
name="站点数据刷新",
minutes=settings.SITEDATA_REFRESH_INTERVAL * 60,
kwargs={
'job_id': 'sitedata_refresh'
}
)
# 推荐缓存
self._scheduler.add_job(
self.start,
"interval",
id="recommend_refresh",
name="推荐缓存",
hours=24,
next_run_time=datetime.now(pytz.timezone(settings.TZ)) + timedelta(seconds=3),
kwargs={
'job_id': 'recommend_refresh'
}
)
# 初始化工作流服务
self.init_workflow_jobs()
# 初始化插件服务
self.init_plugin_jobs()
# 打印服务
logger.debug(self._scheduler.print_jobs())
# 启动定时服务
self._scheduler.start()
def start(self, job_id: str, *args, **kwargs): def start(self, job_id: str, *args, **kwargs):
""" """
@@ -496,7 +501,6 @@ class Scheduler(metaclass=Singleton):
""" """
if not self._scheduler: if not self._scheduler:
return return
# 移除该工作流的全部服务 # 移除该工作流的全部服务
self.remove_workflow_job(workflow) self.remove_workflow_job(workflow)
# 添加工作流服务 # 添加工作流服务
@@ -625,17 +629,18 @@ class Scheduler(metaclass=Singleton):
""" """
关闭定时服务 关闭定时服务
""" """
try: with lock:
if self._scheduler: try:
logger.info("正在停止定时任务...") if self._scheduler:
self._event.set() logger.info("正在停止定时任务...")
self._scheduler.remove_all_jobs() self._event.set()
if self._scheduler.running: self._scheduler.remove_all_jobs()
self._scheduler.shutdown() if self._scheduler.running:
self._scheduler = None self._scheduler.shutdown()
logger.info("定时任务停止完成") self._scheduler = None
except Exception as e: logger.info("定时任务停止完成")
logger.error(f"停止定时任务失败::{str(e)} - {traceback.format_exc()}") except Exception as e:
logger.error(f"停止定时任务失败::{str(e)} - {traceback.format_exc()}")
@staticmethod @staticmethod
def clear_cache(): def clear_cache():