Skip to content

Commit 79e9068

Browse files
author
jravenel
committed
feat: add viewers to files
1 parent 1d1072f commit 79e9068

File tree

2 files changed

+443
-18
lines changed
  • libs/naas-abi/naas_abi/apps/nexus/apps

2 files changed

+443
-18
lines changed

libs/naas-abi/naas_abi/apps/nexus/apps/api/app/api/endpoints/files.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
"""File management API endpoints backed by ABI ObjectStorageService."""
22

33
from datetime import datetime
4-
from pathlib import PurePosixPath
4+
from pathlib import Path, PurePosixPath
5+
import shutil
6+
import subprocess
7+
import tempfile
58

69
from fastapi import APIRouter, Depends, File, Form, HTTPException, Query, Request, Response, UploadFile
710
from naas_abi.apps.nexus.apps.api.app.api.endpoints.auth import get_current_user_required
@@ -244,6 +247,12 @@ async def list_files(request: Request, path: str = Query("", description="Direct
244247
".yaml": "text/yaml",
245248
".yml": "text/yaml",
246249
".pdf": "application/pdf",
250+
".png": "image/png",
251+
".jpg": "image/jpeg",
252+
".jpeg": "image/jpeg",
253+
".gif": "image/gif",
254+
".webp": "image/webp",
255+
".svg": "image/svg+xml",
247256
}
248257
content_type = content_types.get(ext, "application/octet-stream")
249258
except Exceptions.ObjectNotFound:
@@ -400,6 +409,65 @@ async def upload_file(
400409
# =============================================================================
401410

402411

412+
@router.get("/preview/pdf/{path:path}")
413+
async def preview_file_as_pdf(request: Request, path: str):
414+
"""Preview a presentation file as PDF (requires LibreOffice)."""
415+
storage = get_object_storage(request)
416+
normalized_path = normalize_relative_path(path)
417+
ext = PurePosixPath(normalized_path).suffix.lower()
418+
if ext not in {".ppt", ".pptx"}:
419+
raise HTTPException(status_code=400, detail="Only PPT/PPTX preview is supported")
420+
if _is_directory(storage, normalized_path):
421+
raise HTTPException(status_code=400, detail="Cannot preview a directory")
422+
423+
try:
424+
content_bytes = _read_bytes(storage, normalized_path)
425+
except Exceptions.ObjectNotFound as exc:
426+
raise HTTPException(status_code=404, detail="File not found") from exc
427+
428+
soffice = shutil.which("soffice") or shutil.which("libreoffice")
429+
if not soffice:
430+
raise HTTPException(
431+
status_code=501,
432+
detail="PPTX preview is unavailable: LibreOffice is not installed on the API service.",
433+
)
434+
435+
with tempfile.TemporaryDirectory(prefix="nexus-ppt-preview-") as tmp_dir:
436+
input_path = Path(tmp_dir) / PurePosixPath(normalized_path).name
437+
output_name = f"{PurePosixPath(normalized_path).stem}.pdf"
438+
output_path = Path(tmp_dir) / output_name
439+
input_path.write_bytes(content_bytes)
440+
441+
result = subprocess.run(
442+
[
443+
soffice,
444+
"--headless",
445+
"--convert-to",
446+
"pdf",
447+
"--outdir",
448+
str(Path(tmp_dir)),
449+
str(input_path),
450+
],
451+
capture_output=True,
452+
text=True,
453+
timeout=60,
454+
check=False,
455+
)
456+
if result.returncode != 0 or not output_path.exists():
457+
raise HTTPException(
458+
status_code=500,
459+
detail="Failed to convert presentation to PDF preview.",
460+
)
461+
462+
pdf_bytes = output_path.read_bytes()
463+
464+
return Response(
465+
content=pdf_bytes,
466+
media_type="application/pdf",
467+
headers={"Content-Disposition": f'inline; filename="{output_name}"'},
468+
)
469+
470+
403471
@router.get("/raw/{path:path}")
404472
async def read_file_raw(request: Request, path: str):
405473
"""Read raw file bytes (for binary previews/downloads)."""
@@ -425,6 +493,12 @@ async def read_file_raw(request: Request, path: str):
425493
".yaml": "text/yaml",
426494
".yml": "text/yaml",
427495
".pdf": "application/pdf",
496+
".png": "image/png",
497+
".jpg": "image/jpeg",
498+
".jpeg": "image/jpeg",
499+
".gif": "image/gif",
500+
".webp": "image/webp",
501+
".svg": "image/svg+xml",
428502
}
429503
content_type = content_types.get(ext, "application/octet-stream")
430504
filename = PurePosixPath(normalized_path).name

0 commit comments

Comments
 (0)