mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
from urllib.parse import quote
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from starlette.responses import Response
|
|
|
|
from app.core.database import get_db
|
|
from app.core.responses import JavaJSONResponse, ok
|
|
from app.core.security import require_normal
|
|
from app.repositories.correctword import CorrectWordRepository
|
|
from app.schemas.correctword import CorrectWordFileBody
|
|
from app.services.correctword import CorrectWordService
|
|
|
|
correctword_router = APIRouter()
|
|
|
|
|
|
def _java_urlencode(value: str) -> str:
|
|
# java.net.URLEncoder leaves alphanumerics plus .-*_ unescaped, encodes
|
|
# spaces as '+', and encodes '~'. The controller then replaces '+' with
|
|
# '%20'. urllib always leaves '~', so handle that final difference here.
|
|
return quote(value, safe="*.-_").replace("~", "%7E")
|
|
|
|
|
|
def _service(session: AsyncSession) -> CorrectWordService:
|
|
return CorrectWordService(CorrectWordRepository(session))
|
|
|
|
|
|
@correctword_router.post("/correct-word/file")
|
|
async def create_file(
|
|
body: CorrectWordFileBody, request: Request, session: AsyncSession = Depends(get_db)
|
|
) -> JavaJSONResponse:
|
|
return ok(await _service(session).create(body, require_normal(request)))
|
|
|
|
|
|
@correctword_router.put("/correct-word/file/{file_id}")
|
|
async def update_file(
|
|
file_id: str,
|
|
body: CorrectWordFileBody,
|
|
request: Request,
|
|
session: AsyncSession = Depends(get_db),
|
|
) -> JavaJSONResponse:
|
|
await _service(session).update(file_id, body, require_normal(request))
|
|
return ok()
|
|
|
|
|
|
@correctword_router.get("/correct-word/file/list")
|
|
async def list_files(
|
|
request: Request,
|
|
page: str | None = None,
|
|
limit: str | None = None,
|
|
session: AsyncSession = Depends(get_db),
|
|
) -> JavaJSONResponse:
|
|
return ok(await _service(session).page(require_normal(request), page, limit))
|
|
|
|
|
|
@correctword_router.get("/correct-word/file/select")
|
|
async def select_files(request: Request, session: AsyncSession = Depends(get_db)) -> JavaJSONResponse:
|
|
return ok(await _service(session).all(require_normal(request)))
|
|
|
|
|
|
@correctword_router.get("/correct-word/file/download/{file_id}")
|
|
async def download_file(
|
|
file_id: str, request: Request, session: AsyncSession = Depends(get_db)
|
|
) -> Response:
|
|
require_normal(request)
|
|
item = await _service(session).get(file_id)
|
|
if item is None or not item["content"]:
|
|
return Response(status_code=404)
|
|
body = "\n".join(item["content"]).encode("utf-8")
|
|
file_name = str(item["fileName"])
|
|
ascii_name = "".join(character if ord(character) < 128 else "_" for character in file_name)
|
|
disposition = f"attachment; filename=\"{ascii_name}\"; filename*=UTF-8''{_java_urlencode(file_name)}"
|
|
return Response(
|
|
body,
|
|
media_type="application/octet-stream",
|
|
headers={"Content-Disposition": disposition, "Content-Length": str(len(body))},
|
|
)
|
|
|
|
|
|
@correctword_router.delete("/correct-word/file/{file_id}")
|
|
async def delete_file(
|
|
file_id: str, request: Request, session: AsyncSession = Depends(get_db)
|
|
) -> JavaJSONResponse:
|
|
require_normal(request)
|
|
await _service(session).delete([file_id])
|
|
return ok()
|
|
|
|
|
|
@correctword_router.post("/correct-word/file/batch-delete")
|
|
async def batch_delete_files(
|
|
file_ids: list[str], request: Request, session: AsyncSession = Depends(get_db)
|
|
) -> JavaJSONResponse:
|
|
require_normal(request)
|
|
await _service(session).delete(file_ids)
|
|
return ok()
|