From 8b6288aefe53d06065f1dbd7ff917368d0a2e16e Mon Sep 17 00:00:00 2001 From: Ettore Dreucci Date: Sun, 28 Sep 2025 19:38:37 +0200 Subject: [PATCH] Handle directory-modify events and search for modified file --- src/DebouncedHandler.py | 49 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/DebouncedHandler.py b/src/DebouncedHandler.py index 5fb8fc4..e15fcb4 100644 --- a/src/DebouncedHandler.py +++ b/src/DebouncedHandler.py @@ -2,6 +2,7 @@ import threading import logging from watchdog.events import PatternMatchingEventHandler +from pathlib import Path from config import * from helpers import export_single_zone @@ -29,11 +30,53 @@ def schedule_export(trigger_path): debounce_timer.start() logging.debug("Debounce timer started/reset (%.1fs)", DEBOUNCE_SECONDS) +def _most_recent_file_under(path: Path, max_depth: int = 2) -> Path | None: + if not path.exists(): + return None + best = None # (mtime, filepath) + base_depth = len(path.parts) + for root, dirs, files in os.walk(path): + depth = len(Path(root).parts) - base_depth + if depth > max_depth: + # prune deeper traversal + dirs[:] = [] + continue + for fn in files: + p = Path(root) / fn + try: + m = p.stat().st_mtime + except Exception: + continue + if best is None or m > best[0]: + best = (m, p) + return best[1] if best else None + class DebouncedHandler(PatternMatchingEventHandler): def __init__(self, patterns=None, ignore_patterns=None, ignore_directories=False, case_sensitive=True): super().__init__(patterns=patterns or ["*"], ignore_patterns=ignore_patterns or [], ignore_directories=ignore_directories, case_sensitive=case_sensitive) def on_any_event(self, event): - # When any matching event occurs, start/reset debounce timer - logging.debug(f"Filesystem event: {event.event_type} on {event.src_path}") - schedule_export(event.src_path) \ No newline at end of file + try: + src = getattr(event, "src_path", None) + dest = getattr(event, "dest_path", None) + trigger = None + + if dest: + trigger = dest + elif src: + p = Path(src) + if p.is_file(): + trigger = str(p) + else: + candidate = _most_recent_file_under(p) + if candidate: + trigger = str(candidate) + else: + trigger = str(src) + else: + trigger = WATCH_DIR + logging.debug(f"Filesystem event: {event.event_type} on {trigger}") + schedule_export(event.src_path) + except Exception as e: + logging.exception(f"Error handling filesystem event; scheduling export for watch dir as fallback: {e}") + schedule_export(WATCH_DIR) \ No newline at end of file