From 7832f6e6b82ab5160aebd6ef7017602dcefc93b6 Mon Sep 17 00:00:00 2001 From: Ignacio Rivero Date: Tue, 4 Mar 2025 23:46:22 -0300 Subject: [PATCH] Added manifest.json, made the site more mobile-friendly --- main.py | 224 +++-------------- static/icon512_maskable.png | Bin 0 -> 14382 bytes static/icon512_rounded.png | Bin 0 -> 21433 bytes static/manifest.json | 27 ++ templates/index.html | 474 ++++++++++++++++++++++++++++++++++++ 5 files changed, 537 insertions(+), 188 deletions(-) create mode 100644 static/icon512_maskable.png create mode 100644 static/icon512_rounded.png create mode 100644 static/manifest.json create mode 100644 templates/index.html diff --git a/main.py b/main.py index 31aff2d..e2278f9 100755 --- a/main.py +++ b/main.py @@ -9,8 +9,7 @@ import os import time import multiprocessing -from flask import request -from flask import jsonify +from flask import request, jsonify, send_from_directory from PyQt5.QtWidgets import * from PyQt5.QtCore import * @@ -486,199 +485,32 @@ def index(): grouped_channels.setdefault(channel["group"], []).append(channel) flat_channel_list = [channel for channel in channels] - - html = f""" - - - IPMPV - - - -

Welcome to IPMPV

-

Current Channel: {channels[current_index]['name'] if current_index is not None else "None"}

- - """ -# -# - - global deinterlace - global low_latency - deinterlace_state = "ON" if deinterlace else "OFF" - retroarch_state = "ON" if retroarch_p and retroarch_p.poll() is None else "OFF" - html += f""" - - - -

Toggle OSD

- - """ - html += f""" -

Play Custom URL

- -

All Channels

-
- """ - + + # Create the channel groups HTML + channel_groups_html = "" for group, ch_list in grouped_channels.items(): - html += f'
{group}' + channel_groups_html += f'
{group}' for channel in ch_list: index = flat_channel_list.index(channel) # Get correct global index - html += f''' + channel_groups_html += f'''
''' - html += '
' - - - html += """ -
- - - - """ - + channel_groups_html += '
' + + # Replace placeholders with actual values + html = open("templates/index.html").read() + html = html.replace("%CURRENT_CHANNEL%", channels[current_index]['name'] if current_index is not None else "None") + html = html.replace("%RETROARCH_STATE%", "ON" if retroarch_p and retroarch_p.poll() is None else "OFF") + html = html.replace("%RETROARCH_LABEL%", "Stop RetroArch" if retroarch_p and retroarch_p.poll() is None else "Start RetroArch") + html = html.replace("%DEINTERLACE_STATE%", "ON" if deinterlace else "OFF") + html = html.replace("%RESOLUTION%", resolution) + html = html.replace("%LATENCY_STATE%", "ON" if low_latency else "OFF") + html = html.replace("%LATENCY_LABEL%", "Lo" if low_latency else "Hi") + html = html.replace("%CHANNEL_GROUPS%", channel_groups_html) + return html def is_valid_url(url): @@ -765,7 +597,7 @@ def toggle_retroarch(): print("Launching RetroArch") retroarch_env = os.environ.copy() retroarch_env["MESA_GL_VERSION_OVERRIDE"] = "3.3" - retroarch_p = subprocess.Popen(re.split('\s', ipmpv_retroarch_cmd if ipmpv_retroarch_cmd is not None else 'retroarch'), env=retroarch_env) + retroarch_p = subprocess.Popen(re.split("\\s", ipmpv_retroarch_cmd if ipmpv_retroarch_cmd is not None else 'retroarch'), env=retroarch_env) return jsonify(state=True) @app.route("/toggle_latency") @@ -823,6 +655,22 @@ def toggle_resolution(): return jsonify(res=get_current_resolution()) +@app.route('/manifest.json') +def serve_manifest(): + return send_from_directory("static", 'manifest.json', + mimetype='application/manifest+json') + +# Serve icon files from root +@app.route('/icon512_rounded.png') +def serve_rounded_icon(): + return send_from_directory("static", 'icon512_rounded.png', + mimetype='image/png') + +@app.route('/icon512_maskable.png') +def serve_maskable_icon(): + return send_from_directory("static", 'icon512_maskable.png', + mimetype='image/png') + if __name__ == "__main__": # Start Qt process qt_proc = multiprocessing.Process(target=qt_process) diff --git a/static/icon512_maskable.png b/static/icon512_maskable.png new file mode 100644 index 0000000000000000000000000000000000000000..0db1f7a299cb37fd554b354ce49e07bdafcec32a GIT binary patch literal 14382 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 literal 0 HcmV?d00001 diff --git a/static/icon512_rounded.png b/static/icon512_rounded.png new file mode 100644 index 0000000000000000000000000000000000000000..be2088f08013b69d4f13daaf3695871bba893a6e GIT binary patch literal 21433 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 KrHUnuZ~qUYgiAUA literal 0 HcmV?d00001 diff --git a/static/manifest.json b/static/manifest.json new file mode 100644 index 0000000..0555cf9 --- /dev/null +++ b/static/manifest.json @@ -0,0 +1,27 @@ +{ + "theme_color":"#222222", + "background_color":"#222222", + "start_url": "/", + "icons": + [ + { + "purpose":"maskable", + "sizes":"512x512", + "src":"icon512_maskable.png", + "type":"image/png" + },{ + "purpose":"any", + "sizes":"512x512", + "src":"icon512_rounded.png", + "type":"image/png" + } + ], + "orientation":"any", + "display":"standalone", + "dir":"auto", + "lang":"en", + "name":"IPMPV", + "short_name":"IPMPV", + "description":"Remote control for your IPMPV instance", + "id":"cc.netpaws.ipmpv" +} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..848153c --- /dev/null +++ b/templates/index.html @@ -0,0 +1,474 @@ + + + + IPMPV + + + + + + + + +

+

Welcome to IPMPV

+

Current Channel: %CURRENT_CHANNEL%

+ +
+ + + + +
+ +
+

Toggle OSD

+
+ + +
+
+ +
+

Play Custom URL

+
+
+ + + +
+
+
+ +

All Channels

+
+ + %CHANNEL_GROUPS% +
+
+ + + + \ No newline at end of file