# Vault - Project Documentation ## About Resilientní úložiště s redundantní strukturou. Program spravuje 2+ kontejnerů (disk image souborů), které obsahují: - Souborovou strukturu přístupnou přes FUSE mount - Metadata o lokacích ostatních kontejnerů - Informace o verzích - Synchronizované kopie stejného obsahu napříč všemi kontejnery **Klíčový princip:** Aplikace běží jako tray daemon, mountuje vault jako běžnou složku. Uživatel pracuje se svým oblíbeným file managerem (Nautilus, Dolphin, Thunar). Aplikace na pozadí zajišťuje synchronizaci mezi replikami. **Platforma:** Pouze Linux (FUSE mount). Windows/Mac možná později. --- ## Specifikace ### Formát úložiště - **Kontejner:** Raw disk image (.vault) se sparse alokací - **Filesystem:** exFAT (cross-platform, bez 4GB limitu) - **Přípona:** `.vault` - **Velikost:** Uživatel zadá při vytvoření - **Struktura uvnitř:** ``` myvault.vault (sparse soubor) └── [exFAT filesystem] ├── .vault/ │ ├── manifest.json │ └── lock # Lock soubor pro exkluzivní přístup ├── documents/ │ └── file.txt └── photos/ └── image.jpg ``` ### Mount - **Metoda:** udisksctl (loop device + mount, bez root) - **Mount point:** Automatický (udisksctl) nebo uživatelem zvolený - **Exkluzivní přístup:** Lock soubor s fcntl - pouze jedna instance může mít vault otevřený ### Čitelnost bez aplikace (bez Vault app) - `sudo mount -o loop myvault.vault /mnt/vault` ### Resize - Při zaplnění: varování uživateli (notifikace při >90% využití) - Uživatel rozhodne o zvětšení přes GUI dialog ### Umístění kontejnerů - Kdekoli s RW přístupem (různé disky, síťová umístění, USB, cloud) - Každý kontejner obsahuje metadata s cestami k ostatním kontejnerům ### Synchronizace - **Úroveň:** Jednotlivé soubory (NE celé .vault obrazy) - **Interní Python implementace** (bez rsync) - **Hash** (SHA-256) pro detekci změn obsahu - **Timestamp** pro určení master verze (novější vyhrává) - Předpoklad: většinou budou všechny kontejnery dostupné → synchronní zápis - Fallback: při nedostupnosti některého kontejneru se při reconnectu synchronizuje podle timestampu - Chunked copy s progress callbackem pro velké soubory - **Background sync:** Změny se detekují přes inotify/watchdog a propagují automaticky **Jak sync funguje:** 1. Všechny repliky jsou mountnuté současně (každá do jiného temp mount pointu) 2. Uživatel vidí pouze hlavní mount point 3. Při změně souboru → soubor se zkopíruje do všech mountnutých replik 4. Při reconnect nedostupné repliky → porovnání manifestů → kopírování pouze změněných souborů ### GUI - **Framework:** PySide6 - **Typ:** System tray aplikace (daemon) - **Jazyk UI:** Čeština - **Uživatel pracuje:** Se standardním file managerem OS --- ## GUI - System Tray App ### Tray ikona - stavy | Ikona | Stav | |-------|------| | Zelená | Vault otevřen, vše synchronizováno | | Modrá | Synchronizace probíhá | | Žlutá | Některé repliky nedostupné | | Červená | Chyba (vault zaplněn, sync selhala, atd.) | | Šedá | Žádný vault otevřen | ### Tray menu ``` My Vault (3/3 replik online) [status] ──────────────────────────────────── Otevřít složku [otevře mount point v file manageru] ──────────────────────────────────── Vytvořit nový vault... Otevřít vault... Zavřít vault ──────────────────────────────────── Přidat repliku... Spravovat repliky... ──────────────────────────────────── Synchronizovat Zvětšit vault... ──────────────────────────────────── Ukončit ``` ### Dialogy - **Nový vault:** Název, cesta, velikost (s quick buttony 1/5/10/50 GB) - **Otevřít vault:** Výběr .vault souboru - **Spravovat repliky:** Tabulka replik se statusem a tlačítkem pro odebrání - **Zvětšit vault:** Aktuální využití, nová velikost - **Sync progress:** Progress bar, aktuální soubor, log, cancel --- ## Architektura ``` Vault/ ├── Vault.py # Entry point ├── pyproject.toml # Poetry konfigurace ├── src/ │ ├── core/ # Business logika (BEZ UI importů!) │ │ ├── vault.py # Hlavní třída Vault - orchestrace │ │ ├── container.py # Mount/unmount přes udisksctl │ │ ├── image_manager.py # Vytváření/resize sparse .vault souborů │ │ ├── lock.py # Exkluzivní přístup (fcntl) │ │ ├── sync_manager.py # Synchronizace mezi replikami │ │ ├── file_watcher.py # watchdog/inotify pro detekci změn │ │ ├── file_sync.py # Kopírování souborů s progress callback │ │ ├── manifest.py # Metadata - lokace, verze, soubory │ │ └── file_entry.py # Reprezentace souboru (path, hash, timestamp) │ └── ui/ │ ├── tray_app.py # System tray aplikace + menu │ ├── notifications.py # System notifikace (notify-send) │ └── dialogs/ │ ├── new_vault.py │ ├── open_vault.py │ ├── manage_replicas.py │ ├── resize_vault.py │ └── sync_progress.py └── tests/ ├── test_file_entry.py ├── test_manifest.py ├── test_lock.py ├── test_image_manager.py ├── test_container.py ├── test_file_watcher.py ├── test_file_sync.py ├── test_sync_manager.py └── test_vault.py ``` --- ## Metadata struktura (.vault/manifest.json) ```json { "vault_id": "550e8400-e29b-41d4-a716-446655440000", "vault_name": "My Vault", "version": 1, "created": "2026-01-28T10:30:00Z", "last_modified": "2026-01-28T15:45:00Z", "image_size_mb": 10240, "locations": [ { "path": "/mnt/disk1/myvault.vault", "last_seen": "2026-01-28T15:45:00Z", "status": "active" }, { "path": "/mnt/usb/myvault.vault", "last_seen": "2026-01-28T15:45:00Z", "status": "active" } ], "files": [ { "path": "documents/file.txt", "hash": "sha256:e3b0c44...", "size": 1234, "created": "2026-01-28T10:30:00Z", "modified": "2026-01-28T14:20:00Z" } ] } ``` --- ## Závislosti ### Python (Poetry) ``` PySide6>=6.10.1 # GUI framework pyfuse3>=3.4.2 # FUSE binding (nepoužito - udisksctl místo FUSE) watchdog>=6.0.0 # File system events (inotify) loguru>=0.7.3 # Logging python-dotenv>=1.2.1 # Environment variables # Dev pytest>=9.0.2 pytest-cov>=7.0.0 ruff>=0.14.14 mypy>=1.19.1 ``` ### Systémové závislosti (Linux) ```bash sudo apt install udisks2 exfatprogs ``` --- ## Aktuální stav **Fáze 1-5: Dokončeno** - Kompletní core logika (vault, container, image_manager, manifest, file_entry, lock, sync_manager, file_watcher, file_sync) - System tray GUI s menu, notifikacemi, dialogy - Správa replik (přidání, odebrání, tabulka se statusy) - Automatická detekce dostupnosti replik (30s polling) s auto-reconnect - Resize vault přes GUI dialog - Detekce zaplnění s varováním při >90% - Graceful shutdown (SIGINT/SIGTERM) - 130 testů, vše passing - ruff + mypy clean