refactor: modularize Panoramax dependencies, improve environment variable management, and update Docker container configuration

This commit is contained in:
kdeterme 2026-07-26 09:16:04 +02:00
parent bec7153b7a
commit 034cf1e918
5 changed files with 22 additions and 12 deletions

View file

@ -55,7 +55,6 @@ RUN pip install --no-cache-dir -r requirements/base.txt && \
fi fi
# 1. Copie des répertoires volumineux et statiques (très bonne mise en cache) # 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/scripts/ /app/scripts/
COPY streetup/common/ /app/common/ COPY streetup/common/ /app/common/
COPY streetup/home/ /app/home/ COPY streetup/home/ /app/home/
@ -83,6 +82,7 @@ COPY streetup/observations/ /app/observations/
COPY streetup/controls/ /app/controls/ COPY streetup/controls/ /app/controls/
COPY streetup/interventions/ /app/interventions/ COPY streetup/interventions/ /app/interventions/
COPY streetup/assets/ /app/assets/ 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) # 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/ COPY streetup/road_detection/__init__.py /app/road_detection/

View file

@ -5,10 +5,12 @@ services:
restart: unless-stopped restart: unless-stopped
ports: ports:
- "5434:5432" # Mappé sur le port 5434 de l'hôte pour éviter tout conflit avec PostgreSQL local - "5434:5432" # Mappé sur le port 5434 de l'hôte pour éviter tout conflit avec PostgreSQL local
env_file:
- ./streetup/.env
environment: environment:
POSTGRES_DB: streetup POSTGRES_DB: ${DB_NAME:-streetup}
POSTGRES_USER: admin POSTGRES_USER: ${DB_USER:-admin}
POSTGRES_PASSWORD: replace_by_your_pwd POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes: volumes:
- streetup_db_data:/var/lib/postgresql - streetup_db_data:/var/lib/postgresql
- ./streetup/scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro - ./streetup/scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro

View file

@ -1,6 +1,5 @@
import os import os
import math import math
import cv2
import requests import requests
import dateutil.parser import dateutil.parser
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
@ -311,6 +310,11 @@ def extract_frames_from_video(video_path, gps_points, output_dir, camera_offset=
if not gps_points: if not gps_points:
raise ValueError("GPS track points are required for video positioning.") 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) cap = cv2.VideoCapture(video_path)
if not cap.isOpened(): if not cap.isOpened():
raise ValueError(f"Could not open video file: {video_path}") raise ValueError(f"Could not open video file: {video_path}")

View file

@ -502,7 +502,6 @@ def process_upload_task(upload_id):
from django.core.signing import BadSignature, SignatureExpired from django.core.signing import BadSignature, SignatureExpired
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404 from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
import boto3
@login_required @login_required
def serve_panoramax_picture(request, picture_id, path): def serve_panoramax_picture(request, picture_id, path):
@ -526,13 +525,18 @@ def serve_panoramax_picture(request, picture_id, path):
except (BadSignature, SignatureExpired): except (BadSignature, SignatureExpired):
return HttpResponseForbidden("Expired or invalid authorization token") return HttpResponseForbidden("Expired or invalid authorization token")
aws_key = getattr(settings, 'PANORAMAX_AWS_ACCESS_KEY_ID', 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_SECRET_ACCESS_KEY', 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) bucket = getattr(settings, 'PANORAMAX_AWS_S3_BUCKET', None)
prefix = getattr(settings, 'PANORAMAX_AWS_S3_PREFIX', 'photos').strip('/') 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) # 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() uuid_str = str(picture_id).replace("-", "").lower()
prefix1 = uuid_str[0:2] prefix1 = uuid_str[0:2]
prefix2 = uuid_str[2:4] 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) 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 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'] s3_redirect_url = r.headers['Location']
# Parse the direct S3 URL to extract bucket, endpoint, and key # Parse the direct S3 URL to extract bucket, endpoint, and key

View file

@ -25,7 +25,7 @@ from django.utils.translation import gettext_lazy as _
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent 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 # Quick-start development settings - unsuitable for production