feat 手动整理支持自动识别批量处理,增加进度显示

This commit is contained in:
jxxghp 2023-08-28 12:50:21 +08:00
parent 921783d6bb
commit 683ba4cfad
2 changed files with 185 additions and 82 deletions

View File

@ -5,11 +5,7 @@ from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app import schemas
from app.chain.media import MediaChain
from app.chain.transfer import TransferChain
from app.core.config import settings
from app.core.context import MediaInfo
from app.core.metainfo import MetaInfo
from app.core.security import verify_token
from app.db import get_db
from app.schemas import MediaType
@ -19,11 +15,11 @@ router = APIRouter()
@router.post("/manual", summary="手动转移", response_model=schemas.Response)
def manual_transfer(path: str,
tmdbid: int,
type_name: str,
target: str = None,
tmdbid: int = None,
type_name: str = None,
season: int = None,
transfer_type: str = settings.TRANSFER_TYPE,
transfer_type: str = None,
episode_format: str = None,
episode_detail: str = None,
episode_part: str = None,
@ -52,17 +48,8 @@ def manual_transfer(path: str,
target = Path(target)
if not target.exists():
return schemas.Response(success=False, message=f"目标路径不存在")
# 识别元数据
meta = MetaInfo(in_path.stem)
mtype = MediaType(type_name)
# 整合数据
meta.type = mtype
if season:
meta.begin_season = season
# 识别媒体信息
mediainfo: MediaInfo = MediaChain(db).recognize_media(tmdbid=tmdbid, mtype=mtype)
if not mediainfo:
return schemas.Response(success=False, message=f"媒体信息识别失败tmdbid: {tmdbid}")
# 类型
mtype = MediaType(type_name) if type_name else None
# 自定义格式
epformat = None
if episode_offset or episode_part or episode_detail or episode_format:
@ -75,10 +62,11 @@ def manual_transfer(path: str,
# 开始转移
state, errormsg = TransferChain(db).manual_transfer(
in_path=in_path,
mediainfo=mediainfo,
transfer_type=transfer_type,
target=target,
meta=meta,
tmdbid=tmdbid,
mtype=mtype,
season=season,
transfer_type=transfer_type,
epformat=epformat,
min_filesize=min_filesize
)

View File

@ -7,6 +7,7 @@ from typing import List, Optional, Tuple, Union
from sqlalchemy.orm import Session
from app.chain import ChainBase
from app.chain.media import MediaChain
from app.core.config import settings
from app.core.context import MediaInfo
from app.core.meta import MetaBase
@ -35,6 +36,7 @@ class TransferChain(ChainBase):
self.downloadhis = DownloadHistoryOper(self._db)
self.transferhis = TransferHistoryOper(self._db)
self.progress = ProgressHelper()
self.mediachain = MediaChain(self._db)
def process(self) -> bool:
"""
@ -51,21 +53,8 @@ class TransferChain(ChainBase):
return False
logger.info(f"获取到 {len(torrents)} 个已完成的下载任务")
# 开始进度
self.progress.start(ProgressKey.FileTransfer)
# 总数
total_num = len(torrents)
# 已处理数量
processed_num = 0
self.progress.update(value=0,
text=f"开始转移下载任务文件,共 {total_num} 个任务 ...",
key=ProgressKey.FileTransfer)
for torrent in torrents:
# 更新进度
self.progress.update(value=processed_num / total_num * 100,
text=f"正在转移 {torrent.title} ...",
key=ProgressKey.FileTransfer)
# 识别元数据
meta: MetaBase = MetaInfo(title=torrent.title)
if not meta.name:
@ -166,15 +155,7 @@ class TransferChain(ChainBase):
# 转移完成
self.transfer_completed(hashs=torrent.hash, transinfo=transferinfo)
# 计数
processed_num += 1
# 更新进度
self.progress.update(value=processed_num / total_num * 100,
text=f"{torrent.title} 转移完成",
key=ProgressKey.FileTransfer)
# 结束进度
self.progress.end(ProgressKey.FileTransfer)
# 结束
logger.info("下载器文件转移执行完成")
return True
@ -333,22 +314,47 @@ class TransferChain(ChainBase):
return True, ""
def manual_transfer(self, in_path: Path,
mediainfo: MediaInfo,
transfer_type: str = settings.TRANSFER_TYPE,
target: Path = None,
meta: MetaBase = None,
tmdbid: int = None,
mtype: MediaType = None,
season: int = None,
transfer_type: str = None,
epformat: EpisodeFormat = None,
min_filesize: int = 0) -> Tuple[bool, str]:
"""
手动转移
:param in_path: 源文件路径
:param mediainfo: 媒体信息
:param transfer_type: 转移类型
:param target: 目标路径
:param meta: 元数据
:param tmdbid: TMDB ID
:param mtype: 媒体类型
:param season: 季度
:param transfer_type: 转移类型
:param epformat: 剧集格式
:param min_filesize: 最小文件大小(MB)
"""
logger.info(f"手动转移:{in_path} ...")
# 默认转移类型
if not transfer_type:
transfer_type = settings.TRANSFER_TYPE
if tmdbid:
# 有输入TMDBID时单个识别
meta = MetaInfo(in_path.stem)
# 整合数据
if mtype:
meta.type = mtype
if season:
meta.begin_season = season
# 识别媒体信息
mediainfo: MediaInfo = self.mediachain.recognize_media(tmdbid=tmdbid, mtype=mtype)
if not mediainfo:
return False, f"媒体信息识别失败tmdbid: {tmdbid}, type: {mtype.value}"
# 开始进度
self.progress.start(ProgressKey.FileTransfer)
self.progress.update(value=0,
text=f"开始转移 {in_path} ...",
key=ProgressKey.FileTransfer)
# 开始转移
transferinfo: TransferInfo = self.transfer(
path=in_path,
@ -382,6 +388,115 @@ class TransferChain(ChainBase):
'mediainfo': mediainfo,
'transferinfo': transferinfo
})
self.progress.end(ProgressKey.FileTransfer)
logger.info(f"{in_path} 转移完成")
return True, ""
else:
# 错误信息
errmsgs = []
# 自动识别所有文件
transfer_files = SystemUtils.list_files(directory=in_path,
extensions=settings.RMT_MEDIAEXT,
min_filesize=min_filesize)
if not transfer_files:
return False, "没有找到可转移的文件"
# 开始进度
self.progress.start(ProgressKey.FileTransfer)
# 总数
total_num = len(transfer_files)
# 已处理数量
processed_num = 0
self.progress.update(value=0,
text=f"开始转移 {in_path},共 {total_num} 个文件 ...",
key=ProgressKey.FileTransfer)
for transfer_file in transfer_files:
# 更新进度
self.progress.update(value=processed_num / total_num * 100,
text=f"正在转移 {transfer_file.name} ...",
key=ProgressKey.FileTransfer)
# 上级目录元数据
meta = MetaInfo(title=transfer_file.parent.name)
# 文件元数据,不包含后缀
file_meta = MetaInfo(title=transfer_file.stem)
# 合并元数据
file_meta.merge(meta)
if not file_meta.name:
logger.error(f"{transfer_file} 无法识别有效信息")
errmsgs.append(f"{transfer_file.name} 无法识别有效信息")
# 更新进度
processed_num += 1
self.progress.update(value=processed_num / total_num * 100,
text=f"{transfer_file.name} 无法识别有效信息",
key=ProgressKey.FileTransfer)
continue
# 整合数据
if mtype:
file_meta.type = mtype
if season:
file_meta.begin_season = season
# 识别媒体信息
mediainfo: MediaInfo = self.mediachain.recognize_media(meta=file_meta)
if not mediainfo:
logger.error(f"{transfer_file} 媒体信息识别失败")
errmsgs.append(f"{transfer_file.name} 媒体信息识别失败")
# 更新进度
processed_num += 1
self.progress.update(value=processed_num / total_num * 100,
text=f"{transfer_file.name} 媒体信息识别失败!",
key=ProgressKey.FileTransfer)
continue
# 开始转移
transferinfo: TransferInfo = self.transfer(
path=in_path,
mediainfo=mediainfo,
transfer_type=transfer_type,
target=target,
meta=file_meta,
epformat=epformat,
min_filesize=min_filesize
)
if not transferinfo:
return False, "文件转移模块运行失败"
if not transferinfo.target_path:
logger.error(f"{transfer_file} 转移失败:{transferinfo.message}")
errmsgs.append(f"{transfer_file.name} 转移失败:{transferinfo.message}")
# 更新进度
processed_num += 1
self.progress.update(value=processed_num / total_num * 100,
text=f"{transfer_file.name} 转移失败:{transferinfo.message}",
key=ProgressKey.FileTransfer)
continue
# 新增转移成功历史记录
self.__insert_sucess_history(
src_path=transfer_file,
meta=file_meta,
mediainfo=mediainfo,
transferinfo=transferinfo
)
# 刮削元数据
self.scrape_metadata(path=transferinfo.target_path, mediainfo=mediainfo)
# 刷新媒体库
self.refresh_mediaserver(mediainfo=mediainfo, file_path=transferinfo.target_path)
# 发送通知
self.send_transfer_message(meta=file_meta, mediainfo=mediainfo, transferinfo=transferinfo)
# 广播事件
self.eventmanager.send_event(EventType.TransferComplete, {
'meta': file_meta,
'mediainfo': mediainfo,
'transferinfo': transferinfo
})
# 更新进度
processed_num += 1
self.progress.update(value=processed_num / total_num * 100,
text=f"{transfer_file.name} 转移完成",
key=ProgressKey.FileTransfer)
# 结束进度
logger.info(f"转移完成,共 {total_num} 个文件,成功 {total_num - len(errmsgs)} 个,失败 {len(errmsgs)}")
self.progress.end(ProgressKey.FileTransfer)
if errmsgs:
return False, "\n".join(errmsgs)
return True, ""
def __insert_sucess_history(self, src_path: Path, meta: MetaBase,