From 31ea05e3cbfdd84c73f6c80464dfd267f9029c0c Mon Sep 17 00:00:00 2001 From: Michael Woods Date: Wed, 24 Dec 2025 19:52:14 -0500 Subject: [PATCH] Adding defunct changes. Still testing. --- packetserver/http/routers/bulletins.py | 116 +++++++++---------------- packetserver/http/server.py | 4 +- 2 files changed, 45 insertions(+), 75 deletions(-) diff --git a/packetserver/http/routers/bulletins.py b/packetserver/http/routers/bulletins.py index 6cbeb2d..4b29235 100644 --- a/packetserver/http/routers/bulletins.py +++ b/packetserver/http/routers/bulletins.py @@ -1,91 +1,61 @@ -# packetserver/http/routers/bulletins.py -from fastapi import APIRouter, Path, Query, Depends, HTTPException, status, Request, APIRouter as PrefixedRouter +from fastapi import APIRouter, Path, Query, Depends, HTTPException, Request, status from fastapi.responses import HTMLResponse from typing import Optional +from pydantic import BaseModel, Field, constr from datetime import datetime import transaction -from pydantic import BaseModel, Field, constr from persistent.list import PersistentList -from packetserver.http.dependencies import get_current_http_user -from packetserver.http.auth import HttpUser -from packetserver.http.server import templates -from packetserver.server.bulletin import Bulletin # core class +from ..dependencies import get_current_http_user # relative +from ..auth import HttpUser +from ..server import templates # relative import - this is now safe +from packetserver.server.bulletin import Bulletin +# Existing API router (keep) router = APIRouter(prefix="/api/v1", tags=["bulletins"]) + +# ... your existing list_bulletins and get_bulletin routes ... + +# New non-prefixed router for HTML pages html_router = APIRouter(tags=["bulletins-html"]) +@html_router.get("/bulletins", response_class="HTMLResponse") +async def bulletin_list_page(request: Request, limit: Optional[int] = Query(50, le=100)): + # Local import to avoid circular issues + from .bulletins import list_bulletins as api_list_bulletins + api_resp = await api_list_bulletins(limit=limit, since=None) + bulletins = api_resp["bulletins"] -class CreateBulletinRequest(BaseModel): - subject: constr(min_length=1, max_length=100) = Field(..., description="Bulletin subject/title") - body: constr(min_length=1) = Field(..., description="Bulletin body text") + current_user = None + try: + current_user = await get_current_http_user()(request) # optional call + except: + pass + return templates.TemplateResponse( + "bulletin_list.html", + {"request": request, "bulletins": bulletins, "current_user": current_user.username if current_user else None} + ) -@router.get("/bulletins") -async def list_bulletins( - limit: Optional[int] = Query(20, le=100, description="Max bulletins to return"), - since: Optional[str] = Query(None, description="ISO UTC timestamp filter") -): - from packetserver.runners.http_server import get_db_connection - conn = get_db_connection() - root = conn.root() +@html_router.get("/bulletins/{bid}", response_class="HTMLResponse") +async def bulletin_detail_page(request: Request, bid: int): + from .bulletins import get_bulletin as api_get_bulletin + try: + bulletin = await api_get_bulletin(bid=bid, current_user=None) + except HTTPException: + raise HTTPException(status_code=404, detail="Bulletin not found") - bulletins_list = root.get('bulletins', []) - if not bulletins_list: - return {"bulletins": [], "total": 0} + current_user = None + try: + current_user = await get_current_http_user()(request) + except: + pass - since_dt = None - if since: - try: - since_dt = datetime.fromisoformat(since.replace("Z", "+00:00")) - except ValueError: - raise HTTPException(status_code=400, detail="Invalid 'since' format") + return templates.TemplateResponse( + "bulletin_detail.html", + {"request": request, "bulletin": bulletin, "current_user": current_user.username if current_user else None} + ) - filtered = [] - for bull in reversed(bulletins_list): # newest first (assuming appended order) - if since_dt and bull.created_at < since_dt: - continue - filtered.append({ - "id": bull.id, - "author": bull.author, - "subject": bull.subject, - "body": bull.body, - "created_at": bull.created_at.isoformat() + "Z", - "updated_at": bull.updated_at.isoformat() + "Z", - }) - - return { - "bulletins": filtered[:limit], - "total": len(filtered) - } - - -@router.get("/bulletins/{bid}") -async def get_bulletin( - bid: int = Path(..., description="Bulletin ID"), - current_user: HttpUser = Depends(get_current_http_user) # require auth, but public read -): - from packetserver.runners.http_server import get_db_connection - conn = get_db_connection() - root = conn.root() - - bulletins_list = root.get('bulletins', []) - for bull in bulletins_list: - if bull.id == bid: - return { - "id": bull.id, - "author": bull.author, - "subject": bull.subject, - "body": bull.body, - "created_at": bull.created_at.isoformat() + "Z", - "updated_at": bull.updated_at.isoformat() + "Z", - } - - raise HTTPException(status_code=404, detail="Bulletin not found") - -from fastapi import status -from pydantic import BaseModel, Field, constr -# datetime already imported elsewhere, but ensure class CreateBulletinRequest(BaseModel): subject: constr(min_length=1, max_length=100) = Field(..., description="Bulletin subject/title") @@ -104,7 +74,7 @@ async def create_bulletin( # Ensure the bulletins list and counter exist if 'bulletins' not in root: - root['bulletins'] = persistent.list.PersistentList() + root['bulletins'] = PersistentList() new_bulletin = Bulletin( author=current_user.username, # uppercase callsign diff --git a/packetserver/http/server.py b/packetserver/http/server.py index f156978..c861882 100644 --- a/packetserver/http/server.py +++ b/packetserver/http/server.py @@ -4,7 +4,7 @@ from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from pathlib import Path -from .routers import public, profile, messages, send, bulletins +from .routers import public, profile, messages, send from packetserver.http.routers.bulletins import html_router BASE_DIR = Path(__file__).parent.resolve() @@ -36,7 +36,7 @@ templates.env.filters["timestamp_to_date"] = timestamp_to_date app.mount("/static", StaticFiles(directory=BASE_DIR / "static"), name="static") # Now safe to import dashboard (it needs templates) -from .routers import dashboard # add this line +from .routers import dashboard, bulletins # Include routers app.include_router(public.router)