Preserve completed episodes from failed batches
This commit is contained in:
+44
-6
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user