50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
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}) |