{"id":49566200,"url":"https://github.com/ujas-dev/filevault","last_synced_at":"2026-05-03T11:47:47.158Z","repository":{"id":342096327,"uuid":"1172786132","full_name":"ujas-dev/filevault","owner":"ujas-dev","description":"Complete file organizer, deduplicator \u0026 secure shredder.","archived":false,"fork":false,"pushed_at":"2026-03-04T18:21:56.000Z","size":36,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-03T11:47:19.174Z","etag":null,"topics":["automation","cli","deduplication","exif","file-organizer","gui","open-source","pdf-rename","python","secure-delete","watchdog"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ujas-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-04T17:28:28.000Z","updated_at":"2026-03-04T18:21:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ujas-dev/filevault","commit_stats":null,"previous_names":["ujas-dev/filevault"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ujas-dev/filevault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujas-dev%2Ffilevault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujas-dev%2Ffilevault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujas-dev%2Ffilevault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujas-dev%2Ffilevault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ujas-dev","download_url":"https://codeload.github.com/ujas-dev/filevault/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujas-dev%2Ffilevault/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32568036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","cli","deduplication","exif","file-organizer","gui","open-source","pdf-rename","python","secure-delete","watchdog"],"created_at":"2026-05-03T11:47:46.587Z","updated_at":"2026-05-03T11:47:47.145Z","avatar_url":"https://github.com/ujas-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🗄️ FileVault v4.0\n\n\u003e Complete file organizer, deduplicator \u0026 secure shredder.\n\u003e **One engine — CLI, YAML config, GUI all call the exact same `run_job()` function.**\n\n[![Version](https://img.shields.io/badge/version-4.0.0-blue)]()\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue)]()\n[![CustomTkinter](https://img.shields.io/badge/GUI-CustomTkinter-purple)]()\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)]()\n\n---\n\n## Architecture\n\n```\nfilevault.py          ← THE ENGINE (all logic lives here)\n  └── run_job(cfg)    ← single function: CLI, GUI and YAML all call this\n\nfilevault_gui.py      ← GUI frontend: builds same cfg dict, calls run_job()\nfilevault.yaml        ← YAML config: loaded to same cfg dict, runs same engine\nplugins/              ← custom rename rule plugins\n```\n\n**There is no gap between GUI and CLI.** If a feature works in the GUI, it works from CLI and YAML too.\n\n---\n\n## Quick Start\n\n```bash\npip install customtkinter blake3 pymupdf pypdf pikepdf\npip install python-docx openpyxl python-pptx Pillow imagehash\npip install watchdog pyyaml piexif\n\n# CLI — basic\npython filevault.py /source /target\n\n# CLI — dry-run, move unique only, no sub-folders\npython filevault.py /source /target --dry-run --move-mode unique --no-subfolders\n\n# YAML config\npython filevault.py --config filevault.yaml\n\n# GUI (requires display — see VNC setup for Docker)\npython filevault_gui.py\n\n# Or launch GUI from CLI\npython filevault.py --gui\n\n# Watch mode (real-time daemon)\npython filevault.py /source /target --watch\n\n# Scheduler — daily at 2 AM\npython filevault.py /source /target --schedule daily --at 02:00\n\n# Undo last job\npython filevault.py --undo\n\n# Windows right-click menu (run as Administrator)\npython filevault.py --register-context-menu\n```\n\n---\n\n## CLI Reference\n\n| Flag | Default | Description |\n|---|---|---|\n| `source` `target` | required | Source and target folders |\n| `--config FILE` | — | Load YAML/JSON config (CLI flags override it) |\n| `--dry-run` | off | Preview all actions, zero files touched |\n| `--move-mode` | `all` | `all` / `unique` / `dupes` |\n| `--no-subfolders` | off | Dump all files flat in target root |\n| `--subfolder-mode` | `unique_dupes` | `unique_dupes` / `by_type` / `flat` |\n| `--passes N` | 7 | Shred overwrite passes |\n| `--workers N` | 8 | Parallel hash threads |\n| `--no-shred-dupes` | off | Move dupes without shredding source |\n| `--shred-all` | off | Shred even unique files after copy |\n| `--date-prefix` | off | Prefix images with EXIF date |\n| `--no-metadata-rename` | off | Skip smart rename |\n| `--quick-scan` | off | Hash first 4MB only (faster) |\n| `--plugin-dir DIR` | — | Load rename plugins from folder |\n| `--watch` | off | Real-time file watcher daemon |\n| `--schedule` | — | `once` / `daily` / `interval` |\n| `--at TIME` | — | Time for `once`/`daily` e.g. `02:00` |\n| `--every N` | 60 | Minutes for `interval` |\n| `--undo` | off | Reverse last job from report |\n| `--no-json/csv/html` | off | Suppress specific report formats |\n| `--register-context-menu` | — | Add Windows right-click menu entry |\n| `--gui` | off | Launch GUI |\n\n---\n\n## Move Modes\n\n| Mode | What happens | Use case |\n|---|---|---|\n| `all` | Move unique + dupes, source fully emptied | Full migration |\n| `unique` | Move only unique files, shred dupes in-place, nothing goes to target/duplicates | Clean archive |\n| `dupes` | Move only extra copies to target, unique files stay | Audit duplicates |\n\n---\n\n## Output Folder Structure\n\n| Subfolder Mode | Result |\n|---|---|\n| `unique_dupes` | `target/unique/` + `target/duplicates/` |\n| `by_type` | `target/pdf/`, `target/images/`, `target/office/`, `target/other/` |\n| `flat` | All files directly in `target/`, no sub-folders created |\n\nSet `use_subfolders: false` in YAML or `--no-subfolders` in CLI to skip sub-folder creation entirely.\n\n---\n\n## EXIF Metadata Editor\n\nApplies to image files before copy. Configure in YAML:\n\n```yaml\nexif_edits:\n  remove_gps: true              # strip GPS coordinates (privacy)\n  remove_device: true           # strip Make/Model/Software\n  set_datetime: null            # null = remove all date fields\n  set_author: \"Your Name\"       # set Artist + Copyright\n  set_description: null         # null = remove description\n```\n\nOr in GUI: ⚙️ Configure → 🔬 EXIF Metadata Editor section.\n\n---\n\n## Plugin System\n\nDrop `.py` files in a folder and point `plugin_dir` at it:\n\n```python\n# plugins/my_rule.py\nEXTENSIONS = [\".pdf\", \".epub\"]   # or [\"*\"] for all\n\ndef rename(fp, meta) -\u003e str | None:\n    if meta.get(\"title\"):\n        return f\"[DONE] {meta['title']}{fp.suffix}\"\n    return None          # None = skip this plugin\n```\n\n---\n\n## Scheduler (YAML)\n\n```yaml\n# One-time\nschedule:\n  type: once\n  at: \"2026-03-10 02:00\"\n\n# Daily\nschedule:\n  type: daily\n  at: \"02:00\"\n\n# Every N minutes\nschedule:\n  type: interval\n  every_minutes: 60\n```\n\n---\n\n## Undo\n\nEvery job writes `filevault_report.json`. Undo reads it and reverse-moves everything:\n\n```bash\npython filevault.py --undo                          # real undo\npython filevault.py --undo --dry-run                # preview undo\npython filevault.py --undo --config filevault.yaml  # custom report path\n```\n\nGUI: ↩️ Undo tab.\n\n---\n\n## What Makes FileVault Unique\n\n| Feature | FileVault | CCleaner | dupeGuru | AllDup |\n|---|---|---|---|---|\n| Copy integrity gate (verify before shred) | ✅ | ❌ | ❌ | ❌ |\n| PDF/eBook smart rename from metadata | ✅ | ❌ | ❌ | ❌ |\n| EXIF metadata editor (strip GPS, date, device) | ✅ | ❌ | ❌ | ❌ |\n| Plugin system for rename rules | ✅ | ❌ | ❌ | ❌ |\n| Watch mode daemon | ✅ | ❌ | ❌ | ❌ |\n| Undo last job | ✅ | ❌ | ❌ | ❌ |\n| Scheduler (once/daily/interval) | ✅ | ❌ | ❌ | ❌ |\n| Windows context-menu integration | ✅ | ✅ | ❌ | ❌ |\n| CLI + YAML + GUI same engine | ✅ | ❌ | ❌ | ❌ |\n| HTML audit dashboard (offline, shareable) | ✅ | ❌ | ❌ | ❌ |\n| Photo perceptual hash (survives recompress) | ✅ | ❌ | ✅ | ✅ |\n| DoD secure shred (up to 35 passes) | ✅ | ❌ | ❌ | ❌ |\n| Fully open source | ✅ | ❌ | ✅ | ❌ |\n\n---\n\n## Install (all features)\n\n```bash\npip install customtkinter blake3 pymupdf pypdf pikepdf python-docx openpyxl python-pptx\npip install Pillow imagehash watchdog pyyaml piexif\n```\n\nMinimum (no GUI, no smart rename, no perceptual hash):\n\n```bash\n# Zero extra deps — uses stdlib sha256, basic file ops\npython filevault.py /source /target\n```\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fujas-dev%2Ffilevault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fujas-dev%2Ffilevault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fujas-dev%2Ffilevault/lists"}