Рефакторинг структуры проекта: шаблоны, статика и модули приложения
This commit is contained in:
167
zkart_app/routes.py
Normal file
167
zkart_app/routes.py
Normal file
@@ -0,0 +1,167 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from flask import Blueprint, jsonify, redirect, render_template, request, send_from_directory, session
|
||||
|
||||
from .config import ADMIN_LOGIN, ADMIN_PASSWORD, ADMIN_PATH, BASE_DIR
|
||||
from .db import fetch_scope_data, get_db, scope_tables
|
||||
|
||||
bp = Blueprint("main", __name__)
|
||||
|
||||
def require_admin() -> bool:
|
||||
return bool(session.get("is_admin"))
|
||||
|
||||
|
||||
def parse_int(form_value: str | None) -> int | None:
|
||||
if not form_value:
|
||||
return None
|
||||
try:
|
||||
return int(form_value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
@bp.get("/")
|
||||
def index():
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@bp.get("/api/data")
|
||||
def api_data():
|
||||
scope = (request.args.get("scope") or "infra").strip().lower()
|
||||
if scope in {"ib", "sec", "security"}:
|
||||
scope = "ib"
|
||||
else:
|
||||
scope = "infra"
|
||||
return jsonify(fetch_scope_data(scope))
|
||||
|
||||
|
||||
@bp.route(ADMIN_PATH, methods=["GET", "POST"])
|
||||
def admin_login_or_panel():
|
||||
conn = get_db()
|
||||
raw_scope = (request.args.get("scope") or request.form.get("scope") or "infra").strip().lower()
|
||||
scope = "ib" if raw_scope in {"ib", "sec", "security"} else "infra"
|
||||
tables = scope_tables(scope)
|
||||
|
||||
if request.method == "POST" and not require_admin() and request.form.get("action") == "login":
|
||||
if request.form.get("username") == ADMIN_LOGIN and request.form.get("password") == ADMIN_PASSWORD:
|
||||
session["is_admin"] = True
|
||||
conn.close()
|
||||
return redirect(ADMIN_PATH)
|
||||
conn.close()
|
||||
return render_template("login.html", error="Неверный логин или пароль")
|
||||
|
||||
if not require_admin():
|
||||
conn.close()
|
||||
return render_template("login.html", error=None)
|
||||
|
||||
if request.method == "POST":
|
||||
action = request.form.get("action", "")
|
||||
if action == "logout":
|
||||
session.pop("is_admin", None)
|
||||
conn.close()
|
||||
return redirect(ADMIN_PATH)
|
||||
|
||||
if action == "add_vendor":
|
||||
name = (request.form.get("name") or "").strip()
|
||||
if name:
|
||||
conn.execute(f"INSERT OR IGNORE INTO {tables['vendors']}(name) VALUES (?)", (name,))
|
||||
|
||||
elif action == "add_category":
|
||||
name = (request.form.get("name") or "").strip()
|
||||
if name:
|
||||
conn.execute(f"INSERT OR IGNORE INTO {tables['categories']}(name) VALUES (?)", (name,))
|
||||
|
||||
elif action == "add_product":
|
||||
vendor_id = parse_int(request.form.get("vendor_id"))
|
||||
name = (request.form.get("name") or "").strip()
|
||||
url = (request.form.get("url") or "").strip()
|
||||
if vendor_id and name:
|
||||
conn.execute(
|
||||
f"INSERT OR IGNORE INTO {tables['products']}(vendor_id, name, url) VALUES (?, ?, ?)",
|
||||
(vendor_id, name, url or None),
|
||||
)
|
||||
if url:
|
||||
conn.execute(
|
||||
f"UPDATE {tables['products']} SET url = ? WHERE vendor_id = ? AND name = ?",
|
||||
(url, vendor_id, name),
|
||||
)
|
||||
|
||||
elif action == "delete_vendor":
|
||||
v_id = parse_int(request.form.get("vendor_id"))
|
||||
if v_id:
|
||||
conn.execute(f"DELETE FROM {tables['vendors']} WHERE id = ?", (v_id,))
|
||||
|
||||
elif action == "delete_category":
|
||||
c_id = parse_int(request.form.get("category_id"))
|
||||
if c_id:
|
||||
conn.execute(f"DELETE FROM {tables['categories']} WHERE id = ?", (c_id,))
|
||||
|
||||
elif action == "delete_product":
|
||||
p_id = parse_int(request.form.get("product_id"))
|
||||
if p_id:
|
||||
conn.execute(f"DELETE FROM {tables['products']} WHERE id = ?", (p_id,))
|
||||
|
||||
elif action == "save_matrix":
|
||||
products = [r["id"] for r in conn.execute(f"SELECT id FROM {tables['products']}")]
|
||||
categories = [r["id"] for r in conn.execute(f"SELECT id FROM {tables['categories']}")]
|
||||
new_pairs: list[tuple[int, int]] = []
|
||||
for p_id in products:
|
||||
for c_id in categories:
|
||||
if request.form.get(f"pc_{p_id}_{c_id}"):
|
||||
new_pairs.append((p_id, c_id))
|
||||
conn.execute(f"DELETE FROM {tables['product_categories']}")
|
||||
conn.executemany(
|
||||
f"INSERT OR IGNORE INTO {tables['product_categories']}(product_id, category_id) VALUES (?, ?)",
|
||||
new_pairs,
|
||||
)
|
||||
conn.execute(f"DELETE FROM {tables['vendor_categories']}")
|
||||
conn.execute(
|
||||
f"""
|
||||
INSERT OR IGNORE INTO {tables['vendor_categories']}(vendor_id, category_id)
|
||||
SELECT DISTINCT p.vendor_id, pc.category_id
|
||||
FROM {tables['products']} p
|
||||
JOIN {tables['product_categories']} pc ON pc.product_id = p.id
|
||||
"""
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return redirect(f"{ADMIN_PATH}?scope={scope}")
|
||||
|
||||
vendors = [dict(r) for r in conn.execute(f"SELECT id, name FROM {tables['vendors']} ORDER BY lower(name)")]
|
||||
categories = [dict(r) for r in conn.execute(f"SELECT id, name FROM {tables['categories']} ORDER BY lower(name)")]
|
||||
products = [
|
||||
dict(r)
|
||||
for r in conn.execute(
|
||||
f"""
|
||||
SELECT p.id, p.name, p.vendor_id, v.name AS vendor_name
|
||||
, p.url
|
||||
FROM {tables['products']} p
|
||||
JOIN {tables['vendors']} v ON v.id = p.vendor_id
|
||||
ORDER BY lower(v.name), lower(p.name)
|
||||
"""
|
||||
)
|
||||
]
|
||||
links = {
|
||||
(r["product_id"], r["category_id"])
|
||||
for r in conn.execute(f"SELECT product_id, category_id FROM {tables['product_categories']}")
|
||||
}
|
||||
conn.close()
|
||||
return render_template(
|
||||
"admin.html",
|
||||
vendors=vendors,
|
||||
categories=categories,
|
||||
products=products,
|
||||
links=links,
|
||||
scope=scope,
|
||||
)
|
||||
|
||||
|
||||
@bp.get("/health")
|
||||
def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@bp.get("/assets/mont-logo")
|
||||
def mont_logo():
|
||||
return send_from_directory(BASE_DIR, "mont_logo.png")
|
||||
Reference in New Issue
Block a user