# FotkyBuzalkovi — kontext pro import do nové konverzace > Přečti tento soubor na začátku konverzace. Obsahuje vše potřebné pro navázání bez opakování. --- ## Co je projekt Systém pro zálohu, organizaci a tagování ~200 000 rodinných fotek. Lokální provoz, bez webových uživatelů. Rodina vlastní Nikon D80, naposledy foceno Vánoce 2025. --- ## Infrastruktura | Server | IP | Hostname | Role | |---------|---------------|----------|------| | tower | 192.168.1.76 | `tower` | hlavní NAS (Unraid), spouští skripty | | tower1 | 192.168.1.50 | `Tower1` | archivní NAS (Unraid), fyzická záloha fotek | **SSH:** root přístupy — tower: `root/7309208104`, tower1: `root/Vlado7309208104++` **SSH klíče:** sdílené mezi tower a tower1. **PostgreSQL:** `192.168.1.76:5432`, user `vladimir.buzalka`, heslo `Vlado7309208104++`, DB `fotky_buzalkovi` **Záloha fotek:** vždy fyzicky na Tower1 → `/mnt/user/ZalohaVsechObrazku` - Z tower přes NFS: `/mnt/remotes/TOWER1.LAN_ZalohaVsechObrazku` - Z Windows PC přes UNC: `\\Tower1\ZalohaVsechObrazku` --- ## Klíčová architektonická rozhodnutí - **Databáze:** pouze PostgreSQL + filesystem (MongoDB a Redis vyřazeny) - **Identita fotky:** 3 úrovně hashů — `sha256_file` (byte), `sha256_pixels` (pixely), `phash` (vizuální podobnost). BLAKE3 pro deduplikaci zálohy. - **EXIF parser:** ExifRead je primární (Pillow má GPS bug) - **Embedding** (CLIP/pgvector) — odloženo na později --- ## DB tabulky v fotky_buzalkovi ### Skupina 1: Zpracovaná metadata fotek - `photos` — naparsované EXIF/IPTC/XMP, hashe, rozměry, GPS. Sloupec `zaloha_id` → FK na `zaloha_obrazku`. - `tags`, `photo_tags` — tagování ### Skupina 2: Zálohovací pipeline (vytvořeno 2026-05-24) ```sql zaloha_obrazku id SERIAL PK, blake3_hash VARCHAR(64) UNIQUE, cesta_zalohy TEXT, nazev_souboru VARCHAR(512), velikost BIGINT, datum_kopirovani TIMESTAMP zdrojove_soubory id SERIAL PK, hostname VARCHAR(255), cesta_zdroje TEXT, nazev_souboru VARCHAR(512), velikost BIGINT, datum_nalezeni TIMESTAMP, blake3_hash VARCHAR(64), zaloha_id INTEGER → FK zaloha_obrazku(id) UNIQUE(hostname, cesta_zdroje) ``` ### Propojení (vytvořeno 2026-05-26) `photos.zaloha_id` → `zaloha_obrazku.id` — každá zpracovaná fotka v `photos` je svázána se zdrojovou zálohou. Resume importu funguje přes LEFT JOIN na tomto sloupci. --- ## Zálohovací skripty ### Linux — servery (Unraid) **Soubor:** `00 PictureCollector/collect_pictures.py` **Nasazen jako Unraid User Script "CollectPictures" na obou serverech:** - `/boot/config/plugins/user.scripts/scripts/CollectPictures/` **Logika:** 1. Skenuje `/mnt/user/` rekurzivně 2. Přeskočí adresáře v `EXCLUDED_DIR_NAMES` (case-insensitive): `ZalohaVsechObrazku`, `ZalohaVšechObrázků` 3. Pro každý JPG/JPEG spočítá BLAKE3 hash 4. Nový hash → zkopíruje do zálohy + zapíše do obou tabulek 5. Duplikát → jen zapíše do `zdrojove_soubory`, nekopíruje 6. Bezpečné pro opakované spuštění — přeskočí soubory již v DB **ZALOHA_DIR podle hostname (automaticky):** ```python "Tower1" → /mnt/user/ZalohaVsechObrazku # lokální "tower" → /mnt/remotes/TOWER1.LAN_ZalohaVsechObrazku # NFS ``` **Cesta zálohy:** `ZalohaVsechObrazku/{hostname}/Foto/2023/img.jpg` **Závislosti:** `blake3`, `psycopg2-binary` — nainstalováno na obou serverech 2026-05-24. --- ### Windows — libovolný PC v síti **Soubor:** `00 PictureCollector/collect_pictures_windows.py` **Rozdíly:** - Skenuje všechny `DRIVE_FIXED` disky (ne síťové, ne CD) — detekce přes `ctypes` - Záloha přes UNC: `\\Tower1\ZalohaVsechObrazku` - Cesta zálohy: `ZalohaVsechObrazku\{hostname}\{disk}\cesta` (např. `…\JMENO-PC\D\Foto\img.jpg`) - Navíc přeskakuje: `C:\Windows`, `$Recycle.Bin`, `System Volume Information`, `Recovery` - Instalace: `pip install blake3 psycopg2-binary` --- ## Pomocné skripty (Windows, lokálně v 00 PictureCollector\) | Soubor | Účel | |--------|------| | `ssh_deploy.py` | Nasadí skript na tower | | `ssh_deploy_tower1.py` | Nasadí skript na Tower1 | | `stats.py` | Statistiky zálohy z DB (počty, velikosti, per hostname) | | `create_tables.py` | Vytvoří tabulky v DB | | `verify_tables.py` | Ověří strukturu tabulek | | `clear_tables.py` | TRUNCATE obou tabulek (pozor!) | --- ## Stav k 2026-05-25 - collect_pictures.py běží na tower (probíhá, 100TB NAS) — k 2026-05-25 ráno: 54 GB / 36 598 unikátních souborů - Tower1 spuštěn, přidal 104 souborů - Windows skript připraven, zatím nespuštěn na žádném PC ## Stav k 2026-05-26 - `zaloha_obrazku` má 1 502 539 záznamů, `zdrojove_soubory` 2 192 650 - Tabulka `photos` vyprázdněna (původně 85 833 testovacích záznamů z filesystémového skenu) - Přidán sloupec `photos.zaloha_id` (FK → `zaloha_obrazku.id`) pro propojení tabulek - Nový skript `30 SběrDat/collect_and_import.py` čte z `zaloha_obrazku`, zpracuje metadata a ukládá přímo do `photos` (bez mezilehlého JSONL). Resume přes `zaloha_id`. Překlad cesty: `/mnt/remotes/TOWER1.LAN_ZalohaVsechObrazku/...` → `//Tower1/ZalohaVsechObrazku/...` - Starší skripty `10_collect_metadata.py` + `import_to_db.py` zůstávají jako reference, ale produkce běží přes `collect_and_import.py`. --- ## Zpracování metadat (Skupina 1) **Soubor:** `30 SběrDat/collect_and_import.py` **Spuštění (Windows, lokální .venv):** ``` .\.venv\Scripts\python.exe "30 SběrDat\collect_and_import.py" --workers 4 ``` **Co dělá:** 1. Načte z `zaloha_obrazku` jen záznamy bez odpovídajícího řádku v `photos` (LEFT JOIN přes `zaloha_id`) 2. Pro každou cestu přeloží Linux NFS → Windows UNC 3. Spočítá: SHA-256 souboru i pixelů, pHash, dHash, EXIF (ExifRead), IPTC, XMP, GPS, rozměry 4. Vloží do `photos` po dávkách s `ON CONFLICT (sha256_file) DO NOTHING` (per-batch commit) 5. Resume = bezpečné, znovuspuštění pokračuje kde skončilo **Argumenty:** `--workers N`, `--batch-size N`, `--limit N`, `--dry-run` **Závislosti:** psycopg2, python-dotenv, exifread, imagehash, Pillow --- ## Otevřené otázky 1. Co s "sirotky" bez EXIF — importovat s mtime / odmítnout / označit? 2. Při shodě `sha256_pixels` — přeskočit / sloučit metadata / uložit oba jako související? 3. Storage layout — nechat in-place / `archiv/YYYY/MM/` / content-addressable? 4. Navázat prací s daty až doběhnou servery — EXIF analýza, podobné fotky, organizace, prohlížeč