fix: prevent duplicate transfer uploads

This commit is contained in:
jxxghp
2026-05-20 16:39:07 +08:00
parent 72ead2970c
commit e00aa42f94
4 changed files with 182 additions and 6 deletions
+35 -4
View File
@@ -101,6 +101,18 @@ class JobManager:
return None, season
return media.tmdb_id or media.douban_id, season
@staticmethod
def __get_file_key(fileitem: FileItem) -> Optional[Tuple[str, str]]:
"""
获取源文件唯一键,用于跨媒体作业识别同一个整理任务。
"""
if not fileitem or not fileitem.path:
return None
normalized_path = (
Path(str(fileitem.path).replace("\\", "/")).as_posix().rstrip("/") or "/"
)
return fileitem.storage or "local", normalized_path
def __get_id(self, task: TransferTask = None) -> Tuple:
"""
获取作业ID
@@ -146,8 +158,19 @@ class JobManager:
"""
if not all([task, task.meta, task.fileitem]):
return False
file_key = self.__get_file_key(task.fileitem)
if not file_key:
return False
with job_lock:
__mediaid__ = self.__get_id(task)
# 同一个源文件可能在识别前后落入不同作业,必须跨作业去重。
if any(
self.__get_file_key(t.fileitem) == file_key
for job in self._job_view.values()
for t in job.tasks
):
logger.debug(f"任务 {task.fileitem.name} 已存在,跳过重复添加")
return False
if __mediaid__ not in self._job_view:
self._job_view[__mediaid__] = TransferJob(
media=self.__get_media(task),
@@ -166,7 +189,7 @@ class JobManager:
# 不重复添加任务
if any(
[
t.fileitem == task.fileitem
self.__get_file_key(t.fileitem) == file_key
for t in self._job_view[__mediaid__].tasks
]
):
@@ -282,10 +305,13 @@ class JobManager:
"""
if not task or not task.fileitem:
return
file_key = self.__get_file_key(task.fileitem)
if not file_key:
return
with job_lock:
for mediaid, job in self._job_view.items():
for job_task in job.tasks:
if job_task.fileitem != task.fileitem:
if self.__get_file_key(job_task.fileitem) != file_key:
continue
if job_task.state not in ["completed", "failed"]:
job_task.state = "failed"
@@ -309,11 +335,14 @@ class JobManager:
"""
根据文件项移除任务,并返回任务所在的作业ID
"""
file_key = self.__get_file_key(fileitem)
if not file_key:
return None, None
with job_lock:
for mediaid in list(self._job_view):
job = self._job_view[mediaid]
for task in job.tasks:
if task.fileitem == fileitem:
if self.__get_file_key(task.fileitem) == file_key:
job.tasks.remove(task)
# 如果没有作业了,则移除作业
if not job.tasks:
@@ -1594,7 +1623,9 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton):
# 更新任务信息
task.mediainfo = mediainfo
# 更新队列任务
self.jobview.migrate_task(task)
if not self.jobview.migrate_task(task):
logger.info(f"{task.fileitem.name} 已存在整理任务,跳过重复处理")
return False, f"{task.fileitem.name} 已在整理队列中"
# 获取集数据
if task.mediainfo.type == MediaType.TV and not task.episodes_info: