Spaces:
Sleeping
Sleeping
| 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 | |
| # ============================== | |
| def home(): | |
| return render_template("index.html") | |
| # ============================== | |
| # Login Page | |
| # ============================== | |
| 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 | |
| # ============================== | |
| 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 | |
| # ============================== | |
| 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 | |
| # ============================== | |
| def logout(): | |
| session.clear() | |
| return redirect("/") | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860, debug=True) |