豆瓣想看移植为插件

This commit is contained in:
jxxghp 2023-07-25 08:51:36 +08:00
parent 3b5863befa
commit 478c0cb5b6
11 changed files with 429 additions and 161 deletions

View File

@ -26,8 +26,7 @@ ENV LANG="C.UTF-8" \
QB_PASSWORD="adminadmin" \
MEDIASERVER="emby" \
EMBY_HOST="http://127.0.0.1:8096" \
EMBY_API_KEY="" \
DOUBAN_USER_IDS=""
EMBY_API_KEY=""
WORKDIR "/app"
COPY . .
RUN apt-get update \

View File

@ -55,7 +55,6 @@ docker pull jxxghp/moviepilot:latest
- **TORRENT_TAG** 种子标签,默认为`MOVIEPILOT`设置后只有MoviePilot添加的下载才会处理留空所有下载器中的任务均会处理
- **LIBRARY_PATH** 媒体库目录,**注意:需要将`moviepilot`的映射路径与宿主机`真实路径`保持一致**,多个目录使用`,`分隔
- **LIBRARY_CATEGORY** 媒体库二级分类开关,`true`/`false`,默认`false`,开启后会根据配置`category.yaml`自动在媒体库目录下建立二级目录分类
- **DOUBAN_USER_IDS** 豆瓣用户ID用于同步豆瓣标记的`想看`数据,自动添加订阅,多个用户使用,分隔
- **TRANSFER_TYPE** 转移方式,支持`link`/`copy`/`move`/`softlink`
- **COOKIECLOUD_HOST** CookieCloud服务器地址格式`http://ip:port`,必须配置,否则无法添加站点
- **COOKIECLOUD_KEY** CookieCloud用户KEY

View File

@ -1,18 +1,11 @@
from pathlib import Path
from typing import Optional, List
from typing import Union
from app.chain import ChainBase
from app.chain.download import DownloadChain
from app.chain.search import SearchChain
from app.chain.subscribe import SubscribeChain
from app.core.config import settings
from app.core.context import Context
from app.core.context import MediaInfo
from app.core.metainfo import MetaInfo
from app.helper.rss import RssHelper
from app.log import logger
from app.schemas import MediaType, Notification, MessageChannel
from app.schemas import MediaType
class DoubanChain(ChainBase):
@ -20,17 +13,6 @@ class DoubanChain(ChainBase):
豆瓣处理链
"""
_interests_url: str = "https://www.douban.com/feed/people/%s/interests"
_cache_path: Path = settings.TEMP_PATH / "__doubansync_cache__"
def __init__(self):
super().__init__()
self.rsshelper = RssHelper()
self.downloadchain = DownloadChain()
self.searchchain = SearchChain()
self.subscribechain = SubscribeChain()
def recognize_by_doubanid(self, doubanid: str) -> Optional[Context]:
"""
根据豆瓣ID识别媒体信息
@ -96,99 +78,3 @@ class DoubanChain(ChainBase):
"""
return self.run_module("douban_discover", mtype=mtype, sort=sort, tags=tags,
page=page, count=count)
def remote_sync(self, channel: MessageChannel, userid: Union[int, str]):
"""
同步豆瓣想看数据发送消息
"""
self.post_message(Notification(channel=channel,
title="开始同步豆瓣想看 ...", userid=userid))
self.sync()
self.post_message(Notification(channel=channel,
title="同步豆瓣想看数据完成!", userid=userid))
def sync(self):
"""
通过用户RSS同步豆瓣想看数据
"""
if not settings.DOUBAN_USER_IDS:
return
# 读取缓存
caches = self._cache_path.read_text().split("\n") if self._cache_path.exists() else []
for user_id in settings.DOUBAN_USER_IDS.split(","):
# 同步每个用户的豆瓣数据
if not user_id:
continue
logger.info(f"开始同步用户 {user_id} 的豆瓣想看数据 ...")
url = self._interests_url % user_id
results = self.rsshelper.parse(url)
if not results:
logger.error(f"未获取到用户 {user_id} 豆瓣RSS数据{url}")
return
# 解析数据
for result in results:
dtype = result.get("title", "")[:2]
title = result.get("title", "")[2:]
if dtype not in ["想看"]:
continue
if not result.get("link"):
continue
douban_id = result.get("link", "").split("/")[-2]
if not douban_id or douban_id in caches:
continue
# 根据豆瓣ID获取豆瓣数据
doubaninfo: Optional[dict] = self.douban_info(doubanid=douban_id)
if not doubaninfo:
logger.warn(f'未获取到豆瓣信息,标题:{title}豆瓣ID{douban_id}')
continue
logger.info(f'获取到豆瓣信息,标题:{title}豆瓣ID{douban_id}')
# 识别媒体信息
meta = MetaInfo(doubaninfo.get("original_title") or doubaninfo.get("title"))
if doubaninfo.get("year"):
meta.year = doubaninfo.get("year")
mediainfo: MediaInfo = self.recognize_media(meta=meta)
if not mediainfo:
logger.warn(f'未识别到媒体信息,标题:{title}豆瓣ID{douban_id}')
continue
# 加入缓存
caches.append(douban_id)
# 查询缺失的媒体信息
exist_flag, no_exists = self.downloadchain.get_no_exists_info(meta=meta, mediainfo=mediainfo)
if exist_flag:
logger.info(f'{mediainfo.title_year} 媒体库中已存在')
continue
logger.info(f'{mediainfo.title_year} 媒体库中不存在,开始搜索 ...')
# 搜索
contexts = self.searchchain.process(mediainfo=mediainfo,
no_exists=no_exists)
if not contexts:
logger.warn(f'{mediainfo.title_year} 未搜索到资源')
# 添加订阅
self.subscribechain.add(title=mediainfo.title,
year=mediainfo.year,
mtype=mediainfo.type,
tmdbid=mediainfo.tmdb_id,
season=meta.begin_season,
exist_ok=True,
username="豆瓣想看")
continue
# 自动下载
downloads, lefts = self.downloadchain.batch_download(contexts=contexts, no_exists=no_exists)
if downloads and not lefts:
# 全部下载完成
logger.info(f'{mediainfo.title_year} 下载完成')
else:
# 未完成下载
logger.info(f'{mediainfo.title_year} 未下载未完整,添加订阅 ...')
# 添加订阅
self.subscribechain.add(title=mediainfo.title,
year=mediainfo.year,
mtype=mediainfo.type,
tmdbid=mediainfo.tmdb_id,
season=meta.begin_season,
exist_ok=True,
username="豆瓣想看")
logger.info(f"用户 {user_id} 豆瓣想看同步完成")
# 保存缓存
self._cache_path.write_text("\n".join(caches))

View File

@ -4,19 +4,18 @@ from typing import Any, Union
from app.chain import ChainBase
from app.chain.cookiecloud import CookieCloudChain
from app.chain.douban import DoubanChain
from app.chain.download import DownloadChain
from app.chain.mediaserver import MediaServerChain
from app.chain.site import SiteChain
from app.chain.subscribe import SubscribeChain
from app.chain.transfer import TransferChain
from app.core.event import Event as ManagerEvent
from app.core.event import eventmanager, EventManager
from app.core.plugin import PluginManager
from app.core.event import Event as ManagerEvent
from app.log import logger
from app.schemas.types import EventType, MessageChannel
from app.utils.object import ObjectUtils
from app.utils.singleton import Singleton
from app.schemas.types import EventType, MessageChannel
class CommandChian(ChainBase):
@ -70,11 +69,6 @@ class Command(metaclass=Singleton):
"description": "禁用站点",
"data": {}
},
"/douban_sync": {
"func": DoubanChain().remote_sync,
"description": "同步豆瓣想看",
"data": {}
},
"/mediaserver_sync": {
"func": MediaServerChain().remote_sync,
"description": "同步媒体服务器",

View File

@ -143,8 +143,6 @@ class Settings(BaseSettings):
LIBRARY_PATH: str = None
# 二级分类
LIBRARY_CATEGORY: bool = True
# 豆瓣用户ID用于同步豆瓣数据使用,分隔
DOUBAN_USER_IDS: str = ""
# 电影重命名格式
MOVIE_RENAME_FORMAT: str = "{{title}}{% if year %} ({{year}}){% endif %}" \
"/{{title}}{% if year %} ({{year}}){% endif %}{% if part %}-{{part}}{% endif %}{% if videoFormat %} - {{videoFormat}}{% endif %}" \

View File

@ -7,6 +7,8 @@ from app.core.config import settings
from app.db.models import Base
from app.db.plugindata_oper import PluginDataOper
from app.db.systemconfig_oper import SystemConfigOper
from app.helper.message import MessageHelper
from app.schemas import Notification, NotificationType, MessageChannel
class PluginChian(ChainBase):
@ -34,9 +36,14 @@ class _PluginBase(metaclass=ABCMeta):
plugin_desc: str = ""
def __init__(self):
# 插件数据
self.plugindata = PluginDataOper()
# 处理链
self.chain = PluginChian()
# 系统配置
self.systemconfig = SystemConfigOper()
# 系统消息
self.systemmessage = MessageHelper()
@abstractmethod
def init_plugin(self, config: dict = None):
@ -139,3 +146,13 @@ class _PluginBase(metaclass=ABCMeta):
:param key: 数据key
"""
return self.plugindata.get_data(key)
def post_message(self, channel: MessageChannel = None, mtype: NotificationType = None, title: str = None,
text: str = None, image: str = None, link: str = None, userid: str = None):
"""
发送消息
"""
self.chain.post_message(Notification(
channel=channel, mtype=mtype, title=title, text=text,
image=image, link=link, userid=userid
))

View File

@ -2,8 +2,7 @@ import traceback
from datetime import datetime
from multiprocessing.dummy import Pool as ThreadPool
from multiprocessing.pool import ThreadPool
from threading import Event
from typing import Any, List, Dict, Tuple
from typing import Any, List, Dict, Tuple, Optional
from urllib.parse import urljoin
from apscheduler.schedulers.background import BackgroundScheduler
@ -11,20 +10,19 @@ from apscheduler.triggers.cron import CronTrigger
from ruamel.yaml import CommentedMap
from app import schemas
from app.core.event import EventManager, eventmanager
from app.core.config import settings
from app.core.event import EventManager, eventmanager, Event
from app.helper.browser import PlaywrightHelper
from app.helper.cloudflare import under_challenge
from app.helper.module import ModuleHelper
from app.helper.sites import SitesHelper
from app.log import logger
from app.plugins import _PluginBase
from app.schemas import Notification
from app.schemas.types import EventType, NotificationType
from app.utils.http import RequestUtils
from app.utils.site import SiteUtils
from app.utils.string import StringUtils
from app.utils.timer import TimerUtils
from app.schemas.types import EventType
class AutoSignIn(_PluginBase):
@ -54,7 +52,7 @@ class AutoSignIn(_PluginBase):
# 事件管理器
event: EventManager = None
# 定时器
_scheduler = None
_scheduler: Optional[BackgroundScheduler] = None
# 加载的模块
_site_schema: list = []
@ -92,9 +90,12 @@ class AutoSignIn(_PluginBase):
if self._cron:
try:
self._scheduler.add_job(func=self.sign_in,
trigger=CronTrigger.from_crontab(self._cron))
trigger=CronTrigger.from_crontab(self._cron),
name="站点自动签到")
except Exception as err:
logger.error(f"定时任务配置错误:{err}")
# 推送实时消息
self.systemmessage.put(f"执行周期配置错误:{err}")
else:
# 随机时间
triggers = TimerUtils.random_scheduler(num_executions=2,
@ -104,7 +105,8 @@ class AutoSignIn(_PluginBase):
min_interval=6 * 60)
for trigger in triggers:
self._scheduler.add_job(self.sign_in, "cron",
hour=trigger.hour, minute=trigger.minute)
hour=trigger.hour, minute=trigger.minute,
name="站点自动签到")
# 启动任务
if self._scheduler.get_jobs():
@ -183,7 +185,7 @@ class AutoSignIn(_PluginBase):
'component': 'VSwitch',
'props': {
'model': 'notify',
'label': '签到通知',
'label': '发送通知',
}
}
]
@ -205,7 +207,7 @@ class AutoSignIn(_PluginBase):
'props': {
'model': 'cron',
'label': '执行周期',
'placeholder': '0 9,18 * * *'
'placeholder': '5位cron表达式留空自动'
}
}
]
@ -253,7 +255,7 @@ class AutoSignIn(_PluginBase):
], {
"enabled": False,
"notify": True,
"cron": "1 9,18 * * *",
"cron": "",
"queue_cnt": 5,
"sign_sites": []
}
@ -270,7 +272,10 @@ class AutoSignIn(_PluginBase):
自动签到
"""
if event:
logger.info("收到远程签到命令,开始执行签到任务 ...")
logger.info("收到命令,开始站点签到 ...")
self.post_message(channel=event.event_data.get("channel"),
title="开始站点签到 ...",
userid=event.event_data.get("user"))
# 查询签到站点
sign_sites = [site for site in self.sites.get_indexers() if not site.get("public")]
# 过滤掉没有选中的站点
@ -297,10 +302,17 @@ class AutoSignIn(_PluginBase):
} for s in status])
# 发送通知
if self._notify:
self.chain.post_message(Notification(title="站点自动签到",
text="\n".join([f'{s[0]}{s[1]}' for s in status if s])))
self.post_message(title="站点自动签到",
mtype=NotificationType.SiteMessage,
text="\n".join([f'{s[0]}{s[1]}' for s in status if s]))
if event:
self.post_message(channel=event.event_data.get("channel"),
title="站点签到完成!", userid=event.event_data.get("user"))
else:
logger.error("站点签到任务失败!")
if event:
self.post_message(channel=event.event_data.get("channel"),
title="站点签到任务失败!", userid=event.event_data.get("user"))
def __build_class(self, url) -> Any:
for site_schema in self._site_schema:

View File

@ -0,0 +1,356 @@
from pathlib import Path
from threading import Lock
from typing import Optional, Any, List, Dict, Tuple
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from app.chain.download import DownloadChain
from app.chain.search import SearchChain
from app.chain.subscribe import SubscribeChain
from app.core.config import settings
from app.core.context import MediaInfo
from app.core.event import Event
from app.core.event import eventmanager
from app.core.metainfo import MetaInfo
from app.helper.rss import RssHelper
from app.log import logger
from app.plugins import _PluginBase
from app.schemas.types import EventType
lock = Lock()
class DoubanSync(_PluginBase):
# 插件名称
plugin_name = "豆瓣想看"
# 插件描述
plugin_desc = "同步豆瓣想看数据,自动添加订阅。"
# 插件图标
plugin_icon = "douban.png"
# 主题色
plugin_color = "#05B711"
# 插件版本
plugin_version = "1.0"
# 插件作者
plugin_author = "jxxghp"
# 作者主页
author_url = "https://github.com/jxxghp"
# 插件配置项ID前缀
plugin_config_prefix = "doubansync_"
# 加载顺序
plugin_order = 3
# 可使用的用户级别
auth_level = 2
# 私有变量
_interests_url: str = "https://www.douban.com/feed/people/%s/interests"
_scheduler: Optional[BackgroundScheduler] = None
_cache_path: Optional[Path] = None
rsshelper = None
downloadchain = None
searchchain = None
subscribechain = None
# 配置属性
_enabled: bool = False
_cron: str = ""
_notify: bool = False
_days: int = 7
_users: str = ""
def init_plugin(self, config: dict = None):
self._cache_path = settings.TEMP_PATH / "__doubansync_cache__"
self.rsshelper = RssHelper()
self.downloadchain = DownloadChain()
self.searchchain = SearchChain()
self.subscribechain = SubscribeChain()
# 停止现有任务
self.stop_service()
# 配置
if config:
self._enabled = config.get("enabled")
self._cron = config.get("cron")
self._notify = config.get("notify")
self._days = config.get("days")
self._users = config.get("users")
if self._enabled:
self._scheduler = BackgroundScheduler(timezone=settings.TZ)
if self._cron:
try:
self._scheduler.add_job(func=self.sync,
trigger=CronTrigger.from_crontab(self._cron),
name="豆瓣想看")
except Exception as err:
logger.error(f"定时任务配置错误:{err}")
# 推送实时消息
self.systemmessage.put(f"执行周期配置错误:{err}")
else:
self._scheduler.add_job(self.sync, "interval", minutes=30, name="豆瓣想看")
# 启动任务
if self._scheduler.get_jobs():
self._scheduler.print_jobs()
self._scheduler.start()
@staticmethod
def get_command() -> List[Dict[str, Any]]:
"""
定义远程控制命令
:return: 命令关键字事件描述附带数据
"""
return [{
"cmd": "/douban_sync",
"event": EventType.DoubanSync,
"desc": "同步豆瓣想看",
"data": {}
}]
def get_api(self) -> List[Dict[str, Any]]:
"""
获取插件API
[{
"path": "/xx",
"endpoint": self.xxx,
"methods": ["GET", "POST"],
"summary": "API说明"
}]
"""
pass
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
"""
拼装插件配置页面需要返回两块数据1页面配置2数据结构
"""
return [
{
'component': 'VForm',
'content': [
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 6
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'enabled',
'label': '启用插件',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 6
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'notify',
'label': '发送通知',
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 6
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'cron',
'label': '执行周期',
'placeholder': '5位cron表达式留空自动'
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 6
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'days',
'label': '同步天数'
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'content': [
{
'component': 'VTextField',
'props': {
'model': 'users',
'label': '用户列表',
'placeholder': '豆瓣用户ID多个用英文逗号分隔'
}
}
]
}
]
}
]
}
], {
"enabled": False,
"notify": True,
"cron": "*/30 * * * *",
"days": 7,
"users": "",
}
def get_page(self) -> List[dict]:
"""
拼装插件详情页面需要返回页面配置同时附带数据
"""
pass
def stop_service(self):
"""
退出插件
"""
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 sync(self):
"""
通过用户RSS同步豆瓣想看数据
"""
if not self._users:
return
# 读取缓存
caches = self._cache_path.read_text().split("\n") if self._cache_path.exists() else []
for user_id in self._users.split(","):
# 同步每个用户的豆瓣数据
if not user_id:
continue
logger.info(f"开始同步用户 {user_id} 的豆瓣想看数据 ...")
url = self._interests_url % user_id
results = self.rsshelper.parse(url)
if not results:
logger.error(f"未获取到用户 {user_id} 豆瓣RSS数据{url}")
return
# 解析数据
for result in results:
dtype = result.get("title", "")[:2]
title = result.get("title", "")[2:]
if dtype not in ["想看"]:
continue
if not result.get("link"):
continue
# TODO 判断是否在天数范围
douban_id = result.get("link", "").split("/")[-2]
if not douban_id or douban_id in caches:
continue
# 根据豆瓣ID获取豆瓣数据
doubaninfo: Optional[dict] = self.chain.douban_info(doubanid=douban_id)
if not doubaninfo:
logger.warn(f'未获取到豆瓣信息,标题:{title}豆瓣ID{douban_id}')
continue
logger.info(f'获取到豆瓣信息,标题:{title}豆瓣ID{douban_id}')
# 识别媒体信息
meta = MetaInfo(doubaninfo.get("original_title") or doubaninfo.get("title"))
if doubaninfo.get("year"):
meta.year = doubaninfo.get("year")
mediainfo: MediaInfo = self.chain.recognize_media(meta=meta)
if not mediainfo:
logger.warn(f'未识别到媒体信息,标题:{title}豆瓣ID{douban_id}')
continue
# 加入缓存
caches.append(douban_id)
# 查询缺失的媒体信息
exist_flag, no_exists = self.downloadchain.get_no_exists_info(meta=meta, mediainfo=mediainfo)
if exist_flag:
logger.info(f'{mediainfo.title_year} 媒体库中已存在')
continue
logger.info(f'{mediainfo.title_year} 媒体库中不存在,开始搜索 ...')
# 搜索
contexts = self.searchchain.process(mediainfo=mediainfo,
no_exists=no_exists)
if not contexts:
logger.warn(f'{mediainfo.title_year} 未搜索到资源')
# 添加订阅
self.subscribechain.add(title=mediainfo.title,
year=mediainfo.year,
mtype=mediainfo.type,
tmdbid=mediainfo.tmdb_id,
season=meta.begin_season,
exist_ok=True,
username="豆瓣想看")
continue
# 自动下载
downloads, lefts = self.downloadchain.batch_download(contexts=contexts, no_exists=no_exists)
if downloads and not lefts:
# 全部下载完成
logger.info(f'{mediainfo.title_year} 下载完成')
else:
# 未完成下载
logger.info(f'{mediainfo.title_year} 未下载未完整,添加订阅 ...')
# 添加订阅
self.subscribechain.add(title=mediainfo.title,
year=mediainfo.year,
mtype=mediainfo.type,
tmdbid=mediainfo.tmdb_id,
season=meta.begin_season,
exist_ok=True,
username="豆瓣想看")
logger.info(f"用户 {user_id} 豆瓣想看同步完成")
# 保存缓存
self._cache_path.write_text("\n".join(caches))
@eventmanager.register(EventType.DoubanSync)
def remote_sync(self, event: Event):
"""
刷新站点数据
"""
if event:
logger.info("收到命令,开始执行豆瓣想看同步 ...")
self.post_message(channel=event.event_data.get("channel"),
title="开始同步豆瓣想看 ...",
userid=event.event_data.get("user"))
self.sync()
if event:
self.post_message(channel=event.event_data.get("channel"),
title="同步豆瓣想看数据完成!", userid=event.event_data.get("user"))

View File

@ -1,3 +1,4 @@
import warnings
from datetime import datetime
from multiprocessing.dummy import Pool as ThreadPool
from threading import Lock
@ -10,23 +11,19 @@ from ruamel.yaml import CommentedMap
from app import schemas
from app.core.config import settings
from app.core.event import eventmanager
from app.core.event import Event
from app.core.event import eventmanager
from app.helper.browser import PlaywrightHelper
from app.helper.module import ModuleHelper
from app.helper.sites import SitesHelper
from app.log import logger
from app.plugins import _PluginBase
from app.plugins.sitestatistic.siteuserinfo import ISiteUserInfo
from app.schemas import Notification
from app.schemas.types import EventType, NotificationType
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
from app.utils.timer import TimerUtils
import warnings
from app.schemas.types import EventType
warnings.filterwarnings("ignore", category=FutureWarning)
lock = Lock()
@ -56,7 +53,7 @@ class SiteStatistic(_PluginBase):
# 私有属性
sites = None
_scheduler = None
_scheduler: Optional[BackgroundScheduler] = None
_last_update_time: Optional[datetime] = None
_sites_data: dict = {}
_site_schema: List[ISiteUserInfo] = None
@ -95,9 +92,12 @@ class SiteStatistic(_PluginBase):
if self._cron:
try:
self._scheduler.add_job(func=self.refresh_all_site_data,
trigger=CronTrigger.from_crontab(self._cron))
trigger=CronTrigger.from_crontab(self._cron),
name="站点数据统计")
except Exception as err:
logger.error(f"定时任务配置错误:{err}")
# 推送实时消息
self.systemmessage.put(f"执行周期配置错误:{err}")
else:
triggers = TimerUtils.random_scheduler(num_executions=1,
begin_hour=0,
@ -106,7 +106,8 @@ class SiteStatistic(_PluginBase):
max_interval=60)
for trigger in triggers:
self._scheduler.add_job(self.refresh_all_site_data, "cron",
hour=trigger.hour, minute=trigger.minute)
hour=trigger.hour, minute=trigger.minute,
name="站点数据统计")
# 启动任务
if self._scheduler.get_jobs():
@ -207,7 +208,7 @@ class SiteStatistic(_PluginBase):
'props': {
'model': 'cron',
'label': '执行周期',
'placeholder': '0 9,18 * * *'
'placeholder': '5位cron表达式留空自动'
}
}
]
@ -467,10 +468,11 @@ class SiteStatistic(_PluginBase):
for head, date, content in site_user_info.message_unread_contents:
msg_title = f"【站点 {site_user_info.site_name} 消息】"
msg_text = f"时间:{date}\n标题:{head}\n内容:\n{content}"
self.chain.post_message(Notification(title=msg_title, text=msg_text))
self.post_message(mtype=NotificationType.SiteMessage, title=msg_title, text=msg_text)
else:
self.chain.post_message(Notification(title=f"站点 {site_user_info.site_name} 收到 "
f"{site_user_info.message_unread} 条新消息,请登陆查看"))
self.post_message(mtype=NotificationType.SiteMessage,
title=f"站点 {site_user_info.site_name} 收到 "
f"{site_user_info.message_unread} 条新消息,请登陆查看")
@eventmanager.register(EventType.SiteStatistic)
def refresh(self, event: Event):
@ -478,8 +480,14 @@ class SiteStatistic(_PluginBase):
刷新站点数据
"""
if event:
logger.info("收到命令,开始执行站点数据刷新 ...")
logger.info("收到命令,开始刷新站点数据 ...")
self.post_message(channel=event.event_data.get("channel"),
title="开始刷新站点数据 ...",
userid=event.event_data.get("user"))
self.refresh_all_site_data(force=True)
if event:
self.post_message(channel=event.event_data.get("channel"),
title="站点数据刷新完成!", userid=event.event_data.get("user"))
def refresh_all_site_data(self, force: bool = False, specify_sites: list = None):
"""
@ -555,6 +563,7 @@ class SiteStatistic(_PluginBase):
f"总上传:{StringUtils.str_filesize(incUploads)}\n"
f"总下载:{StringUtils.str_filesize(incDownloads)}\n"
f"————————————")
self.chain.post_message(Notification(title="站点数据统计", text="\n".join(messages)))
self.post_message(mtype=NotificationType.SiteMessage,
title="站点数据统计", text="\n".join(messages))
logger.info("站点数据刷新完成")

View File

@ -7,7 +7,6 @@ from apscheduler.schedulers.background import BackgroundScheduler
from app.chain import ChainBase
from app.chain.cookiecloud import CookieCloudChain
from app.chain.douban import DoubanChain
from app.chain.mediaserver import MediaServerChain
from app.chain.subscribe import SubscribeChain
from app.chain.transfer import TransferChain
@ -70,9 +69,6 @@ class Scheduler(metaclass=Singleton):
self._scheduler.add_job(SubscribeChain().refresh, "cron",
hour=trigger.hour, minute=trigger.minute, name="订阅刷新")
# 豆瓣同步每30分钟
self._scheduler.add_job(DoubanChain().sync, "interval", minutes=30, name="同步豆瓣想看")
# 下载器文件转移每5分钟
self._scheduler.add_job(TransferChain().process, "interval", minutes=5, name="下载文件整理")

View File

@ -22,6 +22,8 @@ class EventType(Enum):
SiteSignin = "site.signin"
# 站点数据统计
SiteStatistic = "site.statistic"
# 豆瓣想看
DoubanSync = "douban.sync"
# Webhook消息
WebhookMessage = "webhook.message"
# 转移完成