fix transfer

This commit is contained in:
jxxghp
2023-06-11 14:52:23 +08:00
parent f57e801236
commit 760f603076
9 changed files with 189 additions and 149 deletions

View File

@ -137,10 +137,11 @@ class _ModuleBase(metaclass=ABCMeta):
"""
pass
def list_torrents(self, status: TorrentStatus) -> Optional[List[dict]]:
def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None) -> Optional[List[dict]]:
"""
获取下载器种子列表
:param status: 种子状态
:param hashs: 种子Hash
:return: 下载器中符合状态的种子列表
"""
pass

View File

@ -89,19 +89,53 @@ class QbittorrentModule(_ModuleBase):
:param hashs: 种子Hash
:return: 处理状态
"""
return self.qbittorrent.set_torrents_tag(ids=hashs, tag=['已整理'])
return self.qbittorrent.set_torrents_tag(ids=hashs, tags=['已整理'])
def list_torrents(self, status: TorrentStatus) -> Optional[List[dict]]:
def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None) -> Optional[List[dict]]:
"""
获取下载器种子列表
:param status: 种子状态
:param hashs: 种子Hash
:return: 下载器中符合状态的种子列表
"""
if status == TorrentStatus.TRANSFER:
torrents = self.qbittorrent.get_transfer_torrents(tag=settings.TORRENT_TAG or None)
ret_torrents = []
if hashs:
# 按Hash获取
torrents, _ = self.qbittorrent.get_torrents(ids=hashs)
for torrent in torrents:
content_path = torrent.get("content_path")
if content_path:
torrent_path = Path(content_path)
else:
torrent_path = Path(settings.DOWNLOAD_PATH) / torrent.get('name')
ret_torrents.append({
'title': torrent.get('name'),
'path': torrent_path,
'hash': torrent.get('hash'),
'tags': torrent.get('tags')
})
elif status == TorrentStatus.TRANSFER:
# 获取已完成且未整理的
torrents = self.qbittorrent.get_completed_torrents(tags=settings.TORRENT_TAG)
for torrent in torrents:
tags = torrent.get("tags") or []
if "已整理" in tags:
continue
# 内容路径
content_path = torrent.get("content_path")
if content_path:
torrent_path = Path(content_path)
else:
torrent_path = Path(settings.DOWNLOAD_PATH) / torrent.get('name')
ret_torrents.append({
'title': torrent.get('name'),
'path': torrent_path,
'hash': torrent.get('hash'),
'tags': torrent.get('tags')
})
else:
return None
return torrents
return ret_torrents
def remove_torrents(self, hashs: Union[str, list]) -> bool:
"""

View File

@ -1,5 +1,4 @@
import time
from pathlib import Path
from typing import Optional, Union, Tuple, List
import qbittorrentapi
@ -52,7 +51,7 @@ class Qbittorrent(metaclass=Singleton):
def get_torrents(self, ids: Union[str, list] = None,
status: Union[str, list] = None,
tag: Union[str, list] = None) -> Tuple[List[TorrentDictionary], bool]:
tags: Union[str, list] = None) -> Tuple[List[TorrentDictionary], bool]:
"""
获取种子列表
return: 种子列表, 是否发生异常
@ -62,17 +61,12 @@ class Qbittorrent(metaclass=Singleton):
try:
torrents = self.qbc.torrents_info(torrent_hashes=ids,
status_filter=status)
if tag:
if tags:
results = []
if not isinstance(tag, list):
tag = [tag]
if not isinstance(tags, list):
tags = [tags]
for torrent in torrents:
include_flag = True
for t in tag:
if t and t not in torrent.get("tags"):
include_flag = False
break
if include_flag:
if set(tags).issubset(set(torrent.get("tags"))):
results.append(torrent)
return results, False
return torrents or [], False
@ -81,18 +75,18 @@ class Qbittorrent(metaclass=Singleton):
return [], True
def get_completed_torrents(self, ids: Union[str, list] = None,
tag: Union[str, list] = None) -> Optional[List[TorrentDictionary]]:
tags: Union[str, list] = None) -> Optional[List[TorrentDictionary]]:
"""
获取已完成的种子
return: 种子列表, 如发生异常则返回None
"""
if not self.qbc:
return None
torrents, error = self.get_torrents(status=["completed"], ids=ids, tag=tag)
torrents, error = self.get_torrents(status=["completed"], ids=ids, tags=tags)
return None if error else torrents or []
def get_downloading_torrents(self, ids: Union[str, list] = None,
tag: Union[str, list] = None) -> Optional[List[TorrentDictionary]]:
tags: Union[str, list] = None) -> Optional[List[TorrentDictionary]]:
"""
获取正在下载的种子
return: 种子列表, 如发生异常则返回None
@ -101,7 +95,7 @@ class Qbittorrent(metaclass=Singleton):
return None
torrents, error = self.get_torrents(ids=ids,
status=["downloading"],
tag=tag)
tags=tags)
return None if error else torrents or []
def remove_torrents_tag(self, ids: Union[str, list], tag: Union[str, list]) -> bool:
@ -117,7 +111,7 @@ class Qbittorrent(metaclass=Singleton):
logger.error(f"移除种子Tag出错{err}")
return False
def set_torrents_tag(self, ids: Union[str, list], tag: list):
def set_torrents_tag(self, ids: Union[str, list], tags: list):
"""
设置种子状态为已整理,以及是否强制做种
"""
@ -125,7 +119,7 @@ class Qbittorrent(metaclass=Singleton):
return
try:
# 打标签
self.qbc.torrents_add_tags(tags=tag, torrent_hashes=ids)
self.qbc.torrents_add_tags(tags=tags, torrent_hashes=ids)
except Exception as err:
logger.error(f"设置种子Tag出错{err}")
@ -138,40 +132,6 @@ class Qbittorrent(metaclass=Singleton):
except Exception as err:
logger.error(f"设置强制作种出错:{err}")
def get_transfer_torrents(self, tag: Union[str, list] = None) -> Optional[List[dict]]:
"""
获取下载文件转移任务种子
"""
# 处理下载完成的任务
torrents = self.get_completed_torrents() or []
trans_tasks = []
for torrent in torrents:
torrent_tags = torrent.get("tags") or ""
# 含"已整理"tag的不处理
if "已整理" in torrent_tags:
continue
# 开启标签隔离,未包含指定标签的不处理
if tag and tag not in torrent_tags:
logger.debug(f"{torrent.get('name')} 未包含指定标签:{tag}")
continue
path = torrent.get("save_path")
# 无法获取下载路径的不处理
if not path:
logger.warn(f"未获取到 {torrent.get('name')} 下载保存路径")
continue
content_path = torrent.get("content_path")
if content_path:
torrent_path = Path(content_path)
else:
torrent_path = Path(settings.DOWNLOAD_PATH) / torrent.get('name')
trans_tasks.append({
'title': torrent.get('name'),
'path': torrent_path,
'hash': torrent.get('hash'),
'tags': torrent.get('tags')
})
return trans_tasks
def __get_last_add_torrentid_by_tag(self, tag: Union[str, list],
status: Union[str, list] = None) -> Optional[str]:
"""
@ -179,7 +139,7 @@ class Qbittorrent(metaclass=Singleton):
:return: 种子ID
"""
try:
torrents, _ = self.get_torrents(status=status, tag=tag)
torrents, _ = self.get_torrents(status=status, tags=tag)
except Exception as err:
logger.error(f"获取种子列表出错:{err}")
return None

View File

@ -262,7 +262,7 @@ class TmdbHelper:
continue
index += 1
if not movie.get("names"):
movie = self.get_info(MediaType.MOVIE, movie.get("id"))
movie = self.get_info(mtype=MediaType.MOVIE, tmdbid=movie.get("id"))
if movie and self.__compare_names(name, movie.get("names")):
return movie
if index > 5:
@ -319,7 +319,7 @@ class TmdbHelper:
continue
index += 1
if not tv.get("names"):
tv = self.get_info(MediaType.TV, tv.get("id"))
tv = self.get_info(mtype=MediaType.TV, tmdbid=tv.get("id"))
if self.__compare_names(name, tv.get("names")):
return tv
if index > 5:
@ -374,7 +374,7 @@ class TmdbHelper:
# 匹配别名、译名
for tv in tvs[:5]:
if not tv.get("names"):
tv = self.get_info(MediaType.TV, tv.get("id"))
tv = self.get_info(mtype=MediaType.TV, tmdbid=tv.get("id"))
if not self.__compare_names(name, tv.get("names")):
continue
if __season_match(tv_info=tv, _season_year=season_year):
@ -452,12 +452,12 @@ class TmdbHelper:
for multi in multis[:5]:
if multi.get("media_type") == "movie":
if not multi.get("names"):
multi = self.get_info(MediaType.MOVIE, multi.get("id"))
multi = self.get_info(mtype=MediaType.MOVIE, tmdbid=multi.get("id"))
if self.__compare_names(name, multi.get("names")):
return multi
elif multi.get("media_type") == "tv":
if not multi.get("names"):
multi = self.get_info(MediaType.TV, multi.get("id"))
multi = self.get_info(mtype=MediaType.TV, tmdbid=multi.get("id"))
if self.__compare_names(name, multi.get("names")):
return multi
return {}
@ -541,15 +541,24 @@ class TmdbHelper:
genre_ids.append(genre.get('id'))
return genre_ids
# 设置语言
# 查询TMDB详ngeq
if mtype == MediaType.MOVIE:
tmdb_info = self.__get_movie_detail(tmdbid)
if tmdb_info:
tmdb_info['media_type'] = MediaType.MOVIE
else:
elif mtype == MediaType.TV:
tmdb_info = self.__get_tv_detail(tmdbid)
if tmdb_info:
tmdb_info['media_type'] = MediaType.TV
else:
tmdb_info = self.__get_movie_detail(tmdbid)
if tmdb_info:
tmdb_info['media_type'] = MediaType.MOVIE
else:
tmdb_info = self.__get_tv_detail(tmdbid)
if tmdb_info:
tmdb_info['media_type'] = MediaType.TV
if tmdb_info:
# 转换genreid
tmdb_info['genre_ids'] = __get_genre_ids(tmdb_info.get('genres'))

View File

@ -3,13 +3,13 @@ from typing import Set, Tuple, Optional, Union, List
from app.core.config import settings
from app.core.metainfo import MetaInfo
from app.log import logger
from app.modules import _ModuleBase
from app.modules.transmission.transmission import Transmission
from app.utils.types import TorrentStatus
class TransmissionModule(_ModuleBase):
transmission: Transmission = None
def init_module(self) -> None:
@ -77,19 +77,48 @@ class TransmissionModule(_ModuleBase):
:param hashs: 种子Hash
:return: 处理状态
"""
return self.transmission.set_torrent_tag(ids=hashs, tag=['已整理'])
return self.transmission.set_torrent_tag(ids=hashs, tags=['已整理'])
def list_torrents(self, status: TorrentStatus) -> Optional[List[dict]]:
def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None) -> Optional[List[dict]]:
"""
获取下载器种子列表
:param status: 种子状态
:param hashs: 种子Hash
:return: 下载器中符合状态的种子列表
"""
if status == TorrentStatus.TRANSFER:
torrents = self.transmission.get_transfer_torrents(tag=settings.TORRENT_TAG or None)
ret_torrents = []
if hashs:
# 按Hash获取
torrents, _ = self.transmission.get_torrents(ids=hashs)
for torrent in torrents:
ret_torrents.append({
'title': torrent.name,
'path': Path(torrent.download_dir) / torrent.name,
'hash': torrent.hashString,
'tags': torrent.labels
})
elif status == TorrentStatus.TRANSFER:
# 获取已完成且未整理的
torrents = self.transmission.get_completed_torrents(tags=settings.TORRENT_TAG)
for torrent in torrents:
# 含"已整理"tag的不处理
if "已整理" in torrent.labels or []:
continue
# 下载路径
path = torrent.download_dir
# 无法获取下载路径的不处理
if not path:
logger.debug(f"未获取到 {torrent.name} 下载保存路径")
continue
ret_torrents.append({
'title': torrent.name,
'path': Path(path) / torrent.name,
'hash': torrent.hashString,
'tags': torrent.labels
})
else:
return None
return torrents
return ret_torrents
def remove_torrents(self, hashs: Union[str, list]) -> bool:
"""

View File

@ -1,4 +1,3 @@
from pathlib import Path
from typing import Optional, Union, Tuple, List
import transmission_rpc
@ -50,7 +49,7 @@ class Transmission(metaclass=Singleton):
return None
def get_torrents(self, ids: Union[str, list] = None, status: Union[str, list] = None,
tag: Union[str, list] = None) -> Tuple[List[Torrent], bool]:
tags: Union[str, list] = None) -> Tuple[List[Torrent], bool]:
"""
获取种子列表
返回结果 种子列表, 是否有错误
@ -64,25 +63,22 @@ class Transmission(metaclass=Singleton):
return [], True
if status and not isinstance(status, list):
status = [status]
if tag and not isinstance(tag, list):
tag = [tag]
if tags and not isinstance(tags, list):
tags = [tags]
ret_torrents = []
for torrent in torrents:
# 状态过滤
if status and torrent.status not in status:
continue
# 种子标签
labels = torrent.labels if hasattr(torrent, "labels") else []
include_flag = True
if tag:
for t in tag:
if t and t not in labels:
include_flag = False
break
if include_flag:
ret_torrents.append(torrent)
if tags and not set(tags).issubset(set(labels)):
continue
ret_torrents.append(torrent)
return ret_torrents, False
def get_completed_torrents(self, ids: Union[str, list] = None,
tag: Union[str, list] = None) -> Optional[List[Torrent]]:
tags: Union[str, list] = None) -> Optional[List[Torrent]]:
"""
获取已完成的种子列表
return 种子列表, 发生错误时返回None
@ -90,14 +86,14 @@ class Transmission(metaclass=Singleton):
if not self.trc:
return None
try:
torrents, error = self.get_torrents(status=["seeding", "seed_pending"], ids=ids, tag=tag)
torrents, error = self.get_torrents(status=["seeding", "seed_pending"], ids=ids, tags=tags)
return None if error else torrents or []
except Exception as err:
logger.error(f"获取已完成的种子列表出错:{err}")
return None
def get_downloading_torrents(self, ids: Union[str, list] = None,
tag: Union[str, list] = None) -> Optional[List[Torrent]]:
tags: Union[str, list] = None) -> Optional[List[Torrent]]:
"""
获取正在下载的种子列表
return 种子列表, 发生错误时返回None
@ -107,58 +103,25 @@ class Transmission(metaclass=Singleton):
try:
torrents, error = self.get_torrents(ids=ids,
status=["downloading", "download_pending"],
tag=tag)
tags=tags)
return None if error else torrents or []
except Exception as err:
logger.error(f"获取正在下载的种子列表出错:{err}")
return None
def set_torrent_tag(self, ids: str, tag: list) -> bool:
def set_torrent_tag(self, ids: str, tags: list) -> bool:
"""
设置种子标签
"""
if not ids or not tag:
if not ids or not tags:
return False
try:
self.trc.change_torrent(labels=tag, ids=ids)
self.trc.change_torrent(labels=tags, ids=ids)
return True
except Exception as err:
logger.error(f"设置种子标签出错:{err}")
return False
def get_transfer_torrents(self, tag: Union[str, list] = None) -> List[dict]:
"""
获取下载文件转移任务种子
"""
# 处理下载完成的任务
torrents = self.get_completed_torrents() or []
trans_tasks = []
for torrent in torrents:
# 3.0版本以下的Transmission没有labels
if not hasattr(torrent, "labels"):
logger.error(f"版本可能过低无labels属性请安装3.0以上版本!")
break
torrent_tags = torrent.labels or ""
# 含"已整理"tag的不处理
if "已整理" in torrent_tags:
continue
# 开启标签隔离,未包含指定标签的不处理
if tag and tag not in torrent_tags:
logger.debug(f"{torrent.name} 未包含指定标签:{tag}")
continue
path = torrent.download_dir
# 无法获取下载路径的不处理
if not path:
logger.debug(f"未获取到 {torrent.name} 下载保存路径")
continue
trans_tasks.append({
'title': torrent.name,
'path': Path(path) / torrent.name,
'hash': torrent.hashString,
'tags': torrent.labels
})
return trans_tasks
def add_torrent(self, content: Union[str, bytes],
is_paused: bool = False,
download_dir: str = None,