From 034cf1e91846ac3aa91dcf1daa12321507b0e642 Mon Sep 17 00:00:00 2001 From: kdeterme Date: Sun, 26 Jul 2026 09:16:04 +0200 Subject: [PATCH] refactor: modularize Panoramax dependencies, improve environment variable management, and update Docker container configuration --- Dockerfile | 2 +- docker-compose.yml | 8 +++++--- streetup/panoramax/utils.py | 8 ++++++-- streetup/panoramax/views.py | 14 +++++++++----- streetup/streetup/settings.py | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 417e79e..4cfdaba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -55,7 +55,6 @@ RUN pip install --no-cache-dir -r requirements/base.txt && \ fi # 1. Copie des répertoires volumineux et statiques (très bonne mise en cache) -COPY streetup/road_detection/detection_models/ /app/road_detection/detection_models/ COPY streetup/scripts/ /app/scripts/ COPY streetup/common/ /app/common/ COPY streetup/home/ /app/home/ @@ -83,6 +82,7 @@ COPY streetup/observations/ /app/observations/ COPY streetup/controls/ /app/controls/ COPY streetup/interventions/ /app/interventions/ COPY streetup/assets/ /app/assets/ +COPY streetup/panoramax/ /app/panoramax/ # 4. Copie des fichiers de code de road_detection (sans réimporter les modèles de détection) COPY streetup/road_detection/__init__.py /app/road_detection/ diff --git a/docker-compose.yml b/docker-compose.yml index c66f976..428be84 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,10 +5,12 @@ services: restart: unless-stopped ports: - "5434:5432" # Mappé sur le port 5434 de l'hôte pour éviter tout conflit avec PostgreSQL local + env_file: + - ./streetup/.env environment: - POSTGRES_DB: streetup - POSTGRES_USER: admin - POSTGRES_PASSWORD: replace_by_your_pwd + POSTGRES_DB: ${DB_NAME:-streetup} + POSTGRES_USER: ${DB_USER:-admin} + POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - streetup_db_data:/var/lib/postgresql - ./streetup/scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro diff --git a/streetup/panoramax/utils.py b/streetup/panoramax/utils.py index 17eb704..ee377ff 100644 --- a/streetup/panoramax/utils.py +++ b/streetup/panoramax/utils.py @@ -1,6 +1,5 @@ import os import math -import cv2 import requests import dateutil.parser from datetime import datetime, timedelta, timezone @@ -310,7 +309,12 @@ def extract_frames_from_video(video_path, gps_points, output_dir, camera_offset= """ if not gps_points: raise ValueError("GPS track points are required for video positioning.") - + + try: + import cv2 + except ImportError: + raise ImportError("OpenCV (cv2) is required for video frame extraction but is not installed.") + cap = cv2.VideoCapture(video_path) if not cap.isOpened(): raise ValueError(f"Could not open video file: {video_path}") diff --git a/streetup/panoramax/views.py b/streetup/panoramax/views.py index 03f9818..80e88d3 100644 --- a/streetup/panoramax/views.py +++ b/streetup/panoramax/views.py @@ -502,7 +502,6 @@ def process_upload_task(upload_id): from django.core.signing import BadSignature, SignatureExpired from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404 -import boto3 @login_required def serve_panoramax_picture(request, picture_id, path): @@ -526,13 +525,18 @@ def serve_panoramax_picture(request, picture_id, path): except (BadSignature, SignatureExpired): return HttpResponseForbidden("Expired or invalid authorization token") - aws_key = getattr(settings, 'PANORAMAX_AWS_ACCESS_KEY_ID', None) - aws_secret = getattr(settings, 'PANORAMAX_AWS_SECRET_ACCESS_KEY', None) + aws_key = getattr(settings, 'PANORAMAX_AWS_S3_ACCESS_KEY_ID', None) or getattr(settings, 'PANORAMAX_AWS_ACCESS_KEY_ID', None) + aws_secret = getattr(settings, 'PANORAMAX_AWS_S3_SECRET_ACCESS_KEY', None) or getattr(settings, 'PANORAMAX_AWS_SECRET_ACCESS_KEY', None) bucket = getattr(settings, 'PANORAMAX_AWS_S3_BUCKET', None) prefix = getattr(settings, 'PANORAMAX_AWS_S3_PREFIX', 'photos').strip('/') + try: + import boto3 + except ImportError: + boto3 = None + # Method 1: Direct construction if bucket name is set in settings (Option B direct) - if aws_key and aws_secret and bucket: + if boto3 and aws_key and aws_secret and bucket: uuid_str = str(picture_id).replace("-", "").lower() prefix1 = uuid_str[0:2] prefix2 = uuid_str[2:4] @@ -582,7 +586,7 @@ def serve_panoramax_picture(request, picture_id, path): r = requests.get(url, headers=headers, allow_redirects=False, timeout=5) # If Panoramax redirects to an external S3 storage and we have AWS credentials to sign it: - if r.status_code in [301, 302, 303, 307, 308] and 'Location' in r.headers and aws_key and aws_secret: + if r.status_code in [301, 302, 303, 307, 308] and 'Location' in r.headers and boto3 and aws_key and aws_secret: s3_redirect_url = r.headers['Location'] # Parse the direct S3 URL to extract bucket, endpoint, and key diff --git a/streetup/streetup/settings.py b/streetup/streetup/settings.py index 1b60eb9..108743b 100644 --- a/streetup/streetup/settings.py +++ b/streetup/streetup/settings.py @@ -25,7 +25,7 @@ from django.utils.translation import gettext_lazy as _ # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent -load_dotenv(BASE_DIR / ".env", override=True) +load_dotenv(BASE_DIR / ".env", override=False) # Quick-start development settings - unsuitable for production