instance2 / app.py
ChandimaPrabath's picture
indexer
a6f96dc
raw
history blame
7.66 kB
from flask import Flask, jsonify, render_template, request, Response, abort
import os
import urllib.parse
from hf_scrapper import download_and_cache_file, get_system_proxies
from indexer import indexer
from tvdb import fetch_and_cache_json
from dotenv import load_dotenv
import json
import re
from threading import Thread
load_dotenv()
INDEX_FILE = os.getenv("INDEX_FILE")
TOKEN = os.getenv("TOKEN")
REPO = os.getenv("REPO")
CACHE_DIR = os.getenv("CACHE_DIR")
# Ensure CACHE_DIR exists
if not os.path.exists(CACHE_DIR):
os.makedirs(CACHE_DIR)
indexer()
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)
def prefetch_metadata():
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
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():
prefetch_metadata()
thread = Thread(target=start_prefetching)
thread.daemon = True
thread.start()
app = Flask(__name__)
def get_film_file_path(title):
decoded_title = urllib.parse.unquote(title)
normalized_title = decoded_title.split(' (')[0].strip()
for item in file_structure:
if item['path'].startswith('films'):
for sub_item in item['contents']:
sub_item_title = sub_item['path'].split('/')[-1]
normalized_sub_item_title = sub_item_title.split(' (')[0].strip()
if normalized_title == normalized_sub_item_title:
for file in sub_item['contents']:
if file['type'] == 'file':
return file['path']
return None
def get_tv_show_seasons(title):
seasons = []
for item in file_structure:
if item['path'].startswith('tv'):
for sub_item in item['contents']:
if sub_item['type'] == 'directory' and title in sub_item['path']:
for season in sub_item['contents']:
if season['type'] == 'directory':
episodes = [
{"title": episode['path'].split('/')[-1], "path": episode['path']}
for episode in season['contents'] if episode['type'] == 'file'
]
seasons.append({
"season": season['path'].split('/')[-1],
"episodes": episodes
})
return seasons
return []
def download_film_if_needed(file_path):
cached_file_path = os.path.join(CACHE_DIR, file_path)
if not os.path.exists(cached_file_path):
file_url = f"https://huggingface.co/{REPO}/resolve/main/{file_path}"
success = download_and_cache_file(file_url, TOKEN, cached_file_path, proxies=get_system_proxies())
if not success:
abort(404, description="File not found or failed to download.")
return cached_file_path
@app.route('/')
def home():
return render_template('index.html')
@app.route('/films')
def films():
return render_template('films.html')
@app.route('/api/films')
def list_films():
films = [item for item in file_structure if item['path'].startswith('films')]
return jsonify([sub_item for film in films for sub_item in film['contents']])
@app.route('/tv')
def tv_shows():
return render_template('tvshows.html')
@app.route('/api/tv')
def list_tv():
tv_shows = [item for item in file_structure if item['path'].startswith('tv')]
return jsonify([sub_item for show in tv_shows for sub_item in show['contents']])
@app.route('/api/film/<path:title>')
def film_page(title):
title = urllib.parse.unquote(title)
film_file_path = get_film_file_path(title)
if not film_file_path:
return jsonify({'error': 'Film not found'}), 404
json_cache_path = os.path.join(CACHE_DIR, f"{urllib.parse.quote(title)}.json")
if os.path.exists(json_cache_path):
with open(json_cache_path, 'r') as f:
metadata = json.load(f)
else:
return jsonify({'error': 'Metadata not found'}), 404
cached_url = f"/cached_films/{urllib.parse.quote(title)}"
return jsonify({
'metadata': metadata,
'cached_url': cached_url
})
@app.route('/api/tv/<path:show_title>')
def tv_page(show_title):
show_title = urllib.parse.unquote(show_title)
seasons = get_tv_show_seasons(show_title)
if not seasons:
return jsonify({'error': 'TV show not found'}), 404
json_cache_path = os.path.join(CACHE_DIR, f"{urllib.parse.quote(show_title)}.json")
if os.path.exists(json_cache_path):
with open(json_cache_path, 'r') as f:
metadata = json.load(f)
else:
return jsonify({'error': 'Metadata not found'}), 404
return jsonify({
'metadata': metadata,
'seasons': seasons
})
@app.route('/get_metadata')
def get_metadata():
title = request.args.get('title')
if not title:
return jsonify({'error': 'No title provided'}), 400
json_cache_path = os.path.join(CACHE_DIR, f"{urllib.parse.quote(title)}.json")
if os.path.exists(json_cache_path):
with open(json_cache_path, 'r') as f:
data = json.load(f)
return jsonify(data)
return jsonify({'error': 'Metadata not found'}), 404
@app.route('/api/cache_film/<path:title>')
def cache_film(title):
title = urllib.parse.unquote(title)
film_file_path = get_film_file_path(title)
if not film_file_path:
return jsonify({'error': 'Film not found'}), 404
cached_file_path = os.path.join(CACHE_DIR, film_file_path)
if not os.path.exists(cached_file_path):
file_url = f"https://huggingface.co/{REPO}/resolve/main/{film_file_path}"
success = download_and_cache_file(file_url, TOKEN, cached_file_path, proxies=get_system_proxies())
if not success:
return jsonify({'error': 'Failed to cache film'}), 500
return jsonify({'success': True})
@app.route('/film/<path:title>')
def film_details(title):
return render_template('film_details_page.html', title=title)
@app.route('/cached_films/<path:title>')
def serve_cached_film(title):
cached_file_path = os.path.join(CACHE_DIR, urllib.parse.unquote(title))
if not os.path.exists(cached_file_path):
return jsonify({'error': 'Film not cached'}), 404
def generate():
with open(cached_file_path, 'rb') as f:
while chunk := f.read(8192):
yield chunk
return Response(generate(), mimetype='video/mp4')
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=7860)