fix #516 支持磁力链下载
This commit is contained in:
parent
5eb37b5d28
commit
4e515ec442
@ -234,27 +234,27 @@ class ChainBase(metaclass=ABCMeta):
|
|||||||
return self.run_module("filter_torrents", rule_string=rule_string,
|
return self.run_module("filter_torrents", rule_string=rule_string,
|
||||||
torrent_list=torrent_list, season_episodes=season_episodes)
|
torrent_list=torrent_list, season_episodes=season_episodes)
|
||||||
|
|
||||||
def download(self, torrent_path: Path, download_dir: Path, cookie: str,
|
def download(self, content: Union[Path, str], download_dir: Path, cookie: str,
|
||||||
episodes: Set[int] = None, category: str = None
|
episodes: Set[int] = None, category: str = None
|
||||||
) -> Optional[Tuple[Optional[str], str]]:
|
) -> Optional[Tuple[Optional[str], str]]:
|
||||||
"""
|
"""
|
||||||
根据种子文件,选择并添加下载任务
|
根据种子文件,选择并添加下载任务
|
||||||
:param torrent_path: 种子文件地址
|
:param content: 种子文件地址或者磁力链接
|
||||||
:param download_dir: 下载目录
|
:param download_dir: 下载目录
|
||||||
:param cookie: cookie
|
:param cookie: cookie
|
||||||
:param episodes: 需要下载的集数
|
:param episodes: 需要下载的集数
|
||||||
:param category: 种子分类
|
:param category: 种子分类
|
||||||
:return: 种子Hash,错误信息
|
:return: 种子Hash,错误信息
|
||||||
"""
|
"""
|
||||||
return self.run_module("download", torrent_path=torrent_path, download_dir=download_dir,
|
return self.run_module("download", content=content, download_dir=download_dir,
|
||||||
cookie=cookie, episodes=episodes, category=category)
|
cookie=cookie, episodes=episodes, category=category)
|
||||||
|
|
||||||
def download_added(self, context: Context, torrent_path: Path, download_dir: Path) -> None:
|
def download_added(self, context: Context, download_dir: Path, torrent_path: Path = None) -> None:
|
||||||
"""
|
"""
|
||||||
添加下载任务成功后,从站点下载字幕,保存到下载目录
|
添加下载任务成功后,从站点下载字幕,保存到下载目录
|
||||||
:param context: 上下文,包括识别信息、媒体信息、种子信息
|
:param context: 上下文,包括识别信息、媒体信息、种子信息
|
||||||
:param torrent_path: 种子文件地址
|
|
||||||
:param download_dir: 下载目录
|
:param download_dir: 下载目录
|
||||||
|
:param torrent_path: 种子文件地址
|
||||||
:return: None,该方法可被多个模块同时处理
|
:return: None,该方法可被多个模块同时处理
|
||||||
"""
|
"""
|
||||||
return self.run_module("download_added", context=context, torrent_path=torrent_path,
|
return self.run_module("download_added", context=context, torrent_path=torrent_path,
|
||||||
|
@ -70,16 +70,22 @@ class DownloadChain(ChainBase):
|
|||||||
|
|
||||||
def download_torrent(self, torrent: TorrentInfo,
|
def download_torrent(self, torrent: TorrentInfo,
|
||||||
channel: MessageChannel = None,
|
channel: MessageChannel = None,
|
||||||
userid: Union[str, int] = None) -> Tuple[Optional[Path], str, list]:
|
userid: Union[str, int] = None
|
||||||
|
) -> Tuple[Optional[Union[Path, str]], str, list]:
|
||||||
"""
|
"""
|
||||||
下载种子文件
|
下载种子文件,如果是磁力链,会返回磁力链接本身
|
||||||
:return: 种子路径,种子目录名,种子文件清单
|
:return: 种子路径,种子目录名,种子文件清单
|
||||||
"""
|
"""
|
||||||
torrent_file, _, download_folder, files, error_msg = self.torrent.download_torrent(
|
torrent_file, content, download_folder, files, error_msg = self.torrent.download_torrent(
|
||||||
url=torrent.enclosure,
|
url=torrent.enclosure,
|
||||||
cookie=torrent.site_cookie,
|
cookie=torrent.site_cookie,
|
||||||
ua=torrent.site_ua,
|
ua=torrent.site_ua,
|
||||||
proxy=torrent.site_proxy)
|
proxy=torrent.site_proxy)
|
||||||
|
|
||||||
|
if isinstance(content, str):
|
||||||
|
# 磁力链
|
||||||
|
return content, "", []
|
||||||
|
|
||||||
if not torrent_file:
|
if not torrent_file:
|
||||||
logger.error(f"下载种子文件失败:{torrent.title} - {torrent.enclosure}")
|
logger.error(f"下载种子文件失败:{torrent.title} - {torrent.enclosure}")
|
||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
@ -89,6 +95,8 @@ class DownloadChain(ChainBase):
|
|||||||
text=f"错误信息:{error_msg}\n站点:{torrent.site_name}",
|
text=f"错误信息:{error_msg}\n站点:{torrent.site_name}",
|
||||||
userid=userid))
|
userid=userid))
|
||||||
return None, "", []
|
return None, "", []
|
||||||
|
|
||||||
|
# 返回 种子文件路径,种子目录名,种子文件清单
|
||||||
return torrent_file, download_folder, files
|
return torrent_file, download_folder, files
|
||||||
|
|
||||||
def download_single(self, context: Context, torrent_file: Path = None,
|
def download_single(self, context: Context, torrent_file: Path = None,
|
||||||
@ -98,19 +106,27 @@ class DownloadChain(ChainBase):
|
|||||||
userid: Union[str, int] = None) -> Optional[str]:
|
userid: Union[str, int] = None) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
下载及发送通知
|
下载及发送通知
|
||||||
|
:param context: 资源上下文
|
||||||
|
:param torrent_file: 种子文件路径
|
||||||
|
:param episodes: 需要下载的集数
|
||||||
|
:param channel: 通知渠道
|
||||||
|
:param save_path: 保存路径
|
||||||
|
:param userid: 用户ID
|
||||||
"""
|
"""
|
||||||
_torrent = context.torrent_info
|
_torrent = context.torrent_info
|
||||||
_media = context.media_info
|
_media = context.media_info
|
||||||
_meta = context.meta_info
|
_meta = context.meta_info
|
||||||
_folder_name = ""
|
_folder_name = ""
|
||||||
if not torrent_file:
|
if not torrent_file:
|
||||||
# 下载种子文件
|
# 下载种子文件,得到的可能是文件也可能是磁力链
|
||||||
torrent_file, _folder_name, _file_list = self.download_torrent(_torrent, userid=userid)
|
content, _folder_name, _file_list = self.download_torrent(_torrent, userid=userid)
|
||||||
if not torrent_file:
|
if not content:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
content = torrent_file
|
||||||
# 获取种子文件的文件夹名和文件清单
|
# 获取种子文件的文件夹名和文件清单
|
||||||
_folder_name, _file_list = self.torrent.get_torrent_info(torrent_file)
|
_folder_name, _file_list = self.torrent.get_torrent_info(torrent_file)
|
||||||
|
|
||||||
# 下载目录
|
# 下载目录
|
||||||
if not save_path:
|
if not save_path:
|
||||||
if settings.DOWNLOAD_CATEGORY and _media and _media.category:
|
if settings.DOWNLOAD_CATEGORY and _media and _media.category:
|
||||||
@ -149,7 +165,7 @@ class DownloadChain(ChainBase):
|
|||||||
download_dir = Path(save_path)
|
download_dir = Path(save_path)
|
||||||
|
|
||||||
# 添加下载
|
# 添加下载
|
||||||
result: Optional[tuple] = self.download(torrent_path=torrent_file,
|
result: Optional[tuple] = self.download(content=content,
|
||||||
cookie=_torrent.site_cookie,
|
cookie=_torrent.site_cookie,
|
||||||
episodes=episodes,
|
episodes=episodes,
|
||||||
download_dir=download_dir,
|
download_dir=download_dir,
|
||||||
@ -208,11 +224,10 @@ class DownloadChain(ChainBase):
|
|||||||
# 发送消息
|
# 发送消息
|
||||||
self.post_download_message(meta=_meta, mediainfo=_media, torrent=_torrent, channel=channel)
|
self.post_download_message(meta=_meta, mediainfo=_media, torrent=_torrent, channel=channel)
|
||||||
# 下载成功后处理
|
# 下载成功后处理
|
||||||
self.download_added(context=context, torrent_path=torrent_file, download_dir=download_dir)
|
self.download_added(context=context, download_dir=download_dir, torrent_path=torrent_file)
|
||||||
# 广播事件
|
# 广播事件
|
||||||
self.eventmanager.send_event(EventType.DownloadAdded, {
|
self.eventmanager.send_event(EventType.DownloadAdded, {
|
||||||
"hash": _hash,
|
"hash": _hash,
|
||||||
"torrent_file": torrent_file,
|
|
||||||
"context": context
|
"context": context
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
@ -346,8 +361,11 @@ class DownloadChain(ChainBase):
|
|||||||
if set(torrent_season).issubset(set(need_season)):
|
if set(torrent_season).issubset(set(need_season)):
|
||||||
if len(torrent_season) == 1:
|
if len(torrent_season) == 1:
|
||||||
# 只有一季的可能是命名错误,需要打开种子鉴别,只有实际集数大于等于总集数才下载
|
# 只有一季的可能是命名错误,需要打开种子鉴别,只有实际集数大于等于总集数才下载
|
||||||
torrent_path, _, torrent_files = self.download_torrent(torrent)
|
content, _, torrent_files = self.download_torrent(torrent)
|
||||||
if not torrent_path:
|
if not content:
|
||||||
|
continue
|
||||||
|
if isinstance(content, str):
|
||||||
|
logger.warn(f"{meta.org_string} 下载地址是磁力链,无法确定种子文件集数")
|
||||||
continue
|
continue
|
||||||
torrent_episodes = self.torrent.get_torrent_episodes(torrent_files)
|
torrent_episodes = self.torrent.get_torrent_episodes(torrent_files)
|
||||||
logger.info(f"{meta.org_string} 解析文件集数为 {torrent_episodes}")
|
logger.info(f"{meta.org_string} 解析文件集数为 {torrent_episodes}")
|
||||||
@ -365,10 +383,12 @@ class DownloadChain(ChainBase):
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
# 下载
|
# 下载
|
||||||
download_id = self.download_single(context=context,
|
download_id = self.download_single(
|
||||||
torrent_file=torrent_path,
|
context=context,
|
||||||
|
torrent_file=content if isinstance(content, Path) else None,
|
||||||
save_path=save_path,
|
save_path=save_path,
|
||||||
userid=userid)
|
userid=userid
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# 下载
|
# 下载
|
||||||
download_id = self.download_single(context, save_path=save_path, userid=userid)
|
download_id = self.download_single(context, save_path=save_path, userid=userid)
|
||||||
@ -485,8 +505,11 @@ class DownloadChain(ChainBase):
|
|||||||
and len(meta.season_list) == 1 \
|
and len(meta.season_list) == 1 \
|
||||||
and meta.season_list[0] == need_season:
|
and meta.season_list[0] == need_season:
|
||||||
# 检查种子看是否有需要的集
|
# 检查种子看是否有需要的集
|
||||||
torrent_path, _, torrent_files = self.download_torrent(torrent, userid=userid)
|
content, _, torrent_files = self.download_torrent(torrent, userid=userid)
|
||||||
if not torrent_path:
|
if not content:
|
||||||
|
continue
|
||||||
|
if isinstance(content, str):
|
||||||
|
logger.warn(f"{meta.org_string} 下载地址是磁力链,无法解析种子文件集数")
|
||||||
continue
|
continue
|
||||||
# 种子全部集
|
# 种子全部集
|
||||||
torrent_episodes = self.torrent.get_torrent_episodes(torrent_files)
|
torrent_episodes = self.torrent.get_torrent_episodes(torrent_files)
|
||||||
@ -498,11 +521,13 @@ class DownloadChain(ChainBase):
|
|||||||
continue
|
continue
|
||||||
logger.info(f"{torrent.site_name} - {torrent.title} 选中集数:{selected_episodes}")
|
logger.info(f"{torrent.site_name} - {torrent.title} 选中集数:{selected_episodes}")
|
||||||
# 添加下载
|
# 添加下载
|
||||||
download_id = self.download_single(context=context,
|
download_id = self.download_single(
|
||||||
torrent_file=torrent_path,
|
context=context,
|
||||||
|
torrent_file=content if isinstance(content, Path) else None,
|
||||||
episodes=selected_episodes,
|
episodes=selected_episodes,
|
||||||
save_path=save_path,
|
save_path=save_path,
|
||||||
userid=userid)
|
userid=userid
|
||||||
|
)
|
||||||
if not download_id:
|
if not download_id:
|
||||||
continue
|
continue
|
||||||
# 把识别的集更新到上下文
|
# 把识别的集更新到上下文
|
||||||
|
@ -36,19 +36,22 @@ class QbittorrentModule(_ModuleBase):
|
|||||||
if self.qbittorrent.is_inactive():
|
if self.qbittorrent.is_inactive():
|
||||||
self.qbittorrent = Qbittorrent()
|
self.qbittorrent = Qbittorrent()
|
||||||
|
|
||||||
def download(self, torrent_path: Path, download_dir: Path, cookie: str,
|
def download(self, content: Union[Path, str], download_dir: Path, cookie: str,
|
||||||
episodes: Set[int] = None, category: str = None) -> Optional[Tuple[Optional[str], str]]:
|
episodes: Set[int] = None, category: str = None) -> Optional[Tuple[Optional[str], str]]:
|
||||||
"""
|
"""
|
||||||
根据种子文件,选择并添加下载任务
|
根据种子文件,选择并添加下载任务
|
||||||
:param torrent_path: 种子文件地址
|
:param content: 种子文件地址或者磁力链接
|
||||||
:param download_dir: 下载目录
|
:param download_dir: 下载目录
|
||||||
:param cookie: cookie
|
:param cookie: cookie
|
||||||
:param episodes: 需要下载的集数
|
:param episodes: 需要下载的集数
|
||||||
:param category: 分类
|
:param category: 分类
|
||||||
:return: 种子Hash,错误信息
|
:return: 种子Hash,错误信息
|
||||||
"""
|
"""
|
||||||
if not torrent_path or not torrent_path.exists():
|
if not content:
|
||||||
return None, f"种子文件不存在:{torrent_path}"
|
return
|
||||||
|
if isinstance(content, Path) and not content.exists():
|
||||||
|
return None, f"种子文件不存在:{content}"
|
||||||
|
|
||||||
# 生成随机Tag
|
# 生成随机Tag
|
||||||
tag = StringUtils.generate_random_str(10)
|
tag = StringUtils.generate_random_str(10)
|
||||||
if settings.TORRENT_TAG:
|
if settings.TORRENT_TAG:
|
||||||
@ -58,19 +61,21 @@ class QbittorrentModule(_ModuleBase):
|
|||||||
# 如果要选择文件则先暂停
|
# 如果要选择文件则先暂停
|
||||||
is_paused = True if episodes else False
|
is_paused = True if episodes else False
|
||||||
# 添加任务
|
# 添加任务
|
||||||
state = self.qbittorrent.add_torrent(content=torrent_path.read_bytes(),
|
state = self.qbittorrent.add_torrent(
|
||||||
|
content=content.read_bytes() if isinstance(content, Path) else content,
|
||||||
download_dir=str(download_dir),
|
download_dir=str(download_dir),
|
||||||
is_paused=is_paused,
|
is_paused=is_paused,
|
||||||
tag=tags,
|
tag=tags,
|
||||||
cookie=cookie,
|
cookie=cookie,
|
||||||
category=category)
|
category=category
|
||||||
|
)
|
||||||
if not state:
|
if not state:
|
||||||
return None, f"添加种子任务失败:{torrent_path}"
|
return None, f"添加种子任务失败:{content}"
|
||||||
else:
|
else:
|
||||||
# 获取种子Hash
|
# 获取种子Hash
|
||||||
torrent_hash = self.qbittorrent.get_torrent_id_by_tag(tags=tag)
|
torrent_hash = self.qbittorrent.get_torrent_id_by_tag(tags=tag)
|
||||||
if not torrent_hash:
|
if not torrent_hash:
|
||||||
return None, f"获取种子Hash失败:{torrent_path}"
|
return None, f"获取种子Hash失败:{content}"
|
||||||
else:
|
else:
|
||||||
if is_paused:
|
if is_paused:
|
||||||
# 种子文件
|
# 种子文件
|
||||||
|
@ -34,18 +34,22 @@ class SubtitleModule(_ModuleBase):
|
|||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def download_added(self, context: Context, torrent_path: Path, download_dir: Path) -> None:
|
def download_added(self, context: Context, download_dir: Path, torrent_path: Path = None) -> None:
|
||||||
"""
|
"""
|
||||||
添加下载任务成功后,从站点下载字幕,保存到下载目录
|
添加下载任务成功后,从站点下载字幕,保存到下载目录
|
||||||
:param context: 上下文,包括识别信息、媒体信息、种子信息
|
:param context: 上下文,包括识别信息、媒体信息、种子信息
|
||||||
:param torrent_path: 种子文件地址
|
|
||||||
:param download_dir: 下载目录
|
:param download_dir: 下载目录
|
||||||
|
:param torrent_path: 种子文件地址
|
||||||
:return: None,该方法可被多个模块同时处理
|
:return: None,该方法可被多个模块同时处理
|
||||||
"""
|
"""
|
||||||
if not settings.DOWNLOAD_SUBTITLE:
|
if not settings.DOWNLOAD_SUBTITLE:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 种子信息
|
# 没有种子文件不处理
|
||||||
|
if not torrent_path:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 没有详情页不处理
|
||||||
torrent = context.torrent_info
|
torrent = context.torrent_info
|
||||||
if not torrent.page_url:
|
if not torrent.page_url:
|
||||||
return
|
return
|
||||||
|
@ -36,17 +36,22 @@ class TransmissionModule(_ModuleBase):
|
|||||||
if not self.transmission.is_inactive():
|
if not self.transmission.is_inactive():
|
||||||
self.transmission = Transmission()
|
self.transmission = Transmission()
|
||||||
|
|
||||||
def download(self, torrent_path: Path, download_dir: Path, cookie: str,
|
def download(self, content: Union[Path, str], download_dir: Path, cookie: str,
|
||||||
episodes: Set[int] = None, category: str = None) -> Optional[Tuple[Optional[str], str]]:
|
episodes: Set[int] = None, category: str = None) -> Optional[Tuple[Optional[str], str]]:
|
||||||
"""
|
"""
|
||||||
根据种子文件,选择并添加下载任务
|
根据种子文件,选择并添加下载任务
|
||||||
:param torrent_path: 种子文件地址
|
:param content: 种子文件地址或者磁力链接
|
||||||
:param download_dir: 下载目录
|
:param download_dir: 下载目录
|
||||||
:param cookie: cookie
|
:param cookie: cookie
|
||||||
:param episodes: 需要下载的集数
|
:param episodes: 需要下载的集数
|
||||||
:param category: 分类,TR中未使用
|
:param category: 分类,TR中未使用
|
||||||
:return: 种子Hash
|
:return: 种子Hash
|
||||||
"""
|
"""
|
||||||
|
if not content:
|
||||||
|
return
|
||||||
|
if isinstance(content, Path) and not content.exists():
|
||||||
|
return None, f"种子文件不存在:{content}"
|
||||||
|
|
||||||
# 如果要选择文件则先暂停
|
# 如果要选择文件则先暂停
|
||||||
is_paused = True if episodes else False
|
is_paused = True if episodes else False
|
||||||
# 标签
|
# 标签
|
||||||
@ -55,13 +60,15 @@ class TransmissionModule(_ModuleBase):
|
|||||||
else:
|
else:
|
||||||
labels = None
|
labels = None
|
||||||
# 添加任务
|
# 添加任务
|
||||||
torrent = self.transmission.add_torrent(content=torrent_path.read_bytes(),
|
torrent = self.transmission.add_torrent(
|
||||||
|
content=content.read_bytes() if isinstance(content, Path) else content,
|
||||||
download_dir=str(download_dir),
|
download_dir=str(download_dir),
|
||||||
is_paused=is_paused,
|
is_paused=is_paused,
|
||||||
labels=labels,
|
labels=labels,
|
||||||
cookie=cookie)
|
cookie=cookie
|
||||||
|
)
|
||||||
if not torrent:
|
if not torrent:
|
||||||
return None, f"添加种子任务失败:{torrent_path}"
|
return None, f"添加种子任务失败:{content}"
|
||||||
else:
|
else:
|
||||||
torrent_hash = torrent.hashString
|
torrent_hash = torrent.hashString
|
||||||
if is_paused:
|
if is_paused:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user