diff --git a/src/services/upload_server.py b/src/services/upload_server.py index 5152a92..00ecb48 100644 --- a/src/services/upload_server.py +++ b/src/services/upload_server.py @@ -3,8 +3,9 @@ import os import threading import time +import queue from flask import Flask, request, jsonify, render_template_string -from PyQt6.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal, QTimer UPLOAD_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "data", "photos") ALLOWED_EXTENSIONS = {"jpg", "jpeg", "png", "bmp", "tiff", "tif", "webp", "heic"} @@ -280,10 +281,16 @@ class UploadServer: self.port = port self.signals = UploadSignals() self._callback = None + self._queue = queue.Queue() self.app = Flask(__name__) self._setup_routes() self._thread = None + # Timer Qt qui poll la queue depuis le thread principal + self._poll_timer = QTimer() + self._poll_timer.timeout.connect(self._poll_queue) + self._poll_timer.start(500) + os.makedirs(UPLOAD_DIR, exist_ok=True) def _setup_routes(self): @@ -309,11 +316,7 @@ class UploadServer: saved.append(path) if saved: - # QTimer.singleShot est thread-safe et exécute dans le thread principal - from PyQt6.QtCore import QTimer - from functools import partial - if self._callback: - QTimer.singleShot(0, partial(self._callback, saved)) + self._queue.put(saved) return jsonify({"ok": True, "count": len(saved)}) @@ -321,6 +324,16 @@ class UploadServer: """Définit le callback appelé quand des photos sont uploadées.""" self._callback = callback + def _poll_queue(self): + """Appelé par QTimer dans le thread principal Qt.""" + while not self._queue.empty(): + try: + photos = self._queue.get_nowait() + if self._callback: + self._callback(photos) + except queue.Empty: + break + def start(self): """Démarre le serveur dans un thread daemon.""" self._thread = threading.Thread(