diff --git a/revivetube.py b/revivetube.py new file mode 100644 index 0000000..af8d7ba --- /dev/null +++ b/revivetube.py @@ -0,0 +1,233 @@ +from flask import Flask, request, render_template_string, send_file +import requests +import subprocess +import os +import threading +import time +import shutil + +# Flask-Setup +app = Flask(__name__) + +# API-Schlüssel aus token.txt laden +with open("token.txt", "r") as f: + YOUTUBE_API_KEY = f.read().strip() + +# Konstanten +YOUTUBE_SEARCH_URL = "https://www.googleapis.com/youtube/v3/search" +RIITUBE_BASE_URL = "https://riitube.rc24.xyz/" +VIDEO_FOLDER = "videos" + +# Videos-Ordner erstellen, falls nicht vorhanden +os.makedirs(VIDEO_FOLDER, exist_ok=True) + +# Maximum size limits (1 GB and 5 GB) +MAX_VIDEO_SIZE = 1 * 1024 * 1024 * 1024 # 1 GB +MAX_FOLDER_SIZE = 5 * 1024 * 1024 * 1024 # 5 GB + +# Helper function to calculate the total size of the folder +def get_folder_size(path): + total_size = 0 + for dirpath, dirnames, filenames in os.walk(path): + for f in filenames: + file_path = os.path.join(dirpath, f) + total_size += os.path.getsize(file_path) + return total_size + +# Function to periodically delete videos every 5 minutes +def delete_videos_periodically(): + while True: + time.sleep(86400) # 5 minutes + for filename in os.listdir(VIDEO_FOLDER): + file_path = os.path.join(VIDEO_FOLDER, filename) + if os.path.isfile(file_path): + os.remove(file_path) + print(f"Deleted: {file_path}") + +# Start the periodic deletion in a separate thread +threading.Thread(target=delete_videos_periodically, daemon=True).start() + +# HTML-Templates als Strings +INDEX_TEMPLATE = """ + + + + + + ReviveTube by ReviveMii + + +

ReviveTube by ReviveMii

+
+ + +
+ {% if results %} +

Search Results

+ + {% endif %} +
+ Visit ReviveMii +

This app uses the RiiConnect24 WiiMC API. We are NOT afiliated with RiiConnect24, Nintendo or YouTube. This app is using Code from Wiinet.xyz.

+

It's recommend to bookmark this Page

+

It's normal that Sites take long to load

+ + +""" + +WATCH_WII_TEMPLATE = """ + + + + + + ReviveTube Video + + +
+ + + + + +
+

If the video does not play smoothly, restart the Internet Channel by pressing the Home button and then Reset. It's a bug. It happens if you visit too many Sites

+ + +""" + +WATCH_STANDARD_TEMPLATE = """ + + + + + + ReviveTube Video + + +

ReviveTube Video

+ + + +""" + +# Routen +@app.route("/", methods=["GET"]) +def index(): + query = request.args.get("query") + results = None + + if query: + # YouTube API aufrufen + params = { + "part": "snippet", + "q": query, + "type": "video", + "maxResults": 10, + "key": YOUTUBE_API_KEY, + } + response = requests.get(YOUTUBE_SEARCH_URL, params=params, timeout=3) + data = response.json() + + # Ergebnisse verarbeiten + if response.status_code == 200 and "items" in data: + results = [ + { + "id": item["id"]["videoId"], + "title": item["snippet"]["title"], + "uploader": item["snippet"]["channelTitle"], + "thumbnail": item["snippet"]["thumbnails"]["high"]["url"], + } + for item in data.get("items", []) + ] + return render_template_string(INDEX_TEMPLATE, results=results) + + +@app.route("/watch", methods=["GET"]) +def watch(): + video_id = request.args.get("video_id") + if not video_id: + return "Missing video ID.", 400 + + # User-Agent prüfen + user_agent = request.headers.get("User-Agent", "").lower() + is_wii = "wii" in user_agent + + # Video-Pfade + video_mp4_path = os.path.join(VIDEO_FOLDER, f"{video_id}.mp4") + video_flv_path = os.path.join(VIDEO_FOLDER, f"{video_id}.flv") + + # Video herunterladen, falls nicht vorhanden + if not os.path.exists(video_mp4_path): + video_url = f"{RIITUBE_BASE_URL}video/wii/?q={video_id}" + + try: + response = requests.get(video_url, stream=True, timeout=10) + if response.status_code != 200: + return f"Failed to download video. HTTP Status: {response.status_code}, Reason: {response.reason}", 500 + + # Check file size during download + total_size = 0 + with open(video_mp4_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + total_size += len(chunk) + if total_size > MAX_VIDEO_SIZE: + os.remove(video_mp4_path) + return "Video exceeds 1 GB in size.", 400 + + except requests.exceptions.RequestException as e: + return f"An error occurred while downloading the video: {str(e)}", 500 + + # Check folder size + if get_folder_size(VIDEO_FOLDER) > MAX_FOLDER_SIZE: + shutil.rmtree(VIDEO_FOLDER) + os.makedirs(VIDEO_FOLDER, exist_ok=True) # Recreate the folder after deletion + return "The video folder exceeded 5 GB and was deleted.", 400 + + # Für Wii in FLV umwandeln + if is_wii and not os.path.exists(video_flv_path): + try: + subprocess.run( + [ + "ffmpeg", + "-i", video_mp4_path, + "-ar", "22050", + "-f", "flv", + "-s", "320x240", + "-ab", "32k", + "-filter:v", "fps=fps=15", + video_flv_path + ], + check=True + ) + except subprocess.CalledProcessError as e: + return f"Failed to convert video. Try reloading the Page. Error: {str(e)}", 500 + + # Passendes Template rendern + if is_wii: + return render_template_string(WATCH_WII_TEMPLATE, video_flv=f"/videos/{video_id}.flv") + else: + return render_template_string(WATCH_STANDARD_TEMPLATE, video_mp4=f"/videos/{video_id}.mp4") + + +@app.route("/") +def serve_static(filename): + return send_file(os.path.join(filename)) + + +if __name__ == "__main__": + app.run(debug=True)