Spaces:
Running
Running
| import os | |
| from django.utils import timezone | |
| from django.conf import settings | |
| from rest_framework import viewsets, status | |
| from rest_framework.decorators import action | |
| from rest_framework.response import Response | |
| from rest_framework.permissions import AllowAny | |
| from .models import Simulation | |
| from .serializers import SimulationSerializer | |
| from .fenics_runner import run_simulation | |
| from rest_framework.views import APIView | |
| from DangVan.dangvan import compute_dang_van | |
| import threading | |
| class SimulationViewSet(viewsets.ModelViewSet): | |
| permission_classes = [AllowAny] | |
| queryset = Simulation.objects.all().order_by('-created_at') | |
| serializer_class = SimulationSerializer | |
| def create(self, request, *args, **kwargs): | |
| name = request.data.get('name', '') | |
| parameters = request.data.get('parameters', {}) | |
| simulation = Simulation.objects.create( | |
| name=name, | |
| parameters=parameters, | |
| status='running' | |
| ) | |
| thread = threading.Thread( | |
| target=self._run_simulation_async, | |
| args=(simulation.id, parameters) | |
| ) | |
| thread.start() | |
| serializer = self.get_serializer(simulation) | |
| return Response(serializer.data, status=status.HTTP_201_CREATED) | |
| def _run_simulation_async(self, simulation_id, parameters): | |
| simulation = Simulation.objects.get(id=simulation_id) | |
| try: | |
| result = run_simulation(parameters) | |
| results_dir = os.path.join(settings.BASE_DIR, 'simulation_results') | |
| os.makedirs(results_dir, exist_ok=True) | |
| import shutil | |
| final_result_path = os.path.join( | |
| results_dir, | |
| f'result_{simulation_id}.txt' | |
| ) | |
| shutil.copy(result['results_file'], final_result_path) | |
| final_image_path = os.path.join( | |
| results_dir, | |
| f'result_{simulation_id}.png' | |
| ) | |
| shutil.copy(result['image_file'], final_image_path) | |
| # Copy generated frames if present | |
| frames_meta = None | |
| frames_src = result.get('frames') or [] | |
| if frames_src: | |
| frames_target_dir = os.path.join(results_dir, f'frames_{simulation_id}') | |
| os.makedirs(frames_target_dir, exist_ok=True) | |
| copied = [] | |
| for fp in frames_src: | |
| try: | |
| basename = os.path.basename(fp) | |
| dest = os.path.join(frames_target_dir, basename) | |
| shutil.copy(fp, dest) | |
| copied.append(f'simulation_results/frames_{simulation_id}/{basename}') | |
| except Exception: | |
| continue | |
| if copied: | |
| frames_meta = { | |
| 'dir': f'simulation_results/frames_{simulation_id}', | |
| 'files': copied, | |
| 'count': len(copied), | |
| } | |
| simulation.result_summary = { | |
| 'final_max': result['final_max'], | |
| 'final_mean': result['final_mean'], | |
| 'time_series': result['time_series'], | |
| 'frames': frames_meta | |
| } | |
| simulation.result_file_path = f'simulation_results/result_{simulation_id}.txt' | |
| simulation.result_image_path = f'simulation_results/result_{simulation_id}.png' | |
| simulation.status = 'completed' | |
| simulation.completed_at = timezone.now() | |
| simulation.save() | |
| except Exception as e: | |
| simulation.status = 'failed' | |
| simulation.error_message = str(e) | |
| simulation.save() | |
| def result_image(self, request, pk=None): | |
| simulation = self.get_object() | |
| if simulation.result_image_path: | |
| image_path = os.path.join(settings.BASE_DIR, simulation.result_image_path) | |
| from django.http import FileResponse | |
| return FileResponse(open(image_path, 'rb'), content_type='image/png') | |
| return Response({'error': 'Aucune image disponible'}, status=404) | |
| def frame(self, request, pk=None, index=None): | |
| simulation = self.get_object() | |
| frames = (simulation.result_summary or {}).get('frames') or {} | |
| files = frames.get('files') or [] | |
| try: | |
| idx = int(index) | |
| except Exception: | |
| return Response({'error': 'Index invalide'}, status=400) | |
| if 0 <= idx < len(files): | |
| frame_rel = files[idx] | |
| frame_abs = os.path.join(settings.BASE_DIR, frame_rel) | |
| from django.http import FileResponse | |
| return FileResponse(open(frame_abs, 'rb'), content_type='image/png') | |
| return Response({'error': 'Frame non disponible'}, status=404) | |
| class DangVanView(APIView): | |
| permission_classes = [AllowAny] | |
| def post(self, request): | |
| data = request.data or {} | |
| stress_series = data.get('stress_series') | |
| a = data.get('a') | |
| b = data.get('b') | |
| if stress_series is None or a is None or b is None: | |
| return Response({'error': 'Paramètres requis: stress_series, a, b'}, status=status.HTTP_400_BAD_REQUEST) | |
| try: | |
| result = compute_dang_van(stress_series, a, b) | |
| return Response(result, status=status.HTTP_200_OK) | |
| except Exception as e: | |
| return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) | |