From 4877ec68b12ad9221c8032f5379875cba3e2565c Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 14 Oct 2024 19:45:22 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E4=B8=8B=E8=BD=BD=E6=8C=89?= =?UTF-8?q?=E7=AB=99=E7=82=B9=E4=B8=8A=E4=BC=A0=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/db/models/siteuserdata.py | 24 ++++++++++++++++++- app/db/site_oper.py | 13 +++++++---- app/helper/torrent.py | 44 ++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/app/db/models/siteuserdata.py b/app/db/models/siteuserdata.py index a407ddb8..6bd5364d 100644 --- a/app/db/models/siteuserdata.py +++ b/app/db/models/siteuserdata.py @@ -1,6 +1,6 @@ from datetime import datetime -from sqlalchemy import Column, Integer, String, Sequence, Float, JSON +from sqlalchemy import Column, Integer, String, Sequence, Float, JSON, func from sqlalchemy.orm import Session from app.db import db_query, Base @@ -68,3 +68,25 @@ class SiteUserData(Base): @db_query def get_by_date(db: Session, date: str): return db.query(SiteUserData).filter(SiteUserData.updated_day == date).all() + + @staticmethod + @db_query + def get_latest(db: Session): + """ + 获取各站点最新一天的数据 + """ + subquery = ( + db.query( + SiteUserData.domain, + func.max(SiteUserData.updated_day).label('latest_update_day') + ) + .group_by(SiteUserData.domain) + .subquery() + ) + + # 主查询:按 domain 和 updated_day 获取最新的记录 + return db.query(SiteUserData).join( + subquery, + (SiteUserData.domain == subquery.c.domain) & + (SiteUserData.updated_day == subquery.c.latest_update_day) + ).order_by(SiteUserData.updated_time.desc()).all() diff --git a/app/db/site_oper.py b/app/db/site_oper.py index 8a83acdd..4ea4066b 100644 --- a/app/db/site_oper.py +++ b/app/db/site_oper.py @@ -116,15 +116,14 @@ class SiteOper(DbOper): "updated_day": current_day, "updated_time": current_time }) - siteuserdata = SiteUserData.get_by_domain(self._db, domain=domain, - workdate=current_day, worktime=current_time) + # 按站点+天判断是否存在数据 + siteuserdata = SiteUserData.get_by_domain(self._db, domain=domain, workdate=current_day) if siteuserdata: # 存在则更新 SiteUserData.update(self._db, payload) else: # 不存在则插入 - for key, value in payload.items(): - SiteUserData(**payload).create(self._db) + SiteUserData(**payload).create(self._db) return True, "更新站点用户数据成功" def get_userdata(self) -> List[SiteUserData]: @@ -145,6 +144,12 @@ class SiteOper(DbOper): """ return SiteUserData.get_by_date(self._db, date) + def get_userdata_latest(self) -> List[SiteUserData]: + """ + 获取站点最新数据 + """ + return SiteUserData.get_latest(self._db) + def get_icon_by_domain(self, domain: str) -> SiteIcon: """ 按域名获取站点图标 diff --git a/app/helper/torrent.py b/app/helper/torrent.py index ffcef262..6e42a07f 100644 --- a/app/helper/torrent.py +++ b/app/helper/torrent.py @@ -10,6 +10,7 @@ from torrentool.api import Torrent from app.core.config import settings from app.core.context import Context, TorrentInfo, MediaInfo from app.core.metainfo import MetaInfo +from app.db.site_oper import SiteOper from app.db.systemconfig_oper import SystemConfigOper from app.log import logger from app.schemas.types import MediaType, SystemConfigKey @@ -28,6 +29,7 @@ class TorrentHelper(metaclass=Singleton): def __init__(self): self.system_config = SystemConfigOper() + self.site_oper = SiteOper() def download_torrent(self, url: str, cookie: str = None, @@ -196,14 +198,17 @@ class TorrentHelper(metaclass=Singleton): if not torrent_list: return [] - def get_sort_str(_context): + # 优先规则 + priority = self.system_config.get(SystemConfigKey.TorrentsPriority) + + def get_sort_str(_context, _sitedatas: Dict[str, float] = None): """ - 排序函数,值越大越优先 + 排序函数 """ _meta = _context.meta_info _torrent = _context.torrent_info _media = _context.media_info - # 站点优先级 + # 站点优先级,越大越优先 _site_order = 999 - (_torrent.site_order or 0) # 季数 _season_len = str(len(_meta.season_list)).rjust(2, '0') @@ -214,25 +219,42 @@ class TorrentHelper(metaclass=Singleton): else: # 集数越多的排越前面 _episode_len = str(len(_meta.episode_list)).rjust(4, '0') - # 优先规则 - priority = self.system_config.get(SystemConfigKey.TorrentsPriority) - if priority != "site": - # 排序:标题、资源类型、做种、季集 + if priority == "seeder": + # 做种数优先:标题、资源优先级、做种数、季集 return "%s%s%s%s" % (str(_media.title).ljust(100, ' '), str(_torrent.pri_order).rjust(3, '0'), str(_torrent.seeders).rjust(10, '0'), "%s%s" % (_season_len, _episode_len)) + elif priority == "upload": + # 站点上传量优先:标题、资源优先级、站点、季集 + # 上传量,越大越优先 + if not _sitedatas: + _site_upload = 0 + else: + _site_upload = _sitedatas.get(_torrent.site_name) or 0 + return "%s%s%s%s" % (str(_media.title).ljust(100, ' '), + str(_torrent.pri_order).rjust(3, '0'), + str(_site_upload).rjust(30, '0'), + "%s%s" % (_season_len, _episode_len)) else: - # 排序:标题、资源类型、站点、做种、季集 + # 站点优先:标题、资源优先级、站点、做种、季集 return "%s%s%s%s%s" % (str(_media.title).ljust(100, ' '), str(_torrent.pri_order).rjust(3, '0'), str(_site_order).rjust(3, '0'), str(_torrent.seeders).rjust(10, '0'), "%s%s" % (_season_len, _episode_len)) - # 匹配的资源中排序分组选最好的一个下载 - # 按站点顺序、资源匹配顺序、做种人数下载数逆序排序 - torrent_list = sorted(torrent_list, key=lambda x: get_sort_str(x), reverse=True) + # 获取站点数据 + if priority == "upload": + torrent_list = sorted(torrent_list, + key=lambda x: get_sort_str( + x, + { + site.name: site.upload for site in self.site_oper.get_userdata_latest() + } + ), reverse=True) + else: + torrent_list = sorted(torrent_list, key=lambda x: get_sort_str(x), reverse=True) return torrent_list