Evita baseline completa del watchdog
This commit is contained in:
@@ -40,6 +40,7 @@ class WatchConfig:
|
||||
include_extensions: frozenset[str]
|
||||
exclude_dirs: tuple[Path | str, ...]
|
||||
exclude_patterns: tuple[str, ...]
|
||||
modified_event_max_age_seconds: int
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -187,6 +188,7 @@ def parse_config(data: dict[str, Any], path: Path) -> AppConfig:
|
||||
include_extensions=include_extensions,
|
||||
exclude_dirs=exclude_dirs,
|
||||
exclude_patterns=tuple(watch.get("exclude_patterns", [])),
|
||||
modified_event_max_age_seconds=int(watch.get("modified_event_max_age_seconds", 300)),
|
||||
),
|
||||
backup=BackupConfig(
|
||||
engine=str(backup.get("engine", "robocopy")).lower(),
|
||||
|
||||
@@ -61,8 +61,24 @@ class BakRestConfigApp(ctk.CTk):
|
||||
target_frame = ctk.CTkFrame(self.monitor_tab)
|
||||
target_frame.grid(row=0, column=0, columnspan=2, sticky="ew", padx=8, pady=(8, 0))
|
||||
target_frame.grid_columnconfigure(1, weight=1)
|
||||
target_frame.grid_columnconfigure(3, weight=1)
|
||||
self.target_user_var = tk.StringVar()
|
||||
self.modified_event_max_age_var = tk.StringVar()
|
||||
_label_entry(target_frame, "Utente percorsi", self.target_user_var, 0)
|
||||
ctk.CTkLabel(target_frame, text="Eta max modifica (sec)", anchor="w").grid(
|
||||
row=0,
|
||||
column=2,
|
||||
sticky="w",
|
||||
padx=12,
|
||||
pady=6,
|
||||
)
|
||||
ctk.CTkEntry(target_frame, textvariable=self.modified_event_max_age_var).grid(
|
||||
row=0,
|
||||
column=3,
|
||||
sticky="ew",
|
||||
padx=12,
|
||||
pady=6,
|
||||
)
|
||||
|
||||
left = ctk.CTkFrame(self.monitor_tab)
|
||||
left.grid(row=1, column=0, sticky="nsew", padx=(0, 8), pady=8)
|
||||
@@ -181,6 +197,7 @@ class BakRestConfigApp(ctk.CTk):
|
||||
server_check = backup.setdefault("server_check", {})
|
||||
|
||||
self.target_user_var.set(str(watch.get("target_user", "")))
|
||||
self.modified_event_max_age_var.set(str(watch.get("modified_event_max_age_seconds", 300)))
|
||||
self.include_dirs.set_items(watch.get("include_dirs", []))
|
||||
self.extensions.set_items(watch.get("include_extensions", []))
|
||||
self.exclude_dirs.set_items(watch.get("exclude_dirs", []))
|
||||
@@ -200,6 +217,10 @@ class BakRestConfigApp(ctk.CTk):
|
||||
|
||||
watch["include_dirs"] = self.include_dirs.items()
|
||||
watch["target_user"] = self.target_user_var.get().strip()
|
||||
watch["modified_event_max_age_seconds"] = _safe_int(
|
||||
self.modified_event_max_age_var.get(),
|
||||
300,
|
||||
)
|
||||
watch["include_extensions"] = self.extensions.items()
|
||||
watch["exclude_dirs"] = self.exclude_dirs.items()
|
||||
watch["exclude_patterns"] = self.exclude_patterns.items()
|
||||
|
||||
@@ -6,6 +6,7 @@ autostart = true
|
||||
|
||||
[watch]
|
||||
target_user = ""
|
||||
modified_event_max_age_seconds = 300
|
||||
include_dirs = [
|
||||
"%USERPROFILE%\\\\Desktop",
|
||||
"%USERPROFILE%\\\\Documents",
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from .config import AppConfig
|
||||
@@ -35,7 +36,6 @@ class WatchdogRuntime:
|
||||
watched = 0
|
||||
for include_dir in self.config.watch.include_dirs:
|
||||
if include_dir.exists():
|
||||
self._prime_snapshots(include_dir)
|
||||
observer.schedule(Handler(), str(include_dir), recursive=True)
|
||||
self.logger.info("Monitoring directory: %s", include_dir)
|
||||
watched += 1
|
||||
@@ -72,6 +72,13 @@ class WatchdogRuntime:
|
||||
return
|
||||
|
||||
size, mtime_ns = _safe_snapshot(target_path)
|
||||
if event_type == "modified" and not _mtime_is_recent(
|
||||
mtime_ns,
|
||||
self.config.watch.modified_event_max_age_seconds,
|
||||
):
|
||||
self.logger.info("Ignored stale modified event: %s", target_path)
|
||||
return
|
||||
|
||||
if event_type == "modified" and not self.registry.has_snapshot_changed(
|
||||
str(target_path),
|
||||
size,
|
||||
@@ -94,19 +101,6 @@ class WatchdogRuntime:
|
||||
while not self.stop_event.wait(60):
|
||||
pass
|
||||
|
||||
def _prime_snapshots(self, root: Path) -> None:
|
||||
self.logger.info("Priming file snapshots: %s", root)
|
||||
count = 0
|
||||
for path in root.rglob("*"):
|
||||
if self.stop_event.is_set():
|
||||
break
|
||||
if not self.filter.should_track(path, is_directory=path.is_dir()):
|
||||
continue
|
||||
size, mtime_ns = _safe_snapshot(path)
|
||||
self.registry.update_snapshot(str(path), size, mtime_ns)
|
||||
count += 1
|
||||
self.logger.info("Primed %s file snapshot(s): %s", count, root)
|
||||
|
||||
|
||||
def _safe_snapshot(path: Path) -> tuple[int | None, int | None]:
|
||||
try:
|
||||
@@ -114,3 +108,10 @@ def _safe_snapshot(path: Path) -> tuple[int | None, int | None]:
|
||||
return stat.st_size, stat.st_mtime_ns
|
||||
except OSError:
|
||||
return None, None
|
||||
|
||||
|
||||
def _mtime_is_recent(mtime_ns: int | None, max_age_seconds: int) -> bool:
|
||||
if mtime_ns is None:
|
||||
return False
|
||||
age_seconds = time.time() - (mtime_ns / 1_000_000_000)
|
||||
return age_seconds <= max_age_seconds
|
||||
|
||||
Reference in New Issue
Block a user