[+] More CLI control
This commit is contained in:
+24
-22
@@ -30,7 +30,7 @@ def get_tt_ids_in_jellyfin(jellyfin_dir):
|
|||||||
|
|
||||||
return found_ids
|
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...")
|
print("Gathering basic info...")
|
||||||
jellyfin_tt_ids = get_tt_ids_in_jellyfin(DEFAULT_JELLYFIN_DIR)
|
jellyfin_tt_ids = get_tt_ids_in_jellyfin(DEFAULT_JELLYFIN_DIR)
|
||||||
|
|
||||||
@@ -144,26 +144,27 @@ def detect_anomalies(expected_tt_ids=None):
|
|||||||
else:
|
else:
|
||||||
print("All downloaded torrents have at least one file linked in Jellyfin.")
|
print("All downloaded torrents have at least one file linked in Jellyfin.")
|
||||||
|
|
||||||
print(f"\n=== Anomaly 7: Torrents with missing files on disk ===")
|
if check_missing_files:
|
||||||
torrents_with_missing_files = []
|
print(f"\n=== Anomaly 7: Torrents with missing files on disk ===")
|
||||||
for t in torrents:
|
torrents_with_missing_files = []
|
||||||
try:
|
for t in torrents:
|
||||||
files = qb.torrents_files(torrent_hash=t.hash)
|
try:
|
||||||
if files:
|
files = qb.torrents_files(torrent_hash=t.hash)
|
||||||
first_file_name = getattr(files[0], 'name', '')
|
if files:
|
||||||
save_path = getattr(t, 'save_path', '')
|
first_file_name = getattr(files[0], 'name', '')
|
||||||
if first_file_name and save_path:
|
save_path = getattr(t, 'save_path', '')
|
||||||
full_path = Path(save_path) / first_file_name
|
if first_file_name and save_path:
|
||||||
if not full_path.exists():
|
full_path = Path(save_path) / first_file_name
|
||||||
torrents_with_missing_files.append(t.name)
|
if not full_path.exists():
|
||||||
except Exception:
|
torrents_with_missing_files.append(t.name)
|
||||||
pass
|
except Exception:
|
||||||
|
pass
|
||||||
if torrents_with_missing_files:
|
|
||||||
for name in torrents_with_missing_files:
|
if torrents_with_missing_files:
|
||||||
print(f"Warning: Torrent '{name}' is missing files on disk!")
|
for name in torrents_with_missing_files:
|
||||||
else:
|
print(f"Warning: Torrent '{name}' is missing files on disk!")
|
||||||
print("All torrents have their files intact on disk.")
|
else:
|
||||||
|
print("All torrents have their files intact on disk.")
|
||||||
|
|
||||||
if expected_tt_ids:
|
if expected_tt_ids:
|
||||||
print(f"\n=== Anomaly 4: Provided IMDb IDs missing from Jellyfin ===")
|
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__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Find anomalies between torrents, local downloads, and Jellyfin folders.")
|
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("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()
|
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)
|
||||||
|
|||||||
+26
-23
@@ -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)
|
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}")
|
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.
|
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}]")
|
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()
|
qb = get_qb_client()
|
||||||
existing_t_hashes = check_qbittorrent(qb, imdb_id)
|
|
||||||
|
|
||||||
hashes_to_process = []
|
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:
|
if existing_t_hashes:
|
||||||
print(f"Found {len(existing_t_hashes)} existing torrent(s), skipping local check, search, and download.")
|
print(f"Found {len(existing_t_hashes)} existing torrent(s), skipping local check, search, and download.")
|
||||||
for existing_t_hash in existing_t_hashes:
|
for existing_t_hash in existing_t_hashes:
|
||||||
rename_torrent_and_folder(qb, existing_t_hash, new_name)
|
rename_torrent_and_folder(qb, existing_t_hash, new_name)
|
||||||
|
|
||||||
print(f"\n=== [0.3] Waiting for existing download to finish ===")
|
print(f"\n=== [0.3] Waiting for existing download to finish ===")
|
||||||
wait_for_download(qb, existing_t_hash)
|
wait_for_download(qb, existing_t_hash)
|
||||||
|
|
||||||
hashes_to_process.append((existing_t_hash, "existing"))
|
hashes_to_process.append((existing_t_hash, "existing"))
|
||||||
else:
|
else:
|
||||||
print(f"\n=== [0.5] Checking if already exists in file system ===")
|
print(f"\n=== [0.5] Checking if already exists in file system ===")
|
||||||
fs_match_dir = check_local_filesystem(dl_dir, imdb_id)
|
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 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)
|
hashes_to_process = search_and_download_mteam(qb, imdb_id, new_name, dl_dir)
|
||||||
|
|
||||||
# Process qB torrents
|
# 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("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("--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("--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()
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user