File size: 4,205 Bytes
f8b03c1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | """ๆไนฆ่ฝฌๆข API ๅฑใ"""
from __future__ import annotations
import logging
import urllib.parse
from typing import Any
from django.conf import settings
from django.http import HttpRequest, HttpResponse
from ninja import File, Form, Router, Schema
from ninja.files import UploadedFile
from apps.doc_convert.constants import MbidDefinition
from apps.doc_convert.exceptions import ZnszjDisabledError, ZnszjNotConfiguredError
from apps.doc_convert.services.doc_convert_service import DocConvertService
from apps.doc_convert.services.znszj_loader import get_znszj_client
logger = logging.getLogger(__name__)
router = Router()
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Schema
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
class MbidItem(Schema):
"""ๅไธชๆไนฆ็ฑปๅใ"""
mbid: str
name: str
class MbidCategoryOut(Schema):
"""ๆไนฆ็ฑปๅๅ็ฑปใ"""
category: str
items: list[MbidItem]
class MbidListResponse(Schema):
"""ๆไนฆ็ฑปๅๅ่กจๅๅบใ"""
categories: list[MbidCategoryOut]
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ๅทฅๅๅฝๆฐ
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
def _check_znszj_enabled() -> None:
"""ๆฃๆฅ ZNSZJ_ENABLED ้
็ฝฎ๏ผๆชๅฏ็จๆถๆๅบ 403ใ"""
if not getattr(settings, "ZNSZJ_ENABLED", False):
raise ZnszjDisabledError()
def _get_doc_convert_service() -> DocConvertService:
"""่ทๅ DocConvertService ๅฎไพใ"""
client = get_znszj_client()
if client is None:
raise ZnszjNotConfiguredError()
return DocConvertService(znszj_client=client)
def _build_mbid_list_response(grouped: dict[str, list[MbidDefinition]]) -> MbidListResponse:
"""ๅฐๅ็ปๆฐๆฎ่ฝฌๆขไธบๅๅบ Schemaใ"""
categories = [
MbidCategoryOut(
category=cat,
items=[MbidItem(mbid=item["mbid"], name=item["name"]) for item in items],
)
for cat, items in grouped.items()
]
return MbidListResponse(categories=categories)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ็ซฏ็น
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
@router.get("/mbid-list", response=MbidListResponse, summary="่ทๅๆฏๆ็ๆไนฆ็ฑปๅๅ่กจ")
def get_mbid_list(request: HttpRequest) -> Any:
"""
่ฟๅๆๆๆฏๆ็ๆไนฆ็ฑปๅ๏ผmbid๏ผ๏ผๆ็ฑปๅซๅ็ปใ
ไธไพ่ต็งๆๆจกๅ๏ผๅง็ปๅฏ็จ๏ผไธๅ ZNSZJ_ENABLED ๅผๅ
ณๆงๅถ๏ผใ
"""
from apps.doc_convert.constants import get_mbid_by_category
grouped = get_mbid_by_category()
return _build_mbid_list_response(grouped)
@router.post("/convert", summary="ไผ ็ปๆไนฆ่ฝฌ่ฆ็ด ๅผๆไนฆ")
def convert_document(
request: HttpRequest,
file: UploadedFile = File(...),
mbid: str = Form(...),
) -> HttpResponse:
"""
ไธไผ ไผ ็ปๆไนฆ๏ผ่ฝฌๆขไธบ่ฆ็ด ๅผๆไนฆๅนถ่ฟๅไธ่ฝฝใ
- file: .docx/.doc/.pdf ๆไปถ๏ผๆๅคง 20MB
- mbid: ๆไนฆ็ฑปๅๆ ่ฏ็ฌฆ๏ผๅ่ง /mbid-list๏ผ
้่ฆ ZNSZJ_ENABLED=Trueใ
"""
_check_znszj_enabled()
service = _get_doc_convert_service()
file_content = file.read()
filename = file.name or "document.docx"
result_bytes = service.convert_document(
file_content=file_content,
filename=filename,
mbid=mbid,
)
# ๆ้ ไธ่ฝฝๆไปถๅ
encoded_name = urllib.parse.quote("่ฆ็ด ๅผๆไนฆ.docx", safe="")
response = HttpResponse(
content=result_bytes,
content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
response["Content-Disposition"] = f"attachment; filename*=UTF-8''{encoded_name}"
return response
|