from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer import shutil import os from funcs import get_media_dimensions media_dir = "media" stories_dir = os.path.join(media_dir, "stories") posts_dir = os.path.join(media_dir, "posts") os.makedirs(stories_dir, exist_ok=True) os.makedirs(posts_dir, exist_ok=True) def is_story(width, height, tolerance=0.02): if width == 0 or height == 0: return False ratio = min(width, height) / max(width, height) return abs(ratio - (9 / 16)) <= (9 / 16 * tolerance) def determine_post_type(filepath): lower = filepath.lower() if "posts" in lower: return "posts" try: width, height = get_media_dimensions(filepath) except Exception as e: print(f"Error getting dimensions for {filepath}: {e}") return None return "stories" if is_story(width, height) else "posts" class DownloadHandler(FileSystemEventHandler): def process_file(self, file_path): file = os.path.basename(file_path) # Ignore incomplete or weird temp names if "crdownload" in file or file.count("~") != 3: return if not os.path.exists(file_path): return post_type = determine_post_type(file_path) if post_type == "posts": dest_dir = posts_dir elif post_type == "stories": dest_dir = stories_dir else: print(f"Could not determine post type for {file}. Skipping...") return output_path = os.path.join(dest_dir, file) if os.path.exists(output_path): print(f"File already exists {output_path}. Removing...") os.remove(file_path) return shutil.move(file_path, output_path) print(f"Moved {file_path} → {output_path}") def on_created(self, event): if not event.is_directory: self.process_file(event.src_path) def on_moved(self, event): if not event.is_directory: self.process_file(event.dest_path) if __name__ == "__main__": download_path = os.path.join(os.path.expanduser("~"), "Downloads") event_handler = DownloadHandler() # Initial scan for files already in Downloads for f in os.listdir(download_path): full_path = os.path.join(download_path, f) if os.path.isfile(full_path): event_handler.process_file(full_path) observer = Observer() observer.schedule(event_handler, download_path, recursive=False) observer.start() try: observer.join() except KeyboardInterrupt: observer.stop() observer.join()