from __future__ import annotations import logging import os from typing import Optional from watchdog.events import FileSystemEventHandler from flask_socketio import SocketIO # 외부에서 주입되는 socketio 인스턴스 (app.py에서 설정) socketio: Optional[SocketIO] = None class FileCreatedHandler(FileSystemEventHandler): """파일 생성 감지를 처리하는 Watchdog 핸들러. - temp_ip 등 임시 파일은 무시 - 감지 시 진행률/로그를 SocketIO로 실시간 브로드캐스트 """ def __init__(self, job_id: str, total_files: int): super().__init__() self.job_id = job_id self.total_files = max(int(total_files or 0), 0) self.completed_files = 0 def _broadcast(self, event_name: str, data: dict) -> None: if not socketio: return try: socketio.emit(event_name, data, namespace="/") except Exception as e: logging.warning("[Watchdog] SocketIO 전송 실패: %s", e) def _should_ignore(self, src_path: str) -> bool: # 임시 업로드 디렉터리 하위 파일은 무시 return "temp_ip" in src_path.replace("\\", "/") def on_created(self, event): if event.is_directory: return if self._should_ignore(event.src_path): return self.completed_files = min(self.completed_files + 1, self.total_files or 0) filename = os.path.basename(event.src_path) msg = f"[Watchdog] 생성된 파일: {filename} ({self.completed_files}/{self.total_files})" logging.info(msg) self._broadcast("log_update", {"job_id": self.job_id, "log": msg}) if self.total_files: progress = int((self.completed_files / self.total_files) * 100) self._broadcast("progress", {"job_id": self.job_id, "progress": progress})