working
This commit is contained in:
parent
f7e794774d
commit
09d181eba8
37 changed files with 1898 additions and 5 deletions
|
|
@ -0,0 +1,99 @@
|
|||
"""
|
||||
WatchService - сервис отслеживания файлов с очередью
|
||||
"""
|
||||
import time
|
||||
import threading
|
||||
import queue
|
||||
from pathlib import Path
|
||||
from typing import Callable, Optional
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
from services.file_service import FileService
|
||||
|
||||
|
||||
class PhotoHandler(FileSystemEventHandler):
|
||||
"""Обработчик событий файловой системы"""
|
||||
|
||||
def __init__(self, callback: Callable[[Path], None]):
|
||||
self.callback = callback
|
||||
self._pending_files = queue.Queue()
|
||||
self._processing = True
|
||||
self._processor_thread = threading.Thread(target=self._process_queue, daemon=True)
|
||||
self._processor_thread.start()
|
||||
|
||||
def on_created(self, event):
|
||||
if not event.is_directory:
|
||||
src_path = Path(event.src_path)
|
||||
if FileService.is_photo(src_path):
|
||||
time.sleep(0.1) # Даём время на запись файла
|
||||
self._pending_files.put(src_path)
|
||||
|
||||
def _process_queue(self):
|
||||
while self._processing:
|
||||
try:
|
||||
file_path = self._pending_files.get(timeout=1)
|
||||
if self.callback and file_path.exists():
|
||||
self.callback(file_path)
|
||||
except queue.Empty:
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"Ошибка обработки файла: {e}")
|
||||
|
||||
def stop(self):
|
||||
self._processing = False
|
||||
|
||||
|
||||
class WatchService:
|
||||
"""Сервис для отслеживания папки на новые файлы"""
|
||||
|
||||
def __init__(self):
|
||||
self._observer: Optional[Observer] = None
|
||||
self._event_handler: Optional[PhotoHandler] = None
|
||||
self._is_running = False
|
||||
|
||||
def start(self, watch_folder: Path, on_new_file: Callable[[Path], None]) -> bool:
|
||||
if self._is_running:
|
||||
return False
|
||||
|
||||
if not watch_folder.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
self._event_handler = PhotoHandler(on_new_file)
|
||||
self._observer = Observer()
|
||||
self._observer.schedule(self._event_handler, str(watch_folder), recursive=False)
|
||||
self._observer.start()
|
||||
self._is_running = True
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Ошибка запуска отслеживания: {e}")
|
||||
return False
|
||||
|
||||
def stop(self):
|
||||
if self._observer:
|
||||
self._observer.stop()
|
||||
self._observer.join()
|
||||
self._observer = None
|
||||
|
||||
if self._event_handler:
|
||||
self._event_handler.stop()
|
||||
self._event_handler = None
|
||||
|
||||
self._is_running = False
|
||||
|
||||
def is_running(self) -> bool:
|
||||
return self._is_running
|
||||
|
||||
def move_all_existing_files(self, watch_folder: Path, on_file_moved: Callable[[Path], None]) -> int:
|
||||
"""Перемещает все существующие файлы"""
|
||||
count = 0
|
||||
if watch_folder.exists():
|
||||
for file_path in watch_folder.iterdir():
|
||||
if file_path.is_file() and FileService.is_photo(file_path):
|
||||
try:
|
||||
on_file_moved(file_path)
|
||||
count += 1
|
||||
time.sleep(0.05)
|
||||
except Exception as e:
|
||||
print(f"Ошибка перемещения {file_path.name}: {e}")
|
||||
return count
|
||||
Loading…
Add table
Add a link
Reference in a new issue