Add undo/redo stack for tag operations (assign, remove, rename, merge) with Ctrl+Z/Ctrl+Y

This commit is contained in:
2026-04-09 18:04:37 +02:00
parent 2bcd5b1f4b
commit db280fb5c2
24 changed files with 2705 additions and 2316 deletions

183
README.md
View File

@@ -1,174 +1,103 @@
# 🏷️ Tagger
# Tagger
Desktopová aplikace pro správu a organizaci souborů pomocí hierarchických tagů (štítků).
Desktopová aplikace pro správu a organizaci souborů pomocí hierarchických tagů.
## Hlavní funkce
## Hlavní funkce
- 📁 Rekurzivní procházení složek
- 🏷️ Hierarchické tagy (kategorie/název)
- 🔍 Filtrování podle tagů a textu
- 💾 Metadata v JSON souborech (.!tag)
- 🎬 Automatická detekce rozlišení videí (ffprobe)
- 🎨 Dvě verze GUI: klasické a moderní (qBittorrent-style)
- Rekurzivní procházení složek
- Hierarchické tagy (kategorie/název)
- Filtrování podle tagů (AND / OR / NOT logika) a textu
- Metadata v JSON souborech (.!tag) — cestují se souborem
- Integrace s CSFD.cz (automatické načítání žánrů, roku, země)
- Tvorba hardlink struktury adresářů dle tagů
- Automatická detekce rozlišení videí (ffprobe)
## 🚀 Rychlý start
## Rychlý start
```bash
# Instalace závislostí
poetry install
# Spuštění (moderní GUI)
poetry run python Tagger_modern.py
# Nebo klasické GUI
# Spuštění
poetry run python Tagger.py
```
## 📸 Screenshot
## Klávesové zkratky
### Moderní GUI (qBittorrent-style)
```
┌─────────────────────────────────────────────────────┐
│ 📁 Otevřít │ 🔄 │ 🏷️ │ 📅 🔍 [____] Toolbar
├────────────┬────────────────────────────────────────┤
│ 📂 Štítky │ Název │Datum│Štítky│Velikost │
│ ├─📁 Stav │ file1.txt│2025 │HD │1.2 MB │
│ │ ☑ Nové │ file2.mp4│ │4K │15 MB │
│ ├─📁 Video│ file3.jpg│ │RAW │845 KB │
│ │ ☐ HD │ │
├────────────┴────────────────────────────────────────┤
│ Připraven 3 vybráno │ 125 souborů │
└─────────────────────────────────────────────────────┘
```
| Zkratka | Akce |
|---------|------|
| `Ctrl+O` | Otevřít složku |
| `Ctrl+T` | Přiřadit tagy |
| `Ctrl+D` | Nastavit datum |
| `Ctrl+W` | Zavřít složku |
| `F5` | Refresh |
| `Del` | Odebrat z indexu |
## 🎯 Použití
1. **Otevři složku** - Načti soubory ze složky (rekurzivně)
2. **Vytvoř tagy** - Hierarchická struktura (kategorie → tagy)
3. **Přiřaď tagy** - Označ soubory, vyber tagy
4. **Filtruj** - Klikni na tagy pro filtrování souborů
5. **Vyhledávej** - Textové vyhledávání v názvech
## ⌨️ Keyboard Shortcuts (moderní GUI)
- `Ctrl+O` - Otevřít složku
- `Ctrl+T` - Přiřadit tagy
- `Ctrl+D` - Nastavit datum
- `F5` - Refresh
- `Del` - Smazat z indexu
## 🏗️ Architektura
## Architektura
```
┌─────────────────────────────────┐
│ Presentation (UI) │ ← Tkinter GUI
│ Presentation (PySide6/Qt6) │ src/ui/gui.py
├─────────────────────────────────┤
│ Business Logic │ ← FileManager, TagManager
│ Business Logic │ src/core/ (bez UI importů)
├─────────────────────────────────┤
│ Data Layer │ File, Tag models
│ Data Layer │ File, Tag, TagManager, FileManager
├─────────────────────────────────┤
│ Persistence │ JSON .!tag soubory
│ Persistence │ JSON .!tag soubory
└─────────────────────────────────┘
```
## 📁 Struktura projektu
## Struktura projektu
```
Tagger/
├── Tagger.py # Entry point (klasické GUI)
├── Tagger_modern.py # Entry point (moderní GUI)
├── PROJECT_NOTES.md # ⭐ Kompletní dokumentace
├── Tagger.py # Entry point
├── src/
│ ├── core/ # Business logika
│ │ ├── file.py
│ ├── core/ # Business logika (žádné UI importy!)
│ │ ├── tag.py
│ │ ├── file.py
│ │ ├── file_manager.py
│ │ ── tag_manager.py
│ │ ── tag_manager.py
│ │ ├── config.py
│ │ ├── csfd.py
│ │ ├── hardlink_manager.py
│ │ └── media_utils.py
│ └── ui/
── gui.py # Klasické GUI
│ └── gui_modern.py # Moderní GUI
└── tests/ # 116 testů
── gui.py # Qt6 GUI
└── tests/ # 274 testů
```
## 🧪 Testování
## Testování
```bash
# Všechny testy (116 testů, 100% core coverage)
poetry run pytest tests/ -v
# S coverage report
poetry run pytest tests/ --cov=src/core --cov-report=html
poetry run pytest tests/ -q
```
## 📝 Dokumentace
## Technologie
**Veškerá dokumentace je v jednom souboru:**
👉 **[PROJECT_NOTES.md](PROJECT_NOTES.md)** ⭐
Obsahuje:
- Kompletní dokumentaci projektu
- Architektonická rozhodnutí (ADR)
- Coding standards
- Git workflow
- Known issues & TODO
- Debugování tipy
- Pravidla pro AI asistenty
## 🛠️ Technologie
- **Python:** 3.12
- **GUI:** Tkinter (standard library)
- **Dependencies:** Pillow (PIL)
- **Python:** 3.14+
- **GUI:** PySide6/Qt6
- **Dependencies:** requests, beautifulsoup4, loguru, python-dotenv
- **Package manager:** Poetry
- **Testing:** pytest
## 📊 Metriky
## Metriky
- **Řádky kódu:** ~1060 Python LOC
- **Testy:** 116 (všechny ✅)
- **Test coverage:** 100% core modulů
- **GUI verze:** 2 (klasická + moderní)
- **Testy:** 274 (100% core coverage)
- **Verze:** 1.1.0
## 🎯 Design Decisions
## Design Decisions
### Proč JSON místo databáze?
- Jednoduchý backup (copy složky)
- Git-friendly (plain text)
- ✅ Portable (žádné DB dependencies)
- ✅ Metadata zůstanou při přesunu souboru
- Jednoduchý backup (copy složky)
- Git-friendly (plain text, diffovatelné)
- Metadata zůstanou při přesunu souboru (sidecar)
- Portable — žádné DB závislosti
### Proč Tkinter?
- ✅ Standard library (žádné extra deps)
- ✅ Cross-platform
- ✅ Dobře dokumentované
### Proč sidecar soubory (.!tag)?
- Metadata cestují se souborem při přesunu/kopírování
- Čitelné i bez aplikace
- Každý soubor je nezávislý — žádný single point of failure
### Proč Poetry?
- ✅ Deterministické buildy (poetry.lock)
- ✅ Dev dependencies oddělené
- ✅ Moderní nástroj
## 🐛 Known Issues
- Git merge konflikty s poetry.lock při merge devel→feature
- Dlouhé operace (ffprobe) blokují UI - TODO: threading
## 🚀 Plánované features
- [ ] Progress bar pro dlouhé operace
- [ ] Undo/Redo mechanismus
- [ ] Export do CSV/Excel
- [ ] Dark mode theme
- [ ] Drag & drop souborů
## 📄 License
## License
MIT License
## 👤 Autor
honza
---
**Pro detailní dokumentaci viz [PROJECT_NOTES.md](PROJECT_NOTES.md)**