Files
watchlist/README.md
T
ki dbb92cb1ef
CI / test (push) Has been cancelled
chore(release): v0.5.1-beta — push Docker image to Gitea Container Registry
- bin/build-and-push.sh: baut + pusht Image in die Gitea-Registry
  unter git.pkop.de/vibecode/watchlist:<version>
- bin/get-version.py: liest __version__ aus app/__init__.py
  (single source of truth, kein Quoting-Wahnsinn in Bash)
- bin/build-image.sh + write-manifest.sh nutzen den neuen Helper
- dist/README.md: erklärt die Registry-Policy (kein Tar im Repo)
- load-image.sh entfernt — Tars gibt's nicht mehr
- .gitignore: dist/*.tar + manifest.json ausschließen,
  dist/README.md bleibt dokumentiert
- docker-compose.yml: Hinweis auf Registry-Image
- CI-Workflow: vereinfacht, Push läuft lokal (idempotent)
- Version auf 0.5.1-beta gebumpt

Verifiziert end-to-end:
  bin/build-and-push.sh          -> Image in Gitea-Registry
  docker rmi ...                 -> lokal weg
  docker pull ...                -> aus Registry gezogen
  docker run ...                 -> startet, version 0.5.1-beta, 8 unique Items
2026-07-22 00:00:43 +02:00

176 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WatchStack
> **v0.5.0-beta** — eine Watchlist für **Bücher, Serien & mehr** — inspiriert von MyAnimeList, aber mit eigenem Konzept.
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![Repo](https://img.shields.io/badge/repo-Vibecode%2Fwatchlist-blue)](https://git.pkop.de/Vibecode/watchlist)
[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org)
[![Docker](https://img.shields.io/badge/docker-ready-blue)](#-docker)
WatchStack ist eine **single-user-lokale** Watchlist-App. Bücher und Serien teilen sich eine Oberfläche, ein Datenmodell und eine Such- und Filterlogik. Keine Anmeldung, kein Cloud-Zwang — läuft komplett auf deiner Maschine oder in einem Docker-Container.
## ✨ Features
- 📚 **Bücher**: Titel, Autor, Bände / Kapitel / Seiten, ISBN, Cover via Open Library
- 📺 **Serien**: Staffeln, Episoden, Sender / Streaming, Sendezeitraum, Cover-URL
- 🗂 **Status**: Plan · Laufend · Abgeschlossen · Pausiert · Abgebrochen (5 Stufen, MAL-ähnlich)
-**Bewertungen** 110 mit Auto-Status: 0% → Plan, 100% → Done (+ `end_date`)
- 🔎 **Suche & Filter**: Volltext, Status, Genre, Tag, Sortierung
- 📊 **Dashboard**: Verteilung pro Medium, Durchschnittsbewertung
- 🏷 **Genres & Tags** frei verwaltbar
- 🌙 **Dark Theme** Default, modernes UI mit Hero + Drawer + Modals
- 🐳 **Docker**: Image in der Gitea Container Registry — `docker pull git.pkop.de/vibecode/watchlist:<ver>`
- 🌐 **CORS offen** für lokale Entwicklung; in Produktion via Reverse-Proxy einschränken
## ⚠️ Beta-Hinweis
**v0.5.1-beta** bedeutet:
- Kernfunktionalität (CRUD, Suche, Stats, Progress) ist stabil und getestet
- Datenmodell kann sich noch ändern (siehe `models.py` — additive Änderungen wahrscheinlich)
- Datenbank-Migrationen sind **nicht** enthalten — bei Major-Upgrades DB sichern
- Public-API-Pfade stabil; Sub-Ressourcen (Genres/Tags) noch in Bewegung
Bitte Issues und Wünsche im [Repo](https://git.pkop.de/Vibecode/watchlist) melden.
## 🚀 Quickstart
### Option A: Image aus Gitea-Registry (empfohlen)
```bash
docker pull git.pkop.de/vibecode/watchlist:0.5.1-beta
docker run -d --name watchstack -p 8000:8000 -v watchstack-data:/data git.pkop.de/vibecode/watchlist:0.5.1-beta
```
Das Image liegt im **Packages**-Tab des Repos (Gitea Container Registry,
OCI-konform). Auch über die Web-UI einsehbar unter
`https://git.pkop.de/Vibecode/-/packages`.
### Option B: Docker Compose / lokal bauen
```bash
docker compose up -d
# → http://localhost:8000
# Oder direkt:
docker build -t watchstack:beta .
docker run -d --name watchstack -p 8000:8000 -v watchstack-data:/data watchstack:beta
```
Die SQLite-DB liegt im benannten Volume `watchstack-data` (Pfad `/data/watchstack.db` im Container). Backups: `docker run --rm -v watchstack-data:/data -v $PWD:/backup alpine tar czf /backup/ws-$(date +%F).tgz /data`.
### Option B: Lokal (Python 3.11+)
```bash
git clone https://git.pkop.de/Vibecode/watchlist.git
cd watchlist
./run.sh # legt venv an, installiert deps, startet auf 127.0.0.1:8000
```
### Option C: Manuell
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload
```
## 🔧 Konfiguration (Umgebungsvariablen)
| Variable | Default | Zweck |
|---|---|---|
| `WATCHSTACK_DATA_DIR` | `./data` | Pfad für SQLite-DB (im Container: `/data`) |
| `WATCHSTACK_HOST` | `127.0.0.1` | Bind-Adresse (Docker: `0.0.0.0`) |
| `WATCHSTACK_PORT` | `8000` | HTTP-Port |
| `WATCHSTACK_WORKERS` | `2` | gunicorn-Worker (nur Docker) |
| `WATCHSTACK_HTTP_TIMEOUT` | `8` | Timeout für Open-Library-Lookup (Sek.) |
## 📚 API-Übersicht
| Methode | Pfad | Zweck |
|---|---|---|
| GET | `/api/health` | Service-Info + Version |
| GET | `/api/media` | Liste, Filter via Query-Params |
| POST | `/api/media` | Anlegen (201) |
| GET | `/api/media/{id}` | Detail |
| PATCH | `/api/media/{id}` | Teil-Update |
| DELETE | `/api/media/{id}` | Löschen (204) |
| POST | `/api/media/{id}/progress` | `{"delta":1}` oder `{"set_to":N}` |
| GET | `/api/genres`, `/api/tags` | Taxonomien |
| GET | `/api/stats` | Verteilungen + ⌀-Bewertung |
| GET | `/api/lookup/book?isbn=…` | Cover via Open Library |
**Beispiel** — neuen Eintrag anlegen:
```bash
curl -X POST http://localhost:8000/api/media \
-H 'Content-Type: application/json' \
-d '{
"kind": "book",
"title": "Der Name des Windes",
"author": "Patrick Rothfuss",
"total_pages": 662, "pages_read": 100,
"status": "reading", "rating": 9.0,
"genres": ["Fantasy"], "tags": ["Königsmörder"]
}'
```
Vollständige interaktive Doku: <http://localhost:8000/docs> (Swagger UI, von FastAPI generiert).
## 🏗 Projektstruktur
```
watchlist/
├── app/
│ ├── __init__.py # __version__
│ ├── main.py # FastAPI-App + Routen
│ ├── database.py # Engine + Session
│ ├── models.py # SQLAlchemy-Modelle
│ ├── schemas.py # Pydantic-Schemas
│ ├── crud.py # DB-Operationen
│ ├── external.py # Open-Library-Client
│ ├── seed.py # Demo-Daten
│ └── static/ # Frontend (HTML/CSS/JS)
├── data/ # SQLite-DB (gitignored, Volume im Container)
├── bin/ # build-and-push.sh, build-image.sh, write-manifest.sh
├── .github/workflows/ # CI
├── Dockerfile # Multi-stage Build
├── docker-compose.yml
├── LICENSE # Apache-2.0 (offizieller Volltext)
├── NOTICE # Copyright + Drittanbieter
└── README.md
```
## 🛠 Entwicklung
```bash
# Tests (bisher Smoke-Tests ad-hoc; pytest-Suite ist Roadmap)
python -c "from app.main import app; print(app.title, app.version)"
# Code-Style
ruff check app/ # (optional, nicht in requirements)
```
## 📜 Lizenz
**Apache License 2.0** — siehe [LICENSE](./LICENSE) (vollständiger Text) und [NOTICE](./NOTICE) (Drittanbieter-Hinweise).
Kurzfassung: Du darfst das Projekt privat und kommerziell nutzen, verändern, weitergeben — unter Beibehaltung des Copyright-Hinweises und der Lizenz. Es gibt **keine** Patent-Gewähr; Änderungen müssen markiert werden. Volltext in der LICENSE-Datei.
## 🤝 Contributing
PRs willkommen — am besten mit Issue vorab. Bitte:
- Coding-Style einhalten (PEP 8, KISS, DRY)
- Keine externen Tracker; Issues im Gitea-Repo
- Tests für neue Logik (pytest-Suite kommt)
## 🔮 Roadmap
- [ ] pytest-Suite mit Coverage-Report
- [ ] Backup-/Restore-Endpoint
- [ ] Import von MAL-XML / Trakt-Listen
- [ ] Manga als dritte Medienart (Volumes, Chapters)
- [ ] Multi-User mit OIDC-Login (optional, hinter Feature-Flag)
- [ ] Cover-Caching-Proxy
- [ ] Deutsche Übersetzungen der Status-Labels i18n-ready