Files
XCDownloader/series.py
2025-04-25 12:12:02 +00:00

154 lines
6.3 KiB
Python

import os
from urllib.parse import urlparse
from common import sanitize_filename, download_with_aria2c, download_file_with_progress, aria2c_exists
def show_series_categories(series_dict):
print("\nSeries Categories\n" + "*" * 30)
categories = sorted(series_dict.keys())
for i, cat in enumerate(categories, 1):
print(f"{i}. {cat}")
try:
cat_index = int(input("\nSelect a category number: ").strip())
if 1 <= cat_index <= len(categories):
selected_category = categories[cat_index - 1]
show_series_names(series_dict, selected_category)
except ValueError:
print("Invalid input.")
def show_series_names(series_dict, category):
while True:
print(f"\nSeries in Category: {category}\n" + "*" * 30)
series_names = sorted(series_dict[category].keys())
for i, name in enumerate(series_names, 1):
print(f"{i}. {name}")
print(f"\nMenu for Category: {category} \n" + "*" * 30)
print(f"1. Download all series from category: {category}")
print("2. Select a series name number")
choice = input("Select (1 or 2): ").strip()
if choice == '1':
for name in series_dict[category]:
for season in series_dict[category][name]:
for episode in series_dict[category][name][season]:
download_series_episode(category, name, season, episode)
elif choice == '2':
try:
name_index = int(input("Enter series number: ").strip())
series_names = sorted(series_dict[category].keys())
if 1 <= name_index <= len(series_names):
selected_name = series_names[name_index - 1]
result = open_series_menu(series_dict, category, selected_name)
if result == "mainmenu":
return
except ValueError:
print("Invalid input.")
else:
print("Invalid input.")
def open_series_menu(series_dict, category, selected_name):
while True:
print(f"\nMenu for Series: {selected_name} \n" + "*" * 30)
print(f"1. Show all seasons and episodes for: {selected_name}")
print(f"2. Download all seasons and episodes for: {selected_name}")
print("3. Go Back (to Series List)")
print("4. Go to Main Menu")
print("5. Exit the script")
sub_choice = input("Select: ").strip()
if sub_choice == '1':
result = show_seasons(series_dict, category, selected_name)
if result == "mainmenu":
return "mainmenu"
elif sub_choice == '2':
for season in series_dict[category][selected_name]:
for episode in series_dict[category][selected_name][season]:
download_series_episode(category, selected_name, season, episode)
elif sub_choice == '3':
return
elif sub_choice == '4':
return "mainmenu"
elif sub_choice == '5':
print("\nExiting the script. Goodbye!")
exit()
else:
print("Invalid selection.")
def show_seasons(series_dict, category, series_name):
print(f"\nSeasons for {series_name} in {category}\n" + "*" * 30)
seasons = sorted(series_dict[category][series_name].keys())
for i, season in enumerate(seasons, 1):
print(f"{i}. {season}")
try:
season_index = int(input("\nSelect a season: ").strip())
if 1 <= season_index <= len(seasons):
selected_season = seasons[season_index - 1]
result = show_episodes(series_dict, category, series_name, selected_season)
if result == "mainmenu":
return "mainmenu"
except ValueError:
print("Invalid input.")
def show_episodes(series_dict, category, series_name, season):
episodes = series_dict[category][series_name][season]
print(f"\nEpisodes in {season} of {series_name} ({category})\n" + "*" * 30)
for i, ep in enumerate(episodes, 1):
print(f"{i}. {ep['title']}")
while True:
print("\nEpisode Menu\n" + "*" * 30)
print("1. Download selected Episodes")
print("2. Download all Episodes")
print("3. Go back (to Seasons List)")
print("4. Go to Main Menu")
print("5. Exit the script")
choice = input("Select: ").strip()
if choice == '1':
selected = input_range("Enter episode numbers (e.g., 1,2,4-6): ", len(episodes))
for idx in selected:
download_series_episode(category, series_name, season, episodes[idx - 1])
elif choice == '2':
for ep in episodes:
download_series_episode(category, series_name, season, ep)
elif choice == '3':
return
elif choice == '4':
return "mainmenu"
elif choice == '5':
exit()
else:
print("Invalid choice.")
def input_range(prompt, max_val):
inp = input(prompt)
selected = set()
for part in inp.split(','):
if '-' in part:
start, end = map(int, part.split('-'))
selected.update(range(start, end + 1))
else:
selected.add(int(part))
return [i for i in selected if 1 <= i <= max_val]
def download_series_episode(category, series_name, season, episode):
title = sanitize_filename(episode['title'])
group = sanitize_filename(category)
s_name = sanitize_filename(series_name)
base_dir = os.path.join("Series", group, s_name, season, episode['episode'])
os.makedirs(base_dir, exist_ok=True)
media_ext = os.path.splitext(episode['media_url'])[1]
media_path = os.path.join(base_dir, f"{title}{media_ext}")
if not os.path.exists(media_path) or os.path.getsize(media_path) < 5 * 1024 * 1024:
if aria2c_exists():
download_with_aria2c(episode['media_url'], media_path)
else:
download_file_with_progress(episode['media_url'], media_path, title)
else:
print(f"✔ Already downloaded: {title}")
if episode['logo_url']:
logo_filename = os.path.basename(urlparse(episode['logo_url']).path)
logo_path = os.path.join(base_dir, logo_filename)
if not os.path.exists(logo_path):
download_file_with_progress(episode['logo_url'], logo_path, f"{title} (logo)")
else:
print(f"✔ Logo exists for {title}")