update
This commit is contained in:
40
CLAUDE.md
40
CLAUDE.md
@@ -23,9 +23,10 @@ Drei Komponenten:
|
|||||||
- MutationObserver registriert neue Cards beim IntersectionObserver
|
- MutationObserver registriert neue Cards beim IntersectionObserver
|
||||||
- `yt-navigate-finish` Event-Listener fuer SPA-Navigation
|
- `yt-navigate-finish` Event-Listener fuer SPA-Navigation
|
||||||
- Deduplizierung ueber `sentUrls` Set, wird bei Navigation geleert
|
- Deduplizierung ueber `sentUrls` Set, wird bei Navigation geleert
|
||||||
- Batch-Versand: sammelt sichtbare Videos, sendet als Array
|
- Batch-Versand: sammelt sichtbare Videos mit Profil-ID, sendet als Array
|
||||||
- Selektoren ohne Klassen: nur Tags (`h3`, `img`) und Attribute (`href`, `src`)
|
- Selektoren ohne Klassen: nur Tags (`h3`, `img`) und Attribute (`href`, `src`)
|
||||||
- `background.js` — empfaengt Batch vom Content Script, sendet POST an Server
|
- `background.js` — empfaengt Batch vom Content Script, sendet POST an Server
|
||||||
|
- `popup.html/popup.js` — Profil-Auswahl (holt Profile vom Server, speichert in browser.storage.local)
|
||||||
- Laden via `about:debugging#/runtime/this-firefox` → "Temporaeres Add-on laden" → `manifest.json`
|
- Laden via `about:debugging#/runtime/this-firefox` → "Temporaeres Add-on laden" → `manifest.json`
|
||||||
|
|
||||||
### Server (`backend/`)
|
### Server (`backend/`)
|
||||||
@@ -34,24 +35,28 @@ Drei Komponenten:
|
|||||||
- Dockerisiert: `docker compose up --build -d` im `backend/` Verzeichnis
|
- Dockerisiert: `docker compose up --build -d` im `backend/` Verzeichnis
|
||||||
- Laeuft auf `http://localhost:8000`
|
- Laeuft auf `http://localhost:8000`
|
||||||
- Download-Service speichert Videos unter `/videos/{id}.mp4`
|
- Download-Service speichert Videos unter `/videos/{id}.mp4`
|
||||||
- Streaming: heruntergeladene Videos von Datei, sonst Live-Stream via yt-dlp + ffmpeg (fragmentiertes MP4)
|
- Stream-Service: heruntergeladene Videos von Datei, sonst Live-Stream via yt-dlp + ffmpeg (fragmentiertes MP4)
|
||||||
- Dedup: beim Batch-Import wird bestehender Eintrag mit gleicher Video-ID geloescht und neu eingefuegt
|
- Dedup: beim Batch-Import wird bestehender Eintrag mit gleicher Video-ID geloescht und neu eingefuegt
|
||||||
- Sortierung: nach ID absteigend (erstes Video im Batch bekommt hoechste ID)
|
- Sortierung: nach ID absteigend (erstes Video im Batch bekommt hoechste ID)
|
||||||
|
- Profile: fest in DB definiert, Videos ueber Many-to-Many zugeordnet
|
||||||
|
|
||||||
### App (`app/`)
|
### App (`app/`)
|
||||||
- **Kotlin, Jetpack Compose**, Android/Android TV
|
- **Kotlin, Jetpack Compose**, Android/Android TV
|
||||||
- Gradle-Projekt, Modul `frontend`
|
- Gradle-Projekt, Modul `frontend`
|
||||||
- Screens: AllVideos (Grid), Downloaded, VideoDetail, VideoPlayer
|
- Screens: AllVideos (Grid), Downloaded, VideoDetail, VideoPlayer
|
||||||
- Retrofit fuer API-Calls, Coil fuer Thumbnails, ExoPlayer fuer Streaming
|
- Retrofit fuer API-Calls, Coil fuer Thumbnails, ExoPlayer fuer Streaming
|
||||||
- Navigation mit Bottom Bar, Dark Theme
|
- Navigation mit TopBar (Profil-Auswahl) und Bottom Bar, Dark Theme
|
||||||
|
- Profil-Auswahl wird in SharedPreferences persistiert, filtert Videos nach Profil
|
||||||
|
- Lokaler Download: Videos werden auf dem Geraet gespeichert, lokal bevorzugt abgespielt
|
||||||
- Server-IP konfigurierbar in `ApiClient.kt` (aktuell `192.168.178.92`)
|
- Server-IP konfigurierbar in `ApiClient.kt` (aktuell `192.168.178.92`)
|
||||||
- Emulator: Android Studio → Device Manager → Pixel 6a, API 35
|
- Emulator: Android Studio → Device Manager → Pixel 6a, API 35
|
||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
- `POST /videos` — Video-Batch von Extension empfangen (Liste von Videos, Dedup + Reverse-Insert)
|
- `GET /profiles` — alle Profile abrufen
|
||||||
- `GET /videos` — alle Videos abrufen (sortiert nach ID absteigend)
|
- `POST /videos` — Video-Batch von Extension empfangen (Dedup, Reverse-Insert, Profil-Zuordnung)
|
||||||
- `GET /videos/downloaded` — heruntergeladene Videos abrufen
|
- `GET /videos` — alle Videos abrufen (optional `?profile_id=X`, sortiert nach ID absteigend)
|
||||||
|
- `GET /videos/downloaded` — heruntergeladene Videos abrufen (optional `?profile_id=X`)
|
||||||
- `POST /videos/{id}/download` — Download auf Server triggern
|
- `POST /videos/{id}/download` — Download auf Server triggern
|
||||||
- `GET /videos/{id}/stream` — Video streamen (von Datei oder Live via yt-dlp/ffmpeg)
|
- `GET /videos/{id}/stream` — Video streamen (von Datei oder Live via yt-dlp/ffmpeg)
|
||||||
- `GET /videos/{id}/file` — Video-Datei zum Download auf Client ausliefern
|
- `GET /videos/{id}/file` — Video-Datei zum Download auf Client ausliefern
|
||||||
@@ -60,29 +65,32 @@ Drei Komponenten:
|
|||||||
|
|
||||||
```
|
```
|
||||||
backend/
|
backend/
|
||||||
main.py — FastAPI App, CORS, Startup
|
main.py — FastAPI App, CORS, Startup, Seed-Profile
|
||||||
database.py — SQLAlchemy Engine, Session, Base
|
database.py — SQLAlchemy Engine, Session, Base
|
||||||
models.py — Video Model (id, title, youtuber, thumbnail_url, youtube_url, file_path, created_at)
|
models.py — Video, Profile, video_profiles (Many-to-Many)
|
||||||
schemas.py — Pydantic Schemas (VideoCreate, VideoResponse)
|
schemas.py — Pydantic Schemas (VideoCreate, VideoResponse, ProfileResponse)
|
||||||
routes/videos.py — Alle API-Routen
|
routes/videos.py — Video- und Profil-Routen
|
||||||
services/
|
services/
|
||||||
video_service.py — CRUD-Operationen, Dedup
|
video_service.py — CRUD-Operationen, Dedup, Profil-Filter
|
||||||
download_service.py — yt-dlp Download + Live-Streaming
|
download_service.py — yt-dlp Download
|
||||||
|
stream_service.py — Live-Streaming via yt-dlp + ffmpeg
|
||||||
Dockerfile — Python 3.12 + ffmpeg
|
Dockerfile — Python 3.12 + ffmpeg
|
||||||
docker-compose.yml — Service-Definition, Port 8000, Volume /videos
|
docker-compose.yml — Service-Definition, Port 8000, Volume /videos
|
||||||
.dockerignore — videos/, __pycache__/
|
.dockerignore — videos/, __pycache__/
|
||||||
.gitignore — videos/, __pycache__/
|
.gitignore — videos/, __pycache__/
|
||||||
|
|
||||||
browser_extension/
|
browser_extension/
|
||||||
manifest.json — Manifest V2, Permissions fuer youtube.com + localhost
|
manifest.json — Manifest V2, Permissions, browser_action
|
||||||
content.js — DOM-Extraktion + IntersectionObserver + Batch-Versand
|
content.js — DOM-Extraktion + IntersectionObserver + Batch-Versand mit Profil
|
||||||
background.js — Batch-POST an Server
|
background.js — Batch-POST an Server
|
||||||
|
popup.html — Profil-Auswahl UI
|
||||||
|
popup.js — Profile laden, Auswahl speichern
|
||||||
|
|
||||||
app/
|
app/
|
||||||
.gitignore — .gradle/, build/, .idea/, local.properties
|
.gitignore — .gradle/, build/, .idea/, local.properties
|
||||||
frontend/src/main/java/com/youtubeapp/
|
frontend/src/main/java/com/youtubeapp/
|
||||||
MainActivity.kt — Einstiegspunkt
|
MainActivity.kt — Einstiegspunkt
|
||||||
data/ — Video, ApiClient, VideoApi, VideoRepository
|
data/ — Video, Profile, ApiClient, VideoApi, VideoRepository, LocalStorageService
|
||||||
ui/screens/ — AllVideos, Downloaded, VideoDetail, VideoPlayer
|
ui/screens/ — AllVideos, Downloaded, VideoDetail, VideoPlayer
|
||||||
ui/components/ — VideoCard
|
ui/components/ — VideoCard
|
||||||
ui/viewmodel/ — VideoViewModel
|
ui/viewmodel/ — VideoViewModel
|
||||||
@@ -94,7 +102,7 @@ app/
|
|||||||
|
|
||||||
- Kein Jellyfin — erfuellt nicht die Anforderung, Videos vor dem Download aufzulisten
|
- Kein Jellyfin — erfuellt nicht die Anforderung, Videos vor dem Download aufzulisten
|
||||||
- Kein PostgreSQL/MySQL — SQLite reicht fuer den Prototyp
|
- Kein PostgreSQL/MySQL — SQLite reicht fuer den Prototyp
|
||||||
- Keine Benutzerprofile im Prototyp
|
- Profile fest in DB — kein UI zum Erstellen/Loeschen, werden direkt in der Datenbank verwaltet
|
||||||
- Videos werden auf dem Server gespeichert, Client speichert nur bei explizitem Download
|
- Videos werden auf dem Server gespeichert, Client speichert nur bei explizitem Download
|
||||||
- DOM-Extraktion statt ytInitialData-Parsing — funktioniert auch bei SPA-Navigation und Scrollen
|
- DOM-Extraktion statt ytInitialData-Parsing — funktioniert auch bei SPA-Navigation und Scrollen
|
||||||
- IntersectionObserver statt blindem Scan — nur sichtbare Videos erfassen
|
- IntersectionObserver statt blindem Scan — nur sichtbare Videos erfassen
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
# Browser Extension
|
# Browser Extension
|
||||||
- Content Script — YouTube-DOM auslesen, Videodaten extrahieren
|
- Content Script — YouTube-DOM auslesen, Videodaten extrahieren
|
||||||
- Background Script — Daten gruppiert an Server senden (POST /videos)
|
- Background Script — Daten gruppiert an Server senden (POST /videos)
|
||||||
|
- Popup — Profil vom Server laden und auswaehlen
|
||||||
# Server
|
# Server
|
||||||
## API
|
## API
|
||||||
- POST /videos — Video-Batch empfangen, Duplikate entfernen
|
- POST /videos — Video-Batch empfangen, Duplikate entfernen, Profil zuordnen
|
||||||
- GET /videos — alle Videos abrufen
|
- GET /videos — alle Videos abrufen (optional nach Profil filtern)
|
||||||
- GET /videos/downloaded — heruntergeladene Videos abrufen
|
- GET /profiles — alle Profile abrufen
|
||||||
|
- GET /videos/downloaded — heruntergeladene Videos abrufen (optional nach Profil filtern)
|
||||||
- POST /videos/{id}/download — Download triggern
|
- POST /videos/{id}/download — Download triggern
|
||||||
- GET /videos/{id}/stream — Video streamen
|
- GET /videos/{id}/stream — Video streamen
|
||||||
- GET /videos/{id}/file — Video-Datei zum Download ausliefern
|
- GET /videos/{id}/file — Video-Datei zum Download ausliefern
|
||||||
@@ -15,6 +17,8 @@
|
|||||||
- StreamService — Live-Streaming via yt-dlp + ffmpeg
|
- StreamService — Live-Streaming via yt-dlp + ffmpeg
|
||||||
## Model
|
## Model
|
||||||
- Video — id, title, youtuber, thumbnail_url, youtube_url, file_path
|
- Video — id, title, youtuber, thumbnail_url, youtube_url, file_path
|
||||||
|
- Profile — id, name
|
||||||
|
- video_profiles — video_id, profile_id (Many-to-Many)
|
||||||
# App
|
# App
|
||||||
## Screens
|
## Screens
|
||||||
- AllVideosScreen — alle Videos als Cards
|
- AllVideosScreen — alle Videos als Cards
|
||||||
@@ -26,6 +30,7 @@
|
|||||||
## Services
|
## Services
|
||||||
- LocalStorageService — Videos lokal speichern, pruefen, loeschen
|
- LocalStorageService — Videos lokal speichern, pruefen, loeschen
|
||||||
## API
|
## API
|
||||||
- ServerApi — kommuniziert mit FastAPI (GET /videos, POST /download, GET /stream, GET /videos/{id}/file)
|
- ServerApi — kommuniziert mit FastAPI (GET /profiles, GET /videos, POST /download, GET /stream, GET /videos/{id}/file)
|
||||||
## Model
|
## Model
|
||||||
- Video — id, title, youtuber, thumbnailUrl, youtubeUrl, isDownloaded, localFilePath
|
- Video — id, title, youtuber, thumbnailUrl, youtubeUrl, isDownloaded, localFilePath, profileIds
|
||||||
|
- Profile — id, name
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
# Browser Extension intern
|
# Browser Extension intern
|
||||||
- Videodaten erfassen
|
- Videodaten erfassen
|
||||||
# Browser Extension -> Server
|
# Browser Extension -> Server
|
||||||
- Videodaten gruppiert senden
|
- Profile abrufen
|
||||||
|
- Videodaten gruppiert mit Profil senden
|
||||||
# Server intern
|
# Server intern
|
||||||
- Videodaten persistieren
|
- Videodaten persistieren
|
||||||
- Video herunterladen
|
- Video herunterladen
|
||||||
@@ -9,7 +10,8 @@
|
|||||||
- Video streamen
|
- Video streamen
|
||||||
- Videodatei senden
|
- Videodatei senden
|
||||||
# App -> Server
|
# App -> Server
|
||||||
- Videos abrufen
|
- Profile abrufen
|
||||||
|
- Videos nach Profil abrufen
|
||||||
- Video download anfragen
|
- Video download anfragen
|
||||||
- Video stream anfragen
|
- Video stream anfragen
|
||||||
# App intern
|
# App intern
|
||||||
|
|||||||
Reference in New Issue
Block a user