Add watchlist episode offset naming

This commit is contained in:
Dymas
2026-05-25 17:57:42 +02:00
parent d10ae832b3
commit 75262d261d
8 changed files with 210 additions and 14 deletions
+31 -1
View File
@@ -20,7 +20,7 @@ from uuid import uuid4
PROJECT_ROOT = Path(__file__).resolve().parent
ANI_CLI = os.environ.get("ANI_CLI_BIN") or shutil.which("ani-cli") or "ani-cli"
APP_NAME = "ani-cli-web"
VERSION = "0.44.1"
VERSION = "0.45.0"
ALLANIME_BASE = "allanime.day"
ALLANIME_API = f"https://api.{ALLANIME_BASE}"
ALLANIME_REFERER = "https://allmanga.to"
@@ -709,6 +709,18 @@ def normalize_season(value):
return str(number)
def normalize_episode_offset(value):
text = str(value or "").strip()
if not text:
return None
if not re.match(r"^[0-9]+$", text):
raise ValueError("Episode offset must be a positive number")
number = int(text, 10)
if number < 1:
raise ValueError("Episode offset must be a positive number")
return str(number)
def normalize_media_type(value, default="tv"):
media_type = str(value or default).strip().lower()
return media_type if media_type in MEDIA_TYPE_CHOICES else default
@@ -741,6 +753,21 @@ def episode_label(value):
return re.sub(r"[^0-9A-Za-z.]+", "-", text).strip("-") or "00"
def apply_episode_offset(value, offset):
normalized_offset = normalize_episode_offset(offset)
text = str(value or "").strip()
if not normalized_offset or not text:
return text
match = re.match(r"^0*([0-9]+)(.*)$", text)
if not match:
return text
number = int(match.group(1) or "0", 10)
if number < 1:
return text
suffix = match.group(2) or ""
return f"{int(normalized_offset, 10) + number - 1}{suffix}"
def extract_episode_from_filename(path):
match = re.search(r"\bEpisode\s+([0-9][0-9A-Za-z.\-]*)\s*$", path.stem)
return match.group(1) if match else None
@@ -763,6 +790,7 @@ def finalize_library_files(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"))
target_dir.mkdir(parents=True, exist_ok=True)
files = sorted(
[path for path in staging_dir.iterdir() if path.is_file()],
@@ -781,6 +809,7 @@ def finalize_library_files(job):
if ep is None:
ep = str(fallback_episode)
fallback_episode += 1
ep = apply_episode_offset(ep, episode_offset)
final_name = f"{library_name} - S{season}E{episode_label(ep)}{source.suffix}"
destination = unique_destination(target_dir / final_name)
shutil.move(str(source), str(destination))
@@ -824,6 +853,7 @@ def build_job(payload, config):
"anime_name": anime_name,
"media_type": media_type,
"season": normalize_season(payload.get("season")),
"episode_offset": normalize_episode_offset(payload.get("episode_offset")),
"query": query,
"result_index": index,
"mode": mode,