fix 订阅下载统计1.5增加消息推送

This commit is contained in:
thsrite
2024-03-29 09:57:17 +08:00
parent 23b173b1bd
commit 48907b6081
4 changed files with 315 additions and 98 deletions

View File

@@ -28,5 +28,5 @@ MoviePilot三方插件市场https://github.com/thsrite/MoviePilot-Plugins/
- [云盘实时链接 1.5](docs%2FCloudLinkMonitor.md)
- [源文件恢复 1.2](docs%2FLinkToSrc.md)
- [微信消息转发 1.3](docs%2FWeChatForward.md)
- [订阅下载统计 1.4](docs%2FSubscribeStatistic.md)
- [订阅下载统计 1.5](docs%2FSubscribeStatistic.md)

View File

@@ -2,6 +2,7 @@
### 更新记录
- 1.5 增加消息推送
- 1.4 无订阅站点也统计数量
- 1.3 fix bug
- 1.2 fix bug

View File

@@ -146,7 +146,7 @@
"SubscribeStatistic": {
"name": "订阅下载统计",
"description": "统计指定时间内各站点订阅及下载情况。",
"version": "1.4",
"version": "1.5",
"icon": "https://raw.githubusercontent.com/thsrite/MoviePilot-Plugins/main/icons/subscribestatistic.png",
"author": "thsrite",
"level": 1

View File

@@ -1,4 +1,5 @@
import json
from datetime import datetime, timedelta
from app.db.downloadhistory_oper import DownloadHistoryOper
from app.db.site_oper import SiteOper
@@ -6,6 +7,13 @@ from app.plugins import _PluginBase
from app.db.subscribe_oper import SubscribeOper
from typing import Any, List, Dict, Tuple
import pytz
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from app.log import logger
from app.core.config import settings
from app.schemas import NotificationType
from app.schemas.types import SystemConfigKey
@@ -17,7 +25,7 @@ class SubscribeStatistic(_PluginBase):
# 插件图标
plugin_icon = "https://raw.githubusercontent.com/thsrite/MoviePilot-Plugins/main/icons/subscribestatistic.png"
# 插件版本
plugin_version = "1.4"
plugin_version = "1.5"
# 插件作者
plugin_author = "thsrite"
# 作者主页
@@ -31,13 +39,18 @@ class SubscribeStatistic(_PluginBase):
# 任务执行间隔
_enabled = False
_notify = False
_onlyonce = False
_movie_subscribe_days = None
_tv_subscribe_days = None
_movie_download_days = None
_tv_download_days = None
_notify_type = None
_msgtype = None
subscribe = None
downloadhis = None
siteoper = None
_cron: str = ""
def init_plugin(self, config: dict = None):
self.subscribe = SubscribeOper()
@@ -45,10 +58,98 @@ class SubscribeStatistic(_PluginBase):
self.siteoper = SiteOper()
if config:
self._enabled = config.get("enabled")
self._notify = config.get("notify")
self._onlyonce = config.get("onlyonce")
self._cron = config.get("cron")
self._movie_subscribe_days = config.get("movie_subscribe_days")
self._tv_subscribe_days = config.get("tv_subscribe_days")
self._movie_download_days = config.get("movie_download_days")
self._tv_download_days = config.get("tv_download_days")
self._notify_type = config.get("notify_type")
self._msgtype = config.get("msgtype")
if self._enabled and (
self._cron or self._onlyonce) and self._notify and self._msgtype and self._notify_type:
# 定时服务
self._scheduler = BackgroundScheduler(timezone=settings.TZ)
# 立即运行一次
if self._onlyonce:
logger.info(f"订阅下载统计服务启动,立即运行一次")
self._scheduler.add_job(self.notify, 'date',
run_date=datetime.now(
tz=pytz.timezone(settings.TZ)) + timedelta(seconds=3),
name="订阅下载统计")
# 关闭一次性开关
self._onlyonce = False
# 保存配置
self.__update_config()
# 周期运行
if self._cron:
try:
self._scheduler.add_job(func=self.notify,
trigger=CronTrigger.from_crontab(self._cron),
name="订阅下载统计")
except Exception as err:
logger.error(f"定时任务配置错误:{err}")
# 推送实时消息
self.systemmessage.put(f"执行周期配置错误:{err}")
# 启动任务
if self._scheduler.get_jobs():
self._scheduler.print_jobs()
self._scheduler.start()
def notify(self):
"""
发送统计消息
"""
text = ""
if 'movie_subscribes' in self._notify_type:
text += "【电影订阅统计】\n"
_, movie_subscribe_sites, movie_subscribe_datas = self.__get_movie_subscribes()
movie_subscribe_dict = dict(zip(movie_subscribe_sites, movie_subscribe_datas))
movie_subscribe_dict = dict(sorted(movie_subscribe_dict.items(), key=lambda x: x[1], reverse=True))
for movie_subscribe_site in movie_subscribe_dict.keys():
text += f"{movie_subscribe_site}: {movie_subscribe_dict[movie_subscribe_site]}\n"
text += "\n"
if 'tv_subscribes' in self._notify_type:
text += "【电视剧订阅统计】\n"
_, tv_subscribe_sites, tv_subscribe_datas = self.__get_tv_subscribes()
tv_subscribe_dict = dict(zip(tv_subscribe_sites, tv_subscribe_datas))
tv_subscribe_dict = dict(sorted(tv_subscribe_dict.items(), key=lambda x: x[1], reverse=True))
for tv_subscribe_site in tv_subscribe_dict.keys():
text += f"{tv_subscribe_site}: {tv_subscribe_dict[tv_subscribe_site]}\n"
text += "\n"
if 'movie_downloads' in self._notify_type:
text += "【电影下载统计】\n"
_, movie_download_sites, movie_download_datas = self.__get_movie_downloads()
movie_download_dict = dict(zip(movie_download_sites, movie_download_datas))
movie_download_dict = dict(sorted(movie_download_dict.items(), key=lambda x: x[1], reverse=True))
for movie_download_site in movie_download_dict.keys():
text += f"{movie_download_site}: {movie_download_dict[movie_download_site]}\n"
text += "\n"
if 'tv_downloads' in self._notify_type:
text += "【电视剧下载统计】\n"
_, tv_download_sites, tv_download_datas = self.__get_tv_downloads()
tv_download_dict = dict(zip(tv_download_sites, tv_download_datas))
tv_download_dict = dict(sorted(tv_download_dict.items(), key=lambda x: x[1], reverse=True))
for tv_download_site in tv_download_dict.keys():
text += f"{tv_download_site}: {tv_download_dict[tv_download_site]}\n"
# 发送通知
mtype = NotificationType.Manual
if self._msgtype:
mtype = NotificationType.__getitem__(str(self._msgtype)) or NotificationType.Manual
self.post_message(title="订阅下载统计",
mtype=mtype,
text=text)
def get_state(self) -> bool:
return self._enabled
@@ -60,10 +161,108 @@ class SubscribeStatistic(_PluginBase):
def get_api(self) -> List[Dict[str, Any]]:
pass
def __get_movie_subscribes(self):
"""
获取电影订阅统计数据
"""
# 电影订阅
movie_subscribes = self.subscribe.list_by_type(mtype='电影', days=self._movie_subscribe_days)
movie_subscribe_sites = []
movie_subscribe_datas = []
if movie_subscribes:
movie_subscribe_site_ids = []
for movie_subscribe in movie_subscribes:
if movie_subscribe.sites:
movie_subscribe_site_ids += [site for site in json.loads(movie_subscribe.sites)]
else:
movie_subscribe_site_ids += self.systemconfig.get(SystemConfigKey.RssSites) or []
for movie_subscribe_site_id in movie_subscribe_site_ids:
site = self.siteoper.get(movie_subscribe_site_id)
if site:
if not movie_subscribe_sites.__contains__(site.name):
movie_subscribe_sites.append(site.name)
movie_subscribe_datas.append(movie_subscribe_site_ids.count(movie_subscribe_site_id))
return movie_subscribes, movie_subscribe_sites, movie_subscribe_datas
def __get_tv_subscribes(self):
"""
获取电视剧订阅统计数据
"""
tv_subscribes = self.subscribe.list_by_type(mtype='电视剧', days=self._tv_subscribe_days)
tv_subscribe_sites = []
tv_subscribe_datas = []
if tv_subscribes:
tv_subscribe_site_ids = []
for tv_subscribe in tv_subscribes:
if tv_subscribe.sites:
tv_subscribe_site_ids += [site for site in json.loads(tv_subscribe.sites)]
else:
tv_subscribe_site_ids += self.systemconfig.get(SystemConfigKey.RssSites) or []
for tv_subscribe_site_id in tv_subscribe_site_ids:
site = self.siteoper.get(tv_subscribe_site_id)
if site:
if not tv_subscribe_sites.__contains__(site.name):
tv_subscribe_sites.append(site.name)
tv_subscribe_datas.append(tv_subscribe_site_ids.count(tv_subscribe_site_id))
return tv_subscribes, tv_subscribe_sites, tv_subscribe_datas
def __get_movie_downloads(self):
"""
获取电影下载统计数据
"""
movie_downloads = self.downloadhis.list_by_type(mtype="电影", days=self._movie_download_days)
movie_download_sites = []
movie_download_datas = []
if movie_downloads:
movie_download_sites2 = []
for movie_download in movie_downloads:
if movie_download.torrent_site:
movie_download_sites2.append(movie_download.torrent_site)
for movie_download_site in movie_download_sites2:
if not movie_download_sites.__contains__(movie_download_site):
movie_download_sites.append(movie_download_site)
if not movie_download_datas.__contains__(movie_download_site):
movie_download_datas.append(movie_download_sites2.count(movie_download_site))
return movie_downloads, movie_download_sites, movie_download_datas
def __get_tv_downloads(self):
"""
获取电视剧下载统计数据
"""
tv_downloads = self.downloadhis.list_by_type(mtype="电视剧", days=self._tv_download_days)
tv_download_sites = []
tv_download_datas = []
if tv_downloads:
tv_download_sites2 = []
for tv_download in tv_downloads:
if tv_download.torrent_site:
tv_download_sites2.append(tv_download.torrent_site)
for tv_download_site in tv_download_sites2:
if not tv_download_sites.__contains__(tv_download_site):
tv_download_sites.append(tv_download_site)
if not tv_download_datas.__contains__(tv_download_site):
tv_download_datas.append(tv_download_sites2.count(tv_download_site))
return tv_downloads, tv_download_sites, tv_download_datas
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
"""
拼装插件配置页面需要返回两块数据1、页面配置2、数据结构
"""
# 编历 NotificationType 枚举,生成消息类型选项
MsgTypeOptions = []
for item in NotificationType:
MsgTypeOptions.append({
"title": item.value,
"value": item.name
})
return [
{
'component': 'VForm',
@@ -87,38 +286,38 @@ class SubscribeStatistic(_PluginBase):
}
]
},
# {
# 'component': 'VCol',
# 'props': {
# 'cols': 12,
# 'md': 4
# },
# 'content': [
# {
# 'component': 'VSwitch',
# 'props': {
# 'model': 'notify',
# 'label': '发送通知',
# }
# }
# ]
# },
# {
# 'component': 'VCol',
# 'props': {
# 'cols': 12,
# 'md': 4
# },
# 'content': [
# {
# 'component': 'VSwitch',
# 'props': {
# 'model': 'onlyonce',
# 'label': '立即运行一次',
# }
# }
# ]
# }
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'notify',
'label': '发送通知',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'onlyonce',
'label': '立即运行一次',
}
}
]
}
]
},
{
@@ -194,6 +393,76 @@ class SubscribeStatistic(_PluginBase):
},
]
},
{
'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': 4
},
'content': [
{
'component': 'VSelect',
'props': {
'multiple': True,
'chips': True,
'model': 'notify_type',
'label': '推送类型',
'items': [
{'title': '电影订阅', 'value': 'movie_subscribes'},
{'title': '电视剧订阅', 'value': 'tv_subscribes'},
{'title': '电影下载', 'value': 'movie_downloads'},
{'title': '电视剧下载', 'value': 'tv_downloads'},
]
}
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4
},
'content': [
{
'component': 'VSelect',
'props': {
'multiple': False,
'chips': True,
'model': 'msgtype',
'label': '消息类型',
'items': MsgTypeOptions
}
}
]
}
]
},
]
},
{
'component': 'VRow',
'content': [
@@ -240,10 +509,15 @@ class SubscribeStatistic(_PluginBase):
}
], {
"enabled": False,
"notify": False,
"onlyonce": False,
"cron": "5 1 * * *",
"movie_subscribe_days": 30,
"tv_subscribe_days": 30,
"movie_download_days": 7,
"tv_download_days": 7
"tv_download_days": 7,
"notify_type": "",
"msgtype": ""
}
def get_page(self) -> List[dict]:
@@ -259,74 +533,16 @@ class SubscribeStatistic(_PluginBase):
]
# 电影订阅
movie_subscribes = self.subscribe.list_by_type(mtype='电影', days=self._movie_subscribe_days)
movie_subscribe_sites = []
movie_subscribe_datas = []
if movie_subscribes:
movie_subscribe_site_ids = []
for movie_subscribe in movie_subscribes:
if movie_subscribe.sites:
movie_subscribe_site_ids += [site for site in json.loads(movie_subscribe.sites)]
else:
movie_subscribe_site_ids += self.systemconfig.get(SystemConfigKey.RssSites) or []
for movie_subscribe_site_id in movie_subscribe_site_ids:
site = self.siteoper.get(movie_subscribe_site_id)
if site:
if not movie_subscribe_sites.__contains__(site.name):
movie_subscribe_sites.append(site.name)
movie_subscribe_datas.append(movie_subscribe_site_ids.count(movie_subscribe_site_id))
movie_subscribes, movie_subscribe_sites, movie_subscribe_datas = self.__get_movie_subscribes()
# 电视剧订阅
tv_subscribes = self.subscribe.list_by_type(mtype='电视剧', days=self._tv_subscribe_days)
tv_subscribe_sites = []
tv_subscribe_datas = []
if tv_subscribes:
tv_subscribe_site_ids = []
for tv_subscribe in tv_subscribes:
if tv_subscribe.sites:
tv_subscribe_site_ids += [site for site in json.loads(tv_subscribe.sites)]
else:
tv_subscribe_site_ids += self.systemconfig.get(SystemConfigKey.RssSites) or []
for tv_subscribe_site_id in tv_subscribe_site_ids:
site = self.siteoper.get(tv_subscribe_site_id)
if site:
if not tv_subscribe_sites.__contains__(site.name):
tv_subscribe_sites.append(site.name)
tv_subscribe_datas.append(tv_subscribe_site_ids.count(tv_subscribe_site_id))
tv_subscribes, tv_subscribe_sites, tv_subscribe_datas = self.__get_tv_subscribes()
# 电影下载
movie_downloads = self.downloadhis.list_by_type(mtype="电影", days=self._movie_download_days)
movie_download_sites = []
movie_download_datas = []
if movie_downloads:
movie_download_sites2 = []
for movie_download in movie_downloads:
if movie_download.torrent_site:
movie_download_sites2.append(movie_download.torrent_site)
for movie_download_site in movie_download_sites2:
if not movie_download_sites.__contains__(movie_download_site):
movie_download_sites.append(movie_download_site)
if not movie_download_datas.__contains__(movie_download_site):
movie_download_datas.append(movie_download_sites2.count(movie_download_site))
movie_downloads, movie_download_sites, movie_download_datas = self.__get_movie_downloads()
# 电视剧下载
tv_downloads = self.downloadhis.list_by_type(mtype="电视剧", days=self._tv_download_days)
tv_download_sites = []
tv_download_datas = []
if tv_downloads:
tv_download_sites2 = []
for tv_download in tv_downloads:
if tv_download.torrent_site:
tv_download_sites2.append(tv_download.torrent_site)
for tv_download_site in tv_download_sites2:
if not tv_download_sites.__contains__(tv_download_site):
tv_download_sites.append(tv_download_site)
if not tv_download_datas.__contains__(tv_download_site):
tv_download_datas.append(tv_download_sites2.count(tv_download_site))
tv_downloads, tv_download_sites, tv_download_datas = self.__get_tv_downloads()
# 拼装页面
return [