Skip to content

mbidjiev/file-sorter-win

Repository files navigation

Desktop File Sorter

Background application for Windows that automatically sorts new files appearing on your Desktop or in the Downloads folder into configurable target directories. Runs silently, uses near-zero CPU when idle, and logs every move.

Includes a GUI control panel (File Sorter Manager.exe) with config editor, live log viewer, and process management — with English / Russian localization.

Supported Windows Versions

Edition Versions
Windows 11 21H2, 22H2, 23H2, 24H2 — all editions (Home, Pro, Enterprise)
Windows 10 1607 through 22H2 — all editions
Windows Server 2016, 2019, 2022, 2025

Works on any Windows release that supports Python 3.8+ and NTFS. The underlying ReadDirectoryChangesW WinAPI used by watchdog has been present since Windows 2000, so even older builds are supported in practice.

Requirements

  • Python 3.8+python.org
    • Make sure Add Python to PATH is checked during installation
  • pip — included with Python

Everything else is installed automatically by install.bat.

Quick Start

  1. Edit config.json or use GUI (File Sorter Manager.exe) — set your watch directories, target folders, and rules via GUI or any text editor.
  2. Run install.bat (as Administrator recommended) — installs dependencies, saves Python path, and creates a Task Scheduler job
  3. Reboot or log out/in — the sorter starts automatically
  4. To start immediately without reboot: run restart.bat or click Start in the GUI

After that the sorter runs silently in the background. Drop a file on the Desktop and it moves to the configured folder within seconds.

GUI Control Panel

Launch File Sorter Manager.exe (built from gui.py via build_exe.bat).

The GUI is a standalone control panel — it does NOT need to run alongside the sorter. It provides:

  • Config editor — edit watch directories, rules, unsorted path, ignore patterns, and settings with Browse buttons for folder selection
  • Live log viewer — tail the latest log file with color-coded levels (ERROR/WARNING/INFO/DEBUG), auto-refresh
  • Process management — Start / Stop / Restart buttons with live status
  • Validation — check config for errors before saving
  • Localization — toggle between English and Russian (button in sidebar)

All changes are written directly to config.json. The sorter reads the config fresh on every launch — no restart needed if it's already running (just toggle Restart).

Configuration — config.json

All settings are in a single file. Changing the config and restarting the sorter applies changes immediately.

Top-level options

Key Type Default Description
watch_directories list[str] required Folders to monitor for new files
unsorted_directory str required Where files with no matching rule go
rules dict[str,str] required Pattern → destination mappings
debounce_seconds float 2.0 Delay after last write before moving
log_file str "file_sorter.log" Base path for log files
max_log_files int 20 How many old log files to keep (cleanup on startup)
quiet bool true If true, suppress console output
sort_existing_on_start bool true Process pre-existing files at startup
debug bool false Enable debug-level messages in log files
ignore_patterns list[str] see below Files matching these patterns are never moved

%VARIABLE% expansion

All paths support environment variables:

  • %USERNAME% — current user name
  • %USERPROFILE% — e.g. C:\Users\John
  • %HOMEPATH%, %APPDATA%, %LOCALAPPDATA%, etc.

Rules syntax

Each rule maps a pattern to a destination directory. Multiple patterns can be grouped with commas in a single key:

"rules": {
    ".pdf":                              "C:/Users/%USERNAME%/Documents/PDF",
    ".doc,.docx":                        "C:/Users/%USERNAME%/Documents/Word",
    ".jpg,.jpeg,.png,.gif,.bmp,.svg,.webp": "C:/Users/%USERNAME%/Pictures",
    ".zip,.rar,.7z,.tar,.gz":            "C:/Users/%USERNAME%/Downloads/Archives",
    "setup*.exe,installer*.msi":         "C:/Users/%USERNAME%/Downloads/Installers"
}

Supported pattern types:

Pattern Example Matches
Exact extension .pdf Any file ending in .pdf (case-insensitive)
Glob pattern Screenshot* Screenshot 2024-01-01.png, Screenshot_new.jpg
Glob pattern Report-202?-*.xlsx Report-2024-01.xlsx, Report-2025-12.xlsx
Comma-separated .jpg,.png,.gif Any of the three extensions → same folder

Matching priority: Rules are checked in the order they appear in config.json — the first match wins. Place specific patterns (e.g. eie-*.tar) before general ones (e.g. .tar).

Files that match no rule are moved to unsorted_directory.

Date-based path tokens

Destinations can include dynamic tokens for date-based subdirectories:

".log": "C:/Users/%USERNAME%/logs/{created:%Y-%m-%d}",
"screenshot*": "C:/Pictures/screenshots/{modified:%Y-%m}"
Token Example value
{created:%Y-%m-%d} 2025-07-02
{modified:%Y-%m} 2025-07
{created:%Y} 2025

Uses strftime format codes. created reads st_ctime (creation time on Windows). modified reads st_mtime.

Ignore patterns

Files matching these patterns are never processed — no logging, no move:

"ignore_patterns": [
    "~$*",           // Office temp files
    "*.crdownload",  // Chrome partial downloads
    "*.tmp",         // Temporary files
    "*.part",        // Firefox/IE partial downloads
    "*.partial",     // Edge partial downloads
    "*.lnk",         // Desktop shortcuts
    "*.url",         // Internet shortcuts
    "desktop.ini",   // System file
    "Thumbs.db"      // System file
]

Example: full configuration

{
    "watch_directories": [
        "C:/Users/%USERNAME%/Desktop",
        "C:/Users/%USERNAME%/Downloads"
    ],
    "unsorted_directory": "C:/Users/%USERNAME%/Desktop/Unsorted",
    "debounce_seconds": 4.0,
    "log_file": "C:/Users/%USERNAME%/Desktop/file_sorter.log",
    "max_log_files": 20,
    "quiet": true,
    "debug": false,
    "sort_existing_on_start": true,
    "ignore_patterns": [
        "~$*",
        "*.crdownload",
        "*.tmp",
        "*.part",
        "*.partial",
        "*.lnk",
        "*.url",
        "desktop.ini",
        "Thumbs.db"
    ],
    "rules": {
        ".pdf,.doc,.docx,.xls,.xlsx":     "C:/Users/%USERNAME%/Documents",
        ".jpg,.jpeg,.png,.gif,.bmp,.svg,.webp": "C:/Users/%USERNAME%/Pictures",
        ".mp3,.wav,.flac":                 "C:/Users/%USERNAME%/Music",
        ".mp4,.mkv,.avi,.mov":             "C:/Users/%USERNAME%/Videos",
        ".zip,.rar,.7z,.tar,.gz":          "C:/Users/%USERNAME%/Downloads/Archives",
        ".exe,.msi":                       "C:/Users/%USERNAME%/Downloads/Installers",
        ".iso":                            "C:/Users/%USERNAME%/Downloads/ISOs",
        ".torrent":                        "C:/Users/%USERNAME%/Downloads/Torrents"
    }
}

Project Files

File Purpose
file_sorter.py Main engine — monitors folders, matches rules, moves files
gui.py GUI control panel source (Tkinter)
File Sorter Manager.exe Compiled GUI (built via build_exe.bat)
config.json All settings and rules
install.bat First-time setup: installs dependencies + creates Task Scheduler job
uninstall.bat Removes the Task Scheduler job
start.bat Starts the sorter in background
stop.bat Stops any running sorter instance
restart.bat Stops + starts the sorter
run_silent.vbs VBScript launcher — starts Python without a console window
run_debug.bat Starts the sorter with a visible console (for troubleshooting)
build_exe.bat Builds File Sorter Manager.exe from gui.py using PyInstaller
requirements.txt Python dependency: watchdog>=3.0
.gitignore Excludes auto-generated files from version control
.runtime/ Auto-generated at runtime: lock file, PID file, Python path cache

Usage

Start

start.bat

Or: wscript.exe run_silent.vbs

Stop

stop.bat

Restart (apply config changes)

restart.bat

Check logs

The log file location is set in config.json under log_file. Each sorter launch creates a new timestamped log file: file_sorter-2025-07-02-14-30-05.log. Old logs are kept — the oldest ones are cleaned up, keeping at most max_log_files (default 20).

Logs can also be viewed live in the GUI (Logs tab).

Apply config changes

  1. Edit config.json (text editor or GUI)
  2. Run restart.bat (or click Restart in the GUI)

The sorter reads the config fresh on every launch.

Debug mode

Set "debug": true in config.json to include [DEBUG] messages in log files (every file detection, every retry attempt, etc). Toggle in the GUI via the Debug mode checkbox.

Troubleshooting startup

If the sorter doesn't start after reboot:

  1. Run run_debug.bat — shows the console with all error messages
  2. Common issues: Python not in PATH, watchdog not installed, invalid config

How It Works

  1. File system monitoring — uses Python's watchdog library, which wraps the native Windows ReadDirectoryChangesW API. No polling — the OS notifies the process only when filesystem events occur. CPU usage when idle: effectively zero.

  2. Debouncing — when a file appears, the script waits debounce_seconds before acting. Each subsequent write to the same file resets the timer. This prevents moving files that are still being downloaded or written.

  3. Rule matching — rules are checked in the order they appear in config.json. First match wins. Extension patterns (starting with .) are compared to the file's extension. Glob patterns are matched via fnmatch. Place specific patterns before general ones for correct prioritization.

  4. Move with retry — if a file is locked by another process (antivirus, still-open handle), the script retries with exponential backoff up to 20 times (~30 sec total).

  5. Name collision handling — if report.pdf already exists in the destination, the file is saved as report (1).pdf, report (2).pdf, etc.

  6. Logging — every successful move is logged at INFO level. A new timestamped log file is created per launch. Old log files are cleaned up automatically, keeping the most recent N (configurable via max_log_files).

  7. Single-instance lock — only one sorter process can run at a time. A mutex lock in .runtime/sorter.lock prevents accidental duplicates.

Directory Auto-Creation

When the sorter starts, it ensures all target directories from rules and unsorted_directory exist — creating parent directories as needed. It also creates directories on-demand when moving files, as a safety net.

What Is Ignored

  • Directories — only files are ever moved
  • Temporary/in-progress downloads*.crdownload, *.tmp, *.part, *.partial
  • Shortcuts*.lnk, *.url
  • System filesdesktop.ini, Thumbs.db
  • Office lock files~$*
  • Any pattern manually added to ignore_patterns

Troubleshooting

Problem Solution
Sorter doesn't start after reboot Run run_debug.bat to see errors. Check Task Scheduler → Desktop File Sorter → History
Files appear but aren't moved Check ignore_patterns in config; check the log file
"ModuleNotFoundError: No module named 'watchdog'" Run pip install -r requirements.txt as Administrator
"Permission denied" in logs Target folder may require admin rights; adjust paths in config
Task Scheduler says "Access denied" Run install.bat as Administrator
Sorter moves file too early (download not finished) Increase debounce_seconds to 5–10 seconds
"Another instance is already running" A sorter process is already active. Run stop.bat then start.bat

Uninstall

Run uninstall.bat — removes the Task Scheduler job. The script files (config, logs, Python files) are not deleted; delete the project folder manually if needed.

About

File sorter for Windows, that runs on background. Fully configurable with GUI & config file, uses near-zero CPU/RAM when idle and logs EVERY move!

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors