Preserve completed episodes from failed batches

This commit is contained in:
Dymas
2026-08-18 08:43:30 +02:00
parent 8e95ffc79b
commit d663318f27
6 changed files with 155 additions and 10 deletions
+44 -6
View File
@@ -1037,6 +1037,16 @@ def extract_episode_from_filename(path):
return match.group(1) if match else None
def episode_match_key(value):
text = str(value or "").strip().lower()
match = re.match(r"^0*([0-9]+)(.*)$", text)
if not match:
return text
number = int(match.group(1) or "0", 10)
suffix = str(match.group(2) or "")
return f"{number}{suffix}" if number > 0 else text
def unique_destination(path):
if not path.exists():
return path
@@ -1048,19 +1058,44 @@ def unique_destination(path):
counter += 1
def finalize_library_files(job):
def cleanup_empty_staging_dirs(staging_dir, remove_root=False):
for path in sorted(staging_dir.rglob("*"), key=lambda item: len(item.parts), reverse=True):
if path.is_dir():
try:
path.rmdir()
except OSError:
pass
if remove_root:
try:
staging_dir.rmdir()
except OSError:
pass
def finalize_library_files(job, episode=None, cleanup_staging=True, allow_empty=False):
staging_dir = job_staging_dir(job)
target_dir = job_output_dir(job)
library_name = sanitize_path_component(job.get("anime_name") or job.get("title"))
media_type = normalize_media_type(job.get("media_type"))
season = season_label(job)
episode_offset = normalize_episode_offset(job.get("episode_offset"))
episode_filter = episode_match_key(episode) if episode not in (None, "") else None
target_dir.mkdir(parents=True, exist_ok=True)
files = sorted(
[path for path in staging_dir.rglob("*") if path.is_file()],
key=lambda path: (path.stat().st_mtime, str(path.relative_to(staging_dir)).lower()),
)
files = []
for path in staging_dir.rglob("*"):
if not path.is_file() or str(path.name).endswith(".part"):
continue
if episode_filter is not None:
extracted = extract_episode_from_filename(path)
if episode_match_key(extracted) != episode_filter:
continue
files.append(path)
files = sorted(files, key=lambda path: (path.stat().st_mtime, str(path.relative_to(staging_dir)).lower()))
if not files:
if allow_empty:
if cleanup_staging:
shutil.rmtree(staging_dir, ignore_errors=True)
return []
raise RuntimeError("No downloaded files were found in the staging folder")
moved = []
@@ -1081,7 +1116,10 @@ def finalize_library_files(job):
shutil.move(str(source), str(destination))
moved.append(str(destination))
shutil.rmtree(staging_dir, ignore_errors=True)
if cleanup_staging:
shutil.rmtree(staging_dir, ignore_errors=True)
else:
cleanup_empty_staging_dirs(staging_dir, remove_root=False)
return moved