Skip to content

Instantly share code, notes, and snippets.

@bobbykjack
Created August 1, 2026 15:44
Show Gist options
  • Select an option

  • Save bobbykjack/4a096084670f65fc0129796c4e6a3920 to your computer and use it in GitHub Desktop.

Select an option

Save bobbykjack/4a096084670f65fc0129796c4e6a3920 to your computer and use it in GitHub Desktop.
import os
import time
import re
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
WATCH_FOLDER = Path("/tmp")
TARGET_FOLDER = Path("/Users/bobby/Pictures/switch-screenshots")
PATTERN = r"^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{8}-[A-F0-9]{32}\.jpg)$"
class FileDropHandler(FileSystemEventHandler):
"""Handles file system events for the monitored folder."""
def on_created(self, event):
# Ignore folder creations; we only care about files
if event.is_directory:
return
file_path = Path(event.src_path)
# Ignore files with a non-matching name
if not re.match(PATTERN, file_path.name):
return
# Prevent errors by letting the system finish copying large files
self._wait_for_file_copy(file_path)
# Trigger your processing workflow
self.process_file(file_path)
def _wait_for_file_copy(self, file_path, timeout=5):
"""Ensures the file is fully written to disk before processing."""
file_size = -1
start_time = time.time()
while time.time() - start_time < timeout:
try:
current_size = os.path.getsize(file_path)
if current_size == file_size and current_size > 0:
return # Size has stabilised, file copy is finished
file_size = current_size
except FileNotFoundError:
return
time.sleep(0.5)
def process_file(self, file_path):
try:
search = re.search(PATTERN, file_path.name)
if not search:
return
target = TARGET_FOLDER / search.group(1)
target = target / search.group(2)
target = target / search.group(3)
target.mkdir(parents=True, exist_ok=True)
file_path.move(target / search.group(4))
print(f"✅ Moved: {file_path}")
print(f" ➡️ To: {target / search.group(4)}\n")
except Exception as e:
print(f"❌ Error processing {file_path.name}: {e}")
if __name__ == "__main__":
event_handler = FileDropHandler()
observer = Observer()
observer.schedule(event_handler, path=str(WATCH_FOLDER), recursive=True)
print(f"\n👀 Watching for dropped files in: {WATCH_FOLDER.resolve()}\n")
observer.start()
try:
while True:
time.sleep(1) # Keeps the main execution thread alive
except KeyboardInterrupt:
print("\nStopping folder monitor...")
observer.stop()
observer.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment