Code - Organise Photos Using EXIF Data

Code - Organise Photos Using EXIF Data
Clean

So, ok this is a little bit of a OCD post...

Throughout the year, we take thousands of photos and store them on Geekden's NAS.

But finding the image later can be a bit of chllange.

The issue is they normally look like this:

But using a bit of phyton we can turn that useless big bulk of images/videos into something useful.

import os
import shutil
from datetime import datetime

try:
    import exifread
except ImportError:
    print("Please install the 'exifread' module using 'pip install exifread'")
    exit(1)

def get_image_creation_date(file_path):
    with open(file_path, 'rb') as image_file:
        tags = exifread.process_file(image_file, details=False)
        if 'EXIF DateTimeOriginal' in tags:
            # Extract the creation date and handle decimal literals
            creation_date = str(tags['EXIF DateTimeOriginal']).split()[0]
            return creation_date
    return None

def is_image_organized(file_path, output_folder):
    # Get the creation date
    creation_date = get_image_creation_date(file_path)

    # Check if the creation date is available and not None
    if creation_date:
        # Check if the image is already organized
        expected_folder = os.path.join(output_folder, creation_date)
        return os.path.dirname(file_path) == expected_folder

    # If the creation date is None, consider the image unorganized
    return False

def reorganize_images(input_folder, output_folder, unorganized_folder, archive_folder):
    # Create unorganized folder if it doesn't exist
    if not os.path.exists(unorganized_folder):
        os.makedirs(unorganized_folder)

    # Create archive folder if it doesn't exist
    if not os.path.exists(archive_folder):
        os.makedirs(archive_folder)

    # Iterate over files in the input folder
    for filename in os.listdir(input_folder):
        file_path = os.path.join(input_folder, filename)

        # Check if the file is an image
        if os.path.isfile(file_path) and any(file_path.lower().endswith(ext) for ext in ['.jpg', '.jpeg', '.png']):
            # Check if the image is already organized
            if is_image_organized(file_path, output_folder):
                print(f'Skipping: {filename} (Already organized)')
                continue

            # Get creation date of the image
            creation_date = get_image_creation_date(file_path)

            if creation_date:
                # Parse the creation date
                date_object = datetime.strptime(creation_date, '%Y:%m:%d')

                # Create subfolder based on the month in the output folder
                month_folder = os.path.join(output_folder, date_object.strftime('%Y-%m'))
                if not os.path.exists(month_folder):
                    os.makedirs(month_folder)

                # Move the image to the corresponding subfolder in the output folder
                new_file_path = os.path.join(month_folder, filename)
                shutil.move(file_path, new_file_path)

                # Print the progress
                print(f'Moved: {filename} to {new_file_path}')
            else:
                # Move the image to the unorganized folder if it doesn't have EXIF data
                unorganized_file_path = os.path.join(unorganized_folder, filename)
                shutil.move(file_path, unorganized_file_path)
                print(f'Moved to Unorganized: {filename}')

    # Move remaining files in the input folder to the archive folder
    for remaining_file in os.listdir(input_folder):
        remaining_file_path = os.path.join(input_folder, remaining_file)
        archive_file_path = os.path.join(archive_folder, remaining_file)
        shutil.move(remaining_file_path, archive_file_path)
        print(f'Moved to Archive: {remaining_file}')

if __name__ == "__main__":
    input_folder = "/Volumes/Data/Photos/"
    output_folder = "/Volumes/Data/2023-Test/"
    unorganized_folder = "/Volumes/Data/2023-Test/Unorganized/"
    archive_folder = "/Volumes/Data/2023-Test/Archive/"

    reorganize_images(input_folder, output_folder, unorganized_folder, archive_folder)

In the console you can see the progress!

Finally, tidy!