Binary uploader works too.

This commit is contained in:
Michael Woods
2025-12-25 23:35:07 -05:00
parent 88d00f97a5
commit 1ab752d170

View File

@@ -6,13 +6,16 @@ from uuid import UUID
import mimetypes import mimetypes
import logging import logging
from traceback import format_exc from traceback import format_exc
import base64
from pydantic import BaseModel
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 from packetserver.http.database import DbDependency
from packetserver.server.objects import Object from packetserver.server.objects import Object
from packetserver.server.users import User from packetserver.server.users import User
from pydantic import BaseModel
router = APIRouter(prefix="/api/v1", tags=["objects"]) router = APIRouter(prefix="/api/v1", tags=["objects"])
@@ -186,3 +189,68 @@ async def create_text_object(
created_at=new_object.created_at, created_at=new_object.created_at,
modified_at=new_object.modified_at modified_at=new_object.modified_at
) )
class BinaryObjectCreate(BaseModel):
data_base64: str
name: Optional[str] = None
private: bool = True
@router.post("/objects/binary", response_model=ObjectSummary)
async def create_binary_object(
payload: BinaryObjectCreate,
db: DbDependency,
current_user: HttpUser = Depends(get_current_http_user)
):
username = current_user.username
# Decode base64
try:
content = base64.b64decode(payload.data_base64, validate=True)
except Exception as e:
raise HTTPException(status_code=400, detail="Invalid base64 encoding")
if not content:
raise HTTPException(status_code=400, detail="Binary content cannot be empty")
obj_name = (payload.name or "binary_object.bin").strip()
if len(obj_name) > 300:
raise HTTPException(status_code=400, detail="Object name too long (max 300 chars)")
if not obj_name:
raise HTTPException(status_code=400, detail="Invalid object name")
try:
with db.transaction() as conn:
root = conn.root()
user = User.get_user_by_username(username, root)
if not user:
raise HTTPException(status_code=404, detail="User not found")
# Pass bytes → forces binary=True
new_object = Object(name=obj_name, data=content)
new_object.private = payload.private
obj_uuid = new_object.write_new(db, username=username)
logging.info(f"User {username} created binary object {obj_uuid} ({obj_name}, {len(content)} bytes via base64)")
except HTTPException:
raise
except Exception as e:
logging.error(f"Binary object creation failed for {username}: {e}\n{format_exc()}")
raise HTTPException(status_code=500, detail="Failed to create binary object")
# Build summary
content_type, _ = mimetypes.guess_type(new_object.name)
if content_type is None:
content_type = "application/octet-stream" # always safe for binary
return ObjectSummary(
uuid=obj_uuid,
name=new_object.name,
binary=new_object.binary, # should be True
size=new_object.size,
content_type=content_type,
private=new_object.private,
created_at=new_object.created_at,
modified_at=new_object.modified_at
)