diora-web/podcasts/migrations/0007_episode_transcript_cache.py
mrwnslz 38d7f6c643 Podcasts: Kapitel aus dem ID3-Tag der Audiodatei, Transkripte
- Ohne Kapitel im Feed (kein PSC, keine chapters_url oder dort nichts)
  liest die Folgen-Detailansicht einmalig den ID3v2-Tag am Anfang der
  Audiodatei (Range-Anfrage, höchstens 4 MB, Weiterleitungen mit
  SSRF-Prüfung) und übernimmt dessen CHAP-Frames (v2.3/v2.4,
  Unsynchronisation, erweiterter Header, Synchsafe-Größen, CTOC-Reihenfolge).
  Eigener Parser nach der ID3-Spezifikation; Ergebnis wird wie die
  JSON-Kapitel zwischengespeichert, vorübergehende Fehler nicht.
- Neu: GET /podcasts/episodes/<id>/transcript/ holt das beste Transkript
  (JSON vor VTT vor SRT, Deutsch bzw. ohne Sprachangabe vor Englisch),
  zerlegt es in Abschnitte {start, end, speaker, text}, fasst kurze
  Schnipsel desselben Sprechers bis zum Satzende bzw. ~30 s zusammen und
  speichert das Ergebnis (eigene Tabelle EpisodeTranscript). HTML: 404
  {"error": "unsupported"}.
- Folgen-Detail liefert zusätzlich has_transcript.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:54:03 +02:00

25 lines
934 B
Python

# Generated by Django 6.1 on 2026-10-02 07:44
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('podcasts', '0006_episodeprogress_favorite'),
]
operations = [
migrations.CreateModel(
name='EpisodeTranscript',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sources', models.JSONField(default=list)),
('data', models.JSONField(blank=True, null=True)),
('error', models.CharField(blank=True, max_length=20)),
('fetched_at', models.DateTimeField(auto_now=True)),
('episode', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='transcript_cache', to='podcasts.podcastepisode')),
],
),
]