File size: 2,652 Bytes
9b53f70
 
 
 
 
91f1a3a
9b53f70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3370310
 
 
 
 
 
9b53f70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91f1a3a
9b53f70
 
 
 
 
 
 
00d2c12
 
 
 
 
 
9b53f70
e014541
 
 
 
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
"""Endpoint dùng chung: trạng thái job, tải file kết quả."""

from __future__ import annotations

import os
from urllib.parse import quote

from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse

from ..core.files import session_dir, delete_session
from ..core.jobs import jobs

router = APIRouter(prefix="/api", tags=["common"])


@router.delete("/sessions/{sid}")
def drop_session(sid: str):
    """Xoá phiên tạm sau khi user đã tải kết quả về máy (không bắt buộc)."""
    return {"deleted": delete_session(sid), "session": sid}


@router.get("/jobs/{job_id}")
def job_status(job_id: str):
    job = jobs.get(job_id)
    if not job:
        raise HTTPException(404, "job không tồn tại")
    return job.to_dict()


@router.get("/queue/stats")
def queue_stats():
    """Số liệu hàng đợi: số job đang chạy/chờ theo loại + tổng job trong bộ nhớ."""
    return jobs.stats()


@router.post("/jobs/{job_id}/cancel")
def job_cancel(job_id: str):
    jobs.cancel(job_id)
    return {"ok": True}


@router.get("/sessions/{sid}/inputs")
def list_inputs(sid: str):
    """Liệt kê video trong thư mục inputs của phiên (dùng khi đẩy từ Down list)."""
    d = os.path.join(session_dir(sid), "inputs")
    if not os.path.isdir(d):
        return {"session": sid, "files": []}
    out = []
    for name in sorted(os.listdir(d)):
        full = os.path.join(d, name)
        if os.path.isfile(full):
            out.append({
                "file": f"inputs/{name}",
                "name": name,
                "size": os.path.getsize(full),
                "url": f"/api/files/{sid}/inputs/{quote(name)}",
            })
    return {"session": sid, "files": out}


@router.get("/files/{sid}/{path:path}")
def get_file(sid: str, path: str):
    base = os.path.abspath(session_dir(sid))
    # Chấp cả "/" lẫn "\" trong path (Windows) -> chuẩn hoá trước khi nối.
    rel = path.replace("\\", "/").strip("/")
    full = os.path.abspath(os.path.join(base, *rel.split("/")))
    # Phải nằm trong phiên VÀ là FILE thật: trỏ vào THƯ MỤC thì FileResponse
    # ném lỗi 500, trong khi đúng nghĩa là 404.
    if not full.startswith(base) or not os.path.isfile(full):
        raise HTTPException(404, "file không tồn tại")
    # inline (KHÔNG attachment) -> trình duyệt render video/ảnh trực tiếp trong <video>.
    # Nút tải vẫn hoạt động nhờ thuộc tính `download` phía frontend.
    return FileResponse(full, filename=os.path.basename(full),
                        content_disposition_type="inline")