feat:订阅统计
This commit is contained in:
parent
73bdca282c
commit
dd5c0de7b1
@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
|
||||
from app import schemas
|
||||
from app.chain.subscribe import SubscribeChain
|
||||
from app.core.config import settings
|
||||
from app.core.context import MediaInfo
|
||||
from app.core.metainfo import MetaInfo
|
||||
from app.core.security import verify_token, verify_uri_token
|
||||
from app.db import get_db
|
||||
@ -14,6 +15,7 @@ from app.db.models.subscribe import Subscribe
|
||||
from app.db.models.subscribehistory import SubscribeHistory
|
||||
from app.db.models.user import User
|
||||
from app.db.userauth import get_current_active_user
|
||||
from app.helper.subscribe import SubscribeHelper
|
||||
from app.scheduler import Scheduler
|
||||
from app.schemas.types import MediaType
|
||||
|
||||
@ -334,6 +336,38 @@ def delete_subscribe(
|
||||
return schemas.Response(success=True)
|
||||
|
||||
|
||||
@router.get("/popular", summary="热门订阅(基于用户共享数据)", response_model=List[schemas.MediaInfo])
|
||||
def popular_subscribes(
|
||||
stype: str,
|
||||
page: int = 1,
|
||||
count: int = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询热门订阅
|
||||
"""
|
||||
subscribes = SubscribeHelper().get_statistic(stype=stype, page=page, count=count)
|
||||
if subscribes:
|
||||
ret_medias = []
|
||||
for sub in subscribes:
|
||||
media = MediaInfo()
|
||||
media.type = MediaType(sub.get("type"))
|
||||
media.title = sub.get("name")
|
||||
media.year = sub.get("year")
|
||||
media.tmdb_id = sub.get("tmdbid")
|
||||
media.douban_id = sub.get("doubanid")
|
||||
media.bangumi_id = sub.get("bangumiid")
|
||||
media.tvdb_id = sub.get("tvdbid")
|
||||
media.imdb_id = sub.get("imdbid")
|
||||
media.season = sub.get("season")
|
||||
media.overview = sub.get("description")
|
||||
media.vote_average = sub.get("vote")
|
||||
media.poster_path = sub.get("poster")
|
||||
media.backdrop_path = sub.get("backdrop")
|
||||
ret_medias.append(media)
|
||||
return [media.to_dict() for media in ret_medias]
|
||||
return []
|
||||
|
||||
|
||||
@router.get("/{subscribe_id}", summary="订阅详情", response_model=schemas.Subscribe)
|
||||
def read_subscribe(
|
||||
subscribe_id: int,
|
||||
|
@ -19,6 +19,7 @@ from app.db.subscribe_oper import SubscribeOper
|
||||
from app.db.subscribehistory_oper import SubscribeHistoryOper
|
||||
from app.db.systemconfig_oper import SystemConfigOper
|
||||
from app.helper.message import MessageHelper
|
||||
from app.helper.subscribe import SubscribeHelper
|
||||
from app.helper.torrent import TorrentHelper
|
||||
from app.log import logger
|
||||
from app.schemas import NotExistMediaInfo, Notification
|
||||
@ -36,6 +37,7 @@ class SubscribeChain(ChainBase):
|
||||
self.searchchain = SearchChain()
|
||||
self.subscribeoper = SubscribeOper()
|
||||
self.subscribehistoryoper = SubscribeHistoryOper()
|
||||
self.subscribehelper = SubscribeHelper()
|
||||
self.torrentschain = TorrentsChain()
|
||||
self.mediachain = MediaChain()
|
||||
self.message = MessageHelper()
|
||||
@ -122,6 +124,9 @@ class SubscribeChain(ChainBase):
|
||||
kwargs.update({
|
||||
'lack_episode': kwargs.get('total_episode')
|
||||
})
|
||||
else:
|
||||
# 避免season为0的问题
|
||||
season = None
|
||||
# 更新媒体图片
|
||||
self.obtain_images(mediainfo=mediainfo)
|
||||
# 合并信息
|
||||
@ -153,6 +158,7 @@ class SubscribeChain(ChainBase):
|
||||
text=f"{err_msg}",
|
||||
image=mediainfo.get_message_image(),
|
||||
userid=userid))
|
||||
return None, err_msg
|
||||
elif message:
|
||||
logger.info(f'{mediainfo.title_year} {metainfo.season} 添加订阅成功')
|
||||
if username:
|
||||
@ -164,12 +170,28 @@ class SubscribeChain(ChainBase):
|
||||
title=f"{mediainfo.title_year} {metainfo.season} 已添加订阅",
|
||||
text=text,
|
||||
image=mediainfo.get_message_image()))
|
||||
# 发送事件
|
||||
EventManager().send_event(EventType.SubscribeAdded, {
|
||||
"subscribe_id": sid,
|
||||
"username": username,
|
||||
"mediainfo": mediainfo.to_dict(),
|
||||
})
|
||||
# 发送事件
|
||||
EventManager().send_event(EventType.SubscribeAdded, {
|
||||
"subscribe_id": sid,
|
||||
"username": username,
|
||||
"mediainfo": mediainfo.to_dict(),
|
||||
})
|
||||
# 统计订阅
|
||||
self.subscribehelper.sub_reg_async({
|
||||
"name": title,
|
||||
"year": year,
|
||||
"type": metainfo.type.value,
|
||||
"tmdbid": mediainfo.tmdb_id,
|
||||
"imdbid": mediainfo.imdb_id,
|
||||
"tvdbid": mediainfo.tvdb_id,
|
||||
"doubanid": mediainfo.douban_id,
|
||||
"bangumiid": mediainfo.bangumi_id,
|
||||
"season": metainfo.begin_season,
|
||||
"poster": mediainfo.get_poster_image(),
|
||||
"backdrop": mediainfo.get_backdrop_image(),
|
||||
"vote": mediainfo.vote_average,
|
||||
"description": mediainfo.overview
|
||||
})
|
||||
# 返回结果
|
||||
return sid, ""
|
||||
|
||||
|
91
app/helper/subscribe.py
Normal file
91
app/helper/subscribe.py
Normal file
@ -0,0 +1,91 @@
|
||||
from threading import Thread
|
||||
from typing import List
|
||||
|
||||
from cachetools import TTLCache, cached
|
||||
|
||||
from app.db.subscribe_oper import SubscribeOper
|
||||
from app.db.systemconfig_oper import SystemConfigOper
|
||||
from app.schemas.types import SystemConfigKey
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.singleton import Singleton
|
||||
|
||||
|
||||
class SubscribeHelper(metaclass=Singleton):
|
||||
"""
|
||||
订阅数据统计
|
||||
"""
|
||||
|
||||
_sub_reg = "https://movie-pilot.org/subscribe/add"
|
||||
|
||||
_sub_report = "https://movie-pilot.org/subscribe/report"
|
||||
|
||||
_sub_statistic = "https://movie-pilot.org/subscribe/statistic"
|
||||
|
||||
def __init__(self):
|
||||
self.systemconfig = SystemConfigOper()
|
||||
if not self.systemconfig.get(SystemConfigKey.SubscribeReport):
|
||||
if self.sub_report():
|
||||
self.systemconfig.set(SystemConfigKey.SubscribeReport, "1")
|
||||
|
||||
@cached(cache=TTLCache(maxsize=10, ttl=1800))
|
||||
def get_statistic(self, stype: str, page: int = 1, count: int = 30) -> List[dict]:
|
||||
"""
|
||||
获取订阅统计数据
|
||||
"""
|
||||
res = RequestUtils(timeout=15).get_res(self._sub_statistic, params={
|
||||
"stype": stype,
|
||||
"page": page,
|
||||
"count": count
|
||||
})
|
||||
if res and res.status_code == 200:
|
||||
return res.json()
|
||||
return []
|
||||
|
||||
def sub_reg(self, sub: dict) -> bool:
|
||||
"""
|
||||
新增订阅统计
|
||||
"""
|
||||
res = RequestUtils(timeout=5, headers={
|
||||
"Content-Type": "application/json"
|
||||
}).post_res(self._sub_reg, json=sub)
|
||||
if res and res.status_code == 200:
|
||||
return True
|
||||
return False
|
||||
|
||||
def sub_reg_async(self, sub: dict) -> bool:
|
||||
"""
|
||||
异步新增订阅统计
|
||||
"""
|
||||
# 开新线程处理
|
||||
Thread(target=self.sub_reg, args=(sub,)).start()
|
||||
return True
|
||||
|
||||
def sub_report(self) -> bool:
|
||||
"""
|
||||
上报存量订阅统计
|
||||
"""
|
||||
subscribes = SubscribeOper().list()
|
||||
if not subscribes:
|
||||
return True
|
||||
res = RequestUtils(content_type="application/json",
|
||||
timeout=10).post(self._sub_report,
|
||||
json={
|
||||
"subscribes": [
|
||||
{
|
||||
"name": sub.name,
|
||||
"year": sub.year,
|
||||
"type": sub.type,
|
||||
"tmdbid": sub.tmdbid,
|
||||
"imdbid": sub.imdbid,
|
||||
"tvdbid": sub.tvdbid,
|
||||
"doubanid": sub.doubanid,
|
||||
"bangumiid": sub.bangumiid,
|
||||
"season": sub.season,
|
||||
"poster": sub.poster,
|
||||
"backdrop": sub.backdrop,
|
||||
"vote": sub.vote,
|
||||
"description": sub.description
|
||||
} for sub in subscribes
|
||||
]
|
||||
})
|
||||
return True if res else False
|
@ -82,6 +82,8 @@ class SystemConfigKey(Enum):
|
||||
TransferExcludeWords = "TransferExcludeWords"
|
||||
# 插件安装统计
|
||||
PluginInstallReport = "PluginInstallReport"
|
||||
# 订阅统计
|
||||
SubscribeReport = "SubscribeReport"
|
||||
|
||||
|
||||
# 处理进度Key字典
|
||||
|
Loading…
x
Reference in New Issue
Block a user