from flask import Flask, render_template, request, redirect, url_for, session import qrcode from PIL import Image import os import pandas as pd import requests from io import StringIO from urllib.parse import quote app = Flask(__name__) app.secret_key = "supersecretkey" # ============================== # Login Credentials # ============================== USERNAME = "admin" PASSWORD = "123456" # ============================== # Folder Setup # ============================== UPLOAD_FOLDER = "static/generated" os.makedirs(UPLOAD_FOLDER, exist_ok=True) # ============================== # Google Sheet Configuration # ============================== SHEET_ID = "1F90Q1scHpX4U_OIBDA_yZF3BozUGfJtl-1XucV4XBCM" GID = "0" GOOGLE_SHEET_CSV = f"https://docs.google.com/spreadsheets/d/{SHEET_ID}/gviz/tq?tqx=out:csv&gid={GID}" def fetch_sheet(): try: response = requests.get(GOOGLE_SHEET_CSV) if response.status_code != 200: return None df = pd.read_csv(StringIO(response.text)) df.columns = df.columns.str.strip().str.lower() if "asset id" not in df.columns: return None df.rename(columns={"asset id": "Asset ID"}, inplace=True) return df except: return None # ============================== # Home Page # ============================== @app.route("/") def home(): return render_template("index.html") # ============================== # Login Page # ============================== @app.route("/login", methods=["GET", "POST"]) def login(): if request.method == "POST": username = request.form.get("username") password = request.form.get("password") asset_id = request.form.get("asset_id") if username == USERNAME and password == PASSWORD: session["logged_in"] = True return redirect(url_for("show_asset", asset_id=asset_id)) return render_template("login.html", error="Invalid Credentials", asset_id=asset_id) asset_id = request.args.get("asset_id") return render_template("login.html", asset_id=asset_id) # ============================== # Generate QR # ============================== @app.route("/generate", methods=["POST"]) def generate_qr(): asset_id = request.form.get("data").strip() fill_color = request.form.get("fill_color") back_color = request.form.get("back_color") size = int(request.form.get("size")) logo = request.files.get("logo") df = fetch_sheet() if df is None: return render_template("index.html", error="Sheet Error") df["Asset ID"] = df["Asset ID"].astype(str).str.strip() result = df[df["Asset ID"].str.lower() == asset_id.lower()] if result.empty: return render_template("index.html", error="Asset Not Found") row = result.iloc[0] asset_url = request.url_root + "login?asset_id=" + quote(asset_id) qr = qrcode.QRCode( error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=size, border=4, ) qr.add_data(asset_url) qr.make(fit=True) img = qr.make_image(fill_color=fill_color, back_color=back_color).convert("RGB") # ============================== # Center Logo (Uploaded OR Default) # ============================== try: if logo and logo.filename != "": logo_img = Image.open(logo) else: logo_img = Image.open("static/default_logo.png") qr_width, qr_height = img.size logo_size = qr_width // 4 logo_img = logo_img.resize((logo_size, logo_size)) pos = ( (qr_width - logo_size) // 2, (qr_height - logo_size) // 2 ) img.paste(logo_img, pos) except: pass qr_path = os.path.join(UPLOAD_FOLDER, "qr.png") img.save(qr_path) asset_info = { "Asset ID": row.get("Asset ID", ""), "Asset Type": row.get("asset type", ""), "Asset Name": row.get("asset name", ""), "Allotted To": row.get("allotted to", ""), "Department": row.get("department", ""), "Room Number": row.get("room number", ""), } return render_template( "index.html", qr_image="generated/qr.png", asset=asset_info ) # ============================== # Asset Details Page # ============================== @app.route("/asset/") def show_asset(asset_id): if not session.get("logged_in"): return redirect(url_for("login", asset_id=asset_id)) df = fetch_sheet() if df is None: return "Sheet Error" df["Asset ID"] = df["Asset ID"].astype(str).str.strip() result = df[df["Asset ID"].str.lower() == asset_id.lower()] if result.empty: return "Asset Not Found" row = result.iloc[0] asset_info = { "Asset ID": row.get("Asset ID", ""), "Asset Type": row.get("asset type", ""), "Asset Name": row.get("asset name", ""), "Allotted To": row.get("allotted to", ""), "Department": row.get("department", ""), "Room Number": row.get("room number", ""), } return render_template("asset_card.html", asset=asset_info) # ============================== # Logout # ============================== @app.route("/logout") def logout(): session.clear() return redirect("/") if __name__ == "__main__": app.run(host="0.0.0.0", port=7860, debug=True)