main.py
The "main.py" script is a Python program designed to organize files within a specified directory based on their file extensions. It enhances file organization and grouping for better management by moving files into subdirectories that correspond to specific categories, such as programming languages, file types, and data formats. This script provides a way to efficiently organize and categorize files in a given folder, making it easier to find and manage files of different types.
Notes on main.py
- The script uses constants defined in "constants.py" to categorize files into different groups.
- It provides a clear structure for adding new categories or modifying existing ones.
- The "constants.py" file allows customization of file extensions and categories.
Code
"""_File Organizer_
@date:
August 28, 2023
@version:
1.0
@license:
This code is licensed under the MIT License.
@file:
main.py
@description:
This script is a Python program designed to organize files
within a specified directory into different categories
based on their file extensions. It aims to enhance file
organization and grouping for better management. The script
achieves this by moving files into subdirectories that correspond
to specific categories such as programming languages, file types, and data formats.
@usage:
Run this script with the necessary dependencies installed and provide the name of the folder
you would like to organized. The script will organize the files in that folder.
@example:
$ python main.py
"""
"""_imports_"""
import os
import shutil
import sys
from typing import List
from tqdm import tqdm
from constants import *
#---
# Imported for testing purposes only
#---
from test import run_test, delete_dir
"""_summary_
_desc_: returns the extension of a file name.
_param_: file_name (str): The name of the file.
_returns_: str: The extension of the file name.
"""
def get_extension(file_name: str) -> str:
return "." + file_name.split(".")[-1].lower()
def move_file(subcategory_dir: str, file: str) -> None:
if not os.path.exists(os.path.join(TARGET_DIR_, subcategory_dir)):
os.makedirs(os.path.join(TARGET_DIR_, subcategory_dir))
source_path = os.path.join(TARGET_DIR_, file)
destination_path = os.path.join(TARGET_DIR_, subcategory_dir, os.path.basename(file))
shutil.move(source_path, destination_path)
"""_summary_
_desc_: organizes files into different categories based on their file extensions.
_param_: files (List[str]): A list of file paths.
_returns_: None: This function does not return anything.
"""
def organize_files(files: List[str]) -> None:
#for file in files:
for file in tqdm(files, desc="\n[organizing files]", unit="file"):
if file.lower() != MAKEFILE_:
extension = get_extension(file)
else:
extension = "Makefile"
for extensions, category in file_extensions.items():
if extension in extensions:
category_dir = category
if extension in [".cpp", ".hpp", ".asm", "Makefile"]:
subdir_name = "Cpp"
elif extension in [".c", ".h", ".pch", ".o", ".a"]:
subdir_name = "C"
elif extension in [".java"]:
subdir_name = "Java"
elif extension in [".py", ".pyw", ".ipynb"]:
subdir_name = "Python"
elif extension in [".js", ".html", ".css", ".scss", ".sass", ".php", ".ts"]:
subdir_name = "Web"
elif extension in [".rb"]:
subdir_name = "Ruby"
elif extension in [".cs", ".vs"]:
subdir_name = "CSharp"
elif extension in [".rs"]:
subdir_name = "Rust"
elif extension in [".xlsx", ".xls"]:
subdir_name = "Spreadsheets"
elif extension in [".pptx", ".ppt"]:
subdir_name = "Presentations"
elif extension in [".csv", ".dat", ".db", ".dbf", ".log", ".mdb", ".sav", ".sql", ".json", ".xml"]:
subdir_name = "Data-Sets"
elif extension in [".git"]:
subdir_name = "Git"
elif extension in [".exe"]:
subdir_name = "Executables"
else:
#check if no subdirs are present
subdir_name = OTHER_STR_
move_file(os.path.join(category_dir, subdir_name), file)
break
else:
move_file(os.path.join(OTHER_STR_), file)
"""_summary_
_desc_: exits the program.
_returns_: None
_param_: exit_code: int corresponding to the exit code
"""
def quit(exit_code: int) -> None:
sys.exit(exit_code)
"""_summary_
_desc_: establishes the current directory and returns a list of files in the directory.
_returns_: List[str]: A list of file names in the current directory.
_raises_: FileNotFoundError: If the target directory is not found.
"""
def establish_current_dir() -> List[str]:
try:
with os.scandir(TARGET_DIR_) as entries:
files = [entry.name for entry in entries] # if entry.is_file()
return files
except FileNotFoundError:
print(ERROR_MSG_)
quit(exit_code=1)
def main() -> None:
run_test()
files = establish_current_dir()
organize_files(files)
input("\nPress [Enter] to continue...")
delete_dir()
if __name__ == "__main__":
main()
constants.py
The "constants.py" file contains constants used throughout the program to categorize files into different groups. It defines file extensions and their corresponding categories, making it easy to maintain and expand the categorization system. You can customize the values in this file to fit your specific needs.
Code
"""_File Organizer_
@date:
August 28, 2023
@version:
1.0
@license:
This code is licensed under the MIT License.
@file:
constants.py
@description:
This file contains the constants used throughout the program
@usage:
Change the value of the TARGET_DIR_ variable to the folder you would like organized.
"""
'''_Could be changed to "Desktop" or any folder you would like organized_'''
TARGET_DIR_ = "__TEST__"
'''_List is unhashable, using tuples instead_'''
IMAGES_ = (".jpeg", ".png", ".jpg", ".gif",
".bmp", ".svg", ".tiff", ".heic", ".webp")
TEXT_ = (".txt", ".rtf", ".md")
VIDEO_ = (".mp4", ".mkv", ".avi", ".mov",
".wmv", ".flv", ".ogg", ".webm")
AUDIO_ = (".mp3", ".wav", ".m4a", ".flac")
APPLICATIONS_ = (".exe", ".lnk", ".msi", ".app")
CODE_ = (".cpp", ".hpp", ".asm", ".js", ".html", ".css", ".scss",
".sass", ".php", ".ts", ".c", ".h", ".pch", ".o", ".a",
".java", ".rb", ".rs", ".py", ".pyw", ".ipynb", ".cs", ".vs"
".xcodeproj")
INSTALL_ = (".dmg", ".pkg", ".deb", ".rpm")
COMPRESSED_ = (".zip", ".rar", ".tar", ".gz", ".7z")
DOCUMENTS_ = (".doc", ".pdf", ".docx", ".ppt", ".pptx", ".odt", ".ods",
".xls", ".xlsx", ".csv", ".dat", ".db", ".dbf", ".log",
".mdb", ".sav", ".sql", ".json", ".xml")
OTHER_ = ("",)
'''_file categories used in organize_files()_'''
file_extensions = {
IMAGES_: "Images",
TEXT_: "Text",
VIDEO_: "Video",
AUDIO_: "Audio",
APPLICATIONS_: "Applications",
CODE_: "Code",
INSTALL_: "Install",
COMPRESSED_: "Compressed",
DOCUMENTS_: "Documents",
OTHER_: "Other"
}
'''_other constants defined for clarity_'''
MAKEFILE_ = "makefile"
OTHER_STR_ = "Other"
ERROR_MSG_ = f"[{TARGET_DIR_} directory not found]\n"
test.py
The "test.py" script provides a testing environment for the file organizer program. It includes functions to create random files with different extensions in a target directory. This allows you to test the file organizer's functionality without affecting your actual files.
Notes on test.py
The script uses random file extensions to simulate a variety of file types for testing purposes.
It ensures that the target directory is created before running tests.
This testing script is separate from the main program and is useful for verifying the file organizer's functionality.
Use the
run_test()
function to create a set of random files in the specified target directory.Use the
delete_dir()
function to remove the target directory and its contents after testing.
Code
"""_File Organizer_
@date:
August 28, 2023
@version:
1.0
@license:
This code is licensed under the MIT License.
@file:
contants.py
@description:
This file contains the constants used throughout the program
@usage:
Chnage the value of the TARGET_DIR_ variable to the folder you would like organized.
"""
"""_imports_"""
import os
import shutil
from typing import List
import random
import string
from constants import *
_MAX_ = 100
"""_summary_
_desc_: creates a new directory and moves a randomly generated file into it.
_param_: None
_returns_: None
"""
def make_dir() -> None:
random_sequence = ''.join(random.choice(string.ascii_lowercase) for _ in range(4))
all_extensions = (
IMAGES_ + TEXT_ + VIDEO_ + AUDIO_ + APPLICATIONS_ + CODE_ +
INSTALL_ + COMPRESSED_ + DOCUMENTS_ + OTHER_
)
random_extension = random.choice(all_extensions)
file_name = random_sequence + random_extension
with open(file_name, "w") as f:
pass
shutil.move(file_name, os.path.join(TARGET_DIR_, file_name))
"""_summary_
_desc_: create a directory if it doesn't exist.
_param_: None
_returns_: None
"""
def establish() -> None:
if not os.path.exists(TARGET_DIR_):
os.makedirs(TARGET_DIR_)
"""_summary_
_desc_: deletes the directory specified by the constant TARGET_DIR_.
_param_: None
_returns_: None
"""
def delete_dir() -> None:
shutil.rmtree(TARGET_DIR_)
"""_summary_
_desc_: run the test by establishing a connection and creating directories.
_param_: None
_returns_:
None
"""
def run_test() -> None:
establish()
for i in range(_MAX_):
make_dir()
Things on the TODO list:
- Command line Args -> e.g:
pyhton3 main.py "Downloads"
- Using
.aksdirectory()
from theTkinter
library - Eventually, make a GUI
Note
I got the C++ disease in my freshman year and it's still sort of going on. I am sorry in advance if I insulted anyone with the use of unnecessary underscores, Doxygen style documentation, documenting my functions above the prototype and not inside the body, and defining a separate file for my constants (sort of like a .h
file).