Fixed database code everywhere, dashboard is still happy everywhere now.
This commit is contained in:
@@ -37,8 +37,7 @@ def init_db() -> ZODB.DB:
|
|||||||
return _db
|
return _db
|
||||||
|
|
||||||
host, port = _get_zeo_address(settings.zeo_file)
|
host, port = _get_zeo_address(settings.zeo_file)
|
||||||
storage = ZEO.ClientStorage((host, port))
|
_db = ZEO.DB((host, port))
|
||||||
_db = ZODB.DB(storage)
|
|
||||||
return _db
|
return _db
|
||||||
|
|
||||||
def get_db() -> ZODB.DB:
|
def get_db() -> ZODB.DB:
|
||||||
@@ -54,7 +53,9 @@ def get_connection() -> Generator[Connection, None, None]:
|
|||||||
try:
|
try:
|
||||||
yield conn
|
yield conn
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
#print("not closing connection")
|
||||||
|
#conn.close()
|
||||||
|
pass
|
||||||
|
|
||||||
# Optional: per-request transaction (if you want automatic commit/abort)
|
# Optional: per-request transaction (if you want automatic commit/abort)
|
||||||
def get_transaction_manager():
|
def get_transaction_manager():
|
||||||
|
|||||||
@@ -3,18 +3,17 @@ from fastapi import Depends, HTTPException, status
|
|||||||
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||||
|
|
||||||
from .auth import HttpUser
|
from .auth import HttpUser
|
||||||
from .database import get_transaction
|
from .database import ConnectionDependency
|
||||||
|
|
||||||
security = HTTPBasic()
|
security = HTTPBasic()
|
||||||
|
|
||||||
|
|
||||||
async def get_current_http_user(credentials: HTTPBasicCredentials = Depends(security)):
|
async def get_current_http_user(conn: ConnectionDependency, credentials: HTTPBasicCredentials = Depends(security)):
|
||||||
"""
|
"""
|
||||||
Authenticate via Basic Auth using HttpUser from ZODB.
|
Authenticate via Basic Auth using HttpUser from ZODB.
|
||||||
Injected by the standalone runner (get_db_connection available).
|
Injected by the standalone runner (get_db_connection available).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with get_transaction() as conn:
|
|
||||||
root = conn.root()
|
root = conn.root()
|
||||||
|
|
||||||
http_users = root.get("httpUsers")
|
http_users = root.get("httpUsers")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from fastapi.responses import HTMLResponse
|
|||||||
from packetserver.http.dependencies import get_current_http_user
|
from packetserver.http.dependencies import get_current_http_user
|
||||||
from packetserver.http.auth import HttpUser
|
from packetserver.http.auth import HttpUser
|
||||||
from packetserver.http.server import templates
|
from packetserver.http.server import templates
|
||||||
|
from packetserver.http.database import ConnectionDependency
|
||||||
|
|
||||||
router = APIRouter(tags=["dashboard"])
|
router = APIRouter(tags=["dashboard"])
|
||||||
|
|
||||||
@@ -15,11 +16,13 @@ from .bulletins import list_bulletins
|
|||||||
|
|
||||||
@router.get("/dashboard", response_class=HTMLResponse)
|
@router.get("/dashboard", response_class=HTMLResponse)
|
||||||
async def dashboard(
|
async def dashboard(
|
||||||
|
conn: ConnectionDependency,
|
||||||
request: Request,
|
request: Request,
|
||||||
current_user: HttpUser = Depends(get_current_http_user)
|
current_user: HttpUser = Depends(get_current_http_user)
|
||||||
):
|
):
|
||||||
# Internal call – pass explicit defaults to avoid Query object injection
|
# Internal call – pass explicit defaults to avoid Query object injection
|
||||||
messages_resp = await api_get_messages(
|
messages_resp = await api_get_messages(
|
||||||
|
conn,
|
||||||
current_user=current_user,
|
current_user=current_user,
|
||||||
type="all",
|
type="all",
|
||||||
limit=100,
|
limit=100,
|
||||||
@@ -27,7 +30,7 @@ async def dashboard(
|
|||||||
)
|
)
|
||||||
messages = messages_resp["messages"]
|
messages = messages_resp["messages"]
|
||||||
|
|
||||||
bulletins_resp = await list_bulletins(limit=10, since=None)
|
bulletins_resp = await list_bulletins(conn, limit=10, since=None)
|
||||||
recent_bulletins = bulletins_resp["bulletins"]
|
recent_bulletins = bulletins_resp["bulletins"]
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
@@ -42,11 +45,12 @@ async def dashboard(
|
|||||||
|
|
||||||
@router.get("/dashboard/profile", response_class=HTMLResponse)
|
@router.get("/dashboard/profile", response_class=HTMLResponse)
|
||||||
async def profile_page(
|
async def profile_page(
|
||||||
|
conn: ConnectionDependency,
|
||||||
request: Request,
|
request: Request,
|
||||||
current_user: HttpUser = Depends(get_current_http_user)
|
current_user: HttpUser = Depends(get_current_http_user)
|
||||||
):
|
):
|
||||||
from packetserver.http.routers.profile import profile as api_profile
|
from packetserver.http.routers.profile import profile as api_profile
|
||||||
profile_data = await api_profile(current_user=current_user)
|
profile_data = await api_profile(conn, current_user=current_user)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"profile.html",
|
"profile.html",
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ async def mark_message_retrieved(
|
|||||||
|
|
||||||
@html_router.get("/messages", response_class=HTMLResponse)
|
@html_router.get("/messages", response_class=HTMLResponse)
|
||||||
async def message_list_page(
|
async def message_list_page(
|
||||||
|
conn: ConnectionDependency,
|
||||||
request: Request,
|
request: Request,
|
||||||
type: str = Query("received", alias="msg_type"), # matches your filter links
|
type: str = Query("received", alias="msg_type"), # matches your filter links
|
||||||
limit: Optional[int] = Query(50, le=100),
|
limit: Optional[int] = Query(50, le=100),
|
||||||
@@ -168,7 +169,7 @@ async def message_list_page(
|
|||||||
):
|
):
|
||||||
from packetserver.http.server import templates
|
from packetserver.http.server import templates
|
||||||
# Directly call the existing API endpoint function
|
# Directly call the existing API endpoint function
|
||||||
api_resp = await get_messages(current_user=current_user, type=type, limit=limit, since=None)
|
api_resp = await get_messages(conn, current_user=current_user, type=type, limit=limit, since=None)
|
||||||
messages = api_resp["messages"]
|
messages = api_resp["messages"]
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import mimetypes
|
|||||||
|
|
||||||
from packetserver.http.dependencies import get_current_http_user
|
from packetserver.http.dependencies import get_current_http_user
|
||||||
from packetserver.http.auth import HttpUser
|
from packetserver.http.auth import HttpUser
|
||||||
|
from packetserver.http.database import DbDependency, ConnectionDependency
|
||||||
from packetserver.server.objects import Object
|
from packetserver.server.objects import Object
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@@ -22,15 +23,11 @@ class ObjectSummary(BaseModel):
|
|||||||
modified_at: datetime
|
modified_at: datetime
|
||||||
|
|
||||||
@router.get("/objects", response_model=List[ObjectSummary])
|
@router.get("/objects", response_model=List[ObjectSummary])
|
||||||
async def list_my_objects(current_user: HttpUser = Depends(get_current_http_user)):
|
async def list_my_objects(db: DbDependency, current_user: HttpUser = Depends(get_current_http_user)):
|
||||||
from packetserver.runners.http_server import get_db_connection
|
|
||||||
|
|
||||||
conn = get_db_connection()
|
|
||||||
root = conn.root()
|
|
||||||
|
|
||||||
username = current_user.username # uppercase callsign
|
username = current_user.username # uppercase callsign
|
||||||
|
|
||||||
core_objects = Object.get_objects_by_username(username, root)
|
core_objects = Object.get_objects_by_username(username, db)
|
||||||
|
|
||||||
# Sort newest first by created_at
|
# Sort newest first by created_at
|
||||||
core_objects.sort(key=lambda o: o.created_at, reverse=True)
|
core_objects.sort(key=lambda o: o.created_at, reverse=True)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from fastapi.staticfiles import StaticFiles
|
|||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from .database import init_db
|
||||||
from .routers import public, profile, messages, send
|
from .routers import public, profile, messages, send
|
||||||
|
|
||||||
BASE_DIR = Path(__file__).parent.resolve()
|
BASE_DIR = Path(__file__).parent.resolve()
|
||||||
@@ -40,6 +41,9 @@ from .routers.message_detail import router as message_detail_router
|
|||||||
from .routers.messages import html_router
|
from .routers.messages import html_router
|
||||||
from .routers.objects import router as objects_router
|
from .routers.objects import router as objects_router
|
||||||
|
|
||||||
|
# initialize database
|
||||||
|
init_db()
|
||||||
|
|
||||||
# Include routers
|
# Include routers
|
||||||
app.include_router(public.router)
|
app.include_router(public.router)
|
||||||
app.include_router(profile.router)
|
app.include_router(profile.router)
|
||||||
|
|||||||
@@ -13,14 +13,10 @@ import argparse
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
import ZODB.FileStorage
|
|
||||||
import ZODB.DB
|
|
||||||
import logging
|
|
||||||
from packetserver.http.server import app
|
from packetserver.http.server import app
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Run the PacketServer HTTP API server")
|
parser = argparse.ArgumentParser(description="Run the PacketServer HTTP API server")
|
||||||
parser.add_argument("--db", required=True, help="DB path (local /path/to/Data.fs) or ZEO (host:port)")
|
|
||||||
parser.add_argument("--host", default="0.0.0.0", help="Bind host (default: 0.0.0.0)")
|
parser.add_argument("--host", default="0.0.0.0", help="Bind host (default: 0.0.0.0)")
|
||||||
parser.add_argument("--port", type=int, default=8080, help="Port to listen on (default: 8080)")
|
parser.add_argument("--port", type=int, default=8080, help="Port to listen on (default: 8080)")
|
||||||
parser.add_argument("--reload", action="store_true", help="Enable auto-reload during development")
|
parser.add_argument("--reload", action="store_true", help="Enable auto-reload during development")
|
||||||
|
|||||||
Reference in New Issue
Block a user