Spaces:
Paused
Paused
from flask import Flask, jsonify, request, send_from_directory | |
import os | |
import json | |
import threading | |
from hf_scrapper import download_file, get_system_proxies, get_download_progress | |
from indexer import indexer | |
from tvdb import fetch_and_cache_json | |
import re | |
app = Flask(__name__) | |
# Constants and Configuration | |
CACHE_DIR = os.getenv("CACHE_DIR") | |
INDEX_FILE = os.getenv("INDEX_FILE") | |
TOKEN = os.getenv("TOKEN") | |
FILM_STORE_JSON_PATH = os.path.join(CACHE_DIR, "film_store.json") | |
download_threads = {} | |
# Ensure CACHE_DIR exists | |
if not os.path.exists(CACHE_DIR): | |
os.makedirs(CACHE_DIR) | |
if not os.path.exists(FILM_STORE_JSON_PATH): | |
with open(FILM_STORE_JSON_PATH, 'w') as json_file: | |
json.dump({}, json_file) | |
# Index the file structure | |
indexer() | |
# Load the file structure JSON | |
if not os.path.exists(INDEX_FILE): | |
raise FileNotFoundError(f"{INDEX_FILE} not found. Please make sure the file exists.") | |
with open(INDEX_FILE, 'r') as f: | |
file_structure = json.load(f) | |
# Function Definitions | |
def load_json(file_path): | |
"""Load JSON data from a file.""" | |
with open(file_path, 'r') as file: | |
return json.load(file) | |
def find_movie_path(json_data, title): | |
"""Find the path of the movie in the JSON data based on the title.""" | |
for directory in json_data: | |
if directory['type'] == 'directory' and directory['path'] == 'films': | |
for sub_directory in directory['contents']: | |
if sub_directory['type'] == 'directory': | |
for item in sub_directory['contents']: | |
if item['type'] == 'file' and title.lower() in item['path'].lower(): | |
return item['path'] | |
return None | |
def get_film_id(title): | |
"""Generate a film ID based on the title.""" | |
return title.replace(" ", "_").lower() | |
def prefetch_metadata(): | |
"""Prefetch metadata for all items in the file structure.""" | |
for item in file_structure: | |
if 'contents' in item: | |
for sub_item in item['contents']: | |
original_title = sub_item['path'].split('/')[-1] | |
media_type = 'series' if item['path'].startswith('tv') else 'movie' | |
title = original_title | |
year = None | |
# Extract year from the title if available | |
match = re.search(r'\((\d{4})\)', original_title) | |
if match: | |
year_str = match.group(1) | |
if year_str.isdigit() and len(year_str) == 4: | |
title = original_title[:match.start()].strip() | |
year = int(year_str) | |
else: | |
parts = original_title.rsplit(' ', 1) | |
if len(parts) > 1 and parts[-1].isdigit() and len(parts[-1]) == 4: | |
title = parts[0].strip() | |
year = int(parts[-1]) | |
fetch_and_cache_json(original_title, title, media_type, year) | |
def start_prefetching(): | |
"""Start the metadata prefetching in a separate thread.""" | |
prefetch_metadata() | |
# Start prefetching metadata | |
thread = threading.Thread(target=start_prefetching) | |
thread.daemon = True | |
thread.start() | |
# API Endpoints | |
def get_movie(): | |
"""Endpoint to get the movie by title.""" | |
title = request.args.get('title') | |
if not title: | |
return jsonify({"error": "Title parameter is required"}), 400 | |
# Load the film store JSON | |
with open(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)) | |
# If not cached, find the movie path in the index file | |
json_data = load_json(INDEX_FILE) | |
movie_path = find_movie_path(json_data, 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/Unicone-Studio/jellyfin_media/resolve/main/{movie_path}" | |
proxies = get_system_proxies() | |
film_id = get_film_id(title) | |
# Start the download in a separate thread if not already downloading | |
if film_id not in download_threads or not download_threads[film_id].is_alive(): | |
thread = threading.Thread(target=download_file, args=(file_url, TOKEN, cache_path, proxies, film_id, title)) | |
download_threads[film_id] = thread | |
thread.start() | |
return jsonify({"status": "Download started", "film_id": film_id}) | |
def get_progress(film_id): | |
"""Endpoint to get the download progress of a movie.""" | |
progress = get_download_progress(film_id) | |
return jsonify({"film_id": film_id, "progress": progress}) | |
def get_film_id_by_title(): | |
"""Endpoint to get the film ID by providing the movie title.""" | |
title = request.args.get('title') | |
if not title: | |
return jsonify({"error": "Title parameter is required"}), 400 | |
film_id = get_film_id(title) | |
return jsonify({"film_id": film_id}) | |
def get_film_store(): | |
"""Endpoint to get the film store JSON.""" | |
if os.path.exists(FILM_STORE_JSON_PATH): | |
with open(FILM_STORE_JSON_PATH, 'r') as json_file: | |
film_store_data = json.load(json_file) | |
return jsonify(film_store_data) | |
return jsonify({}), 404 | |
# Routes | |
def index(): | |
return "Server Runing" | |
# Main entry point | |
if __name__ == "__main__": | |
app.run(debug=True, host="0.0.0.0", port=7860) | |