Jamie Software Lab
Projects / CLI File Organiser
Python CLI argparse Automation

CLI File Organiser

Point it at a messy directory and it sorts files into folders by type (images, documents, video, etc.) or by date. Supports dry-run preview, undo, custom rules via config, and full logging.

Status Active
Install pip install
Dependencies Zero (stdlib only)
Platform Windows / macOS / Linux

Demo

Terminal output from a real run on a messy Downloads folder.

zsh : ~/Downloads
$ tidyfiles --dry-run ~/Downloads [DRY RUN] Scanning 47 files in ~/Downloads… report_Q4.pdf → Documents/report_Q4.pdf IMG_2847.jpg → Images/IMG_2847.jpg IMG_2848.png → Images/IMG_2848.png setup.exe → Programs/setup.exe budget.xlsx → Documents/budget.xlsx lecture_notes.docx → Documents/lecture_notes.docx podcast_ep12.mp3 → Audio/podcast_ep12.mp3 holiday.mp4 → Video/holiday.mp4 archive.zip → Archives/archive.zip data.csv → Data/data.csv …and 37 more ✓ 47 files would be moved into 7 folders No files modified (dry run) $ tidyfiles ~/Downloads Scanning 47 files in ~/Downloads… ✓ 47 files moved into 7 folders Undo log saved to .tidyfiles_undo.json $ tidyfiles --undo ~/Downloads ✓ 47 files restored to original locations

Install & run

terminal
$ pip install tidyfiles $ tidyfiles --help usage: tidyfiles [-h] [--dry-run] [--undo] [--by {type,date}] [--config CONFIG] [--verbose] path Organise files in a directory by type or date. positional arguments: path Directory to organise options: -h, --help show this help message and exit --dry-run Preview changes without moving files --undo Reverse the last organise operation --by {type,date} Sort by file type (default) or modified date --config CONFIG Path to custom rules JSON file --verbose, -v Show detailed output

Custom rules

Drop a JSON config to override the default mappings.

{ "rules": { "Documents": [".pdf", ".docx", ".xlsx", ".pptx", ".txt", ".md"], "Images": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"], "Video": [".mp4", ".mkv", ".mov", ".avi", ".webm"], "Audio": [".mp3", ".wav", ".flac", ".m4a", ".ogg"], "Archives": [".zip", ".tar", ".gz", ".rar", ".7z"], "Code": [".py", ".js", ".ts", ".html", ".css", ".json"], "Data": [".csv", ".json", ".xml", ".sql", ".db"] }, "ignore": [".DS_Store", "Thumbs.db", ".gitkeep"], "default_folder": "Other" }

Features

Dry run
Preview every move before it happens. Nothing touches disk until you're sure.
Undo
Every run saves a JSON undo log. One command reverses everything.
Sort by type or date
Group by extension (Images, Documents…) or by modified-date (2025-01, 2025-02…).
Custom rules
JSON config overrides the defaults. Map any extension to any folder name.
Conflict handling
If a file already exists at the target, appends _1, _2, etc. No overwrites.
Zero dependencies
Pure Python stdlib: argparse, pathlib, json, shutil, logging. Nothing to install.

How it works

Simple pipeline, no surprises.

Parse args
argparse handles --dry-run, --undo, --by, --config, --verbose, and the target path.
Load rules
Default type→folder map merged with custom config JSON. Ignore list filters system files.
Plan moves
Walk directory, match each file's extension to a folder. Handle conflicts with numeric suffixes.
Execute / preview
Dry-run prints the plan. Normal run moves files and saves an undo log as JSON.

Decisions

The tradeoffs that keep it useful.

argparse over click

Zero dependencies is a hard constraint. argparse is in the stdlib and handles subcommands, types, and help text without any pip install.

JSON undo log

Every move is recorded as {"from": ..., "to": ...}. The undo command reads this file and reverses each move. Simple, auditable, human-readable.

Config-driven rules

Hardcoded defaults cover 90% of use cases. The config file lets users override without touching the source code : separation of data and logic.

Next steps

Planned improvements, kept realistic.

  • Watch mode: monitor a directory and auto-organise new files as they appear.
  • Recursive mode for nested subdirectories.
  • PyPI publish with proper setuptools/pyproject.toml packaging.
  • Test suite with pytest and temporary directory fixtures.