philiprehberger-file-organizer
Rule-based file sorting engine with pattern matching and dry run support.
Installation
pip install philiprehberger-file-organizer
Usage
from philiprehberger_file_organizer import Organizer, Rule
organizer = Organizer(
rules=[
Rule(extensions=[".pdf", ".doc", ".docx"], destination="~/Documents"),
Rule(extensions=[".jpg", ".png", ".gif"], destination="~/Pictures"),
Rule(extensions=[".mp4", ".mkv"], destination="~/Videos"),
Rule(pattern="invoice_*", destination="~/Documents/Invoices"),
]
)
# Preview what would happen (dry run)
report = organizer.preview("~/Downloads")
for action in report.actions:
print(f"{action.source} -> {action.destination}")
# Execute
report = organizer.organize("~/Downloads")
print(f"Moved {report.total_moved} files ({report.total_size} bytes)")
# Undo
restored = Organizer.undo("~/Downloads")
Testing rules and bulk-adding
Use Rule.matches(path) to evaluate a rule against any path in isolation — handy for unit tests, REPL exploration, or debugging why a file is (or isn't) matched. Name-based checks (extensions, pattern, name_contains) work on any path string without touching disk; size and age filters require the file to exist.
rule = Rule(pattern="invoice_*.pdf", destination="~/Documents/Invoices")
rule.matches("invoice_2026.pdf") # True
rule.matches("photo.jpg") # False
Use Organizer.add_rules([...]) to append rules in bulk. Returns the organizer so calls can be chained.
organizer = Organizer(rules=[])
organizer.add_rules([
Rule(extensions=[".pdf"], destination="~/Documents"),
Rule(extensions=[".jpg", ".png"], destination="~/Pictures"),
]).add_rules([
Rule(pattern="invoice_*", destination="~/Documents/Invoices"),
])
Rule Options
| Option | Description |
|---|---|
extensions |
Match by file extension |
pattern |
Match by glob pattern |
name_contains |
Match if filename contains string |
larger_than |
Minimum file size in bytes |
smaller_than |
Maximum file size in bytes |
older_than_days |
Match files older than N days |
newer_than_days |
Match files newer than N days |
predicate |
Custom matching function |
Move Hooks
Register callbacks that fire after each successful move. Useful for logging, checksums, notifications, or kicking off downstream pipelines without subclassing.
organizer = Organizer(rules=rules)
@organizer.on_move
def log_move(action, rule):
print(f"moved {action.source.name} -> {action.destination} (rule #{action.rule_index})")
Hooks fire only on organize() (not preview()), and only after the file has actually moved. Hook exceptions are captured in report.errors.
Conflict Resolution
organizer = Organizer(rules=rules, conflict="rename") # default: adds (1), (2)...
organizer = Organizer(rules=rules, conflict="skip") # skip existing
organizer = Organizer(rules=rules, conflict="overwrite") # overwrite existing
API
| Function / Class | Description |
|---|---|
Organizer(rules, conflict, recursive) |
Rule-based file organizer with preview(), organize(), and undo() methods |
Organizer.on_move(hook) |
Register a (action, rule) -> None callback fired after each successful move |
Organizer.add_rules(rules) |
Append multiple rules at once; returns the organizer for chaining |
Rule(destination, extensions, pattern, ...) |
A rule that matches files by extension, pattern, size, or age |
Rule.matches(path) |
Return True if the rule matches the given path — useful for testing rules in isolation |
MoveAction |
Describes a planned or executed file move (source, destination, size) |
OrganizeReport |
Result of an organize operation with actions, skipped, errors, total_moved, total_size |
Development
pip install -e .
python -m pytest tests/ -v
Support
If you find this project useful:
License
Metadata
Release files for philiprehberger-file-organizer 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| philiprehberger_file_organizer-0.3.0.tar.gz | 189.7 kB | Without provenance | Details for philiprehberger_file_organizer-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| philiprehberger_file_organizer-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for philiprehberger_file_organizer-0.3.0-py3-none-any.whl |
Total release size: 197.1 kB
Release files / philiprehberger_file_organizer-0.3.0.tar.gz
| Download URL | philiprehberger_file_organizer-0.3.0.tar.gz |
|---|---|
| Size | 189.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dd582200bfa196919ff18d8dc758b22d0f90ab318eb6906d49c6e33082d76233
|
|
BLAKE2b-256 checksum How to use checksums |
21988f81964664d1581ca75eb05e8267e4f638a05b398c6eb5f5db7ae48254e6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / philiprehberger_file_organizer-0.3.0-py3-none-any.whl
| Download URL | philiprehberger_file_organizer-0.3.0-py3-none-any.whl |
|---|---|
| Size | 7.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
66464420e09f12c8758557162473c7193f288e5c7d4fbd762363a75da5d6ccc1
|
|
BLAKE2b-256 checksum How to use checksums |
232aa6477aaa2b5485b5d92b7e1dd9cf052a6a62ed2b738ac50b4b6302831d08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for philiprehberger-file-organizer 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.