Smart CLI tool to organize messy directories by file type, date, or size with safety features
Project description
file-organizer
A smart CLI tool to organize messy directories (Downloads, Desktop, etc.) by file type, date, or size — with safety features like dry-run, undo, and configurable ignore patterns.
Features
- Organize by type — Images, Documents, Videos, Audio, Archives, Code, Executables, Spreadsheets, Presentations, Fonts, Data
- Organize by date — Group files by modification date (year-month or year-month-day)
- Organize by size — Small / Medium / Large buckets (configurable thresholds)
- Safety first — Dry-run by default, explicit
--applyto execute,--undoto revert - Configurable — YAML config with custom ignore patterns, size limits, date formats
- Cross-platform — Works on Windows, macOS, Linux
- Rich output — Beautiful tables and progress with
rich - Recursive mode — Organize nested subdirectories with
--recursive - Progress bar — Visual progress during file moves
- Category summary — File count & size per category in dry-run
- Export plan — Save organization plan to JSON for review/scripting
Installation
pipx (recommended)
pipx install file-organizer
pip
pip install file-organizer
From source
git clone https://github.com/OWNER/file-organizer.git
cd file-organizer
pip install -e .
Quick Start
# Preview what would happen (dry-run)
file-organizer organize ~/Downloads --by type
# Actually organize by file type
file-organizer organize ~/Downloads --by type --apply
# Organize by date (year-month folders)
file-organizer organize ~/Downloads --by date --apply
# Organize by size
file-organizer organize ~/Downloads --by size --apply
# Organize recursively (includes subdirectories)
file-organizer organize ~/Downloads --by type --recursive --apply
# Export plan to JSON for review
file-organizer organize ~/Downloads --by type --export-plan plan.json --dry-run
# Skip confirmation prompt
file-organizer organize ~/Downloads --by type --apply -y
# Undo last operation
file-organizer undo
Commands
organize
Organize files in a directory.
file-organizer organize [PATH] [OPTIONS]
Options:
--by, -b Organization mode: type, date, size (default: type)
--apply, -a Actually move files (default: dry-run)
--dry-run Show what would be done without changes
--yes, -y Skip confirmation prompt
--recursive, -r Organize files in subdirectories recursively
--export-plan FILE Export organization plan to JSON file
undo
Revert the last organization operation.
file-organizer undo
config
Manage configuration.
file-organizer config [OPTIONS]
Options:
--show, -s Show current configuration
--set KEY=VALUE Set a configuration value
--reset Reset to default configuration
ignore
Manage ignore patterns.
file-organizer ignore [OPTIONS]
Options:
--add, -a PATTERN Add ignore pattern
--remove, -r PATTERN Remove ignore pattern
--list, -l List ignore patterns
Configuration
Configuration file: ~/.config/file-organizer/config.yaml (Linux/macOS) or %APPDATA%\file-organizer\config.yaml (Windows)
organize:
default_mode: type # type, date, or size
date_format: "%Y-%m" # strftime format for date mode
size_thresholds: # MB thresholds for size mode
small_mb: 1
large_mb: 100
create_subdirs: true # Create category subdirectories
ignore:
patterns: # Glob patterns to ignore
- "*.tmp"
- "*.crdownload"
- "*.part"
- ".DS_Store"
- "Thumbs.db"
hidden_files: true # Ignore hidden files
system_files: true # Ignore system files
safety:
dry_run_by_default: true # Default to dry-run
require_confirmation: false # Ask before applying
max_file_size_mb: 1000 # Skip files larger than this
preserve_timestamps: true # Preserve file timestamps
advanced:
follow_symlinks: false # Follow symbolic links
ignore_errors: false # Continue on errors
log_level: INFO # Logging level
Examples
Set default mode to date:
file-organizer config --set organize.default_mode=date
Add custom ignore pattern:
file-organizer ignore --add "*.bak"
How It Works
- Scan — Reads all files in the target directory (optionally recursive with
--recursive) - Filter — Applies ignore patterns (hidden, system, custom)
- Categorize — Determines destination folder based on mode
- Plan — Creates a move plan with conflict resolution, shows category summary
- Execute — Moves files (only with
--apply), shows progress bar - Log — Saves undo log for reversal
Undo
The last organization is logged to ~/.config/file-organizer/undo_log.json. Run file-organizer undo to move all files back to their original locations.
Development
# Clone and setup
git clone https://github.com/OWNER/file-organizer.git
cd file-organizer
pip install -e ".[dev]"
# Run tests
pytest -v
# Lint
ruff check .
# Type check
mypy src/file_organizer
License
Non-Commercial License — see LICENSE for details.
This software is free for non-commercial use only. Commercial use requires a separate license. Attribution to Blake Nary (thedog737) is required for all uses.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
Made with ❤️ using Python, Typer, and Rich
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file a_file_organizer-0.1.0.tar.gz.
File metadata
- Download URL: a_file_organizer-0.1.0.tar.gz
- Upload date:
- Size: 27.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1db9f2101f4c1a1eb16d6719365ce8bd6d4cc0273221b587cd57f4276300f7fe
|
|
| MD5 |
e1486a8f0d284e2e2da17ff9ecbd0fca
|
|
| BLAKE2b-256 |
8cbbec35c47d9df89e9a7fa3e022cbd48e4d7102550eb6916e7ab7a5b2f8a320
|
Provenance
The following attestation bundles were made for a_file_organizer-0.1.0.tar.gz:
Publisher:
ci.yml on thedog737/file-organizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
a_file_organizer-0.1.0.tar.gz -
Subject digest:
1db9f2101f4c1a1eb16d6719365ce8bd6d4cc0273221b587cd57f4276300f7fe - Sigstore transparency entry: 1742961623
- Sigstore integration time:
-
Permalink:
thedog737/file-organizer@8d33e990653716161e71854ab17215996b44d7f0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/thedog737
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@8d33e990653716161e71854ab17215996b44d7f0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file a_file_organizer-0.1.0-py3-none-any.whl.
File metadata
- Download URL: a_file_organizer-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d359d81aaa473eb004b5316ec75ebea5ada980552b7c1f4030c8e861c4e14bc6
|
|
| MD5 |
824283cad85210211fa0d351c8254fd6
|
|
| BLAKE2b-256 |
beb5ec85ecd01696d60d1dcbb35ad60ecab27ea48254be0a4c2a0114389efcbf
|
Provenance
The following attestation bundles were made for a_file_organizer-0.1.0-py3-none-any.whl:
Publisher:
ci.yml on thedog737/file-organizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
a_file_organizer-0.1.0-py3-none-any.whl -
Subject digest:
d359d81aaa473eb004b5316ec75ebea5ada980552b7c1f4030c8e861c4e14bc6 - Sigstore transparency entry: 1742961828
- Sigstore integration time:
-
Permalink:
thedog737/file-organizer@8d33e990653716161e71854ab17215996b44d7f0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/thedog737
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@8d33e990653716161e71854ab17215996b44d7f0 -
Trigger Event:
push
-
Statement type: