latest
This commit is contained in:
@@ -84,11 +84,69 @@ async def profile(current_user: HttpUser = Depends(get_current_http_user)):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Example future endpoint – list recent messages (placeholder)
|
|
||||||
@app.get("/api/v1/messages")
|
@app.get("/api/v1/messages")
|
||||||
async def list_messages(
|
async def get_messages(
|
||||||
limit: int = 20,
|
current_user: HttpUser = Depends(get_current_http_user),
|
||||||
current_user: HttpUser = Depends(get_current_http_user)
|
type: str = Query("received", description="received, sent, or all"),
|
||||||
|
limit: Optional[int] = Query(20, le=100, description="Max messages to return (default 20, max 100)"),
|
||||||
|
since: Optional[str] = Query(None, description="ISO UTC timestamp (e.g. 2025-12-01T00:00:00Z) to filter newer messages")
|
||||||
):
|
):
|
||||||
# TODO: implement actual message fetching from ZODB
|
"""
|
||||||
return {"messages": [], "note": "Not implemented yet"}
|
List messages for the authenticated user.
|
||||||
|
- received: incoming (default)
|
||||||
|
- sent: outgoing (stored in sender's mailbox)
|
||||||
|
- all: both incoming and outgoing
|
||||||
|
"""
|
||||||
|
if limit is None or limit < 1:
|
||||||
|
limit = 20
|
||||||
|
|
||||||
|
username = current_user.username # already uppercase
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
root = conn.root()
|
||||||
|
|
||||||
|
# Ensure mailbox exists (safe, matches server logic)
|
||||||
|
if 'messages' not in root:
|
||||||
|
root['messages'] = PersistentMapping()
|
||||||
|
if username not in root['messages']:
|
||||||
|
root['messages'][username] = persistent.list.PersistentList()
|
||||||
|
|
||||||
|
mailbox = root['messages'][username]
|
||||||
|
|
||||||
|
# Parse 'since' if provided
|
||||||
|
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 – use ISO UTC (e.g. 2025-12-01T00:00:00Z)")
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
for msg in mailbox:
|
||||||
|
# Filter by type
|
||||||
|
if type == "received" and msg.msg_from == username:
|
||||||
|
continue # skip own sent messages
|
||||||
|
if type == "sent" and msg.msg_from != username:
|
||||||
|
continue # skip received
|
||||||
|
# 'all' includes everything
|
||||||
|
|
||||||
|
# Filter by since
|
||||||
|
if since_dt and msg.sent_at < since_dt:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Basic dict (no attachments data yet)
|
||||||
|
messages.append({
|
||||||
|
"id": str(msg.msg_id),
|
||||||
|
"from": msg.msg_from,
|
||||||
|
"to": list(msg.msg_to) if isinstance(msg.msg_to, tuple) else [msg.msg_to],
|
||||||
|
"sent_at": msg.sent_at.isoformat() + "Z",
|
||||||
|
"text": msg.text,
|
||||||
|
"has_attachments": len(msg.attachments) > 0,
|
||||||
|
"retrieved": msg.retrieved # expose if marked read on RF
|
||||||
|
})
|
||||||
|
|
||||||
|
# Sort newest first
|
||||||
|
messages.sort(key=lambda m: m["sent_at"], reverse=True)
|
||||||
|
|
||||||
|
# Apply limit
|
||||||
|
return {"messages": messages[:limit], "total_returned": len(messages[:limit])}
|
||||||
@@ -34,8 +34,8 @@ def open_database(db_arg: str) -> ZODB.DB.DB:
|
|||||||
port = int(port_str)
|
port = int(port_str)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError(f"Invalid port in ZEO address: {db_arg}")
|
raise ValueError(f"Invalid port in ZEO address: {db_arg}")
|
||||||
storage = ZEO.client_storage(host, port)
|
storage = ZEO.DB((host, port))
|
||||||
return ZODB.DB(storage)
|
return storage
|
||||||
else:
|
else:
|
||||||
# Local FileStorage path
|
# Local FileStorage path
|
||||||
storage = ZODB.FileStorage.FileStorage(db_arg)
|
storage = ZODB.FileStorage.FileStorage(db_arg)
|
||||||
|
|||||||
Reference in New Issue
Block a user