from flask import Flask, jsonify, request, send_from_directory from flask_cors import CORS import os import json from threading import Thread import urllib.parse from Instance import Instance from api import LoadBalancerAPI app = Flask(__name__) CORS(app) # Constants and Configuration CACHE_DIR = os.getenv("CACHE_DIR") INDEX_FILE = os.getenv("INDEX_FILE") TOKEN = os.getenv("TOKEN") REPO = os.getenv("REPO") ID = os.getenv("ID") URL = os.getenv("URL") LOAD_BALANCER_URL = os.getenv("LOAD_BALANCER_URL") load_balancer_api = LoadBalancerAPI(base_url=LOAD_BALANCER_URL) instance = Instance(id=ID, url=URL, cache_dir=CACHE_DIR, index_file=INDEX_FILE, token=TOKEN, repo=REPO, load_balancer_api=load_balancer_api) # API Endpoints @app.route('/api/film/', methods=['GET']) def get_movie_api(title): """Endpoint to get the movie by title.""" if not title: return jsonify({"error": "Title parameter is required"}), 400 # Load the film store JSON with open(instance.FILM_STORE_JSON_PATH, 'r') as json_file: film_store_data = json.load(json_file) # Check if the film is already cached if title in film_store_data: cache_path = film_store_data[title] if os.path.exists(cache_path): return send_from_directory(os.path.dirname(cache_path), os.path.basename(cache_path)) movie_path = instance.find_movie_path(title) if not movie_path: return jsonify({"error": "Movie not found"}), 404 cache_path = os.path.join(CACHE_DIR, movie_path) file_url = f"https://huggingface.co/{REPO}/resolve/main/{movie_path}" proxies = instance.get_system_proxies() film_id = instance.get_film_id(title) # Start the download in a separate thread if not already downloading if film_id not in instance.download_threads or not instance.download_threads[film_id].is_alive(): thread = Thread(target=instance.download_film, args=(file_url, TOKEN, cache_path, proxies, film_id, title)) instance.download_threads[film_id] = thread thread.start() return jsonify({"status": "Download started", "film_id": film_id}) @app.route('/api/tv/<title>/<season>/<episode>', methods=['GET']) def get_tv_show_api(title, season, episode): """Endpoint to get the TV show by title, season, and episode.""" if not title or not season or not episode: return jsonify({"error": "Title, season, and episode parameters are required"}), 400 # Load the TV store JSON with open(instance.TV_STORE_JSON_PATH, 'r') as json_file: tv_store_data = json.load(json_file) # Check if the episode is already cached if title in tv_store_data and season in tv_store_data[title]: for ep in tv_store_data[title][season]: if episode in ep: cache_path = tv_store_data[title][season][ep] print(cache_path) if os.path.exists(cache_path): return send_from_directory(os.path.dirname(cache_path), os.path.basename(cache_path)) tv_path = instance.find_tv_path(title) if not tv_path: return jsonify({"error": "TV show not found"}), 404 episode_path = None for directory in instance.file_structure: if directory['type'] == 'directory' and directory['path'] == 'tv': for sub_directory in directory['contents']: if sub_directory['type'] == 'directory' and title.lower() in sub_directory['path'].lower(): for season_dir in sub_directory['contents']: if season_dir['type'] == 'directory' and season in season_dir['path']: for episode_file in season_dir['contents']: if episode_file['type'] == 'file' and episode in episode_file['path']: episode_path = episode_file['path'] break if not episode_path: return jsonify({"error": "Episode not found"}), 404 cache_path = os.path.join(CACHE_DIR, episode_path) file_url = f"https://huggingface.co/{REPO}/resolve/main/{episode_path}" proxies = instance.get_system_proxies() episode_id = instance.encode_episodeid(title, season, episode) # Start the download in a separate thread if not already downloading if episode_id not in instance.download_threads or not instance.download_threads[episode_id].is_alive(): thread = Thread(target=instance.download_episode, args=(file_url, TOKEN, cache_path, proxies, episode_id, title)) instance.download_threads[episode_id] = thread thread.start() return jsonify({"status": "Download started", "episode_id": episode_id}) @app.route('/api/progress/<id>', methods=['GET']) def get_progress_api(id): """Endpoint to get the download progress of a movie or TV show episode.""" progress = instance.get_download_progress(id) return jsonify({"id": id, "progress": progress}) @app.route('/api/cache/size', methods=['GET']) def get_cache_size_api(): total_size = 0 for dirpath, dirnames, filenames in os.walk(CACHE_DIR): for f in filenames: fp = os.path.join(dirpath, f) total_size += os.path.getsize(fp) readable_size = instance.bytes_to_human_readable(total_size) return jsonify({"cache_size": readable_size}) @app.route('/api/cache/clear', methods=['POST']) def clear_cache_api(): for dirpath, dirnames, filenames in os.walk(CACHE_DIR): for f in filenames: fp = os.path.join(dirpath, f) os.remove(fp) return jsonify({"status": "Cache cleared"}) @app.route('/api/tv/store', methods=['GET']) def get_tv_store_api(): """Endpoint to get the TV store JSON.""" if os.path.exists(instance.TV_STORE_JSON_PATH): with open(instance.TV_STORE_JSON_PATH, 'r') as json_file: tv_store_data = json.load(json_file) return jsonify(tv_store_data) return jsonify({}), 404 @app.route('/api/film/store', methods=['GET']) def get_film_store_api(): """Endpoint to get the film store JSON.""" if os.path.exists(instance.FILM_STORE_JSON_PATH): with open(instance.FILM_STORE_JSON_PATH, 'r') as json_file: tv_store_data = json.load(json_file) return jsonify(tv_store_data) return jsonify({}), 404 @app.route("/api/film/all") def get_all_films_api(): return instance.get_all_films() @app.route("/api/tv/all") def get_all_tvshows_api(): return instance.get_all_tv_shows() @app.route("/api/get/report",methods=["GET"]) def get_report(): report=instance.compile_report() return jsonify(report) # Routes @app.route('/') def index(): return f"{instance.id} Server Running Version {instance.version}" # Main entry point if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=7860)