Files
ImpTune/imptune/api/pages.py
T
kawa f3644790be feat(11-04): add GET /clients/{id} route and client_detail.html template
- Add client_detail route in pages.py with 404 on unknown client_id
- Build grouped dict {client.name: [printers]} for printer_list partial reuse
- Pass clients + driver_data for edit modal compatibility
- Create client_detail.html extending base.html, includes printer_list partial
2026-04-15 14:49:12 +02:00

214 lines
6.4 KiB
Python

import json
from collections import defaultdict
from pathlib import Path
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from peewee import JOIN
router = APIRouter()
templates = Jinja2Templates(directory=str(Path(__file__).parent.parent / "templates"))
@router.get("/", response_class=HTMLResponse)
def dashboard(request: Request):
from imptune.db.models import Printer
recent_printers = list(
Printer.select().order_by(Printer.created_at.desc()).limit(5)
)
recent_packages = list(
Printer.select()
.where(Printer.driver.is_null(False))
.order_by(Printer.created_at.desc())
.limit(5)
)
return templates.TemplateResponse(
request=request,
name="dashboard.html",
context={
"recent_printers": recent_printers,
"recent_packages": recent_packages,
},
)
@router.get("/drivers", response_class=HTMLResponse)
def drivers_page(request: Request):
from imptune.db.models import Driver
drivers = list(Driver.select().order_by(Driver.uploaded_at.desc()))
driver_data = []
for d in drivers:
names = json.loads(d.driver_desc) if d.driver_desc else []
driver_data.append({"driver": d, "names": names})
return templates.TemplateResponse(
request=request,
name="drivers.html",
context={"driver_data": driver_data},
)
@router.get("/printers", response_class=HTMLResponse)
def printers_page(request: Request):
from imptune.db.models import Client, Driver, Printer
query = (
Printer.select(Printer, Client)
.join(Client, JOIN.LEFT_OUTER)
.order_by(Client.name, Printer.name)
)
grouped: dict[str, list] = defaultdict(list)
for p in query:
client_name = p.client.name if p.client_id else "Unassigned"
grouped[client_name].append(p)
clients = list(Client.select().order_by(Client.name))
all_drivers = list(Driver.select().order_by(Driver.uploaded_at.desc()))
driver_data = []
for d in all_drivers:
names = json.loads(d.driver_desc) if d.driver_desc else []
driver_data.append({"driver": d, "names": names})
return templates.TemplateResponse(
request=request,
name="printers.html",
context={
"grouped": grouped,
"clients": clients,
"driver_data": driver_data,
},
)
@router.get("/printers/new", response_class=HTMLResponse)
def printers_new_page(request: Request):
from imptune.db.models import Client, Driver
clients = list(Client.select().order_by(Client.name))
all_drivers = list(Driver.select().order_by(Driver.uploaded_at.desc()))
driver_data = [
{"driver": d, "names": json.loads(d.driver_desc) if d.driver_desc else []}
for d in all_drivers
]
return templates.TemplateResponse(
request=request,
name="printers_new.html",
context={"clients": clients, "driver_data": driver_data},
)
@router.get("/printers/{printer_id}", response_class=HTMLResponse)
def printer_detail(request: Request, printer_id: int):
from imptune.db.models import Client, Driver, Icon, Printer
printer = (
Printer.select(Printer, Client, Driver)
.join(Client, JOIN.LEFT_OUTER)
.switch(Printer)
.join(Driver, JOIN.LEFT_OUTER)
.where(Printer.id == printer_id)
.first()
)
if printer is None:
return HTMLResponse(
content="<h1>404 Not Found</h1><p>Printer not found.</p>",
status_code=404,
)
driver_names: list[str] = []
if printer.driver_id and printer.driver.driver_desc:
driver_names = json.loads(printer.driver.driver_desc)
has_driver = printer.driver_id is not None and bool(driver_names)
icon = Icon.get_or_none(Icon.printer == printer_id)
install_cmd = "powershell.exe -ExecutionPolicy Bypass -File install.ps1"
uninstall_cmd = "powershell.exe -ExecutionPolicy Bypass -File uninstall.ps1"
return templates.TemplateResponse(
request=request,
name="printer_detail.html",
context={
"printer": printer,
"driver_names": driver_names,
"has_driver": has_driver,
"has_icon": icon is not None,
"install_cmd": install_cmd,
"uninstall_cmd": uninstall_cmd,
},
)
@router.get("/clients", response_class=HTMLResponse)
def clients_page(request: Request):
from imptune.db.models import Client
clients = list(Client.select().order_by(Client.name))
return templates.TemplateResponse(
request=request,
name="clients.html",
context={"clients": clients},
)
@router.get("/clients/{client_id}", response_class=HTMLResponse)
def client_detail(request: Request, client_id: int):
from imptune.db.models import Client, Driver, Printer
client = Client.get_or_none(Client.id == client_id)
if client is None:
return HTMLResponse(
content="<h1>404 Not Found</h1><p>Client not found.</p>",
status_code=404,
)
query = (
Printer.select(Printer, Client)
.join(Client, JOIN.LEFT_OUTER)
.where(Printer.client == client_id)
.order_by(Printer.name)
)
grouped = {client.name: list(query)}
clients = list(Client.select().order_by(Client.name))
all_drivers = list(Driver.select().order_by(Driver.uploaded_at.desc()))
driver_data = [
{"driver": d, "names": json.loads(d.driver_desc) if d.driver_desc else []}
for d in all_drivers
]
return templates.TemplateResponse(
request=request,
name="client_detail.html",
context={
"client": client,
"grouped": grouped,
"clients": clients,
"driver_data": driver_data,
},
)
@router.get("/packages", response_class=HTMLResponse)
def packages_page(request: Request):
from imptune.db.models import Client, Driver, Printer
printers = list(
Printer.select(Printer, Client, Driver)
.join(Client, JOIN.LEFT_OUTER)
.switch(Printer)
.join(Driver, JOIN.LEFT_OUTER)
.where(Printer.driver.is_null(False))
.order_by(Printer.name)
)
return templates.TemplateResponse(
request=request,
name="packages.html",
context={"printers": printers},
)