mirror of
https://github.com/d0zingcat/MoviePilot-Plugins.git
synced 2026-05-13 23:16:47 +00:00
fix brushflow 增加H&R做种时间、下载器监控配置项,刷流前置条件逻辑调整,代理下载种子默认为关闭
This commit is contained in:
@@ -226,7 +226,7 @@
|
||||
"BrushFlow": {
|
||||
"name": "站点刷流",
|
||||
"description": "自动托管刷流,将会提高对应站点的访问频率。",
|
||||
"version": "2.4",
|
||||
"version": "2.5",
|
||||
"icon": "brush.jpg",
|
||||
"author": "jxxghp,InfinityPacer",
|
||||
"level": 2
|
||||
|
||||
@@ -51,6 +51,7 @@ class BrushConfig:
|
||||
self.seeder = config.get("seeder")
|
||||
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"))
|
||||
self.seed_ratio = self.__parse_number(config.get("seed_ratio"))
|
||||
self.seed_size = self.__parse_number(config.get("seed_size"))
|
||||
self.download_time = self.__parse_number(config.get("download_time"))
|
||||
@@ -65,12 +66,15 @@ class BrushConfig:
|
||||
self.except_tags = config.get("except_tags", True)
|
||||
self.except_subscribe = config.get("except_subscribe", True)
|
||||
self.brush_sequential = config.get("brush_sequential", False)
|
||||
self.proxy_download = config.get("proxy_download", True)
|
||||
self.proxy_download = config.get("proxy_download", False)
|
||||
self.proxy_delete = config.get("proxy_delete", False)
|
||||
self.log_more = config.get("log_more", False)
|
||||
self.active_time_range = config.get("active_time_range")
|
||||
self.enable_site_config = config.get("enable_site_config", False)
|
||||
self.downloader_monitor = config.get("downloader_monitor")
|
||||
|
||||
self.brush_tag = "刷流"
|
||||
# 站点独立配置
|
||||
self.enable_site_config = config.get("enable_site_config", False)
|
||||
self.site_config = config.get("site_config", "[]")
|
||||
self.group_site_configs = {}
|
||||
|
||||
@@ -91,6 +95,7 @@ class BrushConfig:
|
||||
"seeder",
|
||||
"pubtime",
|
||||
"seed_time",
|
||||
"hr_seed_time",
|
||||
"seed_ratio",
|
||||
"seed_size",
|
||||
"download_time",
|
||||
@@ -185,7 +190,7 @@ class BrushFlow(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "brush.jpg"
|
||||
# 插件版本
|
||||
plugin_version = "2.4"
|
||||
plugin_version = "2.5"
|
||||
# 插件作者
|
||||
plugin_author = "jxxghp,InfinityPacer"
|
||||
# 作者主页
|
||||
@@ -701,6 +706,23 @@ class BrushFlow(_PluginBase):
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
"cols": 12,
|
||||
"md": 4
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VTextField',
|
||||
'props': {
|
||||
'model': 'hr_seed_time',
|
||||
'label': 'H&R做种时间(小时)',
|
||||
'placeholder': '达到后删除任务'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
@@ -1042,6 +1064,22 @@ class BrushFlow(_PluginBase):
|
||||
{
|
||||
'component': 'VRow',
|
||||
"content": [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
'md': 4
|
||||
},
|
||||
'content': [
|
||||
{
|
||||
'component': 'VSwitch',
|
||||
'props': {
|
||||
'model': 'downloader_monitor',
|
||||
'label': '下载器监控',
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
@@ -1182,12 +1220,13 @@ class BrushFlow(_PluginBase):
|
||||
"except_tags": True,
|
||||
"except_subscribe": True,
|
||||
"brush_sequential": False,
|
||||
"proxy_download": True,
|
||||
"proxy_download": False,
|
||||
"proxy_delete": False,
|
||||
"freeleech": "free",
|
||||
"hr": "yes",
|
||||
"enable_site_config": False,
|
||||
"log_more": False
|
||||
"log_more": False,
|
||||
"downloader_monitor": False,
|
||||
}
|
||||
|
||||
def get_page(self) -> List[dict]:
|
||||
@@ -1781,7 +1820,7 @@ class BrushFlow(_PluginBase):
|
||||
|
||||
# 判断能否通过保种体积刷流条件
|
||||
size_condition_passed, reason = self.__evaluate_size_condition_for_brush(torrents_size=torrents_size,
|
||||
brush_torrent_size=torrent.size)
|
||||
add_torrent_size=torrent.size)
|
||||
self.__log_brush_conditions(passed=size_condition_passed, reason=reason, torrent=torrent)
|
||||
if not size_condition_passed:
|
||||
continue
|
||||
@@ -1844,26 +1883,42 @@ class BrushFlow(_PluginBase):
|
||||
return True
|
||||
|
||||
def __evaluate_size_condition_for_brush(self, torrents_size: float,
|
||||
brush_torrent_size: float = 0.0) -> Tuple[bool, Optional[str]]:
|
||||
add_torrent_size: float = 0.0) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
过滤体积不符合条件的种子
|
||||
"""
|
||||
total_size = self.__bytes_to_gb(torrents_size + brush_torrent_size) # 预计总做种体积
|
||||
brush_config = self.__get_brush_config()
|
||||
|
||||
# 如果没有明确指定增加的种子大小,则检查配置中是否有种子大小下限,如果有,使用这个大小作为增加的种子大小
|
||||
preset_condition = False
|
||||
if not add_torrent_size and brush_config.size:
|
||||
size_limits = [float(size) * 1024 ** 3 for size in brush_config.size.split("-")]
|
||||
add_torrent_size = size_limits[0] # 使用配置的种子大小下限
|
||||
preset_condition = True
|
||||
|
||||
total_size = self.__bytes_to_gb(torrents_size + add_torrent_size) # 预计总做种体积
|
||||
|
||||
def generate_message(config):
|
||||
if brush_torrent_size > 0:
|
||||
return (f"当前做种体积 {self.__bytes_to_gb(torrents_size):.1f} GB,"
|
||||
f"刷流种子 {self.__bytes_to_gb(brush_torrent_size):.1f} GB,"
|
||||
f"预计做种体积 {total_size:.1f} GB,已超过做种体积 {config} GB")
|
||||
if add_torrent_size:
|
||||
if preset_condition:
|
||||
return (f"当前做种体积 {self.__bytes_to_gb(torrents_size):.1f} GB,"
|
||||
f"刷流种子下限 {self.__bytes_to_gb(add_torrent_size):.1f} GB,"
|
||||
f"预计做种体积 {total_size:.1f} GB,"
|
||||
f"超过设定的保种体积 {config} GB,暂时停止新增任务")
|
||||
else:
|
||||
return (f"当前做种体积 {self.__bytes_to_gb(torrents_size):.1f} GB,"
|
||||
f"刷流种子大小 {self.__bytes_to_gb(add_torrent_size):.1f} GB,"
|
||||
f"预计做种体积 {total_size:.1f} GB,"
|
||||
f"超过设定的保种体积 {config} GB")
|
||||
else:
|
||||
return f"当前做种体积 {self.__bytes_to_gb(torrents_size):.1f} GB,已超过做种体积 {config} GB,暂时停止新增任务"
|
||||
return (f"当前做种体积 {self.__bytes_to_gb(torrents_size):.1f} GB,"
|
||||
f"超过设定的保种体积 {config} GB,暂时停止新增任务")
|
||||
|
||||
reasons = [
|
||||
("disksize",
|
||||
lambda config: torrents_size + brush_torrent_size > float(config) * 1024 ** 3, generate_message)
|
||||
lambda config: torrents_size + add_torrent_size > float(config) * 1024 ** 3, generate_message)
|
||||
]
|
||||
|
||||
brush_config = self.__get_brush_config()
|
||||
for condition, check, message in reasons:
|
||||
config_value = getattr(brush_config, condition, None)
|
||||
if config_value and check(config_value):
|
||||
@@ -2021,6 +2076,7 @@ class BrushFlow(_PluginBase):
|
||||
|
||||
seeding_torrents_dict = {self.__get_hash(torrent): torrent for torrent in seeding_torrents}
|
||||
|
||||
# 检查种子刷流标签变更情况
|
||||
self.__update_seeding_tasks_based_on_tags(torrent_tasks=torrent_tasks, unmanaged_tasks=unmanaged_tasks,
|
||||
seeding_torrents_dict=seeding_torrents_dict)
|
||||
|
||||
@@ -2096,7 +2152,14 @@ class BrushFlow(_PluginBase):
|
||||
seeding_torrents_dict: Dict[str, Any]):
|
||||
brush_config = self.__get_brush_config()
|
||||
|
||||
if brush_config.downloader_monitor:
|
||||
logger.info("已开启下载器监控,开始同步种子刷流标签记录")
|
||||
else:
|
||||
logger.info("没有开启下载器监控,取消同步种子刷流标签记录")
|
||||
return
|
||||
|
||||
if not brush_config.downloader == "qbittorrent":
|
||||
logger.info("同步种子刷流标签记录目前仅支持qbittorrent")
|
||||
return
|
||||
|
||||
# 初始化汇总信息
|
||||
@@ -2116,15 +2179,15 @@ class BrushFlow(_PluginBase):
|
||||
torrent_task = unmanaged_tasks.pop(torrent_hash)
|
||||
torrent_tasks[torrent_hash] = torrent_task
|
||||
added_tasks.append(torrent_task)
|
||||
logger.info(
|
||||
f"站点 {torrent_task.get('site_name')},刷流任务种子再次加入:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
logger.info(f"站点 {torrent_task.get('site_name')},"
|
||||
f"刷流任务种子再次加入:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
else:
|
||||
# 否则,创建一个新的任务
|
||||
torrent_task = self.__convert_torrent_info_to_task(torrent)
|
||||
torrent_tasks[torrent_hash] = torrent_task
|
||||
added_tasks.append(torrent_task)
|
||||
logger.info(
|
||||
f"站点 {torrent_task.get('site_name')},刷流任务种子加入:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
logger.info(f"站点 {torrent_task.get('site_name')},"
|
||||
f"刷流任务种子加入:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
# 包含刷流标签又在刷流任务中,这里额外处理一个特殊逻辑,就是种子在刷流任务中可能被标记删除但实际上又还在下载器中,这里进行重置
|
||||
else:
|
||||
torrent_task = torrent_tasks[torrent_hash]
|
||||
@@ -2132,7 +2195,8 @@ class BrushFlow(_PluginBase):
|
||||
torrent_task["deleted"] = False
|
||||
reset_tasks.append(torrent_task)
|
||||
logger.info(
|
||||
f"站点 {torrent_task.get('site_name')},在下载器中找到已标记删除的刷流任务对应的种子信息,更新刷流任务状态为正常:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
f"站点 {torrent_task.get('site_name')},在下载器中找到已标记删除的刷流任务对应的种子信息,"
|
||||
f"更新刷流任务状态为正常:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
else:
|
||||
# 不包含刷流标签但又在刷流任务中,则移除管理
|
||||
if torrent_hash in torrent_tasks:
|
||||
@@ -2140,8 +2204,8 @@ class BrushFlow(_PluginBase):
|
||||
torrent_task = torrent_tasks.pop(torrent_hash)
|
||||
unmanaged_tasks[torrent_hash] = torrent_task
|
||||
removed_tasks.append(torrent_task)
|
||||
logger.info(
|
||||
f"站点 {torrent_task.get('site_name')},刷流任务种子移除:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
logger.info(f"站点 {torrent_task.get('site_name')},"
|
||||
f"刷流任务种子移除:{torrent_task.get('title')}|{torrent_task.get('description')}")
|
||||
|
||||
self.save_data("torrents", torrent_tasks)
|
||||
self.save_data("unmanaged", unmanaged_tasks)
|
||||
@@ -2183,12 +2247,30 @@ class BrushFlow(_PluginBase):
|
||||
|
||||
return proxy_delete_torrents, not_proxy_delete_torrents
|
||||
|
||||
def __evaluate_conditions_for_delete(self, site_name: str, torrent_info: dict) -> Tuple[bool, str]:
|
||||
def __evaluate_conditions_for_delete(self, site_name: str, torrent_info: dict, torrent_task: dict) \
|
||||
-> Tuple[bool, str]:
|
||||
"""
|
||||
评估删除条件并返回是否应删除种子及其原因
|
||||
"""
|
||||
brush_config = self.__get_brush_config(sitename=site_name)
|
||||
|
||||
reason = "未能满足设置的删除条件"
|
||||
|
||||
# 当配置了H&R做种时间/分享率时,则H&R种子只有达到预期行为时,才会进行删除,如果没有配置H&R做种时间/分享率,则普通种子的删除规则也适用于H&R种子
|
||||
# 判断是否为H&R种子并且是否配置了特定的H&R条件
|
||||
hit_and_run = torrent_task.get("hit_and_run", False)
|
||||
hr_specific_conditions_configured = hit_and_run and (brush_config.hr_seed_time or brush_config.seed_ratio)
|
||||
if hr_specific_conditions_configured:
|
||||
if (brush_config.hr_seed_time and torrent_info.get("seeding_time")
|
||||
>= float(brush_config.hr_seed_time) * 3600):
|
||||
return True, (f"H&R种子,做种时间 {torrent_info.get('seeding_time') / 3600:.1f} 小时,"
|
||||
f"大于 {brush_config.hr_seed_time} 小时")
|
||||
if brush_config.seed_ratio and torrent_info.get("ratio") >= float(brush_config.seed_ratio):
|
||||
return True, f"H&R种子,分享率 {torrent_info.get('ratio'):.2f},大于 {brush_config.seed_ratio}"
|
||||
return False, "H&R种子,未能满足设置的H&R删除条件"
|
||||
|
||||
# 处理其他场景,1. 不是H&R种子;2. 是H&R种子但没有特定条件配置
|
||||
reason = reason if not hit_and_run else "H&R种子(未设置H&R条件),未能满足设置的删除条件"
|
||||
if brush_config.seed_time and torrent_info.get("seeding_time") >= float(brush_config.seed_time) * 3600:
|
||||
reason = f"做种时间 {torrent_info.get('seeding_time') / 3600:.1f} 小时,大于 {brush_config.seed_time} 小时"
|
||||
elif brush_config.seed_ratio and torrent_info.get("ratio") >= float(brush_config.seed_ratio):
|
||||
@@ -2205,15 +2287,16 @@ class BrushFlow(_PluginBase):
|
||||
brush_config.seed_inactivetime) * 60:
|
||||
reason = f"未活动时间 {torrent_info.get('iatime') / 60:.0f} 分钟,大于 {brush_config.seed_inactivetime} 分钟"
|
||||
else:
|
||||
return False, ""
|
||||
return False, reason
|
||||
|
||||
return True, reason
|
||||
return True, reason if not hit_and_run else "H&R种子(未设置H&R条件)," + reason
|
||||
|
||||
def __delete_torrent_for_evaluate_conditions(self, torrents: List[Any], torrent_tasks: Dict[str, dict],
|
||||
proxy_delete: bool = False) -> List:
|
||||
"""
|
||||
根据条件删除种子并获取已删除列表
|
||||
"""
|
||||
brush_config = self.__get_brush_config()
|
||||
delete_hashs = []
|
||||
|
||||
for torrent in torrents:
|
||||
@@ -2230,13 +2313,17 @@ class BrushFlow(_PluginBase):
|
||||
|
||||
# 删除种子的具体实现可能会根据实际情况略有不同
|
||||
should_delete, reason = self.__evaluate_conditions_for_delete(site_name=site_name,
|
||||
torrent_info=torrent_info)
|
||||
torrent_info=torrent_info,
|
||||
torrent_task=torrent_task)
|
||||
if should_delete:
|
||||
delete_hashs.append(torrent_hash)
|
||||
reason = "触发动态删除," + reason if proxy_delete else reason
|
||||
self.__send_delete_message(site_name=site_name, torrent_title=torrent_title, torrent_desc=torrent_desc,
|
||||
reason=reason)
|
||||
logger.info(f"站点:{site_name},{reason},删除种子:{torrent_title}|{torrent_desc}")
|
||||
else:
|
||||
if brush_config.log_more:
|
||||
logger.info(f"站点:{site_name},{reason},不删除种子:{torrent_title}|{torrent_desc}")
|
||||
|
||||
return delete_hashs
|
||||
|
||||
@@ -2266,11 +2353,13 @@ class BrushFlow(_PluginBase):
|
||||
# 当总体积未超过最大阈值时,不需要执行删除操作
|
||||
if total_torrent_size < max_size:
|
||||
logger.info(
|
||||
f"当前做种体积 {self.__bytes_to_gb(total_torrent_size):.1f} GB,上限 {self.__bytes_to_gb(max_size):.1f} GB,下限 {self.__bytes_to_gb(min_size):.1f} GB,未触发动态删除")
|
||||
f"当前做种体积 {self.__bytes_to_gb(total_torrent_size):.1f} GB,上限 {self.__bytes_to_gb(max_size):.1f} GB,"
|
||||
f"下限 {self.__bytes_to_gb(min_size):.1f} GB,未触发动态删除")
|
||||
return []
|
||||
else:
|
||||
logger.info(
|
||||
f"当前做种体积 {self.__bytes_to_gb(total_torrent_size):.1f} GB,上限 {self.__bytes_to_gb(max_size):.1f} GB,下限 {self.__bytes_to_gb(min_size):.1f} GB,触发动态删除")
|
||||
f"当前做种体积 {self.__bytes_to_gb(total_torrent_size):.1f} GB,上限 {self.__bytes_to_gb(max_size):.1f} GB,"
|
||||
f"下限 {self.__bytes_to_gb(min_size):.1f} GB,触发动态删除")
|
||||
|
||||
need_delete_hashes = []
|
||||
|
||||
@@ -2337,7 +2426,8 @@ class BrushFlow(_PluginBase):
|
||||
reason=reason)
|
||||
logger.info(f"站点:{site_name},{reason},删除种子:{torrent_title}|{torrent_desc}")
|
||||
|
||||
msg = f"站点:{','.join(sites_names)}\n内容:已完成 {len(need_delete_hashes)} 个种子删除,当前做种体积 {self.__bytes_to_gb(total_torrent_size):.1f} GB\n原因:触发动态删除"
|
||||
msg = (f"站点:{','.join(sites_names)}\n内容:已完成 {len(need_delete_hashes)} 个种子删除,"
|
||||
f"当前做种体积 {self.__bytes_to_gb(total_torrent_size):.1f} GB\n原因:触发动态删除")
|
||||
logger.info(msg)
|
||||
self.__send_message(title="【刷流任务状态更新】", text=msg)
|
||||
|
||||
@@ -2348,6 +2438,14 @@ class BrushFlow(_PluginBase):
|
||||
"""
|
||||
处理已经被删除,但是任务记录中还没有被标记删除的种子
|
||||
"""
|
||||
brush_config = self.__get_brush_config()
|
||||
|
||||
if brush_config.downloader_monitor:
|
||||
logger.info("已开启下载器监控,开始同步刷流任务删除记录")
|
||||
else:
|
||||
logger.info("没有开启下载器监控,取消同步刷流任务删除记录")
|
||||
return
|
||||
|
||||
# 先通过获取的全量种子,判断已经被删除,但是任务记录中还没有被标记删除的种子
|
||||
torrent_all_hashes = self.__get_all_hashes(torrents)
|
||||
missing_hashes = [hash_value for hash_value in torrent_check_hashes if hash_value not in torrent_all_hashes]
|
||||
@@ -2481,6 +2579,7 @@ class BrushFlow(_PluginBase):
|
||||
"maxdlspeed": "总下载带宽",
|
||||
"maxdlcount": "同时下载任务数",
|
||||
"seed_time": "做种时间",
|
||||
"hr_seed_time": "H&R做种时间",
|
||||
"seed_ratio": "分享率",
|
||||
"seed_size": "上传量",
|
||||
"download_time": "下载超时时间",
|
||||
@@ -2550,6 +2649,7 @@ class BrushFlow(_PluginBase):
|
||||
"seeder": brush_config.seeder,
|
||||
"pubtime": brush_config.pubtime,
|
||||
"seed_time": brush_config.seed_time,
|
||||
"hr_seed_time": brush_config.hr_seed_time,
|
||||
"seed_ratio": brush_config.seed_ratio,
|
||||
"seed_size": brush_config.seed_size,
|
||||
"download_time": brush_config.download_time,
|
||||
@@ -2568,6 +2668,7 @@ class BrushFlow(_PluginBase):
|
||||
"proxy_delete": brush_config.proxy_delete,
|
||||
"log_more": brush_config.log_more,
|
||||
"active_time_range": brush_config.active_time_range,
|
||||
"downloader_monitor": brush_config.downloader_monitor,
|
||||
"enable_site_config": brush_config.enable_site_config,
|
||||
"site_config": brush_config.site_config
|
||||
}
|
||||
@@ -3301,23 +3402,39 @@ class BrushFlow(_PluginBase):
|
||||
"https://github.com/InfinityPacer/MoviePilot-Plugins/blob/main/README.md "
|
||||
"进行配置,请注意,只需要保留实际配置内容(删除这段)\n")
|
||||
config = """[{
|
||||
"sitename": "测试站点",
|
||||
"freeleech": "free",
|
||||
"hr": "no",
|
||||
"include": "",
|
||||
"exclude": "",
|
||||
"size": "10-500",
|
||||
"seeder": "1",
|
||||
"pubtime": "5-120",
|
||||
"seed_time": 120,
|
||||
"seed_ratio": "",
|
||||
"seed_size": "",
|
||||
"download_time": "",
|
||||
"seed_avgspeed": "",
|
||||
"seed_inactivetime": "",
|
||||
"save_path": "/downloads/site1",
|
||||
"proxy_download": false
|
||||
}]"""
|
||||
"sitename": "站点1",
|
||||
"seed_time": 96,
|
||||
"hr_seed_time": 144
|
||||
}, {
|
||||
"sitename": "站点2",
|
||||
"hr": "yes",
|
||||
"size": "10-500",
|
||||
"seeder": "5-10",
|
||||
"pubtime": "5-120",
|
||||
"seed_time": 96,
|
||||
"save_path": "/downloads/site2",
|
||||
"proxy_download": true,
|
||||
"hr_seed_time": 144
|
||||
}, {
|
||||
"sitename": "站点3",
|
||||
"freeleech": "free",
|
||||
"hr": "yes",
|
||||
"include": "",
|
||||
"exclude": "",
|
||||
"size": "10-500",
|
||||
"seeder": "1",
|
||||
"pubtime": "5-120",
|
||||
"seed_time": 120,
|
||||
"hr_seed_time": 144,
|
||||
"seed_ratio": "",
|
||||
"seed_size": "",
|
||||
"download_time": "",
|
||||
"seed_avgspeed": "",
|
||||
"seed_inactivetime": "",
|
||||
"save_path": "/downloads/site1",
|
||||
"proxy_download": false,
|
||||
"proxy_delete": false,
|
||||
}]"""
|
||||
return desc + config
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user