Spaces:
Paused
Paused
File size: 6,685 Bytes
2ab5f89 5efa5ee da44638 5efa5ee 5c6ae28 5efa5ee 2ab5f89 5efa5ee 632ec73 5efa5ee f0de3f7 5efa5ee f0de3f7 5efa5ee f0de3f7 5efa5ee da44638 5efa5ee da44638 5efa5ee da44638 f0de3f7 5efa5ee da44638 2ab5f89 da44638 2ab5f89 da44638 5efa5ee f0de3f7 5efa5ee da44638 2ab5f89 da44638 5efa5ee 5c6ae28 f0de3f7 5c6ae28 5efa5ee 5c6ae28 5efa5ee 5c6ae28 5efa5ee 5c6ae28 da44638 2ab5f89 da44638 5c6ae28 da44638 2ab5f89 da44638 5efa5ee f0de3f7 5efa5ee 4e15391 f0de3f7 5efa5ee f0de3f7 5efa5ee f0de3f7 2ab5f89 5efa5ee 5c6ae28 5efa5ee 8c81b5f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# app.py
from flask import Flask, jsonify, render_template, request, Response
import os
import json
import re
import urllib.parse
from threading import Thread
from video import ffmpeg_stream
from indexer import indexer
from dotenv import load_dotenv
from tvdb import fetch_and_cache_json
load_dotenv()
INDEX_FILE = os.getenv("INDEX_FILE")
TOKEN = os.getenv("TOKEN")
REPO = os.getenv("REPO")
CACHE_DIR = os.getenv("CACHE_DIR")
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 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 = []
for episode in season['contents']:
if episode['type'] == 'file':
episodes.append({
"title": episode['path'].split('/')[-1],
"path": episode['path']
})
seasons.append({
"season": season['path'].split('/')[-1],
"episodes": episodes
})
return seasons
return []
def start_prefetching():
prefetch_metadata()
def generate(file_url):
token = TOKEN
output_stream = ffmpeg_stream(file_url, token)
thread = Thread(target=start_prefetching)
thread.daemon = True
thread.start()
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/tvshow_player')
def tvshow_player():
return render_template('player.html')
@app.route('/film_player')
def film_player():
return render_template('film_player.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
return jsonify({
'metadata': metadata,
'file_path': film_file_path
})
@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('/stream')
def stream_video():
file_path = request.args.get('path')
if not file_path:
return "File path not provided", 400
file_url = f"https://huggingface.co/{REPO}/resolve/main/{file_path}"
return Response(generate(file_url), mimetype="video/mp4")
@app.route('/film/<path:title>')
def film_details(title):
return render_template('film_details_page.html', title=title)
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=7860)
|