|  | 
|  | 1 | +#!/usr/bin/env python3 | 
|  | 2 | +""" | 
|  | 3 | +Smart File Organizer | 
|  | 4 | +
 | 
|  | 5 | +A utility script to organize files in a specified directory into categorized | 
|  | 6 | +subfolders based on file types. | 
|  | 7 | +
 | 
|  | 8 | +Example categories include: Images, Documents, Videos, Audios, Archives, Scripts, Others. | 
|  | 9 | +
 | 
|  | 10 | +Usage: | 
|  | 11 | +    python smart_file_organizer.py --path "C:\\Users\\YourName\\Downloads" --interval 0 | 
|  | 12 | +
 | 
|  | 13 | +Arguments: | 
|  | 14 | +    --path       Directory path to organize. | 
|  | 15 | +    --interval   Interval in minutes to repeat automatically (0 = run once). | 
|  | 16 | +
 | 
|  | 17 | +Author: | 
|  | 18 | +    Sangam Paudel | 
|  | 19 | +""" | 
|  | 20 | + | 
|  | 21 | +import os | 
|  | 22 | +import shutil | 
|  | 23 | +import argparse | 
|  | 24 | +import time | 
|  | 25 | +from datetime import datetime | 
|  | 26 | + | 
|  | 27 | +FILE_CATEGORIES = { | 
|  | 28 | +    "Images": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".svg"], | 
|  | 29 | +    "Documents": [".pdf", ".doc", ".docx", ".txt", ".ppt", ".pptx", ".xls", ".xlsx"], | 
|  | 30 | +    "Videos": [".mp4", ".mkv", ".mov", ".avi", ".flv", ".wmv"], | 
|  | 31 | +    "Audios": [".mp3", ".wav", ".aac", ".flac", ".ogg"], | 
|  | 32 | +    "Archives": [".zip", ".rar", ".tar", ".gz", ".7z"], | 
|  | 33 | +    "Scripts": [".py", ".js", ".sh", ".bat", ".java", ".cpp", ".c"], | 
|  | 34 | +} | 
|  | 35 | + | 
|  | 36 | + | 
|  | 37 | +def create_folder(folder_path: str) -> None: | 
|  | 38 | +    """ | 
|  | 39 | +    Create a folder if it does not already exist. | 
|  | 40 | +
 | 
|  | 41 | +    Args: | 
|  | 42 | +        folder_path: Path of the folder to create. | 
|  | 43 | +    """ | 
|  | 44 | +    if not os.path.exists(folder_path): | 
|  | 45 | +        os.makedirs(folder_path) | 
|  | 46 | + | 
|  | 47 | + | 
|  | 48 | +def get_category(file_ext: str) -> str: | 
|  | 49 | +    """ | 
|  | 50 | +    Determine the category of a file based on its extension. | 
|  | 51 | +
 | 
|  | 52 | +    Args: | 
|  | 53 | +        file_ext: File extension (e.g., ".txt"). | 
|  | 54 | +
 | 
|  | 55 | +    Returns: | 
|  | 56 | +        Category name (e.g., "Documents") or "Others" if not matched. | 
|  | 57 | +    """ | 
|  | 58 | +    for category, extensions in FILE_CATEGORIES.items(): | 
|  | 59 | +        if file_ext.lower() in extensions: | 
|  | 60 | +            return category | 
|  | 61 | +    return "Others" | 
|  | 62 | + | 
|  | 63 | + | 
|  | 64 | +def organize_files(base_path: str) -> None: | 
|  | 65 | +    """ | 
|  | 66 | +    Organize files in the given directory into subfolders by category. | 
|  | 67 | +
 | 
|  | 68 | +    Args: | 
|  | 69 | +        base_path: Path of the directory to organize. | 
|  | 70 | +    """ | 
|  | 71 | +    files = [f for f in os.listdir(base_path) if os.path.isfile(os.path.join(base_path, f))] | 
|  | 72 | +    if not files: | 
|  | 73 | +        print(f"[{datetime.now().strftime('%H:%M:%S')}] No files found in {base_path}") | 
|  | 74 | +        return | 
|  | 75 | + | 
|  | 76 | +    for file_name in files: | 
|  | 77 | +        source = os.path.join(base_path, file_name) | 
|  | 78 | +        file_ext = os.path.splitext(file_name)[1] | 
|  | 79 | +        category = get_category(file_ext) | 
|  | 80 | +        target_folder = os.path.join(base_path, category) | 
|  | 81 | +        create_folder(target_folder) | 
|  | 82 | + | 
|  | 83 | +        try: | 
|  | 84 | +            shutil.move(source, os.path.join(target_folder, file_name)) | 
|  | 85 | +            print(f"[{datetime.now().strftime('%H:%M:%S')}] Moved: {file_name} -> {category}/") | 
|  | 86 | +        except Exception as e: | 
|  | 87 | +            print(f"[{datetime.now().strftime('%H:%M:%S')}] Error moving {file_name}: {e}") | 
|  | 88 | + | 
|  | 89 | + | 
|  | 90 | +def main() -> None: | 
|  | 91 | +    """Parse command-line arguments and execute the file organizer.""" | 
|  | 92 | +    parser = argparse.ArgumentParser( | 
|  | 93 | +        description="Organize files in a directory into categorized subfolders." | 
|  | 94 | +    ) | 
|  | 95 | +    parser.add_argument( | 
|  | 96 | +        "--path", | 
|  | 97 | +        required=True, | 
|  | 98 | +        help="Directory path to organize." | 
|  | 99 | +    ) | 
|  | 100 | +    parser.add_argument( | 
|  | 101 | +        "--interval", | 
|  | 102 | +        type=int, | 
|  | 103 | +        default=0, | 
|  | 104 | +        help="Interval (in minutes) to repeat automatically (0 = run once)." | 
|  | 105 | +    ) | 
|  | 106 | +    args = parser.parse_args() | 
|  | 107 | + | 
|  | 108 | +    if not os.path.exists(args.path): | 
|  | 109 | +        print(f"Path not found: {args.path}") | 
|  | 110 | +        return | 
|  | 111 | + | 
|  | 112 | +    print(f"Watching directory: {args.path}") | 
|  | 113 | +    print("Organizer started. Press Ctrl+C to stop.\n") | 
|  | 114 | + | 
|  | 115 | +    try: | 
|  | 116 | +        while True: | 
|  | 117 | +            organize_files(args.path) | 
|  | 118 | +            if args.interval == 0: | 
|  | 119 | +                break | 
|  | 120 | +            print(f"Waiting {args.interval} minutes before next run...\n") | 
|  | 121 | +            time.sleep(args.interval * 60) | 
|  | 122 | +    except KeyboardInterrupt: | 
|  | 123 | +        print("\nOrganizer stopped by user.") | 
|  | 124 | + | 
|  | 125 | + | 
|  | 126 | +if __name__ == "__main__": | 
|  | 127 | +    main() | 
0 commit comments