Skip to content

ujas-dev/filevault

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ—„οΈ FileVault v4.0

Complete file organizer, deduplicator & secure shredder. One engine β€” CLI, YAML config, GUI all call the exact same run_job() function.

Version Python 3.10+ CustomTkinter License: MIT


Architecture

filevault.py          ← THE ENGINE (all logic lives here)
  └── run_job(cfg)    ← single function: CLI, GUI and YAML all call this

filevault_gui.py      ← GUI frontend: builds same cfg dict, calls run_job()
filevault.yaml        ← YAML config: loaded to same cfg dict, runs same engine
plugins/              ← custom rename rule plugins

There is no gap between GUI and CLI. If a feature works in the GUI, it works from CLI and YAML too.


Quick Start

pip install customtkinter blake3 pymupdf pypdf pikepdf
pip install python-docx openpyxl python-pptx Pillow imagehash
pip install watchdog pyyaml piexif

# CLI β€” basic
python filevault.py /source /target

# CLI β€” dry-run, move unique only, no sub-folders
python filevault.py /source /target --dry-run --move-mode unique --no-subfolders

# YAML config
python filevault.py --config filevault.yaml

# GUI (requires display β€” see VNC setup for Docker)
python filevault_gui.py

# Or launch GUI from CLI
python filevault.py --gui

# Watch mode (real-time daemon)
python filevault.py /source /target --watch

# Scheduler β€” daily at 2 AM
python filevault.py /source /target --schedule daily --at 02:00

# Undo last job
python filevault.py --undo

# Windows right-click menu (run as Administrator)
python filevault.py --register-context-menu

CLI Reference

Flag Default Description
source target required Source and target folders
--config FILE β€” Load YAML/JSON config (CLI flags override it)
--dry-run off Preview all actions, zero files touched
--move-mode all all / unique / dupes
--no-subfolders off Dump all files flat in target root
--subfolder-mode unique_dupes unique_dupes / by_type / flat
--passes N 7 Shred overwrite passes
--workers N 8 Parallel hash threads
--no-shred-dupes off Move dupes without shredding source
--shred-all off Shred even unique files after copy
--date-prefix off Prefix images with EXIF date
--no-metadata-rename off Skip smart rename
--quick-scan off Hash first 4MB only (faster)
--plugin-dir DIR β€” Load rename plugins from folder
--watch off Real-time file watcher daemon
--schedule β€” once / daily / interval
--at TIME β€” Time for once/daily e.g. 02:00
--every N 60 Minutes for interval
--undo off Reverse last job from report
--no-json/csv/html off Suppress specific report formats
--register-context-menu β€” Add Windows right-click menu entry
--gui off Launch GUI

Move Modes

Mode What happens Use case
all Move unique + dupes, source fully emptied Full migration
unique Move only unique files, shred dupes in-place, nothing goes to target/duplicates Clean archive
dupes Move only extra copies to target, unique files stay Audit duplicates

Output Folder Structure

Subfolder Mode Result
unique_dupes target/unique/ + target/duplicates/
by_type target/pdf/, target/images/, target/office/, target/other/
flat All files directly in target/, no sub-folders created

Set use_subfolders: false in YAML or --no-subfolders in CLI to skip sub-folder creation entirely.


EXIF Metadata Editor

Applies to image files before copy. Configure in YAML:

exif_edits:
  remove_gps: true              # strip GPS coordinates (privacy)
  remove_device: true           # strip Make/Model/Software
  set_datetime: null            # null = remove all date fields
  set_author: "Your Name"       # set Artist + Copyright
  set_description: null         # null = remove description

Or in GUI: βš™οΈ Configure β†’ πŸ”¬ EXIF Metadata Editor section.


Plugin System

Drop .py files in a folder and point plugin_dir at it:

# plugins/my_rule.py
EXTENSIONS = [".pdf", ".epub"]   # or ["*"] for all

def rename(fp, meta) -> str | None:
    if meta.get("title"):
        return f"[DONE] {meta['title']}{fp.suffix}"
    return None          # None = skip this plugin

Scheduler (YAML)

# One-time
schedule:
  type: once
  at: "2026-03-10 02:00"

# Daily
schedule:
  type: daily
  at: "02:00"

# Every N minutes
schedule:
  type: interval
  every_minutes: 60

Undo

Every job writes filevault_report.json. Undo reads it and reverse-moves everything:

python filevault.py --undo                          # real undo
python filevault.py --undo --dry-run                # preview undo
python filevault.py --undo --config filevault.yaml  # custom report path

GUI: ↩️ Undo tab.


What Makes FileVault Unique

Feature FileVault CCleaner dupeGuru AllDup
Copy integrity gate (verify before shred) βœ… ❌ ❌ ❌
PDF/eBook smart rename from metadata βœ… ❌ ❌ ❌
EXIF metadata editor (strip GPS, date, device) βœ… ❌ ❌ ❌
Plugin system for rename rules βœ… ❌ ❌ ❌
Watch mode daemon βœ… ❌ ❌ ❌
Undo last job βœ… ❌ ❌ ❌
Scheduler (once/daily/interval) βœ… ❌ ❌ ❌
Windows context-menu integration βœ… βœ… ❌ ❌
CLI + YAML + GUI same engine βœ… ❌ ❌ ❌
HTML audit dashboard (offline, shareable) βœ… ❌ ❌ ❌
Photo perceptual hash (survives recompress) βœ… ❌ βœ… βœ…
DoD secure shred (up to 35 passes) βœ… ❌ ❌ ❌
Fully open source βœ… ❌ βœ… ❌

Install (all features)

pip install customtkinter blake3 pymupdf pypdf pikepdf python-docx openpyxl python-pptx
pip install Pillow imagehash watchdog pyyaml piexif

Minimum (no GUI, no smart rename, no perceptual hash):

# Zero extra deps β€” uses stdlib sha256, basic file ops
python filevault.py /source /target

License

MIT

About

Complete file organizer, deduplicator & secure shredder.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages