diff --git a/plugins.v2/brushflow/__init__.py b/plugins.v2/brushflow/__init__.py index 4e692c9..3103c87 100644 --- a/plugins.v2/brushflow/__init__.py +++ b/plugins.v2/brushflow/__init__.py @@ -54,6 +54,7 @@ class BrushConfig: self.exclude = config.get("exclude") self.size = config.get("size") self.seeder = config.get("seeder") + self.timezone_offset = (self.__parse_number(config.get("timezone_offset", "+0")) or 0) * 60 # 转换到分钟 self.pubtime = config.get("pubtime") self.seed_time = self.__parse_number(config.get("seed_time")) self.hr_seed_time = self.__parse_number(config.get("hr_seed_time")) @@ -72,6 +73,7 @@ class BrushConfig: self.except_subscribe = config.get("except_subscribe", True) self.brush_sequential = config.get("brush_sequential", False) self.proxy_delete = config.get("proxy_delete", False) + self.del_no_free = config.get("del_no_free", False) if self.freeleech in ["free", "2xfree"] else False self.active_time_range = config.get("active_time_range") self.cron = config.get("cron") self.qb_category = config.get("qb_category") @@ -107,6 +109,7 @@ class BrushConfig: "exclude", "size", "seeder", + "timezone_offset", "pubtime", "seed_time", "hr_seed_time", @@ -119,7 +122,8 @@ class BrushConfig: "proxy_delete", "qb_category", "site_hr_active", - "site_skip_tips" + "site_skip_tips", + "del_no_free" # 当新增支持字段时,仅在此处添加字段名 } try: @@ -173,6 +177,8 @@ class BrushConfig: "exclude": "", "size": "10-500", "seeder": "1", + // 用户本地时区与站点时区的时间偏移,单位为小时。例如:主机时区是UTC+8,站点时区是UTC,应配置为+8;主机时区是UTC,站点时区是UTC+8,应配置为-8 + "timezone_offset": "+0", "pubtime": "5-120", "seed_time": 120, "hr_seed_time": 144, @@ -183,6 +189,8 @@ class BrushConfig: "seed_inactivetime": "", "save_path": "/downloads/site1", "proxy_delete": false, + // 是否删除促销超时的未完成下载,仅当freeleech配置为free或2xfree时有效 + "del_no_free": false, "qb_category": "刷流", "site_hr_active": true, "site_skip_tips": true @@ -251,7 +259,7 @@ class BrushFlow(_PluginBase): # 插件图标 plugin_icon = "brush.jpg" # 插件版本 - plugin_version = "4.3.1" + plugin_version = "4.3.2" # 插件作者 plugin_author = "jxxghp,InfinityPacer" # 作者主页 @@ -1621,6 +1629,27 @@ class BrushFlow(_PluginBase): ] } ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 4 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'del_no_free', + 'label': '删除促销过期的未完成下载', + } + } + ] + } + ] } ] } @@ -1794,6 +1823,7 @@ class BrushFlow(_PluginBase): "except_subscribe": True, "brush_sequential": False, "proxy_delete": False, + "del_no_free": False, "freeleech": "free", "hr": "yes", "enable_site_config": False, @@ -2232,8 +2262,13 @@ class BrushFlow(_PluginBase): if not (seeders_range[0] <= torrent.seeders <= seeders_range[1]): return False, f"做种人数 {torrent.seeders},不在指定范围内" - # 发布时间 - pubdate_minutes = self.__get_pubminutes(torrent.pubdate) + # 发布时间:用户时间 - 站点时间 - 时区偏移 + # e.g.1: 用户UTC+8,站点UTC,timezone_offset应为+8,种子在UTC 0:00/UTC+8 8:00发布; + # 9:17 - 0:00 - 8:00 = 1:17;1小时17分为正确的发布时间与当前的时间差 + # e.g.2: 用户UTC,站点UTC+8,timezone_offset应为-8,种子在UTC 0:00/UTC+8 8:00发布: + # 1:17 - 8:00 - (-8:00) = 1:17;1小时17分为正确的发布时间与当前的时间差 + # timezone_offset为后加功能,默认为0,方便后续更多与时间相关的功能开发,之前在单独站点配置中使用pubtime计算过时区偏移的用户也不受影响 + pubdate_minutes = self.__get_pubminutes(torrent.pubdate) - brush_config.timezone_offset # 已支持独立站点配置,取消单独适配站点时区逻辑,可通过配置项「pubtime」自行适配 # pubdate_minutes = self.__adjust_site_pubminutes(pubdate_minutes, torrent) if brush_config.pubtime: @@ -2241,11 +2276,11 @@ class BrushFlow(_PluginBase): if len(pubtimes) == 1: # 单个值:选择发布时间小于等于该值的种子 if pubdate_minutes > pubtimes[0]: - return False, f"发布时间 {torrent.pubdate},{pubdate_minutes:.0f} 分钟前,不符合条件" + return False, f"发布时间(站点时区){torrent.pubdate},当前配置时区偏移 {brush_config.timezone_offset} 小时,{pubdate_minutes:.0f} 分钟前,不符合条件" else: # 范围值:选择发布时间在范围内的种子 if not (pubtimes[0] <= pubdate_minutes <= pubtimes[1]): - return False, f"发布时间 {torrent.pubdate},{pubdate_minutes:.0f} 分钟前,不在指定范围内" + return False, f"发布时间(站点时区){torrent.pubdate},当前配置时区偏移 {brush_config.timezone_offset} 小时,{pubdate_minutes:.0f} 分钟前,不在指定范围内" return True, None @@ -2528,13 +2563,38 @@ class BrushFlow(_PluginBase): 评估动态删除前置条件并返回是否应删除种子及其原因 """ brush_config = self.__get_brush_config(sitename=site_name) + torrent = (self.get_data("torrents") or {}).get(torrent_info.get("hash", ""), None) + should_delete = False reason = "未能满足动态删除设置的前置删除条件" + if not torrent: + logger.debug(f"未获取到种子 {torrent_info.get("hash", "?")} 的任务信息。") + + while torrent and brush_config.del_no_free: + if not torrent.get("freedate", None): + logger.warning(f"配置了‘删除促销过期的未完成下载’,但未获取到该种子的促销截止时间,跳过。") + break + try: + now = datetime.now() + freedate_origin = torrent.get("freedate") + freedate = freedate_origin.replace("T", " ").replace("Z", "") + freedate = datetime.strptime(freedate, "%Y-%m-%d %H:%M:%S") + delta_minutes = (((now - freedate).total_seconds() + 60) // 60) - brush_config.timezone_offset + logger.debug(f"促销截止(站点时间): {freedate_origin}, 时区偏移: {brush_config.timezone_offset}, 用户当前时间: {now.strftime('%Y-%m-%d %H:%M:%S')}, 时间差: {delta_minutes}分") + if delta_minutes <= 0: + should_delete = True + reason = f"促销已过期。" + except Exception as e: + logger.warning(f"处理‘删除促销过期的未完成下载’时报错,继续判断其他删除条件。") + logger.debug(f"error: {e}") + finally: + break + if brush_config.download_time and torrent_info.get("downloaded") < torrent_info.get( "total_size") and torrent_info.get("dltime") >= float(brush_config.download_time) * 3600: reason = f"下载耗时 {torrent_info.get('dltime') / 3600:.1f} 小时,大于 {brush_config.download_time} 小时" - else: + elif not should_delete: return False, reason return True, reason