Introduction
Have you ever looked at a giant folder full of randomly named photos and videos and wished they could be neatly organized by date—without doing it manually?
With just a little Python code, you can automate that task—and even turn it into a simple app you can run anytime.
This beginner-friendly guide walks you through a real example that:
- Requires no prior coding experience
- Solves a practical, everyday problem
- Teaches you Python step-by-step
- Produces a tool you can share or use yourself
Why Learn Python?
Python is one of the most beginner-friendly programming languages available today. It’s:
- Simple to read and write (it looks almost like plain English)
- Widely used for automation, data analysis, machine learning, and more
- Supported by a large community and countless free tools
One of the best ways to learn Python is by building something practical. This project is a great first step.
What You’ll Build
A simple Python app that automatically organizes your photos and videos into folders based on the date they were taken. The app:
- Scans a folder for photos and videos
- Reads the “date taken” metadata from each file
- Creates folders like 2024/03 or 2024/03/15
- Moves each file into the correct folder
- Handles files with duplicate names
- Offers a graphical interface (no command line needed)
What Is Metadata?
When you take a photo or video, your phone or camera saves extra information inside the file—such as the date, time, and sometimes even location. This data is called metadata.
For images, this metadata is often stored in a format called EXIF. This project reads that information to figure out when each photo or video was taken.
Step 1: Install Python (Recommended: Anaconda)
To get started, we recommend using Anaconda, which includes Python and many useful packages for beginners.
- Go to anaconda.com and download the latest version.
- Install it using the default settings.
- Open Anaconda Prompt (you can find it by searching in your Start menu).
Step 2: Install Required Python Packages
With Anaconda Prompt open, install the two required packages by running:
pip install pymediainfo pillow
pillow
allows the app to read image metadatapymediainfo
reads metadata from video files
Step 3: How the Tool Works
The tool is split into four Python files:
File | Purpose |
---|---|
sort_pics.py |
Core logic for scanning folders and moving files |
gui.py |
Graphical interface for selecting folders and sorting |
utils.py |
Helper functions for logging and file validation |
__main__.py |
allows to run the app with "python -m sort_pics_gui.src |
### sort_pics.py - The Core Logic |
|
- Scans thorugh a folder to find photo and video files | |
- reads "date taken" metadata from each file ( EXIF for images, media info for videos) | |
- Creates folders based on the file's creation date | |
- Moves each file into the appropriate folder | |
- Handles duplicates by renaming them (e.g., IMG_1234_1.jpg ) |
|
### gui.py - The Graphical User Interface |
|
- This file is run to launch the app. It creates a very basic window using Python's tkinter module | |
- Select a folder containing all your media you want to sort | |
- Choose how you want your files organized (by year, month or day) | |
- Click a button to start the sorting process | |
- This file calls functions from sort_pics.py to actually process your files |
|
![]() |
|
### utils.py - Helper Functions |
|
- contains small utility helper functions | |
- Log messages | |
- Checks if folder paths are valid | |
- Returns list of supported file types (image and video formats) |
By separating logic, user interface and helper functions you help organizing your code across multiple files keeping your code neat, similar to different chapters and headlines in an article or a book.
Step 4: Run the App
To run the tool:
- Open Anaconda Prompt
- Navigate to the folder containing your project:
cd "C:\\Users\\TimeMoneyCode\\Documents\\Python\\Sort_Pics"
- Launch the app:
python gui.py
In the window that opens:
- Click “Select Folder” and choose the folder with your unsorted files
- Choose how you'd like them organized:
- Year →
2024
- Year + Month →
2024/03
- Year + Month + Day →
2024/03/15
- Click “Sort Files”
The tool will move the photos and videos into the appropriate folders.
Example
Before:
Unsorted/
├── IMG_1234.jpg
├── vacation.mov
├── birthday.png
After:
Unsorted/
├── 2024/
│ └── 03/
│ ├── IMG_1234.jpg
│ ├── vacation.mov
│ └── birthday.png
If two files have the same name, the tool automatically renames them (e.g., IMG_1234_1.jpg
).
Step 5: Turn It into a Standalone App
To make the app easier to run on any Windows computer (without needing Python), you can turn it into an .exe
file using PyInstaller.
How to Build It:
- Install PyInstaller:
pip install pyinstaller
- Go to the folder containing your script:
cd "C:\\Users\\TimeMoneyCode\\Documents\\Python\\Sort_Pics"
- Build the app:
pyinstaller --onefile --windowed gui.py
After a short time, you’ll find the executable here:
C:\Users\TimeMoneyCode\Documents\Python\Sort_Pics\dist\gui.exe
You can now run the app directly without needing Python installed on that machine.
Why This Is a Great First Project
This project teaches you how to:
- Work with files and folders in Python
- Extract and use real-world data (photo/video metadata)
- Build a graphical interface
- Automate a common, everyday task
- Package your code into a shareable app
It’s small, useful, and achievable—exactly the kind of project that builds confidence when learning Python.
Ideas to Expand This Project
Once you’re comfortable with the basics, consider adding:
- A progress bar to show sorting progress
- A preview of images before sorting
- An option to copy instead of move files
- More organization options using more meta data information (e.g., by file type or camera model)
- A drag-and-drop interface
Final Thoughts
Learning Python doesn’t have to start with long courses or thick textbooks. It can start by solving a small, real-world problem.
This project shows that with a few lines of Python, you can take control of messy folders and save yourself time—all while learning one of the most in-demand skills today.
Whether you’re learning to automate tasks, organize your digital life, or just explore programming, this is a practical and rewarding first step.
Python Scripts
sort_pics.py:
# Created by TimeMoneyCode, 03.06.2025
# Logic for sorting pictures and videos into folders by date
from datetime import datetime
import os
from pathlib import Path
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
from pymediainfo import MediaInfo
# Supported file extensions for images and videos
image_exts = {".jpg", ".jpeg", ".png", ".tiff", ".bmp", ".gif"}
video_exts = {".mp4", ".mov", ".avi", ".mkv", ".wmv", ".flv", ".webm"}
def get_image_date_taken(path):
"""
Extract the date the image was taken from its EXIF metadata.
Returns a string like 'YYYY:MM:DD HH:MM:SS' or None if not found.
"""
try:
image = Image.open(path)
exif_data = image._getexif()
if exif_data:
for tag_id, value in exif_data.items():
tag = TAGS.get(tag_id, tag_id)
if tag == "DateTimeOriginal":
return value
except Exception:
pass
return None
def get_video_date_taken(path):
"""
Extract the date the video was created using pymediainfo.
Returns a string like '2023-05-01 12:34:56' or None if not found.
"""
try:
media_info = MediaInfo.parse(str(path))
for track in media_info.tracks:
if track.track_type == "General":
date = track.encoded_date or track.tagged_date
if date:
# Remove 'UTC ' if present
date = date.replace("UTC ", "")
return date.strip()
except Exception:
pass
return None
def scan_folder(folder, folder_structure):
"""
Scan the given folder for images and videos, extract their date,
and move them into subfolders based on the selected folder_structure.
"""
for file in Path(folder).rglob("*"):
if not file.is_file():
continue # Skip directories
dt = None # Will hold the datetime object
if file.suffix.lower() in image_exts:
date_taken = get_image_date_taken(file)
if date_taken:
try:
dt = datetime.strptime(date_taken, "%Y:%m:%d %H:%M:%S")
except Exception:
pass
print(f"Image: {file} | Date Taken: {date_taken}")
elif file.suffix.lower() in video_exts:
date_taken = get_video_date_taken(file)
if date_taken:
try:
if " " in date_taken and "-" in date_taken:
dt = datetime.strptime(date_taken, "%Y-%m-%d %H:%M:%S")
elif ":" in date_taken and date_taken.count(":") == 2:
dt = datetime.strptime(date_taken, "%Y:%m:%d %H:%M:%S")
except Exception:
pass
print(f"Video: {file} | Date Taken: {date_taken}")
if dt:
new_fp = create_folder(folder, dt, folder_structure)
if new_fp:
move_file(file, new_fp)
else:
print(f"Skipped (no date): {file}")
def create_folder(base_path, dt, folder_structure):
"""
Create a folder path based on the selected structure (year, month, day).
Returns the Path object for the new folder.
"""
if dt:
parts = []
if "year" in folder_structure:
parts.append(dt.strftime("%Y"))
if "month" in folder_structure:
parts.append(dt.strftime("%m"))
if "day" in folder_structure:
parts.append(dt.strftime("%d"))
folder_path = Path(base_path).joinpath(*parts)
folder_path.mkdir(parents=True, exist_ok=True)
return folder_path
return None
def move_file(file, date_folder):
"""
Move the file to the target date_folder.
If a file with the same name exists, add a number to the filename.
"""
target_file = date_folder / file.name
if not target_file.exists():
shutil.move(str(file), str(target_file))
else:
base, ext = os.path.splitext(file.name)
i = 1
while True:
new_name = f"{base}_{i}{ext}"
new_target = date_folder / new_name
if not new_target.exists():
shutil.move(str(file), str(new_target))
break
i += 1
if __name__ == "__main__":
# Example usage for testing (not used by the GUI)
scan_folder("C:\\Users\\linda\\Desktop\\Sort_Pics", ["year", "month"])
gui.py:
# Created by TimeMoneyCode, 03.06.2025
# GUI for sorting pictures and videos by date using Tkinter
from tkinter import Tk, Label, Button, filedialog, messagebox, Checkbutton, IntVar
from sort_pics import scan_folder # Import the sorting logic
class SortPicsApp:
def __init__(self, master):
self.master = master
master.title("Sort Pictures and Videos")
# Label at the top
self.label = Label(
master, text="Select a folder to sort pictures and videos:"
)
self.label.pack(pady=10)
# Button to select the folder
self.select_button = Button(
master, text="Select Folder", command=self.select_folder
)
self.select_button.pack(pady=5)
# Checkboxes to choose folder structure (year, month, day)
self.year_var = IntVar(value=1) # Checked by default
self.month_var = IntVar(value=1) # Checked by default
self.day_var = IntVar(value=0) # Unchecked by default
self.year_cb = Checkbutton(master, text="Year", variable=self.year_var)
self.year_cb.pack(anchor="w", padx=20)
self.month_cb = Checkbutton(master, text="Month", variable=self.month_var)
self.month_cb.pack(anchor="w", padx=20)
self.day_cb = Checkbutton(master, text="Day", variable=self.day_var)
self.day_cb.pack(anchor="w", padx=20)
# Button to start sorting
self.sort_button = Button(master, text="Sort Files", command=self.sort_files)
self.sort_button.pack(pady=5)
self.folder_path = "" # Stores the selected folder path
def select_folder(self):
# Open a dialog to select a folder
self.folder_path = filedialog.askdirectory()
if self.folder_path:
messagebox.showinfo(
"Selected Folder", f"Folder selected: {self.folder_path}"
)
def sort_files(self):
# Check if a folder is selected
if not self.folder_path:
messagebox.showwarning(
"No Folder Selected", "Please select a folder first."
)
return
# Build the folder structure list based on checkboxes
folder_structure = []
if self.year_var.get():
folder_structure.append("year")
if self.month_var.get():
folder_structure.append("month")
if self.day_var.get():
folder_structure.append("day")
if not folder_structure:
messagebox.showwarning(
"No Structure Selected", "Please select at least one folder level."
)
return
# Call the sorting function
try:
scan_folder(self.folder_path, folder_structure)
messagebox.showinfo("Success", "Files sorted successfully!")
except Exception as e:
messagebox.showerror("Error", f"An error occurred: {str(e)}")
# Start the GUI application
if __name__ == "__main__":
root = Tk()
app = SortPicsApp(root)
root.mainloop()
utils.py:
# Created by TimeMoneyCode, 03.06.2025
def log_message(message):
with open("app.log", "a") as log_file:
log_file.write(f"{message}\n")
def validate_folder_path(folder_path):
if not os.path.exists(folder_path):
raise ValueError(f"The folder path '{folder_path}' does not exist.")
return True
def get_supported_extensions():
return {
"images": {".jpg", ".jpeg", ".png", ".tiff", ".bmp", ".gif"},
"videos": {".mp4", ".mov", ".avi", ".mkv", ".wmv", ".flv", ".webm"},
}
main.py
# Created by TimeMoneyCode, 03.06.2025
# This file allows you to run the app with "python -m sort_pics_gui.src"
from gui import SortPicsApp
from tkinter import Tk
if __name__ == "__main__":
root = Tk()
app = SortPicsApp(root)
root.mainloop()
#Python #HowTo #Other