From 1d0073d2fb7f91cef516220dbbae18717bb78caf Mon Sep 17 00:00:00 2001 From: Karl Date: Tue, 15 Jul 2025 15:42:47 +0100 Subject: [PATCH] faster checker --- .vscode/launch.json | 13 ++++++++++- debug_account.py | 47 +++++++++++++++++++++++++++++++++++++++ ktvmanager/lib/checker.py | 46 +++++++++++++++++++++++--------------- routes/api.py | 2 +- 4 files changed, 88 insertions(+), 20 deletions(-) create mode 100644 debug_account.py diff --git a/.vscode/launch.json b/.vscode/launch.json index dd46c02..8623304 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,7 +2,7 @@ "version": "0.2.0", "configurations": [ { - "name": "Python Debugger: Current File", + "name": "Python: Debug Account", "type": "debugpy", "request": "launch", "program": "${file}", @@ -24,6 +24,17 @@ "--host=0.0.0.0" ], "jinja": false + }, + { + "name": "Python: Debug Single Account", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/debug_account.py", + "args": [ + "Karl0ss2903", + "SNJZCKKK9J" + ], + "console": "integratedTerminal" } ] } \ No newline at end of file diff --git a/debug_account.py b/debug_account.py new file mode 100644 index 0000000..9088e9c --- /dev/null +++ b/debug_account.py @@ -0,0 +1,47 @@ +import os +import sys +import argparse +from dotenv import load_dotenv +import mysql.connector + +# Add the project root to the Python path +project_root = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(project_root) + +from ktvmanager.lib.checker import single_account_check +from ktvmanager.lib.get_urls import get_latest_urls_from_dns + +def main(): + parser = argparse.ArgumentParser(description="Debug a single KTV account.") + parser.add_argument("username", help="The username to check.") + parser.add_argument("password", help="The password to check.") + args = parser.parse_args() + + load_dotenv() + + db_connection = mysql.connector.connect( + host=os.getenv("DBHOST"), + user=os.getenv("DBUSER"), + password=os.getenv("DBPASS"), + database=os.getenv("DATABASE"), + port=os.getenv("DBPORT") + ) + + stream_urls = get_latest_urls_from_dns() + + account_data = { + "username": args.username, + "password": args.password + } + + result = single_account_check(account_data, stream_urls) + + if result: + print(f"Account {args.username} is VALID.") + else: + print(f"Account {args.username} is INVALID.") + + db_connection.close() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ktvmanager/lib/checker.py b/ktvmanager/lib/checker.py index 43af803..dca6fcd 100644 --- a/ktvmanager/lib/checker.py +++ b/ktvmanager/lib/checker.py @@ -1,4 +1,5 @@ import requests +from concurrent.futures import ThreadPoolExecutor, as_completed from flask import request, jsonify from ktvmanager.lib.get_urls import get_latest_urls_from_dns @@ -7,29 +8,38 @@ def build_url(stream_url, username, password): def check_url(url): try: - tr = requests - response = tr.get(url, timeout=5) + response = requests.get(url, timeout=5) response.raise_for_status() - if response.json().get("user_info", {}).get("auth"): - return response.json() - except requests.exceptions.RequestException as e: - if e.response and e.response.status_code == 403: - try: - response = requests.get(url, timeout=5) - response.raise_for_status() - if response.json().get("user_info", {}).get("auth"): - return response.json() - except requests.exceptions.RequestException: - return None + data = response.json() + if data.get("user_info", {}).get("auth"): + return data + except (requests.exceptions.RequestException, ValueError): + # Return None for any request/parsing error + return None return None def single_account_check(account_data, stream_urls): - for stream_url in stream_urls: - url = build_url(stream_url, account_data['username'], account_data['password']) - result = check_url(url) + if not stream_urls: + return None + + executor = ThreadPoolExecutor(max_workers=min(10, len(stream_urls))) + future_to_url = { + executor.submit( + check_url, + build_url(stream_url, account_data['username'], account_data['password']) + ): stream_url + for stream_url in stream_urls + } + + final_result = None + for future in as_completed(future_to_url): + result = future.result() if result: - return {"url": stream_url, "data": result} - return None + final_result = {"url": future_to_url[future], "data": result} + break # Found a valid URL, stop checking others + + executor.shutdown(wait=False) # Don't wait for other threads to finish + return final_result def validate_account(): data = request.get_json() diff --git a/routes/api.py b/routes/api.py index a9e1220..9b45633 100644 --- a/routes/api.py +++ b/routes/api.py @@ -2,6 +2,7 @@ from flask import Blueprint, jsonify from ktvmanager.lib.database import get_user_accounts, get_stream_names, single_check, add_account, delete_account, get_user_id_from_username from ktvmanager.lib.get_urls import get_latest_urls_from_dns from ktvmanager.lib.auth import requires_basic_auth, check_login +from ktvmanager.lib.checker import validate_account api_blueprint = Blueprint("api", __name__) @@ -43,7 +44,6 @@ def delete_account_route(username, password): @api_blueprint.route("/validateAccount", methods=["POST"]) @requires_basic_auth def validate_account_route(username, password): - from ktvmanager.lib.checker import validate_account return validate_account() @api_blueprint.route("/Login")