92 lines
3.4 KiB
Python
92 lines
3.4 KiB
Python
import os
|
|
from django.conf import settings
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.http import FileResponse, JsonResponse, Http404
|
|
from django.shortcuts import render, get_object_or_404
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
from documents.models import ManagedDocument
|
|
from documents.permissions import user_has_document_permission
|
|
|
|
|
|
def _get_document_by_code(doc_code):
|
|
"""Utility to fetch ManagedDocument by UUID string/object or integer PK."""
|
|
try:
|
|
return ManagedDocument.objects.get(uuid=doc_code)
|
|
except (ManagedDocument.DoesNotExist, ValueError):
|
|
# Fallback to PK lookup if integer passed
|
|
if str(doc_code).isdigit():
|
|
return get_object_or_404(ManagedDocument, pk=int(doc_code))
|
|
raise Http404("Document non trouvé")
|
|
|
|
|
|
@login_required
|
|
def ifc_viewer_view(request, doc_code):
|
|
"""Renders the full-screen 3D IFC Viewer page for a given document code."""
|
|
document = _get_document_by_code(doc_code)
|
|
|
|
if not user_has_document_permission(request.user, document, required_permission=ManagedDocument.PERMISSION_VIEW):
|
|
raise PermissionDenied("Vous n'avez pas la permission de visualiser ce document.")
|
|
|
|
version = document.latest_version
|
|
if not version or not version.file:
|
|
raise Http404("Aucun fichier disponible pour ce document.")
|
|
|
|
filename = version.filename
|
|
ext = os.path.splitext(filename)[1].lower()
|
|
|
|
context = {
|
|
"document": document,
|
|
"version": version,
|
|
"filename": filename,
|
|
"ext": ext,
|
|
"doc_code": document.uuid,
|
|
}
|
|
return render(request, "bim/viewer.html", context)
|
|
|
|
|
|
@login_required
|
|
def ifc_file_download_view(request, doc_code):
|
|
"""Streams the IFC file for consumption by the WebGL 3D viewer."""
|
|
document = _get_document_by_code(doc_code)
|
|
|
|
if not user_has_document_permission(request.user, document, required_permission=ManagedDocument.PERMISSION_VIEW):
|
|
raise PermissionDenied("Accès refusé.")
|
|
|
|
version = document.latest_version
|
|
if not version or not version.file:
|
|
raise Http404("Fichier non trouvé.")
|
|
|
|
response = FileResponse(
|
|
version.file.open("rb"),
|
|
content_type="application/octet-stream",
|
|
filename=version.filename
|
|
)
|
|
# Enable CORS headers if viewer runs under different subdomains / frames
|
|
response["Access-Control-Allow-Origin"] = "*"
|
|
response["Accept-Ranges"] = "bytes"
|
|
return response
|
|
|
|
|
|
@login_required
|
|
def ifc_document_info_api(request, doc_code):
|
|
"""API endpoint providing document metadata for the BIM viewer UI."""
|
|
document = _get_document_by_code(doc_code)
|
|
|
|
if not user_has_document_permission(request.user, document, required_permission=ManagedDocument.PERMISSION_VIEW):
|
|
return JsonResponse({"error": "Accès refusé"}, status=403)
|
|
|
|
version = document.latest_version
|
|
file_size = version.file.size if version and version.file else 0
|
|
|
|
return JsonResponse({
|
|
"uuid": str(document.uuid),
|
|
"id": document.id,
|
|
"title": document.title,
|
|
"description": document.description or "",
|
|
"filename": version.filename if version else "",
|
|
"version_number": version.version_number if version else 1,
|
|
"file_size": file_size,
|
|
"created_at": document.created_at.isoformat() if document.created_at else None,
|
|
"updated_at": document.updated_at.isoformat() if document.updated_at else None,
|
|
})
|