Files
Tagger/PROJECT_NOTES.md
2025-12-28 17:44:24 +01:00

14 KiB

Tagger - Centrální Poznámky Projektu

DŮLEŽITÉ: Tento soubor obsahuje VŠE co potřebuji vědět o projektu. Pokud pracuji na Tagger, VŽDY nejdříve přečtu tento soubor!

Poslední aktualizace: 2025-12-28 Verze: 1.0.3 Status: Stable, v aktivním vývoji


O projektu

Tagger je desktopová aplikace pro správu a organizaci souborů pomocí hierarchických tagů (štítků).

Hlavní funkce:

  • Rekurzivní procházení složek
  • Hierarchické tagy (kategorie/název)
  • Filtrování podle tagů
  • Metadata uložená v JSON souborech
  • Automatická detekce rozlišení videí (ffprobe)
  • Moderní GUI (qBittorrent-style)
  • Hardlink struktura - vytváření adresářové struktury pomocí hardlinků podle tagů
  • Tříúrovňový konfigurační systém (globální, složkový, souborový)

Struktura projektu

Tagger/
├── Tagger.py                    # Entry point
├── PROJECT_NOTES.md             # ← TENTO SOUBOR - HLAVNÍ ZDROJ PRAVDY
├── CHANGELOG.md                 # Historie verzí
├── pyproject.toml               # Poetry konfigurace
├── poetry.lock                  # Zamčené verze závislostí
├── .gitignore                   # Git ignore pravidla
│
├── src/
│   ├── core/                    # Jádro aplikace (ŽÁDNÉ UI!)
│   │   ├── tag.py               # Tag value object (immutable)
│   │   ├── tag_manager.py       # Správa tagů a kategorií
│   │   ├── file.py              # File s metadaty
│   │   ├── file_manager.py      # Správa souborů, filtrování
│   │   ├── config.py            # Tříúrovňová konfigurace (global, folder, file)
│   │   ├── hardlink_manager.py  # Správa hardlink struktury
│   │   ├── utils.py             # list_files() - rekurzivní procházení
│   │   ├── media_utils.py       # load_icon(), ffprobe
│   │   ├── constants.py         # APP_NAME, VERSION, APP_VIEWPORT
│   │   └── list_manager.py      # Třídění (málo používaný)
│   │
│   └── ui/
│       └── gui.py               # Moderní qBittorrent-style GUI
│
├── tests/                       # 189 testů, 100% core coverage
│   ├── __init__.py
│   ├── conftest.py              # Pytest fixtures
│   ├── test_tag.py              # 13 testů
│   ├── test_tag_manager.py      # 31 testů
│   ├── test_file.py             # 22 testů
│   ├── test_file_manager.py     # 40 testů
│   ├── test_config.py           # 33 testů
│   ├── test_hardlink_manager.py # 28 testů
│   ├── test_utils.py            # 17 testů
│   └── test_media_utils.py      # 3 testy
│
├── src/resources/
│   └── images/32/               # Ikony (32x32 PNG)
│       ├── 32_unchecked.png
│       ├── 32_checked.png
│       └── 32_tag.png
│
└── data/samples/                # Testovací data

Architektura

Vrstvová struktura

┌─────────────────────────────────┐
│  Presentation (UI)              │  ← gui.py
│  - Tkinter GUI                  │  - NESMÍ obsahovat business logiku
│  - Jen zobrazení + interakce   │  - NESMÍ importovat přímo z core
├─────────────────────────────────┤
│  Business Logic                 │  ← FileManager, TagManager, HardlinkManager
│  - Správa souborů/tagů          │  - Callable z UI
│  - Filtrování, validace         │  - Callback pattern pro notifikace
├─────────────────────────────────┤
│  Data Layer                     │  ← File, Tag (models)
│  - File, Tag třídy              │  - Immutable kde je možné
│  - Validation logic             │  - __eq__ a __hash__ správně
├─────────────────────────────────┤
│  Persistence                    │  ← config.py, .!tag soubory
│  - JSON soubory                 │  - UTF-8 encoding VŽDY
│  - Config management            │  - ensure_ascii=False
└─────────────────────────────────┘

Tříúrovňový konfigurační systém

  1. Globální config (.Tagger.!gtag vedle Tagger.py)

    • Geometrie okna, maximalizace
    • Poslední otevřená složka
    • Recent folders
  2. Složkový config (.Tagger.!ftag v projekt složce)

    • Ignore patterns
    • Custom tagy pro složku
    • Hardlink nastavení (output_dir, categories)
    • Rekurzivní skenování
  3. Souborové tagy (.filename.!tag)

    • Tagy souboru
    • Datum
    • Stav (nové, ignorované)

Klíčová pravidla

CO DĚLAT:

  1. UI NESMÍ obsahovat business logiku

    # ❌ ŠPATNĚ
    class GUI:
        def save_file(self):
            with open(file, 'w') as f:
                json.dump(data, f)
    
    # ✅ SPRÁVNĚ
    class GUI:
        def save_file(self):
            self.filemanager.save_file(file)
    
  2. Core moduly NESMÍ importovat UI

    # V src/core/*.py NIKDY:
    import tkinter
    from src.ui import anything
    
  3. Dependency Injection - předávat dependencies přes konstruktor

    class FileManager:
        def __init__(self, tagmanager: TagManager):
            self.tagmanager = tagmanager
    
  4. UTF-8 encoding VŠUDE

    with open(file, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    
  5. Type hints VŽDY

    def filter_files(files: List[File], tags: List[Tag]) -> List[File]:
        pass
    

CO NEDĚLAT:

  1. Globální stav - NIKDY
  2. Magic numbers - použít konstanty
  3. Ignorovat exceptions - vždy logovat nebo ošetřit
  4. Hardcoded paths - použít Path

Klíčové komponenty

1. Tag (immutable value object)

class Tag:
    def __init__(self, category: str, name: str):
        self.category = category  # Nemění se po vytvoření!
        self.name = name

    @property
    def full_path(self) -> str:
        return f"{self.category}/{self.name}"

2. File (reprezentace souboru s metadaty)

class File:
    def __init__(self, file_path: Path, tagmanager=None):
        self.file_path = file_path
        self.filename = file_path.name
        self.metadata_filename = parent / f".{filename}.!tag"
        self.tags: list[Tag] = []
        self.date: str | None = None

Metadata format (.filename.!tag):

{
  "new": false,
  "ignored": false,
  "tags": ["Stav/Nové", "Video/HD"],
  "date": "2025-12-23"
}

3. TagManager (správa tagů)

class TagManager:
    def __init__(self):
        self.tags_by_category = {}  # {category: set(Tag)}
        # Automaticky načte výchozí tagy (Hodnocení, Barva)

Výchozí tagy:

  • Hodnocení: 1-5 hvězd (exkluzivní výběr)
  • Barva: Červená, Modrá, Zelená, Žlutá, Oranžová

4. FileManager (správa souborů)

class FileManager:
    def __init__(self, tagmanager: TagManager):
        self.filelist: list[File] = []
        self.tagmanager = tagmanager
        self.on_files_changed = None  # CALLBACK pro UI!
        self.global_config = load_global_config()
        self.folder_config = {}
class HardlinkManager:
    def __init__(self, output_dir: Path):
        self.output_dir = output_dir

    def create_structure_for_files(files, categories=None) -> (success, fail)
    def find_obsolete_links(files, categories=None) -> List[(link, source)]
    def remove_obsolete_links(files, categories=None) -> (count, paths)
    def sync_structure(files, categories=None) -> (created, c_fail, removed, r_fail)

Příklad struktury:

output/
├── žánr/
│   ├── Komedie/
│   │   └── film.mkv  (hardlink)
│   └── Akční/
│       └── film.mkv  (hardlink)
└── rok/
    └── 1988/
        └── film.mkv  (hardlink)

GUI

Moderní GUI (gui.py)

┌─────────────────────────────────────────────────────┐
│ 📁 Otevřít │ 🔄 │ 🏷️ │ 📅     🔍 [____]  Toolbar
├────────────┬────────────────────────────────────────┤
│ 📂 Štítky  │ ☐ Plná │ Třídění: [Název] [▲]         │
│  ├─📁 Stav │ ┌──────────────────────────────────┐  │
│  │ ☑ Nové  │ │ Název│Datum│Štítky│Velikost    │  │
│  │ ☐ OK    │ │file1 │2025 │HD    │1.2 MB      │  │
│  ├─📁 Video│ │file2 │     │4K    │15 MB       │  │
│  │ ☐ HD    │ └──────────────────────────────────┘  │
│  │ ☐ 4K    │                                       │
├────────────┴───────────────────────────────────────┤
│ Připraven              3 vybráno │ 125 souborů     │
└─────────────────────────────────────────────────────┘

Použít: poetry run python Tagger.py

Funkce:

  • Tabulka s 4 sloupci (Název, Datum, Štítky, Velikost)
  • Toolbar s tlačítky
  • Keyboard shortcuts (Ctrl+O, Ctrl+T, F5, Del...)
  • Status bar se 3 sekcemi
  • Hromadné přiřazování tagů
  • Hardlink menu (Nástroje → Hardlink)

Keyboard shortcuts:

  • Ctrl+O - Otevřít složku
  • Ctrl+Q - Ukončit
  • Ctrl+T - Přiřadit tagy
  • Ctrl+D - Nastavit datum
  • Ctrl+F - Focus search
  • F5 - Refresh
  • Del - Smazat z indexu

Vývoj

Setup prostředí

# Poetry environment (VŽDY použij poetry!)
poetry install
poetry shell

# Nebo přímo:
poetry run python Tagger.py

Testy

# Všechny testy (189 testů)
poetry run pytest tests/ -v

# S coverage
poetry run pytest tests/ --cov=src/core --cov-report=html

# Konkrétní modul
poetry run pytest tests/test_hardlink_manager.py -v

# Quick check
poetry run pytest tests/ -q

Test coverage: 100% core modulů


Coding Standards

Python Style

  • PEP 8 s výjimkami:
    • Max line length: 120 (ne 79)
    • Indentation: 4 mezery (ne taby)
  • UTF-8 encoding všude
  • Type hints povinné
  • Docstrings pro public API

Imports Order

# 1. Standard library
import os
import sys
from pathlib import Path

# 2. Third-party
import tkinter as tk
from PIL import Image

# 3. Local
from src.core.file import File
from src.core.tag import Tag

Git Workflow

Branches

main/master    ← Production (NE commity přímo!)
  ↑
release        ← Release candidate
  ↑
devel          ← Development integration
  ↑
feature/*      ← Feature branches ← VYVÍJÍME TADY

Commit Messages

<type>: <subject>

[optional body]

🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Types:

  • feat: - Nová funkce
  • fix: - Bug fix
  • refactor: - Refactoring
  • test: - Testy
  • docs: - Dokumentace
  • style: - Formátování
  • chore: - Build, dependencies

Plánované features

  • Progress bar pro dlouhé operace
  • Undo/Redo mechanismus
  • Export do CSV/Excel
  • Dark mode theme
  • Drag & drop souborů
  • Image preview v sidebar
  • SQLite fallback pro >10k souborů
  • Full-text search

Nice to have

  • Plugin systém
  • Web interface (Flask)
  • Cloud sync (Dropbox, GDrive)
  • Batch rename podle tagů
  • Smart folder suggestions

Metriky projektu

Testy: 189 (všechny ) Test coverage: 100% core modulů Python verze: 3.12+ Dependencies: Pillow (PIL) Vývojové prostředí: Poetry

Performance:

  • Dobré: <1000 souborů
  • ⚠️ Přijatelné: 1000-5000 souborů
  • Pomalé: >5000 souborů

Debugování

Časté problémy

1. "Cannot import ImageTk"

# Řešení: Použij poetry environment
poetry run python Tagger.py

2. "Config file not found"

# Normální při prvním spuštění
# Vytvoří se automaticky .Tagger.!gtag

3. "Metadata corrupted"

# V config.py je graceful degradation
# Vrátí default config při chybě

Dokumentace

AKTUÁLNÍ:

  • PROJECT_NOTES.md - TENTO SOUBOR (single source of truth)
  • CHANGELOG.md - Historie verzí
  • Docstrings v kódu

Pro AI asistenty (jako Claude)

Když začínám práci na projektu:

  1. PŘEČTI TENTO SOUBOR CELÝ!
  2. Zkontroluj git status
  3. Aktivuj poetry environment
  4. Spusť testy (poetry run pytest tests/)
  5. Dodržuj pravidla výše

Při commitování:

  1. Testy prošly (pytest tests/)
  2. Type hints přidány
  3. UTF-8 encoding
  4. Žádné TODO/FIXME
  5. Commit message formát správný

Při přidání nové funkce:

  1. Testy napsány PŘED implementací (TDD)
  2. Dokumentace aktualizována (TENTO SOUBOR!)
  3. Architecture decision zdokumentováno (pokud významné)
  4. Type hints všude
  5. Error handling přidán

Kontakt & Help

Autor: honza Repository: /home/honza/Documents/Tagger Python: 3.12+ OS: Linux

Pro pomoc:

  • Přečti TENTO soubor
  • Podívej se do testů (tests/)
  • Zkontroluj docstrings v kódu

Last updated: 2025-12-28 Maintainer: Claude Opus 4.5 + honza