File organization using Python 🐍

Let's face it. We all have had, or currently have a cluttered desktop. And we all know the time-consuming job of having to eventually declutter the mess. In this short blog post, I'll be presenting a better way to handle such issues for both programmers and non-programmers alike.


import os
import shutil
import time
from typing import List, Set        

The libraries above will be useful to make our lives easier when developing our script. The 'os' and 'shutil' libraries will serve for manipulating the location of files, folders, and for creating necessary folders, in case they do not exist. The 'time' library will serve to temporarily halt the script, for every created file in order for us to be able to read what the script does, iteration by iteration. Last, but not least in importance, the 'typing' library generic aliases such as 'Dict' and 'Set' will be used for improving the readability of our methods.


In the following code we develop the "create_folders_in_directory" method. It is important to name our methods with meaningful expressions. It could ease the life of your future self and colleagues who might be using parts of your code.

def create_folders_in_directory(directory_path: str, unique_file_types: Set[str]) -> None:
    """Create folders for each file type if they don't already exist

    Args:
        directory_path (str): The main directory path where the folders are located
        unique_file_types (Set[str]): The set with unique file type names (folder names)
    """
    for folder_name in unique_file_types:
        folder_path = os.path.join(directory_path, folder_name)
        if not os.path.exists(folder_path):
            os.mkdir(folder_path)
            print(f"Folder {folder_name} created on {directory_path}")
        else:
            print(f"Folder {folder_name} already exists on {directory_path}")        

The method above takes as arguments, the filepath of the directory that you wish to declutter, as well as a unique list of folder names, where each folder name will be used to create a folder to store corresponding files.


The second and final method, will be the one to organize files, thus the "organize_files" name. This method takes two arguments: A string that represents the file path of the directory that will be decluttered (same argument as the first method), as well as a dictionary of file extensions that point to corresponding folder names.

def organize_files(directory_path: str, file_types: Dict[str, str]) -> None:
    """Function to organize files by moving them to their respective folders based on their file extension

    Args:
        directory_path (str): The main directory path where the folders are located
        file_types (Set[str]): The dictionary with file type (extension) key and corresponding file type name
    """

    index_counter = 0
    for file_name in os.listdir(directory_path):
        filepath = os.path.join(directory_path, file_name)
        if os.path.isfile(filepath):
            print(f"Filepath: {filepath}")

            # Split the filename into it's respective name and extension.
            _, file_extension = os.path.splitext(file_name)
            
            # Remove the dot and convert to lowercase
            file_extension = file_extension[1:].lower()  
            
            print(f"File extension: {file_extension} and {file_extension in file_types}")


            if file_extension in file_types:
                source_path = os.path.join(directory_path, file_name)
                destination_folder = file_types[file_extension]
                destination_path = os.path.join(directory_path, destination_folder, file_name)
                shutil.move(source_path, destination_path)

                print(f"Moved file: {file_name} to folder: {destination_folder}. Processed {index_counter + 1} files")
                index_counter += 1
                time.sleep(3)        

Below we will develop the "main" method with all the necessary components that will be needed to run both methods. We create a "file_types" dictionary that maps a file extension to the appropriate folder name. Then, we get the unique file types through the "set()" function. Then we create a sample directory path named "sample_path", which in my local machine, I already created this directory, as well as sample files that will be moved around. Then we proceed to run both methods that are previously explained.

def main():
    # Dictionary mapping file extensions to folder names
    file_types = {
        "jpg": "Images",
        "png": "Images",
        "gif": "Images",
        "pdf": "Documents",
        "doc": "Documents",
        "docx": "Documents",
        "txt": "TextFiles",
        "xlsx": "Spreadsheets",
        "xls": "Spreadsheets",
        "csv": "Spreadsheets",
        "pptx": "Presentations",
        "mp3": "Audio",
        "mp4": "Videos",
        "zip": "Archives",
        "rar": "Archives",
        "exe": "Executables",
    }

    # Getting the unique file type names from the dictionary
    unique_file_types = set(file_types.values())
    print(f"Unique file types set: {unique_file_types}")
    
    # desktop_path = os.path.expanduser("~/Desktop")
    # print(f"Total number of files: {len(os.listdir(desktop_path))}")

    sample_path = os.path.join(os.getcwd(), 'sample_directory')
    print(f"Total number of files: {len(os.listdir(sample_path))}")
   
    create_folders_in_directory(directory_path=sample_path, unique_file_types=unique_file_types)
    organize_files(directory_path=sample_path, file_types=file_types)        

Above, you can see that I have commented out the "desktop_path" in order to not directly use that variable. It is good practice to test your code on sample inputs before applying such changes on important directories.


Lastly, we can write the following code in order to execute our 'main' method that will run each step to complete our automation script.

if __name__ == '__main__':
    main()        

Below are the results of running this completed script in my local machine, using a sample directory, and a bunch of sample files.

Article content
Executing the 'create_folders_in_directory' will create all of the necessary folders in the given sample directory path.


Article content
Running the organizer function will move the files to the appropriate folder, as shown in the image.


To conclude, I hope that this script serves as an initial point to create more interesting automations. Let me know what you think in the comments! Cheers and happy coding 👋👋


Klajd Arqimandriti

AI Engineer | Big Data Lecturer

1y

Thank you for sharing Said Emre Gün 🤘🤘

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics