Metadata-Version: 2.4
Name: kurmann-familienfilm-manager
Version: 0.3.0
Summary: CLI-Tool und Python-Bibliothek zur Veröffentlichung von Familienfilmen: Medienset-Erstellung, Infuse-Deployment, Webserver-Deployment und Archivierung.
License: MIT License
        
        Copyright (c) 2026 Patrick Kurmann
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/kurmann/familienfilm-manager
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer>=0.12
Requires-Dist: rich>=13
Requires-Dist: kurmann-mediaset-creator>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Dynamic: license-file

# familienfilm-manager

CLI-Tool und Python-Bibliothek zur Veröffentlichung von selbst geschnittenen Familienfilmen.
Orchestriert den gesamten Workflow: Metadaten extrahieren, Medienset erstellen (via `mediaset-creator`),
Infuse-/Webserver-Deployment und Archivierung.

---

## Voraussetzungen

- Python 3.11+
- [ffmpeg](https://ffmpeg.org/) und `ffprobe` im `$PATH`
- [rclone](https://rclone.org/) im `$PATH` (für Deployments und Archivierung)
- [hdiutil](https://ss64.com/mac/hdiutil.html) (macOS, für ISO-Erstellung)
- [kurmann-mediaset-creator](https://pypi.org/project/kurmann-mediaset-creator/) (wird als Dependency installiert)

---

## Installation

```bash
uv pip install kurmann-familienfilm-manager
```

Im Entwicklungsmodus:

```bash
uv sync
```

---

## Verwendung (CLI)

### Gesamtworkflow

```bash
familienfilm-manager publish /pfad/zu/video.m4v \
  --title "Wanderung auf den Napf" \
  --category "Familie Kurmann-Glück" \
  --date "2025-03-24" \
  -v
```

Das Tool:
1. Extrahiert Metadaten (QuickTime-Tags oder Dateiname)
2. Erstellt ein Medienset via `mediaset-creator` mit separaten Profilen (Infuse/Web)
3. Deployt zu Infuse sofort bei Fertigstellung (direkt via rclone, kein ZIP-Entpacken)
4. Deployt zum Webserver nach Fertigstellung der Web-Komprimierung (rclone)
5. Archiviert Original + Sidecars als ISO (hdiutil → rclone move)

### Einzeloperationen

```bash
# Nur Infuse-Deployment eines Verzeichnisses mit Infuse-Dateien
familienfilm-manager deploy-infuse /pfad/zum/infuse-verzeichnis/

# Nur Web-Deployment eines ULID-Verzeichnisses
familienfilm-manager deploy-web /pfad/zum/01JNXYZ.../

# Nur Archivierung
familienfilm-manager archive /pfad/zu/video.m4v --date 2025-03-24
```

### Optionen (publish)

| Option | Beschreibung |
|--------|-------------|
| `--title TEXT` | Video-Titel (überschreibt extrahierte Metadaten) |
| `--description TEXT` | Beschreibung des Videos |
| `--category TEXT` | Kategorie (z.B. «Familie Kurmann-Glück») |
| `--date TEXT` | Aufnahmedatum im ISO-Format (YYYY-MM-DD) |
| `--output-dir PATH` | Basisverzeichnis für die Web-Medienset-Ausgabe |
| `--poster-frame INT` | Frame-Nummer für Vorschaubild (überspringt KI-Auswahl) |
| `--poster-at FLOAT` | Zeitpunkt in Sekunden für Vorschaubild (z.B. 90 oder 1.5) |
| `--poster-crop TEXT` | Bildausschnitt (left/center-left/center/center-right/right) |
| `--ulid TEXT` | ULID für Web-Medienset (überschreibt Sidecar-Wert) |
| `--no-sidecar` | Sidecar-Datei nicht lesen/schreiben |
| `--no-infuse` | Infuse-Deployment überspringen |
| `--no-web` | Web-Deployment überspringen |
| `--no-archive` | Archivierung überspringen |
| `--force` | Neuerstellung erzwingen |
| `--verbose`, `-v` | Zusätzliche Ablaufinformationen auf stderr |

### Ausgabe

stdout enthält den Pfad zum erstellten Verzeichnis (Web-ULID-Verzeichnis oder Infuse-Verzeichnis):

```
/pfad/zum/output/01JNXYZ.../
```

---

## Metadaten-Extraktion

Metadaten werden in folgender Priorität ermittelt:

### Aufnahmedatum

1. **CLI-Parameter** (`--date`) – überschreibt alles
2. **QuickTime-Tag** (`com.apple.quicktime.creationdate`) – bewusst in Final Cut Pro gesetztes Datum
3. **Dateiname** – ISO-Datum am Anfang des Dateinamens (z.B. `2019-12-22 Twannbachschlucht.mov`)
4. **Generische Tags** (`creation_time`, `date`) – oft das Datei-Änderungsdatum, nicht das Aufnahmedatum

Der Dateiname hat bewusst höhere Priorität als generische Tags (`creation_time`), weil der Videoschnitt selten am gleichen Tag wie die Aufnahme stattfindet. So kann das korrekte Aufnahmedatum über den Dateinamen bestimmt werden.

### Titel

1. **CLI-Parameter** (`--title`) – überschreibt alles
2. **QuickTime-Tags** (via ffprobe) – aus Final Cut Pro exportierte Metadaten
3. **Dateiname** – Titel nach dem Datumspräfix:
   - `2025-03-24 Wanderung auf den Napf.m4v` → «Wanderung auf den Napf»
   - `2025-03-24 - Wanderung auf den Napf.m4v` → «Wanderung auf den Napf»

**Wichtig:** Ein Aufnahmedatum ist zwingend erforderlich. Ohne Datum wird die Verarbeitung abgebrochen.

---

## Settings-Sidecar-Datei

Wenn Poster-Einstellungen via CLI angegeben werden (`--poster-frame`, `--poster-at`, `--poster-crop`), speichert der Familienfilm Manager diese automatisch in einer `.settings.toml`-Datei neben dem Video:

```
2025-03-24 Wanderung auf den Napf.m4v
2025-03-24 Wanderung auf den Napf.settings.toml   ← automatisch erstellt
```

Inhalt:
```toml
[poster]
timestamp_seconds = 42.5
crop_position = "center-right"

[web]
ulid = "01JNXYZ..."
```

Bei einem erneuten `publish` werden die Werte automatisch aus der Sidecar-Datei gelesen – CLI-Parameter überschreiben gespeicherte Werte. Die Web-ULID wird nach erfolgreicher Erstellung automatisch gespeichert, damit bei erneutem Publish die gleiche ULID wiederverwendet wird (gleiche URL bleibt stabil).

Die Sidecar-Datei wird bei der Archivierung automatisch mit ins ISO aufgenommen.

**Deaktivieren:** `--no-sidecar` (pro Aufruf) oder `familienfilm-manager config set sidecar.enabled false` (global).

---

## Konfiguration

Einstellungen werden in `~/.config/familienfilm-manager/config.toml` gespeichert.

### Befehle

```bash
# Wert speichern
familienfilm-manager config set <schlüssel> "<wert>"

# Einzelnen Wert lesen
familienfilm-manager config get <schlüssel>

# Alle gespeicherten Werte anzeigen
familienfilm-manager config list
```

### Erlaubte Schlüssel

| Schlüssel | Beschreibung | Standard |
|-----------|--------------|---------|
| `targets.infuse` | rclone-Ziel für Infuse (z.B. `nas:/media/videos/`) | *(leer)* |
| `targets.web` | rclone-Ziel für Webserver (z.B. `azure:container/shares/`) | *(leer)* |
| `targets.archive` | rclone-Ziel für Archiv (z.B. `nas:/archive/familienfilme/`) | *(leer)* |
| `infuse.group_by` | Gruppierung: `year` oder `month` | `year` |
| `defaults.category` | Standard-Kategorie für Videos | *(leer)* |
| `sidecar.enabled` | Sidecar-Dateien automatisch lesen/schreiben | `true` |
| `mediaset.og_base_url` | Stamm-URL für OG-Tags | *(leer)* |
| `mediaset.og_site_name` | OG site_name Metadatum | *(leer)* |
| `tools.ffmpeg` | Pfad zur ffmpeg-Binärdatei | `ffmpeg` |
| `tools.ffprobe` | Pfad zur ffprobe-Binärdatei | `ffprobe` |
| `tools.rclone` | Pfad zur rclone-Binärdatei | `rclone` |

### Beispiel

```bash
familienfilm-manager config set targets.infuse "nas:/media/familienfilme/"
familienfilm-manager config set targets.web "azure:kurmann-glueck/shares/"
familienfilm-manager config set targets.archive "nas:/archive/familienfilme/"
familienfilm-manager config set defaults.category "Familie Kurmann-Glück"
familienfilm-manager config set mediaset.og_base_url "https://kurmannmedia.blob.core.windows.net/kurmann-glueck/"
```

---

## Verwendung (Python API)

```python
from pathlib import Path
from familienfilm_manager.api import (
    PublishRequest,
    RuntimeOptions,
    publish,
)

request = PublishRequest(
    source_path=Path("/pfad/zu/video.m4v"),
    title="Wanderung auf den Napf",
    category="Familie Kurmann-Glück",
    recording_date="2025-03-24",
)

runtime = RuntimeOptions(
    infuse_target="nas:/media/familienfilme/",
    web_target="azure:kurmann-glueck/shares/",
    archive_target="nas:/archive/familienfilme/",
    og_base_url="https://example.com/shares/",
)

result = publish(request, runtime)

if result.success:
    print(f"Infuse: {result.infuse_dir} (deployed: {result.infuse_deployed})")
    print(f"Web: {result.web_dir} (deployed: {result.web_deployed})")
    print(f"Archiv: {result.archived}")
else:
    print(f"Fehler: {result.error_message}")
```

### Öffentliche API-Exporte

```python
from familienfilm_manager.api import (
    publish,                 # Gesamtworkflow
    deploy_infuse,           # Nur Infuse-Deployment
    deploy_web,              # Nur Web-Deployment
    archive,                 # Nur Archivierung
    PublishRequest,          # Fachlicher Request
    PublishResult,           # Ergebnis
    DeployRequest,           # Deploy-Request
    DeployResult,            # Deploy-Ergebnis
    ArchiveRequest,          # Archiv-Request
    ArchiveResult,           # Archiv-Ergebnis
    RuntimeOptions,          # Technische Optionen
    FamilienfilmEvent,       # Fortschritts-Event
    FamilienfilmStage,       # Stage-IDs
)
```

---

## Lizenz

MIT
