mirror of
https://github.com/d0zingcat/MoviePilot-Plugins.git
synced 2026-05-13 15:09:12 +00:00
新增【下载器助手】插件
This commit is contained in:
BIN
icons/DownloaderHelper.png
Normal file
BIN
icons/DownloaderHelper.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
@@ -446,5 +446,13 @@
|
||||
"icon": "contract.png",
|
||||
"author": "DzAvril",
|
||||
"level": 1
|
||||
},
|
||||
"DownloaderHelper": {
|
||||
"name": "下载器助手",
|
||||
"description": "自动做种、站点标签、自动删种。",
|
||||
"version": "1.0",
|
||||
"icon": "DownloaderHelper.png",
|
||||
"author": "hotlcc",
|
||||
"level": 2
|
||||
}
|
||||
}
|
||||
|
||||
59
plugins/downloaderhelper/README.md
Normal file
59
plugins/downloaderhelper/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
## 下载器助手:一个解放双手的插件
|
||||
|
||||
### 1、简介
|
||||
|
||||
作者:hotlcc
|
||||
|
||||
主页:[Github](https://github.com/hotlcc) | [Gitee](https://gitee.com/hotlcc)
|
||||
|
||||
#### 1.1、功能说明
|
||||
|
||||
**三大功能**:
|
||||
|
||||
1. **自动做种**:通常在通过IYUU等工具辅种后,下载器中种子校验完毕但不会立即变成做种状态,可以通过本插件定时扫描下载器中“已完成但未做种”的种子并设为做种状态。
|
||||
1. **站点标签**:如果下载器中种子很多,要想统计各站点的种子数量变得麻烦,可以通过本插件定时(或者通过监听下载添加事件)给种子添加站点标签。
|
||||
1. **自动删种**:定时删除丢失文件的错误种子,或者通过监听源文件删除事件匹配对应的种子自动删除。
|
||||
|
||||
**三条执行路线**:
|
||||
|
||||
1. **定时执行**:通过配置【定时执行周期】实现后台定时执行。
|
||||
1. **事件驱动执行**:通过开启相关监听实现事件驱动执行。
|
||||
1. **手动执行**:通过【即运行一次】或者【设定/服务/执行】手动执行。
|
||||
|
||||
#### 1.2、移植说明
|
||||
|
||||
本插件由本人从原 NAStool 版本【[下载器助手](https://gitee.com/hotlcc/nastool-plugin/tree/master/downloader-helper)】移植而来,功能只增不减。
|
||||
|
||||
插件移植后未花太多心思测试,目前仅测试了 qBittorrent,理论上 Transmission 也不会有太大问题,但由于 MoviePilot 插件机制较原 NAStool 有很大升级,因而不排除存在潜在BUG,望使用者海涵,有问题提 Issues 即可!
|
||||
|
||||
### 2、使用说明
|
||||
|
||||
#### 2.1、配置项说明
|
||||
|
||||
##### 2.1.1、主配置项
|
||||
|
||||
|配置项|说明|
|
||||
|---|---|
|
||||
|启用插件|插件后台任务的总开关,这里的“后台任务”指的是“定时任务”和“事件触发任务”,不会影响【立即运行一次】的执行。|
|
||||
|发送通知|任务执行成功后是否发送通知消息。|
|
||||
|立即运行一次|保存配置后立即运行一次,不受【启用插件】的管控。|
|
||||
|监听下载事件|监听到下载添加事件后会触发插件给添加的种子打站点标签。|
|
||||
|监听源文件事件|监听到源文件删除事件后会触发插件根据文件路径判断该源文件对应的种子下的全部数据文件是否都已删除,若全部数据文件都已删除就删除种子,如果有辅种也会一并删除,同时支持单文件种子、多文件(剧集、原盘)种子。|
|
||||
|站点名称优先|表示在打站点标签时是否优先以站点名称作为标签,否则会以“域名关键字”作为标签;“域名关键字”指的是二级域名段。|
|
||||
|定时执行周期|插件定时服务的cron表达式,仅支持5位的,缺省时不注册定时服务。|
|
||||
|排除种子标签|多个标签通过英文逗号分割,具备配置的任意标签的种子不会进行自动做种、站点标签、自动删种操作。|
|
||||
|站点标签前缀|站点标签的前缀,缺省时不添加前缀。|
|
||||
|Tracker映射|站点标签的原理是根据tracker的域名去匹配站点,但是有的PT站的tracker域名和站点域名不一致,导致匹配不到站点,因此需要对这些特殊站点的tracker做映射;每行一个映射,格式是 `tracker域名:站点域名`,tracker域名至少需要配置二级,站点域名只能配置二级。|
|
||||
|
||||
##### 2.1.2、下载器子任务配置项
|
||||
|
||||
|配置项|说明|
|
||||
|---|---|
|
||||
|任务开关|该下载器子任务的总开关。|
|
||||
|自动做种|是否启用自动做种功能,启用后还需要配合【定时周期】才可以在后台定时执行。|
|
||||
|站点标签|是否启用站点标签功能,启用后还需要配合【定时周期】或者【监听下载事件】才可以在后台定时或者事件驱动执行。|
|
||||
|自动删种|是否启用自动删种功能,启用后还需要配合【定时周期】或者【监听源文件事件】才可以在后台定时或者事件驱动执行。|
|
||||
|
||||
#### 2.2、Q&A
|
||||
|
||||
(待补充)
|
||||
1543
plugins/downloaderhelper/__init__.py
Normal file
1543
plugins/downloaderhelper/__init__.py
Normal file
File diff suppressed because it is too large
Load Diff
258
plugins/downloaderhelper/module.py
Normal file
258
plugins/downloaderhelper/module.py
Normal file
@@ -0,0 +1,258 @@
|
||||
from typing import Set, List
|
||||
|
||||
class Constants():
|
||||
"""
|
||||
常量
|
||||
"""
|
||||
# 下载器ID
|
||||
# qb下载器id
|
||||
qb_downloader_id: str = 'qbittorrent'
|
||||
# tr下载器id
|
||||
tr_downloader_id: str = 'transmission'
|
||||
|
||||
class TaskResult():
|
||||
"""
|
||||
任务执行结果
|
||||
"""
|
||||
def __init__(self, name: str):
|
||||
self.__name: str = name
|
||||
self.__success: bool = True
|
||||
self.__total: int = 0
|
||||
self.__seeding: int = 0
|
||||
self.__tagging: int = 0
|
||||
self.__delete: int = 0
|
||||
|
||||
def get_name(self) -> str:
|
||||
return self.__name
|
||||
|
||||
def set_success(self, success: bool):
|
||||
self.__success = success
|
||||
return self
|
||||
|
||||
def is_success(self):
|
||||
return self.__success
|
||||
|
||||
def set_total(self, total: int):
|
||||
self.__total = total
|
||||
return self
|
||||
|
||||
def get_total(self):
|
||||
return self.__total
|
||||
|
||||
def set_seeding(self, seeding: int):
|
||||
self.__seeding = seeding
|
||||
return self
|
||||
|
||||
def get_seeding(self):
|
||||
return self.__seeding
|
||||
|
||||
def set_tagging(self, tagging: int):
|
||||
self.__tagging = tagging
|
||||
return self
|
||||
|
||||
def get_tagging(self):
|
||||
return self.__tagging
|
||||
|
||||
def set_delete(self, delete: int):
|
||||
self.__delete = delete
|
||||
return self
|
||||
|
||||
def get_delete(self):
|
||||
return self.__delete
|
||||
|
||||
class TaskContext():
|
||||
"""
|
||||
任务上下文
|
||||
"""
|
||||
def __init__(self):
|
||||
# 选择的下载器集合,为None时表示选择全部
|
||||
self.__selected_downloaders: Set[str] = None
|
||||
|
||||
# 启用的子任务
|
||||
# 启用做种
|
||||
self.__enable_seeding: bool = True
|
||||
# 启用打标
|
||||
self.__enable_tagging: bool = True
|
||||
# 启用删种
|
||||
self.__enable_delete: bool = True
|
||||
|
||||
# 选择的种子,为None时表示选择全部
|
||||
#self.__selected_torrents: Set[str] = None
|
||||
self.__selected_torrents = None
|
||||
|
||||
# 源文件删除事件数据
|
||||
self.__deleted_event_data = None
|
||||
|
||||
# 任务结果集
|
||||
self.__results: List[TaskResult] = None
|
||||
|
||||
# 操作用户名
|
||||
self.__username: str = None
|
||||
|
||||
def select_downloader(self, downloader_id: str):
|
||||
"""
|
||||
选择下载器
|
||||
:param downloader_id: 下载器id
|
||||
"""
|
||||
if not downloader_id:
|
||||
return self
|
||||
if not self.__selected_downloaders:
|
||||
self.__selected_downloaders = set()
|
||||
self.__selected_downloaders.add(downloader_id)
|
||||
return self
|
||||
|
||||
def select_downloaders(self, downloader_ids: List[str]):
|
||||
"""
|
||||
选择下载器
|
||||
:param downloader_ids: 下载器ids
|
||||
"""
|
||||
if not downloader_ids:
|
||||
return self
|
||||
for downloader_id in downloader_ids:
|
||||
self.select_downloader(downloader_id)
|
||||
return self
|
||||
|
||||
def __is_selected_the_downloader(self, downloader_id: str) -> bool:
|
||||
"""
|
||||
是否选择了指定的下载器
|
||||
:param downloader_id: 下载器id
|
||||
:return: 是否选择了指定的下载器
|
||||
"""
|
||||
if not downloader_id:
|
||||
return False
|
||||
return True if self.__selected_downloaders == None \
|
||||
or downloader_id in self.__selected_downloaders \
|
||||
else False
|
||||
|
||||
def is_selected_qb_downloader(self) -> bool:
|
||||
"""
|
||||
是否选择了qb下载器
|
||||
:return: 是否选择了qb下载器
|
||||
"""
|
||||
return self.__is_selected_the_downloader(Constants.qb_downloader_id)
|
||||
|
||||
def is_selected_tr_downloader(self) -> bool:
|
||||
"""
|
||||
是否选择了tr下载器
|
||||
:return: 是否选择了tr下载器
|
||||
"""
|
||||
return self.__is_selected_the_downloader(Constants.tr_downloader_id)
|
||||
|
||||
def enable_seeding(self, enable_seeding: bool = True):
|
||||
"""
|
||||
是否启用做种
|
||||
:param enable_seeding: 是否启用做种
|
||||
"""
|
||||
self.__enable_seeding = enable_seeding if enable_seeding else False
|
||||
return self
|
||||
|
||||
def is_enabled_seeding(self) -> bool:
|
||||
"""
|
||||
是否启用了做种
|
||||
:return: 是否启用了做种
|
||||
"""
|
||||
return self.__enable_seeding
|
||||
|
||||
def enable_tagging(self, enable_tagging: bool = True):
|
||||
"""
|
||||
是否启用打标
|
||||
:param enable_tagging: 是否启用打标
|
||||
"""
|
||||
self.__enable_tagging = enable_tagging if enable_tagging else False
|
||||
return self
|
||||
|
||||
def is_enabled_tagging(self) -> bool:
|
||||
"""
|
||||
是否启用了打标
|
||||
:return: 是否启用了打标
|
||||
"""
|
||||
return self.__enable_tagging
|
||||
|
||||
def enable_delete(self, enable_delete: bool = True):
|
||||
"""
|
||||
是否启用删种
|
||||
:param enable_delete: 是否启用删种
|
||||
"""
|
||||
self.__enable_delete = enable_delete if enable_delete else False
|
||||
return self
|
||||
|
||||
def is_enabled_delete(self) -> bool:
|
||||
"""
|
||||
是否启用了删种
|
||||
:return: 是否启用了删种
|
||||
"""
|
||||
return self.__enable_delete
|
||||
|
||||
def select_torrent(self, torrent: str):
|
||||
"""
|
||||
选择种子
|
||||
:param torrent: 种子key
|
||||
"""
|
||||
if not torrent:
|
||||
return self
|
||||
if not self.__selected_torrents:
|
||||
self.__selected_torrents = set()
|
||||
self.__selected_torrents.add(torrent)
|
||||
return self
|
||||
|
||||
def select_torrents(self, torrents: List[str]):
|
||||
"""
|
||||
选择种子
|
||||
:param torrents: 种子keys
|
||||
"""
|
||||
if not torrents:
|
||||
return self
|
||||
for torrent in torrents:
|
||||
self.select_torrent(torrent)
|
||||
return self
|
||||
|
||||
#def get_selected_torrents(self) -> Set[str]:
|
||||
def get_selected_torrents(self):
|
||||
"""
|
||||
获取所有选择的种子
|
||||
"""
|
||||
return self.__selected_torrents
|
||||
|
||||
def set_deleted_event_data(self, deleted_event_data: dict):
|
||||
"""
|
||||
设置源文件删除事件数据
|
||||
"""
|
||||
self.__deleted_event_data = deleted_event_data
|
||||
return self
|
||||
|
||||
def get_deleted_event_data(self) -> dict:
|
||||
"""
|
||||
获取源文件删除事件数据
|
||||
"""
|
||||
return self.__deleted_event_data
|
||||
|
||||
def save_result(self, result: TaskResult):
|
||||
"""
|
||||
存储结果
|
||||
:param result: 结果
|
||||
"""
|
||||
if not result:
|
||||
return self
|
||||
if not self.__results:
|
||||
self.__results = []
|
||||
self.__results.append(result)
|
||||
return self
|
||||
|
||||
def get_results(self) -> List[TaskResult]:
|
||||
"""
|
||||
获取结果集
|
||||
"""
|
||||
return self.__results
|
||||
|
||||
def set_username(self, username: str):
|
||||
"""
|
||||
设置操作用户名
|
||||
"""
|
||||
self.__username = username
|
||||
return self
|
||||
|
||||
def get_username(self) -> str:
|
||||
"""
|
||||
获取操作用户名
|
||||
"""
|
||||
return self.__username
|
||||
Reference in New Issue
Block a user