Career Paths

The Smart File Organizer

Learn how to automate file organization by creating a script that sorts files into subfolders based on their type.

Our Project: Automatic Downloads Sorter

A script that monitors a folder (e.g., "Downloads") and automatically moves each file to the appropriate subfolder (Images, Documents, etc.) based on its extension.

Core Technologies We'll Use:

Python
os
shutil
Step 1 / 6

Step 1: Design and Environment Setup

We define the goal of our script and create the necessary folder to test it.

Project Goal

We will create a script that does the following:

  1. Defines a target folder (e.g., the Downloads folder).
  2. Creates subfolders within it (e.g., "Images", "Documents").
  3. Scans all files in the target folder.
  4. For each file, it checks its extension (e.g., .jpg, .pdf).
  5. Moves the file to the appropriate subfolder.

Environment Setup

We don't need a virtual environment here, as we will only use the built-in os and shutil libraries. However, it is crucial to create a safe folder for testing.

1. On your Desktop, create a new folder named TestDownloads.

2. Inside this folder, create some empty files to have something to sort. For example: report.docx, photo.jpg, archive.zip, song.mp3.

3. Create a Python file, e.g., file_organizer.py, in any location you want (outside the TestDownloads folder).

Step 2 / 6

Step 2: Importing Libraries and Defining Constants

We import the necessary libraries and define the basic constants: the path of the target folder and the structure of our categories.

In our file_organizer.py file, we start by importing the libraries we will need and defining our settings.

  • import os: Provides functions for interacting with the operating system, such as getting the list of files in a folder or creating new folders.
  • import shutil: Provides high-level file operations, such as moving.
  • DOWNLOADS_PATH: We define the path to the folder we want to organize. os.path.join(os.path.expanduser("~"), "Desktop", "TestDownloads") is a reliable way to find the TestDownloads folder on the current user's desktop, regardless of the operating system.
  • FILE_TYPES: A dictionary that is the heart of our logic. The keys are the names of the folders that will be created, and the values are lists of file extensions belonging to each category.

# file_organizer.py
import os
import shutil

# ATTENTION: Make sure the TestDownloads folder exists on your Desktop.
DOWNLOADS_PATH = os.path.join(os.path.expanduser("~"), "Desktop", "TestDownloads")

# Dictionary that maps file extensions to destination folders.
FILE_TYPES = {
    "Images": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg"],
    "Documents": [".pdf", ".docx", ".doc", ".txt", ".xlsx", ".pptx"],
    "Videos": [".mp4", ".mov", ".avi", ".mkv"],
    "Music": [".mp3", ".wav", ".aac"],
    "Compressed": [".zip", ".rar", ".7z"],
    "Scripts": [".py", ".js", ".html", ".css"],
    "Other": [] # For anything that doesn't match elsewhere
}
Step 3 / 6

Step 3: Creating Destination Folders

We write a function that reads the categories from our dictionary and creates the corresponding subfolders if they don't already exist.

Before we start moving files, we need to make sure the destination folders exist. We will create a function create_destination_folders for this purpose.

This function iterates through the keys of the FILE_TYPES dictionary. For each key (e.g., "Images"), it constructs the full path (e.g., .../TestDownloads/Images) and uses os.path.exists() to check if the folder already exists. If it doesn't, it creates it with os.makedirs().


# (In the same file, file_organizer.py, after the constants)

def create_destination_folders():
    """Creates the destination folders if they don't already exist."""
    print("Checking and creating destination folders...")
    for folder_name in FILE_TYPES.keys():
        folder_path = os.path.join(DOWNLOADS_PATH, folder_name)
        if not os.path.exists(folder_path):
            os.makedirs(folder_path)
            print(f"Created folder: {folder_path}")
Step 4 / 6

Step 4: Logic for Matching Extension to Folder

We write a helper function that takes a file extension and returns the name of the correct destination folder.

To keep our code clean, we will create a small helper function get_destination_folder. It will take a file extension (e.g., ".pdf") and search the FILE_TYPES dictionary to find which category it belongs to. If it doesn't find a match, it will return the default "Other" category.


# (In the same file, file_organizer.py)

def get_destination_folder(file_extension):
    """Finds the appropriate destination folder for a given file extension."""
    for folder_name, extensions in FILE_TYPES.items():
        if file_extension.lower() in extensions: # .lower() to catch both .JPG and .jpg
            return folder_name
    return "Other" # Default folder
Step 5 / 6

Step 5: The Main Organization Logic

We implement the main function that scans the folder, checks each file, and moves it to the appropriate subfolder using the helper functions we created.

Now we combine everything in the main organize_files function.

  1. It uses os.listdir(DOWNLOADS_PATH) to get a list of all file and folder names.
  2. It loops through each name.
  3. For each name, it uses os.path.isfile() to make sure it's a file and not a folder (so it doesn't try to move the "Images", "Documents" folders, etc.).
  4. It uses os.path.splitext() to separate the file name from its extension.
  5. It calls our get_destination_folder() function to find where the file should go.
  6. It uses shutil.move() to move the file from its original location (source_path) to the new one (destination_path).

# (In the same file, file_organizer.py)

def organize_files():
    """Scans the downloads folder and moves the files."""
    print(f"\nScanning the folder: {DOWNLOADS_PATH}")
    files_moved = 0
    for filename in os.listdir(DOWNLOADS_PATH):
        source_path = os.path.join(DOWNLOADS_PATH, filename)
        
        if os.path.isfile(source_path):
            _, file_extension = os.path.splitext(filename)
            
            destination_folder_name = get_destination_folder(file_extension)
            destination_path = os.path.join(DOWNLOADS_PATH, destination_folder_name, filename)
            
            shutil.move(source_path, destination_path)
            print(f"Moved: '{filename}' -> '{destination_folder_name}'")
            files_moved += 1
            
    if files_moved == 0:
        print("No new files found to sort.")
    else:
        print(f"\nSorting complete. Moved {files_moved} files.")
Step 6 / 6

Step 6: Running the Script

We add the if __name__ == "__main__": block to call our functions in the correct order and run the program.

Finally, we add the classic if __name__ == "__main__": block to control the execution of our script. This first calls the function that creates the folders and then the function that organizes the files. We have also added a check to create the TestDownloads folder if it doesn't exist, making the script more user-friendly.


# (At the end of the file_organizer.py file)

if __name__ == "__main__":
    # Ensure the test folder exists
    if not os.path.exists(DOWNLOADS_PATH):
        os.makedirs(DOWNLOADS_PATH)
        print(f"Test folder created: {DOWNLOADS_PATH}")
        print("Please add some files to it and run the script again.")
    
    create_destination_folders()
    organize_files()

Project Completion & Next Steps

Congratulations! You have completed the path and now have the full code for the project.

This is the final, complete code for the application. You can copy it, run it locally on your computer (after installing the necessary libraries with `pip`), and experiment by adding your own features!


# file_organizer.py
import os
import shutil
import time

# ΠΡΟΣΟΧΗ: Δημιουργήστε έναν νέο, κενό φάκελο για τη δοκιμή, π.χ., "TestDownloads".
DOWNLOADS_PATH = os.path.join(os.path.expanduser("~"), "Desktop", "TestDownloads")

FILE_TYPES = {
    "Εικόνες": [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp"],
    "Έγγραφα": [".pdf", ".docx", ".doc", ".txt", ".xlsx", ".pptx", ".odt"],
    "Βίντεο": [".mp4", ".mov", ".avi", ".mkv"],
    "Μουσική": [".mp3", ".wav", ".aac"],
    "Συμπιεσμένα": [".zip", ".rar", ".7z", ".tar.gz"],
    "Scripts": [".py", ".js", ".html", ".css", ".sh"],
    "Άλλα": []
}

def create_destination_folders():
    print("Δημιουργία φακέλων προορισμού...")
    for folder_name in FILE_TYPES.keys():
        folder_path = os.path.join(DOWNLOADS_PATH, folder_name)
        os.makedirs(folder_path, exist_ok=True)
    print("Οι φάκελοι είναι έτοιμοι.")

def get_destination_folder(file_extension):
    file_ext_lower = file_extension.lower()
    for folder_name, extensions in FILE_TYPES.items():
        if file_ext_lower in extensions:
            return folder_name
    return "Άλλα"

def organize_files():
    print(f"\nΣάρωση του φακέλου: {DOWNLOADS_PATH}")
    files_moved = 0
    for filename in os.listdir(DOWNLOADS_PATH):
        source_path = os.path.join(DOWNLOADS_PATH, filename)
        
        if os.path.isfile(source_path):
            _, file_extension = os.path.splitext(filename)
            
            if not file_extension:
                continue

            destination_folder_name = get_destination_folder(file_extension)
            destination_path = os.path.join(DOWNLOADS_PATH, destination_folder_name, filename)
            
            try:
                shutil.move(source_path, destination_path)
                print(f"Μετακινήθηκε: '{filename}' -> '{destination_folder_name}'")
                files_moved += 1
            except Exception as e:
                print(f"Σφάλμα κατά τη μετακίνηση του {filename}: {e}")
            
    if files_moved == 0:
        print("Δεν βρέθηκαν νέα αρχεία για ταξινόμηση.")
    else:
        print(f"\nΟλοκληρώθηκε η ταξινόμηση. Μετακινήθηκαν {files_moved} αρχεία.")

if __name__ == "__main__":
    if not os.path.exists(DOWNLOADS_PATH):
        os.makedirs(DOWNLOADS_PATH)
        print(f"Δημιουργήθηκε ο φάκελος δοκιμής: {DOWNLOADS_PATH}")
    
    create_destination_folders()
    
    # Προαιρετικό: Εκτέλεση σε βρόχο για συνεχή παρακολούθηση
    try:
        while True:
            organize_files()
            print("\nΑναμονή για 30 δευτερόλεπτα...")
            time.sleep(30)
    except KeyboardInterrupt:
        print("\nΤο script τερματίστηκε από τον χρήστη.")