notebookVb
This commit is contained in:
@@ -1,153 +1,98 @@
|
||||
# FotkyBuzalkovi
|
||||
|
||||
Systém pro zpracování, ukládání a vyhledávání rodinných fotografií s automatickou extrakcí EXIF metadat.
|
||||
Systém pro organizaci a tagování ~200 000 rodinných fotek. Lokální nasazení, bez cloudu.
|
||||
|
||||
## Architektura
|
||||
## Kde jsme
|
||||
|
||||
Projekt používá kombinaci tří databází, kde každá řeší specifickou úlohu:
|
||||
- **85 833 fotek** zpracovaných v DB (EXIF, hashe, metadata)
|
||||
- **39 961 unikátních souborů** fyzicky zálohovaných na Tower1
|
||||
- Sběr fotek běží ze dvou serverů (tower, Tower1) i z Windows PC
|
||||
- Průzkumný Streamlit dashboard hotový (`run_webreport.py`)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Python aplikace │
|
||||
│ (zpracování fotek, EXIF, hash) │
|
||||
└────────────┬──────────────┬──────────────┬───────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌────────────┐ ┌────────────┐ ┌────────────┐
|
||||
│ PostgreSQL │ │ MongoDB │ │ Redis │
|
||||
│ (relační) │ │ (EXIF/doc) │ │ (cache) │
|
||||
└────────────┘ └────────────┘ └────────────┘
|
||||
192.168.1.76 192.168.1.76 localhost
|
||||
:5432 :27017 :6379
|
||||
```
|
||||
## Stack
|
||||
|
||||
### Proč tři databáze?
|
||||
|
||||
| Databáze | Role | Co ukládá |
|
||||
|----------|------|-----------|
|
||||
| **PostgreSQL** | Strukturovaná data, relace | `photos`, `cameras`, `photo_tags` - ID, cesty, hashe, FK |
|
||||
| **MongoDB** | Flexibilní dokumenty | Plná EXIF metadata (různé fotoaparáty = různá pole) |
|
||||
| **Redis** | Cache + fronty | Miniatury, výsledky vyhledávání, fronta zpracování |
|
||||
|
||||
## Datové úložiště
|
||||
|
||||
### PostgreSQL - `fotky_buzalkovi`
|
||||
|
||||
- **cameras** - seznam fotoaparátů (model, vyrobce)
|
||||
- **photos** - hlavní tabulka (file_name, file_path, file_hash, taken_at, rozměry, FK na camera)
|
||||
- **photo_tags** - tagy ke každé fotce (many-to-many)
|
||||
|
||||
### MongoDB - `fotky_buzalkovi`
|
||||
|
||||
- **photos** kolekce - kompletní EXIF data, GPS souřadnice, nastavení clony, ISO, atd.
|
||||
|
||||
### Redis (plánováno)
|
||||
|
||||
- **cache:thumb:{photo_id}** - cached miniatury (TTL 1h)
|
||||
- **queue:process** - fronta nezpracovaných fotek
|
||||
- **session:{user_id}** - session data
|
||||
|
||||
## K čemu Redis
|
||||
|
||||
1. **Cache miniatur** - generování miniatur je drahé, Redis je drží v RAM (rychlost ~0.1ms vs ~50ms z disku)
|
||||
2. **Cache vyhledávání** - "fotky z dovolené 2025" se může opakovat, výsledek se cachuje
|
||||
3. **Fronta zpracování** - když nahrajete 1000 fotek, Redis funguje jako worker queue
|
||||
4. **Deduplikace** - rychlá kontrola, zda hash fotky už existuje
|
||||
5. **Rate limiting** - omezení uploadů
|
||||
|
||||
## Instalace
|
||||
|
||||
### 1. Python prostředí
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\Activate.ps1
|
||||
pip install psycopg2-binary pymongo redis pillow exifread python-dotenv
|
||||
```
|
||||
|
||||
### 2. PostgreSQL
|
||||
|
||||
Předpoklad: PostgreSQL běží na `192.168.1.76:5432`.
|
||||
|
||||
```powershell
|
||||
python create_schema.py
|
||||
```
|
||||
|
||||
### 3. MongoDB
|
||||
|
||||
Předpoklad: MongoDB běží na `192.168.1.76:27017`.
|
||||
|
||||
```powershell
|
||||
python test_mongo.py
|
||||
```
|
||||
|
||||
### 4. Redis (Windows)
|
||||
|
||||
Redis oficiálně Windows nepodporuje. Tři možnosti:
|
||||
|
||||
**Možnost A - WSL2 (doporučeno):**
|
||||
```powershell
|
||||
wsl --install
|
||||
# v WSL:
|
||||
sudo apt update
|
||||
sudo apt install redis-server
|
||||
sudo service redis-server start
|
||||
```
|
||||
|
||||
**Možnost B - Docker:**
|
||||
```powershell
|
||||
docker run -d --name redis -p 6379:6379 redis:latest
|
||||
```
|
||||
|
||||
**Možnost C - Memurai (Windows-native Redis-kompatibilní):**
|
||||
- Stáhnout z https://www.memurai.com/
|
||||
|
||||
Test:
|
||||
```powershell
|
||||
python test_db_connection.py
|
||||
```
|
||||
|
||||
## Konfigurace
|
||||
|
||||
**⚠️ Hesla v současných skriptech jsou v plain textu - před nasazením přesunout do `.env`:**
|
||||
|
||||
```env
|
||||
PG_HOST=192.168.1.76
|
||||
PG_PORT=5432
|
||||
PG_USER=vladimir.buzalka
|
||||
PG_PASSWORD=...
|
||||
PG_DB=fotky_buzalkovi
|
||||
|
||||
MONGO_URI=mongodb://192.168.1.76:27017/
|
||||
MONGO_DB=fotky_buzalkovi
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
```
|
||||
- **PostgreSQL** (192.168.1.76:5432) — jediná databáze, JSONB nahrazuje MongoDB
|
||||
- **Filesystem** — fotky zůstávají na disku, v DB jen cesty a metadata
|
||||
- **Python** — veškeré skripty (ExifRead pro EXIF, imagehash pro pHash, blake3 pro zálohy)
|
||||
|
||||
## Struktura projektu
|
||||
|
||||
```
|
||||
FotkyBuzalkovi/
|
||||
├── demo_fotky/ # Testovací fotografie
|
||||
├── create_schema.py # Vytvoření PostgreSQL schématu
|
||||
├── test_db_connection.py # Test všech tří databází
|
||||
├── test_mongo.py # Test MongoDB + vytvoření kolekcí
|
||||
├── 00 PictureCollector/ # Sběr fotek ze všech počítačů na Tower1
|
||||
│ ├── collect_pictures.py # Hlavní skript (Linux, běží na tower + Tower1)
|
||||
│ ├── collect_pictures_windows.py # Windows verze (pro libovolný PC v síti)
|
||||
│ ├── create_tables.py # Vytvoření tabulek zaloha_obrazku + zdrojove_soubory
|
||||
│ ├── verify_tables.py # Ověření struktury tabulek
|
||||
│ ├── clear_tables.py # TRUNCATE obou tabulek (pozor!)
|
||||
│ ├── stats.py # Statistiky sběru
|
||||
│ ├── ssh_deploy.py # Nasazení skriptu na tower
|
||||
│ ├── ssh_deploy_tower1.py # Nasazení skriptu na Tower1
|
||||
│ ├── ssh_install_deps.py # Instalace závislostí na tower
|
||||
│ ├── ssh_install_tower1.py # Instalace závislostí na Tower1
|
||||
│ ├── ssh_check_mount.py # Kontrola NFS mountu
|
||||
│ ├── ssh_check_tower1.py # Kontrola Tower1
|
||||
│ └── ssh_find_userscripts.py # Hledání Unraid user scriptů
|
||||
│
|
||||
├── 20 PrůzkumFotek/ # Průzkum a vizualizace dat
|
||||
│ ├── report.py # Streamlit dashboard (spouštět přes run_webreport.py)
|
||||
│ └── analyze_all.py # Konzolová analýza (jednorázová)
|
||||
│
|
||||
├── 30 SběrDat/ # Zpracování fotek — EXIF parsing, import do DB
|
||||
│ ├── explore_photos.py # Explorační skript (hashe, EXIF, IPTC, XMP)
|
||||
│ ├── 10_collect_metadata.py # Sběr metadat z fotek
|
||||
│ ├── import_to_db.py # Import do tabulky photos
|
||||
│ ├── create_schema.py # Vytvoření tabulek photos/tags/photo_tags
|
||||
│ └── photo_exploration.json # Výstup exploreru (7 demo fotek)
|
||||
│
|
||||
├── demo_fotky/ # 7 testovacích fotek (iPhone, screenshot, sirotek)
|
||||
├── output/ # Výstupy skriptů
|
||||
│ └── 10_metadata.jsonl # Nasbíraná metadata
|
||||
├── trash/ # Zastaralé skripty (test_mongo.py, test_db_connection.py)
|
||||
│
|
||||
├── run_webreport.py # Spustí Streamlit dashboard (1 klik v PyCharm)
|
||||
├── .env # Konfigurace (hesla)
|
||||
├── .gitignore
|
||||
└── README.md
|
||||
│
|
||||
├── NAVRH.md # → viz docs/NAVRH.md (architektonická rozhodnutí, hashe, metadata)
|
||||
└── SCHEMA.md # → viz docs/SCHEMA.md (kompletní DB schéma)
|
||||
```
|
||||
|
||||
## Známé problémy
|
||||
## Detailní dokumentace
|
||||
|
||||
- `create_schema.py` používá MySQL syntaxi `INDEX idx_x` uvnitř `CREATE TABLE` - v PostgreSQL je potřeba `CREATE INDEX` zvlášť po `CREATE TABLE`
|
||||
- Hesla jsou hardcodovaná v Python souborech - migrovat do `.env` + `python-dotenv`
|
||||
| Soubor | Obsah |
|
||||
|--------|-------|
|
||||
| [SCHEMA.md](SCHEMA.md) | Kompletní DB schéma — všechny tabulky, sloupce, indexy, constrainty |
|
||||
| [NAVRH.md](NAVRH.md) | Architektonická rozhodnutí, 4 úrovně hashů, EXIF/IPTC/XMP, workflow importu |
|
||||
|
||||
## Roadmap
|
||||
## Infrastruktura
|
||||
|
||||
- [ ] Opravit PostgreSQL schéma (INDEX syntaxe)
|
||||
- [ ] Migrace hesel do `.env`
|
||||
- [ ] Instalace Redis
|
||||
- [ ] Skript pro hromadný import fotek z `demo_fotky/`
|
||||
- [ ] EXIF parser (pillow + exifread)
|
||||
- [ ] Generování miniatur s Redis cache
|
||||
- [ ] Web UI pro prohlížení galerie
|
||||
| Server | IP | Role |
|
||||
|--------|----|------|
|
||||
| **tower** | 192.168.1.76 | Hlavní NAS, PostgreSQL, spouští skripty |
|
||||
| **Tower1** | 192.168.1.50 | Archivní NAS, fyzická záloha fotek (`/mnt/user/ZalohaVsechObrazku`) |
|
||||
|
||||
SSH klíče sdílené mezi servery. Z tower přístup na Tower1 přes NFS mount.
|
||||
|
||||
## Rychlý start
|
||||
|
||||
```powershell
|
||||
# Spustit dashboard
|
||||
python run_webreport.py
|
||||
|
||||
# Nasadit collect_pictures na server
|
||||
python "00 PictureCollector/ssh_deploy.py"
|
||||
python "00 PictureCollector/ssh_deploy_tower1.py"
|
||||
|
||||
# Spustit sběr fotek z Windows PC
|
||||
python "00 PictureCollector/collect_pictures_windows.py"
|
||||
```
|
||||
|
||||
## Otevřené otázky
|
||||
|
||||
1. Fotky bez EXIF (7 % fotek) — importovat s mtime / odmítnout / označit?
|
||||
2. Shoda `sha256_pixels` — přeskočit / sloučit metadata / uložit oba?
|
||||
3. Storage layout — in-place / `archiv/YYYY/MM/` / content-addressable?
|
||||
4. Propojení tabulek skupiny 1 (photos) a skupiny 2 (zaloha_obrazku) — zatím žádný FK
|
||||
5. Fotky 2013–2021 — velký propad, chybí zdroje (mobily, iCloud?)
|
||||
6. 4 210 fotek z 2022 bez kamery — pravděpodobně hromadný export z iCloudu (25.9.2023)
|
||||
|
||||
Reference in New Issue
Block a user