# app.py from flask import Flask, render_template, request, redirect, url_for, session, send_file, jsonify from flask_caching import Cache import requests.auth import os from lib.datetime import filter_accounts_current_month, filter_accounts_expired from lib.reqs import get_urls, get_user_accounts, add_user_account, delete_user_account, get_user_accounts_count from flask import send_from_directory import requests import base64 from flask import Flask from config import DevelopmentConfig from paddleocr import PaddleOCR from PIL import Image import numpy as np os.environ["OMP_NUM_THREADS"] = "1" os.environ["MKL_NUM_THREADS"] = "1" app = Flask(__name__) app.config.from_object( DevelopmentConfig ) cache = Cache(app, config={"CACHE_TYPE": "SimpleCache"}) ocr = PaddleOCR(use_angle_cls=True, lang='en') # Adjust language if needed app.config['SESSION_COOKIE_SECURE'] = True # Only send cookie over HTTPS app.config['SESSION_COOKIE_HTTPONLY'] = True # Prevent JavaScript access app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # Adjust for cross-site requests app.config['PERMANENT_SESSION_LIFETIME'] = 60 * 60 * 24 * 365 # 1 year in seconds cache.clear() # Clears all cache entries @app.before_request def make_session_permanent(): session.permanent = True @app.route('/manifest.json') def serve_manifest(): return send_file('manifest.json', mimetype='application/manifest+json') @app.route("/favicon.ico") def favicon(): return send_from_directory( os.path.join(app.root_path, "static"), "favicon.ico", mimetype="image/vnd.microsoft.icon", ) @app.route("/") def index(): # If the user is logged in, redirect to a protected page like /accounts if session.get("logged_in"): return redirect(url_for("home")) return render_template("index.html") @app.route("/home") @cache.cached(timeout=60) # cache for 120 seconds def home(): if session.get("logged_in"): base_url = app.config["BASE_URL"] # Access base_url from the config all_accounts = get_user_accounts(base_url, session["auth_credentials"]) count = len(all_accounts) current_month_accounts = filter_accounts_current_month(all_accounts) expired_accounts = filter_accounts_expired(all_accounts) return render_template( "home.html", username=session["username"], accounts=count, current_month_accounts=current_month_accounts, expired_accounts=expired_accounts, ) return render_template("index.html") @app.route("/login", methods=["POST"]) def login(): username = request.form["username"] password = request.form["password"] # Encode the username and password in Base64 credentials = f"{username}:{password}" encoded_credentials = base64.b64encode(credentials.encode()).decode() base_url = app.config["BASE_URL"] # Access base_url from the config login_url = f"{base_url}/Login" # Construct the full URL # Send GET request to the external login API with Basic Auth response = requests.get( login_url, auth=requests.auth.HTTPBasicAuth(username, password) ) # Check if login was successful if response.status_code == 200 and response.json().get("auth") == "Success": # Set session variable to indicate the user is logged in session["logged_in"] = True session["username"] = username session["auth_credentials"] = encoded_credentials return redirect(url_for("home")) # Redirect to the Accounts page else: # Show error on the login page error = "Invalid username or password. Please try again." return render_template("index.html", error=error) @app.route("/urls", methods=["GET"]) @cache.cached(timeout=300) # cache for 5 minutes def urls(): # Check if the user is logged in if not session.get("logged_in"): return redirect(url_for("home")) # Placeholder content for Accounts page base_url = app.config["BASE_URL"] # Access base_url from the config return render_template( "urls.html", urls=get_urls(base_url, session["auth_credentials"]) ) @app.route("/accounts", methods=["GET"]) @cache.cached(timeout=120) # cache for 120 seconds def user_accounts(): # Check if the user is logged in if not session.get("logged_in"): return redirect(url_for("home")) # Placeholder content for Accounts page base_url = app.config["BASE_URL"] # Access base_url from the config return render_template( "user_accounts.html", username=session["username"], user_accounts=get_user_accounts(base_url, session["auth_credentials"]), auth=session["auth_credentials"], ) @app.route("/accounts/add", methods=["GET", "POST"]) def add_account(): base_url = app.config["BASE_URL"] # Access base_url from the config if request.method == "POST": username = request.form["username"] password = request.form["password"] stream = request.form["stream"] if add_user_account( base_url, session["auth_credentials"], username, password, stream ): cache.clear() # Clears all cache entries return redirect(url_for("user_accounts")) return render_template("add_account.html") return render_template("add_account.html") @app.route("/accounts/delete", methods=["POST"]) def delete_account(): stream = request.form.get("stream") username = request.form.get("username") base_url = app.config["BASE_URL"] if delete_user_account(base_url, session["auth_credentials"], stream, username): cache.clear() # Clears all cache entries return redirect(url_for("user_accounts")) return redirect(url_for("user_accounts")) @app.route('/OCRupload', methods=['POST']) def OCRupload(): if 'image' not in request.files: return jsonify({"error": "No image file found"}), 400 # Get the uploaded file file = request.files['image'] try: image = Image.open(file.stream) image_np = np.array(image) result = ocr.ocr(image_np) # Extract text extracted_text = [] for line in result[0]: extracted_text.append(line[1][0]) return render_template("add_account.html", username=extracted_text[2], password=extracted_text[3]) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == "__main__": app.run(debug=app.config["DEBUG"], host=app.config["HOST"], port=app.config["PORT"])