#!/usr/bin/env python3 """ File Watcher Monitors sheets_output/ directory and triggers CSV-to-JSON conversion on changes """ import time import json import subprocess from pathlib import Path from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler # Paths BASE_DIR = Path(__file__).parent.parent CONFIG_FILE = BASE_DIR / "config.json" CONVERTER_SCRIPT = BASE_DIR / "scripts" / "csv_to_json.py" class CSVChangeHandler(FileSystemEventHandler): """Handles CSV file changes""" def __init__(self, debounce_seconds=2): self.debounce_seconds = debounce_seconds self.last_modified = {} def on_modified(self, event): """Called when a file is modified""" if event.is_directory: return # Only process CSV files if not event.src_path.endswith('.csv'): return # Debounce: ignore rapid consecutive changes now = time.time() if event.src_path in self.last_modified: if now - self.last_modified[event.src_path] < self.debounce_seconds: return self.last_modified[event.src_path] = now print(f"\nšŸ“ Detected change: {Path(event.src_path).name}") self.trigger_conversion() def on_created(self, event): """Called when a file is created""" if not event.is_directory and event.src_path.endswith('.csv'): print(f"\nšŸ“„ New file: {Path(event.src_path).name}") self.trigger_conversion() def trigger_conversion(self): """Run the CSV-to-JSON converter""" print("šŸ”„ Running CSV-to-JSON conversion...") try: result = subprocess.run( ['python3', str(CONVERTER_SCRIPT)], capture_output=True, text=True, cwd=str(BASE_DIR) ) if result.returncode == 0: print(result.stdout) else: print(f"āŒ Conversion failed:") print(result.stderr) except Exception as e: print(f"āŒ Error running converter: {e}") def load_config(): """Load configuration""" if not CONFIG_FILE.exists(): return { 'file_watcher': { 'enabled': True, 'watch_directory': 'sheets_output', 'debounce_seconds': 2 } } with open(CONFIG_FILE, 'r') as f: return json.load(f) def main(): """Start file watcher""" config = load_config() watcher_config = config.get('file_watcher', {}) if not watcher_config.get('enabled', True): print("āš ļø File watcher is disabled in config.json") return watch_dir = BASE_DIR / watcher_config.get('watch_directory', 'sheets_output') debounce = watcher_config.get('debounce_seconds', 2) if not watch_dir.exists(): print(f"āŒ Watch directory not found: {watch_dir}") print(f"Creating directory: {watch_dir}") watch_dir.mkdir(parents=True, exist_ok=True) print("šŸ‘€ File Watcher Started") print(f"šŸ“‚ Watching: {watch_dir}") print(f"ā±ļø Debounce: {debounce} seconds") print("\nWaiting for CSV file changes... (Press Ctrl+C to stop)\n") event_handler = CSVChangeHandler(debounce_seconds=debounce) observer = Observer() observer.schedule(event_handler, str(watch_dir), recursive=False) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: print("\n\nšŸ‘‹ Stopping file watcher...") observer.stop() observer.join() print("āœ… File watcher stopped") if __name__ == "__main__": main()