From a59776b1dac211eec919db6dc7d3652405176f3f Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 21:53:59 +0100 Subject: [PATCH 1/9] Organized a bit and added helper file helper.py --- .gitignore | 2 + .idea/.gitignore | 3 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/revivetube.iml | 10 + .idea/vcs.xml | 6 + __pycache__/helper.cpython-312.pyc | Bin 0 -> 820 bytes helper.py | 11 + revivetube.py | 426 +++--------------- site_storage/index_template.html | 114 +++++ site_storage/loading_template.html | 92 ++++ site_storage/watch_standard_template.html | 49 ++ site_storage/watch_wii_template.html | 67 +++ 14 files changed, 440 insertions(+), 361 deletions(-) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/revivetube.iml create mode 100644 .idea/vcs.xml create mode 100644 __pycache__/helper.cpython-312.pyc create mode 100644 helper.py create mode 100644 site_storage/index_template.html create mode 100644 site_storage/loading_template.html create mode 100644 site_storage/watch_standard_template.html create mode 100644 site_storage/watch_wii_template.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b578d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +token.txt \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..da5d2d0 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a078ea6 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/revivetube.iml b/.idea/revivetube.iml new file mode 100644 index 0000000..10df758 --- /dev/null +++ b/.idea/revivetube.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/__pycache__/helper.cpython-312.pyc b/__pycache__/helper.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2626013b89e93b1fac67ee96d5303c769234ee9b GIT binary patch literal 820 zcmYjPL2DC16n?X_+fACLG1i7sJZ#f|=3s+|f-Ry1X$8Te^i(gBW~c3HvKwY+n>HpY z;-SZihgMp_n@T)*^qQl1DOjNnISBrNVh)A$(l>D1Dm{RU;_7q}c0l~g)j?=T^{g3szIg|1(hS)b zBnrX^1E_(g4$ow1qkNx_FX5*=B=&KW`Yl|=mSHUM$jldER{GK7V zL6@LPCP75{IvL&%S1$W$4NqEf&#LAUxSt29MEqXSxwbUHv9-p=5of5NLPgpBn z;M!9)Gvu=aa?tS|*B1r1$RtHEse2XXN}aQUEt9Hn!4vbUtXCtWa~nlg5sv3(b*WeI zFj8N^UD7Oiu3)Z^g!wuSYN2&AxizoMa;)r>N{$= z;zwlS^q3;u^>1STH^cb^yieve`X!29OEdCAX3Nx-KSUKKqWM|c8jmPU$Me&)l_ScZ sHV_xGq&Lq;=%5(z1VT4*z3kaRiQV8M81_b0Zv(p$($NM - - - - - Loading... - - - -

Loading

- Loading... -

Fetching Info...

- -
- Loading Screen will NOT work in Dolphin Emulator.

Long Video = Longer Download and Converting.

For videos longer than 7 minutes, there is a chance that they won’t play.
- - -""" def get_file_size(file_path): return os.path.getsize(file_path) + def get_range(file_path, byte_range): with open(file_path, 'rb') as f: f.seek(byte_range[0]) return f.read(byte_range[1] - byte_range[0] + 1) + def get_api_key(): try: with open("token.txt", "r") as f: - return f.read().strip() + return f.read().strip() except FileNotFoundError: raise FileNotFoundError("Missing token.txt. Please go to README.md") + os.makedirs(VIDEO_FOLDER, exist_ok=True) -MAX_VIDEO_SIZE = 1 * 1024 * 1024 * 1024 -MAX_FOLDER_SIZE = 5 * 1024 * 1024 * 1024 +MAX_VIDEO_SIZE = 1 * 1024 * 1024 * 1024 +MAX_FOLDER_SIZE = 5 * 1024 * 1024 * 1024 + def get_folder_size(path): total_size = 0 @@ -169,7 +89,10 @@ def get_folder_size(path): total_size += os.path.getsize(file_path) return total_size + """ +[UNUSED IN THE CURRENT VERSION] + def delete_videos_periodically(): while True: time.sleep(86400) @@ -182,244 +105,13 @@ def delete_videos_periodically(): threading.Thread(target=delete_videos_periodically, daemon=True).start() """ -INDEX_TEMPLATE = """ - - - - - - ReviveTube by ReviveMii - - - -

ReviveTube by ReviveMii

-

A YouTube App for the Wii

-
- - -
- {% if results %} -

Search Results

- - {% endif %} -

Visit ReviveMii

-

\/ Scroll down \/

-

We are NOT affiliated with Nintendo or YouTube. This app uses code from Wiinet.xyz. For more information, scroll down to Open Source Software.

-

It's recommended to bookmark this page. Some sites may take longer to load.

- Terms of Service and Privacy Policy (Last Updated: 7. Dec 2024 12:41 CET)

- Source Code

- Discord Server [Use a Compatible Device] -

Version: v2 Beta (Sometimes I forget to update the Version Number)

- Open Source Software Used in This App -
- Contact -
- Report Bugs & Feedback - - -""" +INDEX_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}index_template.html") + +WATCH_STANDARD_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}watch_standard_template.html") + +WATCH_WII_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}watch_wii_template.html") -WATCH_STANDARD_TEMPLATE = """ - - - - - - {{ title }} - - - -Please access this Site on a Wii - - -""" -WATCH_WII_TEMPLATE = """ - - - - - - {{ title }} - - - - -
- - - - - -
-

{{ title }}

-

Uploaded by: {{ uploader }}

-

Views: {{ viewCount }}

-

Likes: {{ likeCount }}

-

Upload Date: {{ publishedAt }}

- Skip Description -

Description:

-

{{ description | safe }}

-

Comments:

-
- {% if comments %} - {% for comment in comments %} -
-

{{ comment.author }} posted:

-

{{ comment.text|safe }}

-

Likes: {{ comment.likeCount }} | Post date: {{ comment.publishedAt }}

-
- {% endfor %} - {% else %} -

No Comments.

- {% endif %} -
- - -""" @app.route("/thumbnail/") def get_thumbnail(video_id): thumbnail_url = f"https://img.youtube.com/vi/{video_id}/hqdefault.jpg" @@ -439,6 +131,7 @@ def get_thumbnail(video_id): except requests.exceptions.RequestException as e: return f"Error fetching thumbnail: {str(e)}", 500 + def get_video_comments(video_id, max_results=20): api_key = get_api_key() @@ -447,7 +140,7 @@ def get_video_comments(video_id, max_results=20): "videoId": video_id, "key": api_key, "maxResults": max_results, - "order": "relevance" + "order": "relevance" } try: @@ -472,6 +165,8 @@ def get_video_comments(video_id, max_results=20): except requests.exceptions.RequestException as e: print(f"Fehler beim Abrufen der Kommentare: {str(e)}") return [] + + @app.route("/switch_wii", methods=["GET"]) def switch_wii(): video_id = request.args.get("video_id") @@ -489,6 +184,7 @@ def switch_wii(): else: return "Can't start DEBUG Mode.", 500 + @app.route("/switch_n", methods=["GET"]) def switch_n(): video_id = request.args.get("video_id") @@ -506,6 +202,7 @@ def switch_n(): else: return "Can't start DEBUG Mode.", 500 + @app.route("/", methods=["GET"]) def index(): query = request.args.get("query") @@ -537,22 +234,24 @@ def index(): return render_template_string(INDEX_TEMPLATE, results=results) + def format_duration(seconds): minutes = seconds // 60 seconds = seconds % 60 return f"{minutes}:{str(seconds).zfill(2)}" + def get_video_duration_from_file(video_path): try: result = subprocess.run( ['ffprobe', '-v', 'error', '-show_format', '-show_streams', '-of', 'json', video_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - + video_info = json.loads(result.stdout) - + duration = float(video_info['format']['duration']) - + return duration except Exception as e: print(f"Can't fetch Video-Duration: {str(e)}") @@ -583,7 +282,6 @@ def watch(): except requests.exceptions.RequestException as e: return f"Can't connect to Metadata-API: {str(e)}", 500 - comments = [] try: comments = get_video_comments(video_id) @@ -600,28 +298,28 @@ def watch(): alert("This Video is long. There is a chance that the Wii will not play the Video. Try a Video under 7 minutes or something like that."); """ - + if is_wii and os.path.exists(video_flv_path): - return render_template_string(WATCH_WII_TEMPLATE + alert_script, - title=metadata['title'], - uploader=metadata['uploader'], + return render_template_string(WATCH_WII_TEMPLATE + alert_script, + title=metadata['title'], + uploader=metadata['uploader'], channelId=metadata['channelId'], description=metadata['description'].replace("\n", "
"), - viewCount=metadata['viewCount'], + viewCount=metadata['viewCount'], likeCount=metadata['likeCount'], publishedAt=metadata['publishedAt'], comments=comments, - video_id=video_id, + video_id=video_id, video_flv=f"/sigma/videos/{video_id}.flv", alert_message="") - return render_template_string(WATCH_WII_TEMPLATE, - title=metadata['title'], - uploader=metadata['uploader'], + return render_template_string(WATCH_WII_TEMPLATE, + title=metadata['title'], + uploader=metadata['uploader'], channelId=metadata['channelId'], description=metadata['description'].replace("\n", "
"), - viewCount=metadata['viewCount'], - likeCount=metadata['likeCount'], + viewCount=metadata['viewCount'], + likeCount=metadata['likeCount'], publishedAt=metadata['publishedAt'], comments=comments, video_id=video_id, @@ -633,6 +331,7 @@ def watch(): threading.Thread(target=process_video, args=(video_id,)).start() return render_template_string(LOADING_TEMPLATE, video_id=video_id) + def process_video(video_id): video_mp4_path = os.path.join(VIDEO_FOLDER, f"{video_id}.mp4") video_flv_path = os.path.join(VIDEO_FOLDER, f"{video_id}.flv") @@ -703,10 +402,12 @@ def process_video(video_id): except Exception as e: video_status[video_id] = {"status": "error", "message": str(e)} + @app.route("/status/") def check_status(video_id): return jsonify(video_status.get(video_id, {"status": "pending"})) + @app.route("/video_metadata/") def video_metadata(video_id): api_key = get_api_key() @@ -719,7 +420,7 @@ def video_metadata(video_id): try: response = requests.get(YOUTUBE_API_URL, params=params, timeout=1) - response.raise_for_status() + response.raise_for_status() data = response.json() @@ -750,6 +451,7 @@ def video_metadata(video_id): except requests.exceptions.RequestException as e: return f"Fehler bei der API-Anfrage: {str(e)}", 500 + @app.route("/") def serve_video(filename): file_path = os.path.join(filename) @@ -767,7 +469,7 @@ def serve_video(filename): end_byte = int(end_byte) if end_byte else file_size - 1 if start_byte >= file_size or end_byte >= file_size: - abort(416) + abort(416) data = get_range(file_path, (start_byte, end_byte)) content_range = f"bytes {start_byte}-{end_byte}/{file_size}" @@ -785,10 +487,11 @@ def serve_video(filename): return send_file(file_path) + @app.route('/channel', methods=['GET']) def channel_m(): channel_id = request.args.get('channel_id', None) - + if not channel_id: return "Channel ID is required.", 400 @@ -797,7 +500,7 @@ def channel_m(): 'extract_flat': True, 'playlistend': 20, } - + try: with yt_dlp.YoutubeDL(ydl_opts) as ydl: url = f"https://www.youtube.com/channel/{channel_id}/videos" @@ -805,7 +508,7 @@ def channel_m(): if 'entries' not in info: return "No videos found.", 404 - + results = [ { 'id': video['id'], @@ -816,11 +519,12 @@ def channel_m(): } for video in info['entries'] ] - + return render_template_string(INDEX_TEMPLATE, results=results) - + except Exception as e: return f"An error occurred: {str(e)}", 500 + if __name__ == "__main__": app.run(host="0.0.0.0", debug=True, port=5000) diff --git a/site_storage/index_template.html b/site_storage/index_template.html new file mode 100644 index 0000000..37e948e --- /dev/null +++ b/site_storage/index_template.html @@ -0,0 +1,114 @@ + + + + + + ReviveTube by ReviveMii + + + +

ReviveTube by ReviveMii

+

A YouTube App for the Wii

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

Search Results

+ + {% endif %} +

Visit ReviveMii

+

\/ Scroll down \/

+

We are NOT affiliated with Nintendo or YouTube. This app uses code from Wiinet.xyz. For more information, scroll down to Open Source Software.

+

It's recommended to bookmark this page. Some sites may take longer to load.

+ Terms of Service and Privacy Policy (Last Updated: 7. Dec 2024 12:41 CET)

+ Source Code

+ Discord Server [Use a Compatible Device] +

Version: v2 Beta (Sometimes I forget to update the Version Number)

+ Open Source Software Used in This App +
+ Contact +
+ Report Bugs & Feedback + + \ No newline at end of file diff --git a/site_storage/loading_template.html b/site_storage/loading_template.html new file mode 100644 index 0000000..6f07ebe --- /dev/null +++ b/site_storage/loading_template.html @@ -0,0 +1,92 @@ + + + + + + Loading... + + + +

Loading

+ Loading... +

Fetching Info...

+ +
+ Loading Screen will NOT work in Dolphin Emulator.

Long Video = Longer Download and Converting.

For videos longer than 7 minutes, there is a chance that they won’t play.
+ + + \ No newline at end of file diff --git a/site_storage/watch_standard_template.html b/site_storage/watch_standard_template.html new file mode 100644 index 0000000..59b2f29 --- /dev/null +++ b/site_storage/watch_standard_template.html @@ -0,0 +1,49 @@ + + + + + + {{ title }} + + + +Please access this Site on a Wii + + \ No newline at end of file diff --git a/site_storage/watch_wii_template.html b/site_storage/watch_wii_template.html new file mode 100644 index 0000000..22dfca2 --- /dev/null +++ b/site_storage/watch_wii_template.html @@ -0,0 +1,67 @@ + + + + + + {{ title }} + + + + +
+ + + + + +
+

{{ title }}

+

Uploaded by: {{ uploader }}

+

Views: {{ viewCount }}

+

Likes: {{ likeCount }}

+

Upload Date: {{ publishedAt }}

+ Skip Description +

Description:

+

{{ description | safe }}

+

Comments:

+
+ {% if comments %} + {% for comment in comments %} +
+

{{ comment.author }} posted:

+

{{ comment.text|safe }}

+

Likes: {{ comment.likeCount }} | Post date: {{ comment.publishedAt }}

+
+ {% endfor %} + {% else %} +

No Comments.

+ {% endif %} +
+ + \ No newline at end of file From 88f7ae61d70cf8152c5352444e50357bc70a5376 Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 21:55:52 +0100 Subject: [PATCH 2/9] Added files to GitIgnore --- .gitignore | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6b578d4..edb9d07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ - -token.txt \ No newline at end of file +token.txt +.venv +.idea +__pycache__ \ No newline at end of file From bea8f34d0dc612e92e10cb75a1f3d9c6efda9585 Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 21:58:26 +0100 Subject: [PATCH 3/9] Deleted .idea and __pychache__ --- .idea/.gitignore | 3 --- .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 7 ------- .idea/modules.xml | 8 -------- .idea/revivetube.iml | 10 ---------- .idea/vcs.xml | 6 ------ 6 files changed, 40 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/revivetube.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index da5d2d0..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index a078ea6..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/revivetube.iml b/.idea/revivetube.iml deleted file mode 100644 index 10df758..0000000 --- a/.idea/revivetube.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From b1fb83086d748a80c5ec8b26e3fc3e7c81cb98e8 Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 21:59:02 +0100 Subject: [PATCH 4/9] Delete helper.cpython-312.pyc --- __pycache__/helper.cpython-312.pyc | Bin 820 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __pycache__/helper.cpython-312.pyc diff --git a/__pycache__/helper.cpython-312.pyc b/__pycache__/helper.cpython-312.pyc deleted file mode 100644 index 2626013b89e93b1fac67ee96d5303c769234ee9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 820 zcmYjPL2DC16n?X_+fACLG1i7sJZ#f|=3s+|f-Ry1X$8Te^i(gBW~c3HvKwY+n>HpY z;-SZihgMp_n@T)*^qQl1DOjNnISBrNVh)A$(l>D1Dm{RU;_7q}c0l~g)j?=T^{g3szIg|1(hS)b zBnrX^1E_(g4$ow1qkNx_FX5*=B=&KW`Yl|=mSHUM$jldER{GK7V zL6@LPCP75{IvL&%S1$W$4NqEf&#LAUxSt29MEqXSxwbUHv9-p=5of5NLPgpBn z;M!9)Gvu=aa?tS|*B1r1$RtHEse2XXN}aQUEt9Hn!4vbUtXCtWa~nlg5sv3(b*WeI zFj8N^UD7Oiu3)Z^g!wuSYN2&AxizoMa;)r>N{$= z;zwlS^q3;u^>1STH^cb^yieve`X!29OEdCAX3Nx-KSUKKqWM|c8jmPU$Me&)l_ScZ sHV_xGq&Lq;=%5(z1VT4*z3kaRiQV8M81_b0Zv(p$($NM Date: Wed, 1 Jan 2025 22:10:56 +0100 Subject: [PATCH 5/9] Added Requirements.txt using pipreqs --- generateRequirements.sh | 1 + helper.py | 21 +++++++++++++++++++++ requirements.txt | 3 +++ revivetube.py | 20 +------------------- 4 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 generateRequirements.sh create mode 100644 requirements.txt diff --git a/generateRequirements.sh b/generateRequirements.sh new file mode 100644 index 0000000..a182d84 --- /dev/null +++ b/generateRequirements.sh @@ -0,0 +1 @@ +pipreqs . --force --ignore .venv \ No newline at end of file diff --git a/helper.py b/helper.py index a514fcc..fa4c52a 100644 --- a/helper.py +++ b/helper.py @@ -1,3 +1,7 @@ +import json +import subprocess + + def read_file(path): assert isinstance(path, str), "Path must be a string" @@ -9,3 +13,20 @@ def read_file(path): return "Error: File not found." except Exception as e: return f"Error: {str(e)}" + + +def get_video_duration_from_file(video_path): + try: + result = subprocess.run( + ['ffprobe', '-v', 'error', '-show_format', '-show_streams', '-of', 'json', video_path], + stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + + video_info = json.loads(result.stdout) + + duration = float(video_info['format']['duration']) + + return duration + except Exception as e: + print(f"Can't fetch Video-Duration: {str(e)}") + return 0 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..76a77cb --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +Flask==3.1.0 +Requests==2.32.3 +yt_dlp==2024.12.23 diff --git a/revivetube.py b/revivetube.py index 09b58a3..031c86c 100644 --- a/revivetube.py +++ b/revivetube.py @@ -14,7 +14,6 @@ If you use this Code, you agree to https://revivemii.fr.to/revivetube/t-and-p.ht ReviveMii Project: https://revivemii.fr.to/ """ -import json import os import shutil import subprocess @@ -27,7 +26,7 @@ import requests import yt_dlp from flask import Flask, request, render_template_string, send_file, Response, abort, jsonify -from helper import read_file +from helper import read_file, get_video_duration_from_file app = Flask(__name__) @@ -241,23 +240,6 @@ def format_duration(seconds): return f"{minutes}:{str(seconds).zfill(2)}" -def get_video_duration_from_file(video_path): - try: - result = subprocess.run( - ['ffprobe', '-v', 'error', '-show_format', '-show_streams', '-of', 'json', video_path], - stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - - video_info = json.loads(result.stdout) - - duration = float(video_info['format']['duration']) - - return duration - except Exception as e: - print(f"Can't fetch Video-Duration: {str(e)}") - return 0 - - @app.route("/watch", methods=["GET"]) def watch(): video_id = request.args.get("video_id") From 67a55848406d5f9d59bc90da8c11af86b46bbb97 Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 22:21:47 +0100 Subject: [PATCH 6/9] Switched Function to helper.py --- helper.py | 7 ++++++- revivetube.py | 8 +------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/helper.py b/helper.py index fa4c52a..35d162f 100644 --- a/helper.py +++ b/helper.py @@ -29,4 +29,9 @@ def get_video_duration_from_file(video_path): return duration except Exception as e: print(f"Can't fetch Video-Duration: {str(e)}") - return 0 \ No newline at end of file + return 0 + +def format_duration(seconds): + minutes = seconds // 60 + seconds = seconds % 60 + return f"{minutes}:{str(seconds).zfill(2)}" \ No newline at end of file diff --git a/revivetube.py b/revivetube.py index 031c86c..ebfd955 100644 --- a/revivetube.py +++ b/revivetube.py @@ -26,7 +26,7 @@ import requests import yt_dlp from flask import Flask, request, render_template_string, send_file, Response, abort, jsonify -from helper import read_file, get_video_duration_from_file +from helper import read_file, get_video_duration_from_file, format_duration app = Flask(__name__) @@ -234,12 +234,6 @@ def index(): return render_template_string(INDEX_TEMPLATE, results=results) -def format_duration(seconds): - minutes = seconds // 60 - seconds = seconds % 60 - return f"{minutes}:{str(seconds).zfill(2)}" - - @app.route("/watch", methods=["GET"]) def watch(): video_id = request.args.get("video_id") From d0ec2a1817c3d89b68de39fc5925170ad537e094 Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 22:26:12 +0100 Subject: [PATCH 7/9] Fixed SomeThings --- helper.py | 21 ++++++++++++++++++++- revivetube.py | 42 ++++++++++++------------------------------ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/helper.py b/helper.py index 35d162f..47ab0b8 100644 --- a/helper.py +++ b/helper.py @@ -1,4 +1,5 @@ import json +import os import subprocess @@ -34,4 +35,22 @@ def get_video_duration_from_file(video_path): def format_duration(seconds): minutes = seconds // 60 seconds = seconds % 60 - return f"{minutes}:{str(seconds).zfill(2)}" \ No newline at end of file + return f"{minutes}:{str(seconds).zfill(2)}" + + +def get_file_size(file_path): + return os.path.getsize(file_path) + + +def get_range(file_path, byte_range): + with open(file_path, 'rb') as f: + f.seek(byte_range[0]) + return f.read(byte_range[1] - byte_range[0] + 1) + + +def get_api_key(): + try: + with open("token.txt", "r") as f: + return f.read().strip() + except FileNotFoundError: + raise FileNotFoundError("Missing token.txt. Please go to README.md") \ No newline at end of file diff --git a/revivetube.py b/revivetube.py index ebfd955..3f68e7d 100644 --- a/revivetube.py +++ b/revivetube.py @@ -26,7 +26,7 @@ import requests import yt_dlp from flask import Flask, request, render_template_string, send_file, Response, abort, jsonify -from helper import read_file, get_video_duration_from_file, format_duration +import helper app = Flask(__name__) @@ -53,25 +53,7 @@ video_status = {} FILE_SEPARATOR = os.sep -LOADING_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}loading_template.html") - - -def get_file_size(file_path): - return os.path.getsize(file_path) - - -def get_range(file_path, byte_range): - with open(file_path, 'rb') as f: - f.seek(byte_range[0]) - return f.read(byte_range[1] - byte_range[0] + 1) - - -def get_api_key(): - try: - with open("token.txt", "r") as f: - return f.read().strip() - except FileNotFoundError: - raise FileNotFoundError("Missing token.txt. Please go to README.md") +LOADING_TEMPLATE = helper.read_file(f"site_storage{FILE_SEPARATOR}loading_template.html") os.makedirs(VIDEO_FOLDER, exist_ok=True) @@ -104,11 +86,11 @@ def delete_videos_periodically(): threading.Thread(target=delete_videos_periodically, daemon=True).start() """ -INDEX_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}index_template.html") +INDEX_TEMPLATE = helper.read_file(f"site_storage{FILE_SEPARATOR}index_template.html") -WATCH_STANDARD_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}watch_standard_template.html") +WATCH_STANDARD_TEMPLATE = helper.read_file(f"site_storage{FILE_SEPARATOR}watch_standard_template.html") -WATCH_WII_TEMPLATE = read_file(f"site_storage{FILE_SEPARATOR}watch_wii_template.html") +WATCH_WII_TEMPLATE = helper.read_file(f"site_storage{FILE_SEPARATOR}watch_wii_template.html") @app.route("/thumbnail/") @@ -132,7 +114,7 @@ def get_thumbnail(video_id): def get_video_comments(video_id, max_results=20): - api_key = get_api_key() + api_key = helper.get_api_key() params = { "part": "snippet", @@ -223,7 +205,7 @@ def index(): "thumbnail": f"/thumbnail/{entry['videoId']}", "viewCount": entry.get("viewCountText", "Unbekannt"), "published": entry.get("publishedText", "Unbekannt"), - "duration": format_duration(entry.get("lengthSeconds", 0)) # Video Dauer formatiert + "duration": helper.format_duration(entry.get("lengthSeconds", 0)) # Video Dauer formatiert } for entry in data if entry.get("videoId") @@ -266,7 +248,7 @@ def watch(): comments = [] if os.path.exists(video_mp4_path): - video_duration = get_video_duration_from_file(video_flv_path) + video_duration = helper.get_video_duration_from_file(video_flv_path) alert_script = "" if video_duration > 420: alert_script = """ @@ -320,7 +302,7 @@ def process_video(video_id): command = [ "yt-dlp", "-f worstvideo+worstaudio", - "--proxy", "http://localhost:4000", + "http://localhost:4000", "-o", temp_video_path, f"https://m.youtube.com/watch?v={video_id}" ] @@ -386,7 +368,7 @@ def check_status(video_id): @app.route("/video_metadata/") def video_metadata(video_id): - api_key = get_api_key() + api_key = helper.get_api_key() params = { "part": "snippet,statistics", @@ -435,7 +417,7 @@ def serve_video(filename): if not os.path.exists(file_path): return "File not found.", 404 - file_size = get_file_size(file_path) + file_size = helper.get_file_size(file_path) range_header = request.headers.get('Range', None) if range_header: @@ -447,7 +429,7 @@ def serve_video(filename): if start_byte >= file_size or end_byte >= file_size: abort(416) - data = get_range(file_path, (start_byte, end_byte)) + data = helper.get_range(file_path, (start_byte, end_byte)) content_range = f"bytes {start_byte}-{end_byte}/{file_size}" response = Response( From c7eb1f7c13ed7e192ed47f2e005ad7f83a54954b Mon Sep 17 00:00:00 2001 From: rmilooo <73422068+rmilooo@users.noreply.github.com> Date: Wed, 1 Jan 2025 22:27:28 +0100 Subject: [PATCH 8/9] Cleaned up some things --- site_storage/watch_standard_template.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site_storage/watch_standard_template.html b/site_storage/watch_standard_template.html index 59b2f29..abc970a 100644 --- a/site_storage/watch_standard_template.html +++ b/site_storage/watch_standard_template.html @@ -2,7 +2,7 @@ - + {{ title }} -

ReviveTube by ReviveMii

-

A YouTube App for the Wii

-
- - -
- {% if results %} -

Search Results

- - {% endif %} -

Visit ReviveMii

-

\/ Scroll down \/

-

We are NOT affiliated with Nintendo or YouTube. This app uses code from Wiinet.xyz. For more information, scroll down to Open Source Software.

-

It's recommended to bookmark this page. Some sites may take longer to load.

- Terms of Service and Privacy Policy (Last Updated: 7. Dec 2024 12:41 CET)

- Source Code

- Discord Server [Use a Compatible Device] -

Version: v2 Beta (Sometimes I forget to update the Version Number)

- Open Source Software Used in This App -
- Contact -
- Report Bugs & Feedback +

ReviveTube by ReviveMii

+

A YouTube App for the Wii

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

Search Results

+ +{% endif %} +

Visit ReviveMii

+

\/ Scroll down \/

+

We are NOT affiliated with Nintendo or YouTube. This app uses code from Wiinet.xyz. For more + information, scroll down to Open Source Software.

+

It's recommended to bookmark this page. Some sites may take longer to load.

+Terms of Service and Privacy Policy (Last Updated: 7. Dec + 2024 12:41 CET)

+Source Code

+Discord Server [Use a Compatible Device] +

Version: v2 Beta (Sometimes I forget to update the Version Number)

+Open Source Software Used in This App +
+Contact +
+Report Bugs & Feedback \ No newline at end of file diff --git a/site_storage/loading_template.html b/site_storage/loading_template.html index 6f07ebe..72e941d 100644 --- a/site_storage/loading_template.html +++ b/site_storage/loading_template.html @@ -2,7 +2,7 @@ - + Loading... -

Loading

- Loading... -

Fetching Info...

- -
- Loading Screen will NOT work in Dolphin Emulator.

Long Video = Longer Download and Converting.

For videos longer than 7 minutes, there is a chance that they won’t play.
- + + -
- - - - - -
-

{{ title }}

-

Uploaded by: {{ uploader }}

-

Views: {{ viewCount }}

-

Likes: {{ likeCount }}

-

Upload Date: {{ publishedAt }}

- Skip Description -

Description:

-

{{ description | safe }}

-

Comments:

-
- {% if comments %} - {% for comment in comments %} -
-

{{ comment.author }} posted:

-

{{ comment.text|safe }}

-

Likes: {{ comment.likeCount }} | Post date: {{ comment.publishedAt }}

-
- {% endfor %} - {% else %} -

No Comments.

- {% endif %} +
+ + + + + +
+

{{ title }}

+

Uploaded by: {{ uploader }}

+

Views: {{ viewCount }}

+

Likes: {{ likeCount }}

+

Upload Date: {{ publishedAt }}

+Skip Description +

Description:

+

{{ description | safe }}

+

Comments:

+
+ {% if comments %} + {% for comment in comments %} +
+

{{ comment.author }} posted:

+

{{ comment.text|safe }}

+

Likes: {{ comment.likeCount }} | Post date: {{ comment.publishedAt + }}

+ {% endfor %} + {% else %} +

No Comments.

+ {% endif %} +
\ No newline at end of file