From b58f7404f14bf251c3f1faf73b3b86f89c2ea8b2 Mon Sep 17 00:00:00 2001 From: Juned KH Date: Wed, 4 Dec 2024 14:01:12 +0530 Subject: [PATCH] New file selection page --- .dockerignore | 1 + bot/helper/ext_utils/bot_utils.py | 10 +- web/nodes.py | 26 +- web/templates/page.html | 834 ++++++++++++++++++++++++++++++ web/wserver.py | 823 ++++------------------------- 5 files changed, 967 insertions(+), 727 deletions(-) create mode 100644 .dockerignore create mode 100644 web/templates/page.html diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..4195c28e --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +mltbenv/* \ No newline at end of file diff --git a/bot/helper/ext_utils/bot_utils.py b/bot/helper/ext_utils/bot_utils.py index fbfeefb1..0cbd011b 100644 --- a/bot/helper/ext_utils/bot_utils.py +++ b/bot/helper/ext_utils/bot_utils.py @@ -55,16 +55,14 @@ def create_help_buttons(): def bt_selection_buttons(id_): gid = id_[:12] if len(id_) > 25 else id_ - pincode = "".join([n for n in id_ if n.isdigit()][:4]) + pin = "".join([n for n in id_ if n.isdigit()][:4]) buttons = ButtonMaker() BASE_URL = config_dict["BASE_URL"] if config_dict["WEB_PINCODE"]: - buttons.url_button("Select Files", f"{BASE_URL}/app/files/{id_}") - buttons.data_button("Pincode", f"sel pin {gid} {pincode}") + buttons.url_button("Select Files", f"{BASE_URL}/app/files?gid={id_}") + buttons.data_button("Pincode", f"sel pin {gid} {pin}") else: - buttons.url_button( - "Select Files", f"{BASE_URL}/app/files/{id_}?pin_code={pincode}" - ) + buttons.url_button("Select Files", f"{BASE_URL}/app/files?gid={id_}&pin={pin}") buttons.data_button("Done Selecting", f"sel done {gid} {id_}") buttons.data_button("Cancel", f"sel cancel {gid}") return buttons.build_menu(2) diff --git a/web/nodes.py b/web/nodes.py index 8686fbe0..4f478cc9 100644 --- a/web/nodes.py +++ b/web/nodes.py @@ -118,7 +118,7 @@ def make_tree(res, tool=False): folders[-1], is_file=True, parent=previous_node, - size=i["length"], + size=float(i["length"]), priority=priority, file_id=i["index"], progress=round( @@ -130,7 +130,7 @@ def make_tree(res, tool=False): folders[-1], is_file=True, parent=parent, - size=i["length"], + size=float(i["length"]), priority=priority, file_id=i["index"], progress=round( @@ -155,14 +155,14 @@ def create_list(parent, contents=None): contents = [] for i in parent.children: if i.is_folder: - childrens = [] - create_list(i, childrens) + children = [] + create_list(i, children) contents.append( { "id": f"folderNode_{i.file_id}", "name": i.name, "type": "folder", - "children": childrens, + "children": children, } ) else: @@ -177,3 +177,19 @@ def create_list(parent, contents=None): } ) return contents + + +def extract_file_ids(data): + selected_files = [] + unselected_files = [] + for item in data: + if item.get("type") == "file": + if item.get("selected"): + selected_files.append(str(item["id"])) + else: + unselected_files.append(str(item["id"])) + if item.get("children"): + child_selected, child_unselected = extract_file_ids(item["children"]) + selected_files.extend(child_selected) + unselected_files.extend(child_unselected) + return selected_files, unselected_files diff --git a/web/templates/page.html b/web/templates/page.html new file mode 100644 index 00000000..4b5cab1e --- /dev/null +++ b/web/templates/page.html @@ -0,0 +1,834 @@ + + + + + + + Torrent Selector + + + + + + +
+
+
+

Torrent + file selector

+
+
+ 🌙 + +
+
+
+
+
+ +
+
+

Enter PIN

+ + +
+ + +
+ + + + + + + + + \ No newline at end of file diff --git a/web/wserver.py b/web/wserver.py index 97525064..4b461376 100644 --- a/web/wserver.py +++ b/web/wserver.py @@ -1,11 +1,10 @@ from aria2p import API as ariaAPI, Client as ariaClient -from flask import Flask, request +from flask import Flask, request, render_template, jsonify from logging import getLogger, FileHandler, StreamHandler, INFO, basicConfig from qbittorrentapi import NotFound404Error, Client as qbClient from time import sleep -from json import dumps -from web.nodes import make_tree +from web.nodes import extract_file_ids, make_tree app = Flask(__name__) @@ -27,640 +26,8 @@ basicConfig( LOGGER = getLogger(__name__) -page = """ - - - - - - Torrent File Selector - - - - - - - - - - - -
- - -
-
-

Selected files: 0 of 0

-

Selected files size: 0 of 0

-
-
-
- {My_content} - -
-
- - - - - - - -""" - -code_page = """ - - - - - - Torrent Code Checker - - - - - - - - - -
- - -
-
-
-
- - -
- -
- * Dont mess around. Your download will get messed up. -
- - -""" - - -def re_verfiy(paused, resumed, hash_id): +def re_verify(paused, resumed, hash_id): paused = paused.strip() resumed = resumed.strip() if paused: @@ -706,90 +73,114 @@ def re_verfiy(paused, resumed, hash_id): return True -@app.route("/app/files/", methods=["GET"]) -def list_torrent_contents(id_): - if "pin_code" not in request.args.keys(): - return code_page.replace("{form_url}", f"/app/files/{id_}") +@app.route("/app/files") +def files(): + return render_template("page.html") - pincode = "" - for nbr in id_: + +@app.route("/app/files/torrent", methods=["GET", "POST"]) +def handle_torrent(): + if not (gid := request.args.get("gid")): + return jsonify( + { + "files": [], + "engine": "", + "error": "GID is missing", + "message": "GID not specified", + } + ) + + if not (pin := request.args.get("pin")): + return jsonify( + { + "files": [], + "engine": "", + "error": "Pin is missing", + "message": "PIN not specified", + } + ) + code = "" + for nbr in gid: if nbr.isdigit(): - pincode += str(nbr) - if len(pincode) == 4: + code += str(nbr) + if len(code) == 4: break - if request.args["pin_code"] != pincode: - return "

Incorrect pin code

" - - if len(id_) > 20: - res = qbittorrent_client.torrents_files(torrent_hash=id_) - cont = make_tree(res, "qbittorrent") - else: - res = aria2.client.get_files(id_) - cont = make_tree(res, "aria2") - - try: - content = dumps(cont) - except Exception as e: - LOGGER.error(str(e)) - content = dumps({"files": [], "engine": str(e)}) - - return page.replace("{My_content}", content).replace( - "{form_url}", f"/app/files/{id_}?pin_code={pincode}" - ) - - -@app.route("/app/files/", methods=["POST"]) -def set_priority(id_): - data = dict(request.form) - - resume = "" - if len(id_) > 20: - pause = "" - for i, value in data.items(): - if "filenode" in i: - node_no = i.split("_")[-1] - - if value == "on": - resume += f"{node_no}|" - else: - pause += f"{node_no}|" - - pause = pause.strip("|") - resume = resume.strip("|") - - try: - qbittorrent_client.torrents_file_priority( - torrent_hash=id_, file_ids=pause, priority=0 - ) - except NotFound404Error as e: - raise NotFound404Error from e - except Exception as e: - LOGGER.error(f"{e} Errored in paused") - try: - qbittorrent_client.torrents_file_priority( - torrent_hash=id_, file_ids=resume, priority=1 - ) - except NotFound404Error as e: - raise NotFound404Error from e - except Exception as e: - LOGGER.error(f"{e} Errored in resumed") - sleep(1) - if not re_verfiy(pause, resume, id_): - LOGGER.error(f"Verification Failed! Hash: {id_}") - else: - for i, value in data.items(): - if "filenode" in i and value == "on": - node_no = i.split("_")[-1] - resume += f"{node_no}," - - resume = resume.strip(",") - - res = aria2.client.change_option(id_, {"select-file": resume}) - if res == "OK": - LOGGER.info(f"Verified! Gid: {id_}") + if code != pin: + return jsonify( + { + "files": [], + "engine": "", + "error": "Invalid pin", + "message": "The PIN you entered is incorrect", + } + ) + if request.method == "POST": + data = request.get_json(cache=False, force=True) + selected_files, unselected_files = extract_file_ids(data) + if len(gid) > 20: + selected_files = "|".join(selected_files) + unselected_files = "|".join(unselected_files) + set_qbittorrent(gid, selected_files, unselected_files) else: - LOGGER.info(f"Verification Failed! Report! Gid: {id_}") - return list_torrent_contents(id_) + selected_files = ",".join(selected_files) + set_aria2(gid, selected_files) + content = jsonify( + { + "files": [], + "engine": "", + "error": "", + "message": "Your selection has been submitted successfully.", + } + ) + if request.method == "GET": + try: + if len(gid) > 20: + res = qbittorrent_client.torrents_files(torrent_hash=gid) + content = jsonify(make_tree(res, "qbittorrent")) + else: + res = aria2.client.get_files(gid) + content = jsonify(make_tree(res, "aria2")) + except Exception as e: + LOGGER.error(str(e)) + content = jsonify( + { + "files": [], + "engine": "", + "error": "Error getting files", + "message": str(e), + } + ) + return content + + +def set_qbittorrent(gid, selected_files, unselected_files): + try: + qbittorrent_client.torrents_file_priority( + torrent_hash=gid, file_ids=unselected_files, priority=0 + ) + except NotFound404Error as e: + raise NotFound404Error from e + except Exception as e: + LOGGER.error(f"{e} Errored in paused") + try: + qbittorrent_client.torrents_file_priority( + torrent_hash=gid, file_ids=selected_files, priority=1 + ) + except NotFound404Error as e: + raise NotFound404Error from e + except Exception as e: + LOGGER.error(f"{e} Errored in resumed") + sleep(1) + if not re_verify(unselected_files, selected_files, gid): + LOGGER.error(f"Verification Failed! Hash: {gid}") + + +def set_aria2(gid, selected_files): + res = aria2.client.change_option(gid, {"select-file": selected_files}) + if res == "OK": + LOGGER.info(f"Verified! Gid: {gid}") + else: + LOGGER.info(f"Verification Failed! Report! Gid: {gid}") @app.route("/")