#!/usr/bin/env python3 import os import re import time import argparse import mandown def main(): parser = argparse.ArgumentParser( description="Rename Webtoon CBZ files using mandown metadata." ) parser.add_argument( "--folder", required=True, help="Path to the folder containing CBZ files." ) parser.add_argument("--url", required=True, help="Webtoon series URL.") parser.add_argument( "--series", required=True, help="Series name (e.g., 'Tower of God')." ) parser.add_argument( "--dry-run", action="store_true", help="Only print planned renames, do not modify files.", ) args = parser.parse_args() folder_path = args.folder url = args.url series_name = args.series dry_run = args.dry_run print("Fetching metadata with mandown...") series = mandown.get(url) chapters = {int(ch.slug.split(".")[0]): ch.title for ch in series.chapters} for filename in os.listdir(folder_path): match = re.search(r"epNo(\d+)", filename) if not match: continue ep_no = int(match.group(1)) if ep_no not in chapters: print(f"[!] Episode {ep_no} not found in metadata, skipping.") continue chapter_title = chapters[ep_no] safe_title = re.sub(r'[\\/:"*?<>|]+', "", chapter_title) new_name = f"{series_name} - Chapter {ep_no} - {safe_title}.cbz" src = os.path.join(folder_path, filename) dst = os.path.join(folder_path, new_name) if dry_run: print(f"[DRY-RUN] Would rename: {filename} -> {new_name}") else: os.rename(src, dst) print(f"Renamed: {filename} -> {new_name}") time.sleep(0.1) # optional delay if __name__ == "__main__": main()