Adding defunct changes. Still testing.
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
@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()
|
||||
|
||||
bulletins_list = root.get('bulletins', [])
|
||||
if not bulletins_list:
|
||||
return {"bulletins": [], "total": 0}
|
||||
|
||||
since_dt = None
|
||||
if since:
|
||||
current_user = None
|
||||
try:
|
||||
since_dt = datetime.fromisoformat(since.replace("Z", "+00:00"))
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=400, detail="Invalid 'since' format")
|
||||
current_user = await get_current_http_user()(request) # optional call
|
||||
except:
|
||||
pass
|
||||
|
||||
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",
|
||||
}
|
||||
return templates.TemplateResponse(
|
||||
"bulletin_list.html",
|
||||
{"request": request, "bulletins": bulletins, "current_user": current_user.username if current_user else None}
|
||||
)
|
||||
|
||||
@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")
|
||||
|
||||
from fastapi import status
|
||||
from pydantic import BaseModel, Field, constr
|
||||
# datetime already imported elsewhere, but ensure
|
||||
current_user = None
|
||||
try:
|
||||
current_user = await get_current_http_user()(request)
|
||||
except:
|
||||
pass
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"bulletin_detail.html",
|
||||
{"request": request, "bulletin": bulletin, "current_user": current_user.username if current_user else None}
|
||||
)
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user