From 226d9d0508fb98b94746197b41879180a529cd0f Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Tue, 10 Mar 2026 22:08:02 -0400 Subject: [PATCH] [+] More CLI control --- detect_anomalies.py | 46 ++++++++++++++++++++++-------------------- workflow.py | 49 ++++++++++++++++++++++++--------------------- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/detect_anomalies.py b/detect_anomalies.py index 8afde38..fc80a72 100644 --- a/detect_anomalies.py +++ b/detect_anomalies.py @@ -30,7 +30,7 @@ def get_tt_ids_in_jellyfin(jellyfin_dir): return found_ids -def detect_anomalies(expected_tt_ids=None): +def detect_anomalies(expected_tt_ids=None, check_missing_files=False): print("Gathering basic info...") jellyfin_tt_ids = get_tt_ids_in_jellyfin(DEFAULT_JELLYFIN_DIR) @@ -144,26 +144,27 @@ def detect_anomalies(expected_tt_ids=None): else: print("All downloaded torrents have at least one file linked in Jellyfin.") - print(f"\n=== Anomaly 7: Torrents with missing files on disk ===") - torrents_with_missing_files = [] - for t in torrents: - try: - files = qb.torrents_files(torrent_hash=t.hash) - if files: - first_file_name = getattr(files[0], 'name', '') - save_path = getattr(t, 'save_path', '') - if first_file_name and save_path: - full_path = Path(save_path) / first_file_name - if not full_path.exists(): - torrents_with_missing_files.append(t.name) - except Exception: - pass - - if torrents_with_missing_files: - for name in torrents_with_missing_files: - print(f"Warning: Torrent '{name}' is missing files on disk!") - else: - print("All torrents have their files intact on disk.") + if check_missing_files: + print(f"\n=== Anomaly 7: Torrents with missing files on disk ===") + torrents_with_missing_files = [] + for t in torrents: + try: + files = qb.torrents_files(torrent_hash=t.hash) + if files: + first_file_name = getattr(files[0], 'name', '') + save_path = getattr(t, 'save_path', '') + if first_file_name and save_path: + full_path = Path(save_path) / first_file_name + if not full_path.exists(): + torrents_with_missing_files.append(t.name) + except Exception: + pass + + if torrents_with_missing_files: + for name in torrents_with_missing_files: + print(f"Warning: Torrent '{name}' is missing files on disk!") + else: + print("All torrents have their files intact on disk.") if expected_tt_ids: print(f"\n=== Anomaly 4: Provided IMDb IDs missing from Jellyfin ===") @@ -183,6 +184,7 @@ def detect_anomalies(expected_tt_ids=None): if __name__ == "__main__": parser = argparse.ArgumentParser(description="Find anomalies between torrents, local downloads, and Jellyfin folders.") parser.add_argument("tt_ids", nargs="*", help="Optional space-separated list of IMDb IDs (e.g., tt1234567 tt7654321) to verify their presence in Jellyfin.") + parser.add_argument("--check-missing-files", action="store_true", help="Enable the slow check for missing files on disk for all torrents.") args = parser.parse_args() - detect_anomalies(expected_tt_ids=args.tt_ids) + detect_anomalies(expected_tt_ids=args.tt_ids, check_missing_files=args.check_missing_files) diff --git a/workflow.py b/workflow.py index 12b7893..7a837c1 100644 --- a/workflow.py +++ b/workflow.py @@ -251,7 +251,7 @@ def process_local_file(fs_path: Path, title_dir: str, imdb_id: str, jellyfin_bas apply_rename_mapping(mapping, base_src_dir=src_dir_for_mapping, base_dst_dir=jellyfin_base) print(f"Finished processing local file: {fs_path.name}") -def process_imdb_workflow(imdb_id: str, dl_dir: str = DEFAULT_DL_DIR, jellyfin_base_dir: str = DEFAULT_JELLYFIN_DIR, imdb_source: str = "mteam"): +def process_imdb_workflow(imdb_id: str, dl_dir: str = DEFAULT_DL_DIR, jellyfin_base_dir: str = DEFAULT_JELLYFIN_DIR, imdb_source: str = "imdbapi", ignore_existing: bool = False): """ Workflow to automatically find, download, and map torrents for an IMDb ID into a Jellyfin library. """ @@ -277,30 +277,32 @@ def process_imdb_workflow(imdb_id: str, dl_dir: str = DEFAULT_DL_DIR, jellyfin_b new_name = sanitize_filename(f"{year} {title} [{imdb_id}]") - print(f"\n=== [0.2] Checking if torrent already exists in qBittorrent ===") qb = get_qb_client() - existing_t_hashes = check_qbittorrent(qb, imdb_id) - hashes_to_process = [] + + if not ignore_existing: + print(f"\n=== [0.2] Checking if torrent already exists in qBittorrent ===") + existing_t_hashes = check_qbittorrent(qb, imdb_id) - if existing_t_hashes: - print(f"Found {len(existing_t_hashes)} existing torrent(s), skipping local check, search, and download.") - for existing_t_hash in existing_t_hashes: - rename_torrent_and_folder(qb, existing_t_hash, new_name) - - print(f"\n=== [0.3] Waiting for existing download to finish ===") - wait_for_download(qb, existing_t_hash) - - hashes_to_process.append((existing_t_hash, "existing")) - else: - print(f"\n=== [0.5] Checking if already exists in file system ===") - fs_match_dir = check_local_filesystem(dl_dir, imdb_id) - - if fs_match_dir: - print(f"Found existing file/directory in file system: {fs_match_dir.name}, skipping search and download.") - process_local_file(fs_match_dir, title_dir, imdb_id, jellyfin_base_dir) - return + if existing_t_hashes: + print(f"Found {len(existing_t_hashes)} existing torrent(s), skipping local check, search, and download.") + for existing_t_hash in existing_t_hashes: + rename_torrent_and_folder(qb, existing_t_hash, new_name) + + print(f"\n=== [0.3] Waiting for existing download to finish ===") + wait_for_download(qb, existing_t_hash) + + hashes_to_process.append((existing_t_hash, "existing")) + else: + print(f"\n=== [0.5] Checking if already exists in file system ===") + fs_match_dir = check_local_filesystem(dl_dir, imdb_id) + if fs_match_dir: + print(f"Found existing file/directory in file system: {fs_match_dir.name}, skipping search and download.") + process_local_file(fs_match_dir, title_dir, imdb_id, jellyfin_base_dir) + return + + if not hashes_to_process: hashes_to_process = search_and_download_mteam(qb, imdb_id, new_name, dl_dir) # Process qB torrents @@ -314,8 +316,9 @@ if __name__ == "__main__": parser.add_argument("imdb_id", type=str, help="The IMDb ID to process (e.g., tt38872297)") parser.add_argument("--dl-dir", type=str, default=DEFAULT_DL_DIR, help="The qBittorrent download directory") parser.add_argument("--jellyfin-dir", type=str, default=DEFAULT_JELLYFIN_DIR, help="The base Jellyfin library directory") - parser.add_argument("--imdb-source", type=str, choices=["mteam", "imdbapi"], default="mteam", help="The source for IMDb metadata (mteam or imdbapi)") + parser.add_argument("--imdb-source", type=str, choices=["mteam", "imdbapi"], default="imdbapi", help="The source for IMDb metadata (mteam or imdbapi)") + parser.add_argument("--ignore-existing", action="store_true", help="Ignore any existing torrents or local files and force a new search and download.") args = parser.parse_args() - process_imdb_workflow(args.imdb_id, dl_dir=args.dl_dir, jellyfin_base_dir=args.jellyfin_dir, imdb_source=args.imdb_source) + process_imdb_workflow(args.imdb_id, dl_dir=args.dl_dir, jellyfin_base_dir=args.jellyfin_dir, imdb_source=args.imdb_source, ignore_existing=args.ignore_existing)