1+ import argparse
2+ import os
3+ import logging
4+ import shutil # For moving files
5+
6+ def main ():
7+ try :
8+ args = parse_arguments ()
9+ check_directory (args .directory_path )
10+
11+ setup_logging (args .verbose )
12+
13+ organize_directory (args .directory_path )
14+ # Catch any exceptions that may occur
15+ except Exception as e :
16+ print (e )
17+
18+ def parse_arguments ():
19+ # Parse the arguments from cli, order is irrelevant
20+ parser = argparse .ArgumentParser (description = "Organize files in a directory based on their extensions." )
21+ parser .add_argument ("directory_path" , type = str , help = "Path of the directory to be organized" ) # Required argument
22+ parser .add_argument ("-v" , "--verbose" , action = "store_true" , help = "Enable verbose output" ) # Optional argument
23+ return parser .parse_args ()
24+
25+ def check_directory (directory_path ):
26+ if not os .path .isdir (directory_path ):
27+ raise ValueError (f"'{ directory_path } ' is not a valid directory." )
28+
29+ if not os .listdir (directory_path ):
30+ raise ValueError (f"'{ directory_path } ' is an empty directory!" )
31+
32+ if not os .access (directory_path , os .W_OK ):
33+ raise ValueError (f"'{ directory_path } ' is not writable." )
34+
35+ def setup_logging (verbose ):
36+ log_level = logging .INFO if verbose else logging .WARNING
37+ log_format = "%(message)s"
38+ logging .basicConfig (level = log_level , format = log_format )
39+
40+ def organize_directory (directory_path ):
41+ categories = {
42+ "Music" : (".mp3" , ".wav" , ".flac" , ".m4a" , ".aac" , ".ogg" , ".oga" , ".wma" , ".mid" ,),
43+ "Videos" : (".mp4" , ".avi" , ".mkv" , ".mpeg" , ".wmv" , ".vob" , ".flv" , ".mov" , ".3gp" , ".webm" ,),
44+ "Source Files" : (".py" , ".c" , ".cpp" , ".java" , ".js" , ".cs" , ".html" , ".css" , ".php" , ".json" , ".xml" , ".sql" , ".db" ,),
45+ "Executables" : (".exe" , ".msi" , ".sh" , ".bat" , ".apk" , ".jar" , ".deb" , ".run" , ".bin" , ".dmg" , ".iso" ,),
46+ "Pictures" : (".jpg" , ".jpeg" , ".png" , ".gif" , ".bmp" , ".svg" , ".webp" , ".psd" , ".ai" , ".ico" ,),
47+ "Documents" : (".pdf" , ".doc" , ".docx" , ".xls" , ".xlsx" , ".ppt" , ".pptx" , ".txt" , ".md" , ".odt" , ".ods" , ".odp" , ".csv" , ".rtf" ,),
48+ "Compressed" : (".zip" , ".rar" , ".tar" , ".gz" , ".7z" , ".bz2" , ".xz" , ".z" , ".lz" ,),
49+ "Torrents" : (".torrent" ,),
50+ }
51+
52+ for category , extensions in categories .items ():
53+ # Check if there are files with matching extensions for this category
54+ files_with_extension = [file for file in os .listdir (directory_path ) if os .path .isfile (os .path .join (directory_path , file ))
55+ and os .path .splitext (file )[1 ].lower () in extensions ]
56+
57+ if files_with_extension :
58+ # Create a folder for this category if it doesn't exist
59+ category_folder = os .path .join (directory_path , category )
60+ if not os .path .exists (category_folder ):
61+ os .makedirs (category_folder )
62+ logging .info (f"Creating '{ category } ' folder." )
63+ else :
64+ logging .info (f"'{ category } ' folder already exists, reusing." )
65+
66+ for file in files_with_extension :
67+ source_path = os .path .join (directory_path , file )
68+ dest_path = os .path .join (category_folder , file )
69+ shutil .move (source_path , dest_path )
70+ logging .info (f"Moved '{ file } ' to '{ category } ' folder." )
71+
72+ print ("Organizing files complete!" )
73+
74+ if __name__ == "__main__" :
75+ main ()
0 commit comments