DEV Community

Kai Thorne
Kai Thorne

Posted on

"Stop Manually Organizing Your Downloads: A Python Script That Does It For You"

If your Downloads folder looks like a garage after a decade of neglect β€” PDFs next to MP4s, screenshots mixed with installer .exe files β€” this one's for you.

I wrote a Python script that watches my Downloads folder and auto-sorts everything into Documents/, Images/, Videos/, Archives/, and Code/ subfolders.

No external packages. No pip install. No bloated config files. Just Python's standard library.

The One-File Solution

#!/usr/bin/env python3
"""Downloads organizer β€” sorts files by type into categorized folders."""

import os
import shutil
from pathlib import Path

DOWNLOADS = Path.home() / "Downloads"

# Map file extensions to destination folders
RULES = {
    "Documents": [
        ".pdf", ".doc", ".docx", ".txt", ".md", ".csv",
        ".xls", ".xlsx", ".ppt", ".pptx", ".odt",
    ],
    "Images": [
        ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg",
        ".webp", ".ico", ".tiff",
    ],
    "Videos": [
        ".mp4", ".mov", ".avi", ".mkv", ".wmv", ".flv",
        ".webm",
    ],
    "Audio": [
        ".mp3", ".wav", ".flac", ".aac", ".ogg", ".m4a",
    ],
    "Archives": [
        ".zip", ".tar", ".gz", ".7z", ".rar", ".bz2",
    ],
    "Code": [
        ".py", ".js", ".ts", ".html", ".css", ".json",
        ".xml", ".yaml", ".yml", ".sh", ".bat", ".sql",
        ".dockerfile", ".env",
    ],
    "Installers": [
        ".exe", ".msi", ".dmg", ".deb", ".rpm", ".AppImage",
    ],
}

def organize():
    if not DOWNLOADS.exists():
        print(f"❌ Downloads folder not found: {DOWNLOADS}")
        return

    moved = 0
    for item in DOWNLOADS.iterdir():
        if item.is_dir():
            continue  # Skip existing folders

        ext = item.suffix.lower()
        destination = None

        for folder, extensions in RULES.items():
            if ext in extensions:
                destination = DOWNLOADS / folder
                break

        if destination is None:
            destination = DOWNLOADS / "Other"

        destination.mkdir(exist_ok=True)

        # Handle filename collisions
        target = destination / item.name
        if target.exists():
            stem = item.stem
            counter = 1
            while target.exists():
                target = destination / f"{stem}_{counter}{ext}"
                counter += 1

        shutil.move(str(item), str(target))
        moved += 1
        print(f"  πŸ“¦ {item.name} β†’ {folder if destination else 'Other'}")

    print(f"\nβœ… Done! Organized {moved} file(s).")

if __name__ == "__main__":
    organize()
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. Scan β€” Iterates through every file in ~/Downloads/
  2. Match β€” Checks the file extension against the rules dictionary
  3. Move β€” Creates the target folder if it doesn't exist, then moves the file
  4. Collision handling β€” If a file with the same name already exists, appends _1, _2, etc.

Run It

Save the script as organize_downloads.py and run:

python3 organize_downloads.py
Enter fullscreen mode Exit fullscreen mode

Make it even easier β€” add it as a cron job to run every hour:

crontab -e
# Add this line:
0 * * * * /usr/bin/python3 /home/you/organize_downloads.py
Enter fullscreen mode Exit fullscreen mode

Extending It

The RULES dictionary is easy to customize:

  • Add new categories: Just add a new key with a list of extensions
  • Change where files go: Modify the folder names
  • Add subfolder logic: Split Code/ into Code/Python/, Code/JavaScript/ etc.

Why This Matters

This is one of those "5-minute fix that saves you hours" scripts. It's also a great example of:

  • File I/O with pathlib
  • String operations with file extensions
  • Error handling with mkdir(exist_ok=True) and collision detection
  • Standard library only β€” you don't always need pip install to solve real problems

I use this script daily, alongside 12 other utility scripts in my toolkit. If you want the full collection (a web scraper, email engine, PDF generator, rate limiter, and more), check out the Python Scripts Collection β€” 13 ready-to-run scripts with zero external dependencies.

Happy organizing!

Top comments (0)