c65356c16f6b0e71a65f81542b6b1fefbb0237e1
25
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c65356c16f |
4K, Full HD, HD, SD — die Zahl steht beim Überfahren
„1080p" ist eine Angabe für den, der eine Stufe einstellt. Wer sich fragt,
ob es sich lohnt, dafür den Fernseher anzumachen, liest „Full HD". Die
Zeile sagt jetzt das Wort, der Tooltip den genauen Wert und die gemessene
Grösse: `1080p · 1920 × 800`.
**Es gab zwei Leitern, und sie waren sich uneinig.** `Benennung.AusHoehe`
machte aus 2160 ein „2160p", `FileNames.FassungAusHoehe` ein „4K" — auf
derselben Detailseite stand beides übereinander, ein paar Zeilen
auseinander. Die zweite ist weg; sie hatte ausserdem nur die Höhe und
vergab sich damit beim Kinoformat.
Gemessen an zwei echten Dateien: 1920×800 heisst „Full HD" (nur an der
Höhe gemessen hiesse es „HD", und daneben stünde ein 1280×720 mit
demselben Wort), 720×576 heisst „SD".
**1440p fällt unter Full HD.** „QHD" kennt kaum jemand, und ein fünftes
Wort für etwas zwischen zwei bekannten hilft beim Entscheiden nicht.
„8K" steht nur da, damit eine 8K-Datei nicht als 4K gemeldet wird.
**Der Client zerlegt nichts mehr.** Er las die Stufe bisher mit
`display.split(' · ')[0]` heraus — richtig, solange vor der Auflösung nie
etwas anderes steht. Jetzt kommen Wort und genauer Wert als eigene Felder.
**Die Fassung wird nicht mehr gespeichert, sondern gerechnet.** Sie stand
in der Spalte und war damit das, was beim letzten Scan galt: ein neues
Wort hätte keine bestehende Zeile erreicht. Jetzt hält die Spalte nur
noch, was im Dateinamen stand („Mobil"), und die Messung kommt frisch
dazu. Eine Migration räumt die alten gerechneten Werte weg.
**Nicht angefasst:** was eine *gewählte* Stufe ist statt einer gemessenen
— die Umkodierleiter, der Qualitätswähler im Spieler, die Stufen in den
Apps. Wer eine Stufe wählt, wählt eine Zahl.
Die Apps rechnen sich das Wort ohnehin selbst aus und sagen seit jeher
„4K" und „Full HD"; der Server ist ihnen jetzt angeglichen, nicht
umgekehrt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7cd48f5528 |
Wer etwas sieht, kann es jetzt auch sagen
Wer einen Server für andere betreibt, erfährt von Fehlern zuletzt: dass die deutsche Tonspur nach einer halben Stunde aussetzt, merkt der, der den Film sieht, und nicht der, der ihn eingeräumt hat. Bisher gab es dafür keinen Weg ausser dem Zuruf im Wohnzimmer. Gemeldet wird an einem Film, einer Serie, einer einzelnen Staffel und einer einzelnen Folge: Art (Bild, Ton, Untertitel, Angaben, Sonstiges), eine freiwillige Stelle wie 0:34:12 und der Kommentar. Pflicht ist nur der Kommentar — die beiden anderen machen aus einer Liste von Sätzen etwas, das man sortieren und nachstellen kann. **Eine Staffel gibt es als Zeile nicht**, und das prägt den Entwurf. Sie ist Serie plus Nummer, so wie überall sonst in diesem Server; die Meldung trägt deshalb drei Fremdschlüssel und daneben eine Staffelnummer. Dass die Nummer auf eine Staffel zeigt, die es gibt, prüft der Endpunkt beim Schreiben — die Datenbank kann es nicht, es gibt nichts, worauf sie zeigen könnte. **Die Rechteprüfung steht nirgends.** Wer einen Titel nicht sehen darf, findet ihn beim Melden nicht — das erledigt der Freigabefilter, ohne ein einziges `Where`. Elegant und genau deshalb leicht zu zerstören, darum steht dafür ein Test da. **Die eigene Liste überlebt fremde Entscheidungen.** Titel werden nachgeschlagen, nicht verbunden: zieht ein Administrator einen Titel zurück, nachdem jemand ihn gemeldet hat, bleibt die Meldung beim Melder stehen — nur ohne Namen. Ein Join hätte sie verschwinden lassen, und das wäre jemandes eigene Eingabe, weggenommen wegen einer fremden Entscheidung. `IgnoreQueryFilters` wäre die bequeme Abkürzung und gäbe den Namen eines unveröffentlichten Titels über einen Weg heraus, an den beim nächsten Mal niemand denkt. **Erledigt heisst abgehakt, nicht gelöscht**, als Zeitpunkt und nicht als Haken — wie `PublishAt` und `ChangedSince`. Daneben steht „Wieder öffnen"; ein Fehlgriff wäre sonst endgültig. Das Archiv wird erst auf Zuruf geholt: es wächst nur, und für den seltenen Blick dauernd zu zahlen lohnt nicht. **Der Abschnitt steht neben der Prüfliste, nicht darin.** Die versteckt sich, sobald nichts auf Freigabe wartet — das ist der Normalfall, und die Meldungen verschwänden mit ihr. Umgekehrt bleibt der Meldungsabschnitt stehen, auch wenn nichts drinsteht: ein Kanal, der sich versteckt, solange ihn niemand benutzt hat, bringt niemandem bei, dass es ihn gibt. Die Zahl an der Leiste holt sich nur, wer sie nicht ohnehin hat: steht „Zu prüfen" offen, meldet der Abschnitt sie selbst und nach jedem Abhaken. Nebenbei zwei Dinge am Dialog, die hier auffielen. Es gab **kein mehrzeiliges Feld** — und das Einsammeln der Werte hätte ein `<textarea>` still verschluckt: es ist kein `HTMLInputElement` und wäre ins Auffangnetz für Auswahlfelder gelaufen, also als `undefined` hinausgegangen. Der Server hätte „ohne Beschreibung" geantwortet, auf einem Dialog, in dem sichtbar etwas steht. Und `dialog()` meldete sich als einziger nicht beim Seitenwechsel an: ein Dialog von der Detailseite überlebte den Zurück-Knopf und stand danach über der Mediathek. Neun Testfälle auf dem Server, zwölf Läufe. Für den Web-Client gibt es in diesem Projekt keine Tests; dort ist von Hand geprüft. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
579a49b73b |
Der Server wusste, was du zuletzt gesehen hast — und sonst nichts
Für „wie viel habe ich letzte Woche geschaut" gab es keine Daten. `UserItemState` ist eine Zeile je Titel: der letzte Stand. Wer einen Film zweimal sieht, überschreibt den ersten Durchgang; wann etwas lief, wusste der Server nur fürs jeweils letzte Mal. Nachträglich erfinden lässt sich das nicht. Jetzt gibt es ein Sehprotokoll: **eine Zeile je Nutzer, Tag und Titel.** Keine Sitzungen — die brauchen ein Ende, und das kommt oft nie an, wenn der Browser zugemacht oder das Telefon zugeklappt wird. Tagesbündel haben diesen Lebenslauf nicht, es wird nur addiert. **Gezählt wird, was wirklich lief.** Der Zuwachs zwischen zwei Meldungen, gedeckelt auf die Zeit, die dazwischen verstrichen ist (mal zwei als Toleranz für doppelte Geschwindigkeit und ausgefallene Meldungen). Sonst ergäbe ein Sprung von Minute 5 auf Minute 90 anderthalb Stunden Sehzeit in zehn Sekunden. Gemessen an fünf Meldungen im Abstand von elf Sekunden: 88 Sekunden statt 190. Dabei fiel ein zweiter Fall auf: war **gar keine** Zeit verstrichen, griff kein Deckel statt eines engen — eine frisch angelegte Zeile hätte ihre Anfangsstelle voll mitgezählt. Wer einen Film öffnet und sofort auf Minute fünf springt, hat keine fünf Minuten gesehen. Im Profil stehen drei Zahlen, und jede sagt, woher sie kommt: die aufgezeichnete Zeit fängt heute an, die Zahl gesehener Titel steht seit jeher fest. Dazu eine Wochenkurve, die häufigsten Genres und was zuletzt lief. **Jeder sieht nur sich selbst, auch ein Administrator** — es gibt keinen Weg, ein fremdes Konto zu meinen. Zwei Dinge auf dem Weg dorthin: **Eine stellbare Uhr für die Tests.** Zwei Minuten Film lassen sich nicht in fünf Millisekunden sehen, und das ist richtig so — prüfen liess es sich nur, indem die Zeit vergeht, ohne sie zu verbringen. **Ein Namenskonflikt im CSS.** Die leeren Wochenbalken trugen die Klasse `leer`, und die gehört längst der Fläche „hier ist nichts" — mitsamt 24 Pixeln Polster. Jeder leere Balken war dadurch 48 Pixel hoch, egal welche Höhe dastand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d8a1633cf4 |
Das eigene Bild führte aus dem Server heraus
Ein Klick auf den Buchstabenkreis meldete ab. Keine Rückfrage, kein Menü, kein Weg zurück — hinter einer Geste, die überall sonst „mein Konto" heisst. Jetzt führt er auf `#/profil`; Abmelden steht dort als Knopf, mit Nachfrage. Auf der Seite: Bild wählen, tauschen, entfernen. Dazu „Meine Sprache" — **umgezogen, nicht kopiert.** Sie stand mitten in der Verwaltung, und die zeigt der Client nur Administratoren; der Endpunkt erlaubte sie längst jedem. Wer kein Admin war, konnte seine eigene Sprache nirgends ändern. Der Warnhinweis „weicht ab" bleibt in der Verwaltung, denn dort entsteht die Verwirrung — er verweist jetzt aufs Profil. **Vorher musste ein Fehler weg, der seit Monaten dasteht.** `ImageCache.StoreStreamAsync` baute den Schlüssel aus 32 Hexzeichen plus Dateiendung; `PfadFür` verlangt genau 64 Hexzeichen und nichts sonst. Es gab keinen Wert, den beide gelten liessen: **jeder Bildupload gab `null` zurück und endete in einem 502.** Kein Test fragte je danach — jetzt vier. Damit geht nebenbei auch „eigenes Bild hochladen" für Filme und Serien wieder. Weil der Schlüssel keine Endung mehr trägt, kommt der Medientyp beim Ausliefern aus den ersten Bytes der Datei. Vorher ging alles als `image/jpeg` hinaus — bei TMDB stimmte das, bei einem hochgeladenen PNG nicht. **Und die gemerkte Sitzung war eine Kopie, die nie nachzog.** Sie wurde bei der Anmeldung geschrieben und danach nie wieder. Wer sein Bild am Telefon setzt und den Browser am Schreibtisch öffnet, fand dort den alten Buchstaben — bis zum nächsten Anmelden. Gemessen und behoben: beim Hochfahren wird das Konto abgeglichen, und das Profil meldet Änderungen an die Kopfleiste, damit sie ohne Neuladen nachzieht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
255eb7c2f0 |
Spider-Man ist nicht 720p, er ist breit
Die Auflösung wurde allein aus der Höhe gebildet. Ein Kinoformat von 2.39:1 liegt als 1920×800 vor — nach der Höhe gerechnet kam „720p" heraus, und das stand so in der Oberfläche. Jetzt zählt die grössere von Breite und Höhe; Hochformat kippt damit nicht, und 4K-Breitbild heisst nicht mehr 1440p. Die Detailansicht hat zwei Leserschaften, und bisher bekamen beide dasselbe. Wer schauen will, sieht jetzt Laufzeit, Auflösung und die Sprachen — jede einmal, statt „Englisch · Englisch · Englisch · Englisch · Deutsch". Wer die Mediathek betreut, sieht darunter Dateiformat, Grösse und den Ordner. Der Ordner verrät eine falsche Zuordnung in einer Sekunde: steht über der Beschreibung „Hanni & Nanni 3" und der Ordner heisst „Hanni und Nanni", ist die Sache klar. Er kommt nur für Administratoren überhaupt vom Server — versteckt im Client wäre er weiterhin auslesbar. Ein geplanter Titel war unsichtbar. Das ist die Hälfte, die nichts bringt: dass er kommt, ist der Sinn des Planens. Er steht jetzt mit „Verfügbar ab …" in der Mediathek, und die Datei geht trotzdem nicht heraus — Download wie Strom lehnen bis zum Termin ab, auch für Administratoren. Wer vorziehen will, hat „Jetzt veröffentlichen"; eine Hintertür für eine Rolle wäre eine Regel, die manchmal gilt. Was ein Auffrischen geändert hat, steht jetzt unter „Zu prüfen" — in einer eigenen Gruppe mit „Zur Kenntnis" statt „Veröffentlichen". Diese Titel sind sichtbar; es gibt nichts freizugeben, nur etwas abzuhaken. Und das Protokoll sagt endlich, wo es knallt. „InvalidOperationException: Nullable object must have a value." ohne eine einzige Zeile Herkunft ist für niemanden eine Diagnose — weder für den Betreiber noch für mich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c3124ba27c |
Zwei Teile, ein Treffer — und einer verschwand
Du hast drei Filme vermisst, und die Zahlen sagten schon, wo sie sind: 448 Filme plus 13 zweite Fassungen sind genau die 461 Dateien. Es fehlte keine Datei; drei Filme steckten als Fassung in einem anderen. Gemessen, warum. Der Dateinamenleser ist unschuldig — „Teil 2" bleibt im Titel. TMDB aber liefert für „Heiligtümer des Todes Teil 1" wie für „Teil 2" denselben Treffer zuerst, sobald ohne Jahr gesucht werden muss. Und weil zwei Einträge dieselbe Kennung nicht teilen dürfen, wurde der zweite geschluckt. Zwei Dateien, deren Namen verschiedene Jahre nennen, sind jetzt verschiedene Filme. Der erste Anlauf hatte ein Jahr Abstand als Toleranz erlaubt — für Dezember-Erstaufführungen — und verschluckte damit genau den Fall, um den es geht: Teil 1 ist von 2010, Teil 2 von 2011. Dazu sieht man endlich, was nicht zugeordnet werden konnte. „Nicht zugeordnet" listete bisher nur Dateien ganz ohne Titel, und die gibt es bei Filmen nie — deshalb standen dort nur Serien. Daneben eine Liste der Titel mit mehreren Dateien: zwei Fassungen sind die Regel, zwei verschiedene Filme der Fehler, und an den Dateinamen sieht man es sofort. Der Bearbeiten-Dialog hat jetzt Reiter statt Knöpfe, die weitere Fenster öffnen — ein Fenster über einem Fenster, und man wusste nicht mehr, was man zumacht. „Titel ändern" und „Bilder bearbeiten" sind aus dem Kontextmenü raus; über „Bearbeiten" kommt man an beides. Beim Prüfen gefunden: ein Dialog blieb nach einem Seitenwechsel über der neuen Seite stehen. Er hängt an body, nicht am Inhaltsbereich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fcf40e4394 |
Der Orden des Phönix stand vor dem Stein der Weisen
Alphabetisch stimmt das, nur sieht man sie andersherum. Es gibt jetzt einen Sortiertitel: „Harry Potter 1", „Harry Potter 2" — und die Reihe steht in der Ordnung, in der man sie schaut. Leer gelassen bleibt alles wie bisher, beim Titel ohne Artikel davor. Er hat einen eigenen Merker, nicht den des Titels. Wer die Reihenfolge festlegt, soll den Titel trotzdem weiter automatisch bekommen; beides an einem Schalter hiesse, für das eine auf das andere zu verzichten. Eine Korrektur der Zuordnung lässt ihn ebenfalls stehen. Und WALL·E bleibt nicht mehr unter E. Die Kachel wurde nach einer Korrektur zwar neu beschriftet, blieb aber an ihrem Platz — jetzt rutscht sie dorthin, wo sie hingehört. Liegt der Platz im noch nicht geladenen Teil der Liste, geht sie weg und sagt wohin, statt falsch stehenzubleiben. Dazu ein Dialog, in dem alles zu einem Titel beieinander steht: Titel, Sortiertitel, Bilder, Zuordnung. Die vier Menüpunkte gab es schon, jeder für sich richtig — zusammen aber kein Ort. Wer einen Film geraderückt, macht selten nur eines davon. Die Abkürzungen bleiben. Beim Bauen gefunden: das Zurücksetzen des Sortiertitels endete in einer 500. SortTitle.For ist eine C#-Methode, und EF Core übersetzt sie nicht nach SQL. Es geht um eine Zeile — die wird jetzt geladen und zurückgeschrieben, statt die Regel ein zweites Mal als SQL zu schreiben. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
557708b769 |
Ein Klick, der nichts tat, und niemand sagte warum
Eine Serienkachel kannte der Server als Titel nicht: „als gesehen markieren" lief in eine 404, und weil das Kontextmenü die Ablehnung verschluckte, geschah sichtbar gar nichts. Dasselbe beim Favoriten. UserItemState bekommt eine Serienkennung, das Häkchen zieht alle Folgen mit, und was wirft, erscheint als Meldung statt in der Browserkonsole. Dazu eine Mehrfachauswahl in der Mediathek — gesehen, ungesehen, Metadaten neu holen für das Gewählte, in einer Anfrage statt in zweihundert. Ein neues Plakat steht sofort auf der Kachel, und ein Titel, den es nicht mehr gibt, endet nicht mehr in einer Sackgasse. Gemessen: ein POST auf /refresh ohne Rumpf antwortete nach der Erweiterung mit 404 — also genau der Aufruf „alles auffrischen", den es länger gibt als die Auswahl. Der Rumpf wird jetzt von Hand gelesen, und beide Formen stehen in einer Prüfung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d2fbaad871 |
Jeder Titel war seine eigene Dublette, und das seit Monaten
„Metadaten auffrischen" hat an allem, was schon zugeordnet war, schlicht nichts getan. Die Dublettenprüfung schlägt jeden Titel nach, der eine TMDB-Kennung hat — beim Auffrischen also auch den gerade bearbeiteten. Ohne Vergleich auf Gleichheit fand sich jeder als "Dublette seiner selbst", wurde übersprungen und nie fortgeschrieben. Titel, Beschreibung und Bilder blieben für immer so, wie sie beim allerersten Lauf hereinkamen. In der Oberfläche sah das aus, als wirke die Spracheinstellung nicht — und genau so wurde es gemeldet. Gemessen, Ende zu Ende: Serversprache en-US: 101 Dalmatians · The Lion King Serversprache de-DE: 101 Dalmatiner · Der König der Löwen Damit das nie wieder unbemerkt bleibt, weiss der Server jetzt, in welcher Sprache er die Titel hat: eine Spalte MetadataLanguage, gesetzt beim Anreichern, und in der Verwaltung eine Zeile mit der Verteilung. Weicht etwas ab, frischt ein Knopf genau diese Titel auf — nicht den ganzen Bestand, und ohne das Dateisystem noch einmal abzulaufen. Dazu zwei Dinge, die ohne das nicht gingen: ein Titel lässt sich von Hand setzen und wird dabei festgeschrieben wie ein Plakat, mit einem Weg zurück. Und ein Titel, der auf Freigabe wartet, trägt jetzt dasselbe Dreipunktemenü wie eine Kachel — Bilder, Zuordnung, Titel. Ausgerechnet dort fehlte es, obwohl das der Eintrag ist, den man vor der Freigabe geradeziehen will. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
960cca3dae |
Der Abschnitt verschwand alle drei Sekunden und kam wieder
`laden()` setzte `innerHTML = ''` und baute die Mediathekenliste neu — während eines Scans alle drei Sekunden. Der ganze Abschnitt flackerte sichtbar, und wer gerade auf einen Knopf zielte, klickte ins Leere. Schlimmer: jeder Neuaufbau startete über `verfolgen(false)` einen weiteren Takt. Nach einer Minute liefen zwanzig davon nebeneinander. Jetzt wird fortgeschrieben statt neu gezeichnet: eine Zeile je Mediathek, die bleibt, und nur Kopfzeile, Prüfungsknopf und Freigabeknopf ändern sich. Belegt im Browser — nach einem Auffrischen sind es dieselben Knoten, nur die Beschriftung ist eine andere. Dieselbe Behandlung für die Seitenleiste. Und weil Seitenleiste und Verwaltung getrennt nachfragten, zeigten sie zwei Momente — 95 hier, 84 dort, während im Hintergrund Doppelte zusammengelegt wurden. Die Verwaltung reicht ihren Stand jetzt weiter: ein Abruf, zwei Anzeigen. Dazu zwei Dinge, die beim Prüfen auffielen. Zurücksetzen und Entfernen prallen jetzt serverseitig mit 409 ab, solange ein Lauf läuft — die Oberfläche sperrt die Knöpfe, aber darauf darf sich der Server nicht verlassen; ein Aufruf von Hand während eines Scans liess den Lauf an einer DbUpdateConcurrencyException sterben. Und in der Fortschrittszeile steht beim Holen der Folgenmetadaten jetzt der Serienname: „Folge 2×13" allein sagt bei 3815 Folgen nichts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
cfb1e71762 |
3559 von 5884 Dateien verschwanden lautlos
Der Scan erfindet keine Serie mehr, wenn weder Ordner noch Dateiname eine nennen — richtig so. Nur wurde die Datei dann übersprungen, ohne Zeile, ohne Spur. In der Mediathek standen 58 Serien und niemand konnte sagen, wo die anderen geblieben sind. Jetzt bekommt jede solche Datei eine Zeile ohne Zuordnung. Damit ist sie zählbar, auflistbar und nach einer besseren Regel nachträglich zuzuordnen. Untersucht wird sie nicht: ffprobe auf 3559 Dateien kostet eine halbe Stunde für Angaben, die niemand zu sehen bekommt, und sobald die Zuordnung steht, holt der nächste Lauf es nach. Dazu ein Abschnitt "Nicht zugeordnet" in der Verwaltung, nach Grund gebündelt und mit den Pfaden zum Aufklappen. Zwei Gründe gibt es, und sie verlangen Verschiedenes: fehlt die Folgennummer, muss umbenannt werden; fehlt der Serienname, genügt ein Ordner darum herum. Die Liste lässt sich als Datei herunterladen — eine, die man markieren und kopieren muss, schickt niemand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ac04901ccc |
Neun gemeldete Fehler, und die Frage, welcher Build gerade läuft
Ein grosser Commit, weil die Punkte einander bedingen: ohne lesbare Fehlermeldung war die Serienerkennung nicht zu diagnostizieren, und ohne Build-Kennung nicht einmal festzustellen, ob überhaupt der gebaute Stand läuft. Zwei der neun Meldungen betrafen Funktionen, die seit Stunden im Quelltext stehen. Version und Build. Die Version steht fest; daneben eine Kennung aus sechs Zeichen, die sich bei jedem Docker-Bau ändert. Sie steht in der Verwaltung, unter /health und im Protokoll bei jedem Start. Damit ist "reden wir vom selben Build?" in zwei Sekunden beantwortet statt in einem halben Tag. Serien. Lag eine Datei direkt im Serienordner und trug vor der Folgennummer nichts, wurde der ganze Dateiname zum Serientitel: aus 95 Serien wurden 737, jede mit einer Folge, bei jedem Lauf neu. Dazu lief der Scan in Verweise hinein — derselbe Ordner unter zwei Namen ergab zwei Serien. Und weder neue noch umgezogene Dateien standen in der Pfadliste des Laufs, weshalb ein doppelt gesehener Pfad eine zweite Zeile mit gleichem (LibraryId, Path) anlegte und der Eindeutigkeitsindex den ganzen Speichervorgang scheitern liess. Jede Serienanlage wird jetzt im Tagesprotokoll begründet. Fehlermeldungen. "An error occurred while saving the entity changes" stand englisch in einer deutschen Oberfläche und nannte weder Ursache noch nächsten Schritt. Jetzt geht der vollständige Text ins Protokoll und ein deutscher Satz ohne Fehlercode in die Anzeige — auch für "Failed to fetch", das aus dem Browser kam und nie übersetzt wurde. Protokolle. Die Ansicht holte die ganze Datei und zeigte 800 Zeilen davon; bei zwei Megabyte brach die Verbindung ab. Gelesen wird jetzt serverseitig rückwärts, mit einem Knopf für mehr. Auswahlfelder. Die drei <select> zeichnete das Betriebssystem: ein helles Systemmenü mitten in der dunklen Oberfläche. Ersetzt durch ein eigenes Listenfeld mit Tastaturbedienung. Bildwahl. Drei Raster untereinander in einem scrollenden Dialog hiess zwei Scrollebenen übereinander. Jetzt ein Reiter je Bildtyp. Sprache. Die Serversprache stand in der Serverliste zwischen Name, Metadaten und Fassung — gesucht und nicht gefunden. Sie hat jetzt einen eigenen Abschnitt ganz oben. Dazu: ein Knopf, der den erfassten Inhalt einer Mediathek verwirft, ohne Name und Pfad mitzunehmen; ein Abschnitt Speicher mit den drei Pfaden, ihrer Belegung und dem Leeren des Bildspeichers; und die Korrektur einer Zuordnung frischt nur noch die Kachel auf statt die ganze Seite. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fe44d45323 |
Verschobene Dateien hinterliessen eine Leiche
Seit verschwundene Dateien markiert statt gelöscht werden, blieb nach jeder Umbenennung die alte Zeile als "vermisst" stehen. Damit galt die alte Folge nicht als verwaist, die alte Serie nicht als leer — und nach dem Umbenennen eines Serienordners stand alles doppelt da. Jetzt erkennt der Scan eine Verschiebung an Grösse und Änderungszeit und hängt den vorhandenen Eintrag um, statt einen zweiten anzulegen. Der Zeitstempel musste dafür auf Sekunden gerundet werden: er geht durch die Datenbank und kommt nicht auf den Tick genau zurück. Mit Vergleich auf Gleichheit schlug die Erkennung ausnahmslos fehl — der Test zeigte es, nachdem er zweimal dasselbe falsche Ergebnis lieferte. Grösse und Zeit müssen beide stimmen, und das Merkmal muss eindeutig sein. Grösse allein reichte nicht: zwei gleich grosse Dateien gibt es, und die zu vertauschen wäre schlimmer als eine Leiche. Dazu: die Zahl der Titel läuft während eines Scans mit, statt erst am Ende zu springen. Alle fünf Runden, nicht jede — ein Abruf je Sekunde für eine Zahl wäre Verschwendung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
98565e14b5 |
Der Ordner bestimmt die Serie, nicht der Dateiname
Aus einer Serie wurden siebenhundert. Dateien wie "S01E001_Aang.mkv" tragen vor der Folgennummer nichts, also wurde der ganze Dateiname zum Serientitel — jede Folge eine eigene Serie. Und umgekehrt ergab "Doctor Who (2005) - S12E04.mkv" im Ordner "Doctor Who" zwei Serien, weil die Jahresangabe nur im Dateinamen stand. Jetzt gilt: was unter Serien/Pingu/ liegt, gehört zu Pingu. Egal wie tief, egal wie die Datei heisst. Der Ordner ist die verlässlichere Angabe, weil ihn ein Mensch angelegt hat; so macht es Plex seit je und aus demselben Grund. Staffel und Folge liest weiterhin der Dateiname. Ohne bekannte Wurzel bleibt es beim Dateinamen — dort könnte über dem Staffelordner irgendetwas stehen. Diesen Weg gehen nur die Tests. Dazu vier Dinge aus der Benutzung: Die Mediatheken standen scheinbar in zufälliger Reihenfolge. SQLite vergleicht Text zeichengenau, und dort stehen alle Grossbuchstaben vor allen kleinen: "Serien" landete über "film". Jetzt ohne Rücksicht auf Gross- und Kleinschreibung — und umsortierbar über zwei Pfeile. Nicht über Ziehen: das ist schöner, aber mit der Tastatur unbedienbar und auf dem Telefon ein Glücksspiel. Die Sprache des Servers steckte im Dialog "Metadaten", zusammen mit dem TMDB-Schlüssel — also dort, wo niemand nach einer Sprache sucht. Wer die Mediathek auf Englisch vorfand, sah nur "Meine Sprache" und hielt das für die einzige Möglichkeit. Jetzt eine eigene Zeile. Das Kontextmenü gab es nur per Rechtsklick, und den findet nur, wer ihn vermutet — auf dem Telefon gibt es ihn gar nicht. Jetzt drei Punkte auf jeder Kachel, beim Überfahren und bei Tastaturfokus, auf Geräten ohne Zeiger dauerhaft. Und "Zuordnung korrigieren" steht endlich darin: wer zwanzig falsch erkannte Titel vor sich hat, soll sie dort geradeziehen können statt über vierzig Seitenwechsel. Folgen ohne eigenes Bild nehmen das der Serie. TMDB liefert Folgenbilder nur für einen Teil der Folgen und bei kleineren Serien für gar keine; eine graue Fläche sagt nichts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fa18c0d7fa |
Zwei Namen für denselben Titel brachen den ganzen Lauf ab
Der Eindeutigkeitsindex aus Punkt 3 stellte die Regel auf, dichtete aber den einen Weg nicht ab, auf dem sie verletzt wird: der Enricher setzt die TMDB-Kennung, und sobald zwei Einträge derselben Mediathek dieselbe bekamen, brach EF die gesamte Speicherung ab — mit "An error occurred while saving the entity changes", einer Meldung, die den Grund nicht nennt und den ganzen Scan mitnimmt. Jetzt wird die Kennung nicht blind gesetzt, sondern vorgemerkt und nach der Schleife zusammengelegt. Zwei Tests halten den Fall fest: der Anbieter antwortet auf jede Anfrage mit demselben Film beziehungsweise derselben Serie, also genau die Lage, die vorher den Lauf zerriss. Dazu der wahrscheinliche Grund für die siebenhundert Serien: der Serientitel kam ausschliesslich aus dem Dateinamen. Heisst eine Datei nur "S01E01.mkv", steht vor der Folgennummer nichts, und der ganze Dateiname wurde zum Serientitel — zwanzig Folgen ergaben zwanzig Serien namens "S01E01", "S01E02", und so weiter. Jetzt sagt der Ordner den Namen, wenn die Datei ihn nicht nennt; der Staffelordner wird dabei übersprungen, sonst hiesse die Serie "Staffel 1". Plex und Jellyfin lesen ihn seit je so. Dazu die Prüfliste: Folgen werden nach Serie gebündelt, weil zwanzig neue Folgen eine Entscheidung sind und nicht zwanzig. Mit Mehrfachauswahl — anhaken und gemeinsam freigeben oder auf einen Zeitpunkt legen. Und der Zeitpunkt ist ein datetime-local statt eines Textfelds mit Formvorschrift, bei dem jeder Tippfehler erst nach dem Absenden auffiel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
632d3efa35 |
Neue Funde erst prüfen, dann veröffentlichen
Je Mediathek einstellbar, Vorgabe aus: wer eine Mediathek anlegt, will sie sehen. Angeschaltet warten neue Funde unter "Zu prüfen", bis jemand sie freigibt — oder ihnen einen Termin gibt. Ein Zeitpunkt, kein Zustandsfeld. PublishAt null heisst wartet, in der Vergangenheit heisst veröffentlicht, in der Zukunft heisst geplant. Die Sichtbarkeit wird bei der Abfrage gerechnet statt von einem Dienst umgeschaltet; damit stimmt sie nach einem Neustart, nach einer Zeitumstellung und auch dann, wenn der Server zum geplanten Zeitpunkt gar nicht lief. Ein Ticker hätte in jedem dieser Fälle das Falsche getan. Das eigentliche Risiko waren die zwanzig Abfragestellen in vier Dateien. Schriebe jede ihren eigenen Filter, reichte eine vergessene — und auffallen würde es nicht beim Programmieren, sondern wenn jemand im Haushalt einen Titel sieht, den er nicht sehen sollte. Deshalb ein globaler Abfragefilter in FlaroContext, der sich nicht vergessen lässt, und eine Middleware, die je Anfrage setzt, wer Unveröffentlichtes sehen darf. Vorgabe am Kontext ist "alles sehen", damit Scanner und Metadaten ohne Benutzer arbeiten können; für jede HTTP-Anfrage entscheidet die Middleware. Der Test zählt die Inhaltsrouten auf und prüft jede einzeln auf die Abwesenheit eines wartenden Titels. Eine neue Route, die den Filter umgeht, fällt dort durch. Die Migration trägt für alle vorhandenen Titel das Hinzufügedatum als Veröffentlichung nach. Ohne diese zwei Zeilen stünde jeder auf null — und der gesamte Bestand wäre für alle ausser Administratoren verschwunden, sofort beim Start im Container und ohne Meldung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
eb63271e92 |
Ein Kontextmenü auf jeder Kachel — mitsamt Bildauswahl
Gesehen, Favorit und Weglegen gab es ausschliesslich auf der Detailseite. In einer Übersicht mit zwanzig Titeln hiess "die hab ich alle gesehen" vierzig Seitenwechsel. Im ganzen Quelltext stand kein einziger contextmenu-Zuhörer. Drei Wege hinein, weil es drei Arten gibt zu bedienen: Rechtsklick für die Maus, Shift+F10 und die Kontextmenü-Taste für die Tastatur, langer Druck für den Finger. Nur den Rechtsklick anzubieten hiesse, das Menü auf dem Telefon zu verstecken. Der lange Druck bricht bei jeder Bewegung ab, sonst löst Scrollen ihn aus. Die Aktionen wirken auf der Kachel selbst. Die Liste neu zu laden verlöre Bildlauf und Filter — für einen Haken. Dazu die Bildauswahl. Es gab genau einen Bild-Endpunkt, und der lieferte nur aus: wählte TMDB ein schlechtes Plakat, blieb es. Jetzt stehen Plakat, Hintergrund und Schriftzug zur Wahl, dazu eigene Bilder bis 10 MB. Die Kandidaten kosten nichts — TMDB liefert sie beim Einzelabruf ohnehin mit, und bisher wurde alles ausser dem Schriftzug weggeworfen. Drei Merker je Titel, nicht einer: man kann ein eigenes Plakat wollen und trotzdem automatische Hintergründe. Ohne sie überschriebe das nächste Auffrischen jede Handauswahl, und wer einmal ein besseres Plakat gesucht hat, suchte es jedes Mal neu. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
921533050b |
Zwei Titel je Film, und die Sprache lässt sich wählen
Die Mediathek sah zweisprachig aus — "Despicable Me" neben "Ich einfach unverbesserlich". Es gab nur ein Titelfeld, und welche Sprache darin landete, entschied die Einstellung zum Zeitpunkt des Scans. Movie und Series tragen jetzt zusätzlich OriginalTitle. Gesucht wird über beide: wer "Despicable Me" tippt, findet "Ich einfach unverbesserlich". Auf der Detailseite steht der Originaltitel unter dem übersetzten, wenn er abweicht. Die Sprache der Metadaten ist in der Verwaltung eine Auswahl statt eines Textfelds. Vorher musste man "de-DE" wissen, und ein Tippfehler darin nahm TMDB stillschweigend als Englisch an. Dazu eine eigene Sprache je Benutzer. Das Ehrliche daran steht im Dialog: die Daten liegen in einer Sprache vor, und wer eine andere wählt, bekommt, was übersetzt vorliegt — für den Rest die Serversprache, nicht ein leeres Feld. ItemTranslation hält die zweite Sprache, gefüllt über eine Sammelaktion. Nicht nebenbei beim Öffnen: das verteilte die Wartezeit über Wochen und träfe immer den, der gerade etwas sucht. Alle Sprachen für alle Titel vorzuhalten wäre der Bestand mal Sprachen an Abrufen und Speicher, für einen Haushalt mit zweien. Deshalb auf Ansage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
f359807561 |
Der Fortschritt sagt, woran er gerade ist — und schreibt es mit
Vorher stand in der Verwaltung minutenlang "Wird durchsucht…", ohne Hinweis, ob überhaupt etwas passiert. Bei vierzigtausend Dateien ist das nicht zu unterscheiden von einem hängenden Lauf. Scanschritt trägt Phase, Gegenstand und Zählstand und bildet daraus den Satz selbst — im Kern und nicht in der Oberfläche, weil die Apps denselben brauchen und zweimal formuliert er auseinanderdriftet. Sechs Phasen von "Suche Medien in /media/Filme" über "Suche ‚Ich einfach unverbesserlich' bei der Metadatenquelle — 44 von 1204" bis "Räume auf und lege Doppeltes zusammen". Pfade werden auf die letzten zwei Bestandteile gekürzt. ScanAsync und EnrichAsync bekommen je einen optionalen IProgress; optional heisst, dass kein vorhandener Aufrufer bricht. Der Koordinator hält nur den letzten Schritt — eine Liste über vierzigtausend Titel wäre ein Leck im Arbeitsspeicher. Dazu das Tagebuch: eine Datei je Tag unter config/logs, nach lokaler Zeit und nicht nach UTC, weil ein Scan um 23 Uhr am heutigen Datum gesucht wird. Dreissig Tage Aufbewahrung, einstellbar über FLARO_LOG_TAGE — ohne Grenze läuft die config-Partition eines NAS lautlos voll. Es wirft nie: ein volles Dateisystem darf keinen Scan abbrechen. In der Verwaltung lesbar, nach Fehlern filterbar und herunterladbar. Das Containerprotokoll ist nach einem Neustart weg und nur über SSH erreichbar — die Frage "warum wurde der Film gestern Nacht nicht erkannt?" liess sich damit nicht beantworten. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8b67a7ec88 |
Verschwundene Dateien werden gemeldet, nicht stillschweigend gelöscht
Vorher räumte der Scan jede Datei weg, die er nicht mehr sah, und mit der letzten Datei fiel der Titel samt Sehfortschritt aller Benutzer. Für eine wirklich gelöschte Datei ist das richtig. Für eine Platte im Ruhezustand, ein noch nicht eingehängtes Volume oder einen umbenannten Ordner ist es Datenverlust — und für den Scan sehen alle vier Fälle gleich aus. Jetzt trägt MediaFile ein MissingSince. Der Eintrag bleibt stehen, steht in der Verwaltung unter "Nicht mehr gefunden", und gelöscht wird auf Ansage. Taucht die Datei wieder auf, verschwindet die Markierung von selbst. Dazu die Notbremse, und sie ist der eigentliche Grund für den ganzen Punkt: Fehlt der Wurzelpfad, oder liegt dort keine einzige Mediendatei mehr, obwohl vorher welche da waren, bricht der Lauf ab und sagt warum. Ohne sie erklärte ein nicht eingehängtes Volume beim Start des NAS den gesamten Bestand für verschwunden — bei 458 Titeln. Der Abschnitt in der Verwaltung erscheint nur, wenn es etwas zu melden gibt. Ein dauerhaft leerer wäre Rauschen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
63c7ebb6d5 |
Ein Film kommt je Mediathek genau einmal vor
Der Scan verglich den Titel aus dem Dateinamen zeichengenau. Ein Punkt Unterschied — Dr. Dolittle 2 gegen Dr Dolittle 2 —, oder eine Datei mit Jahresangabe neben einer ohne, und es entstanden zwei Einträge. Die Metadaten ordneten beide demselben TMDB-Eintrag zu, beide bekamen denselben Titel, dasselbe Jahr, dasselbe Plakat, und nichts führte sie je wieder zusammen. Drei Ebenen, weil eine nicht trägt. Titelschluessel vergleicht ohne Satzzeichen, ohne Akzente und ohne Grossschreibung; ein fehlendes Jahr passt auf jedes, zwei bekannte verschiedene trennen. Bewusst nicht aggressiver: Spider-Man und Spiderman bleiben getrennt, und die beiden Dune von 1984 und 2021 sowieso. Ein zusammengelegter Film lässt sich nicht mehr trennen, ohne zu wissen, welche Datei wohin gehörte. Ein gefilterter Eindeutigkeitsindex auf (LibraryId, TmdbId) stellt die Regel in die Datenbank statt in Code, der sie einhalten soll. Gefiltert, weil ohne Metadaten alle Einträge null tragen. Zusammenlegung räumt auf, was kein Vergleich erkennen könnte: Ich einfach unverbesserlich und Despicable Me sind derselbe Film, und das verrät allein die TMDB-Kennung. Läuft nach jedem Scan, und von Hand über einen Knopf in der Verwaltung. Der Sehfortschritt wird gefaltet, nicht umgehängt — die weitere Stelle gewinnt, gesehen gewinnt, weggelegt gewinnt nicht. Die Migration räumt zuerst auf und legt dann erst den Index an. Andersherum scheiterte sie auf jeder Datenbank mit Dubletten, und zwar beim Start im Container, wo die Meldung niemand sieht. Gemessen an einer Datenbank mit zwei Dubletten und zwei Sehständen: 3 Filme auf 2, beide Dateien erhalten, Position 1800 statt 300 behalten. Dazu Fassungen. MediaFile.VersionLabel liest Mobil, 4K oder Director's Cut aus dem Namen, sonst aus der gemessenen Bildhöhe. Die Liste ist geschlossen, damit eine Fassung nicht YIFY heisst. Und der Fassungsname beendet jetzt den Titel wie jedes andere Beiwerk — vorher wurde aus "The Matrix (1999) - Mobil.mp4" der Film "The Matrix - Mobil", also ein zweiter Eintrag neben dem Original. Genau die Dublette, um die es ging. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d01c5d43f4 |
Der Scan schreibt auch dann zwischendurch, wenn ffprobe scheitert
Gemessen an achtzig Dateien: der Zählstand steht nach einer Sekunde bei 38, nach zwei bei 75, nach drei bei 80. Der Scan liefert also längst laufend — anders als ich behauptet hatte. Der Grund steht in UntersuchenAsync, das je Datei speichert; ich hatte nur das SaveChangesAsync nach der Schleife gesehen. Eine Lücke bleibt: scheitert die Untersuchung, kehrt sie vor dem Speichern um. Ein Bestand aus Dateien, die ffprobe nicht lesen kann, bliebe damit bis zum Schluss unsichtbar, und wer zusieht, hält den Scan für hängend. Deshalb jetzt zusätzlich alle fünfzig Dateien ein Schreiben aus der Schleife heraus — fünfzig und nicht jede, weil ein Schreibvorgang je Datei bei vierzigtausend mehr kostet, als die Sichtbarkeit wert ist. Für das Aufräumen danach ist das unbedenklich, aber nicht offensichtlich: es löscht alles mit älterer SeenAt-Zeit als der Lauf, und würde die Zeit irgendwo neu genommen statt vor der Schleife festgehalten, risse es den halben Bestand mit. Ein Test über 120 Nulldateien — an denen ffprobe scheitert, also genau der neue Weg — hält das fest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ede4069cd4 |
Der Server weiss jetzt mehr als Titel und Plakat
Bisher standen zu einem Film vier Angaben in der Datenbank: Titel, Jahr, Beschreibung, zwei Bilder. Damit lässt sich eine Kachel zeichnen und sonst nichts — keine Detailseite, die mehr sagt als der Dateiname, keine Vorschläge, kein Filter nach Genre. Alles drei hing daran. Jetzt kommen dazu: **Laufzeit, Bewertung, Werbezeile, Altersfreigabe, Genres, Besetzung, Stab — und der Schriftzug des Titels.** Letzterer ist das, was eine Startseite teuer aussehen lässt: „Blade Runner 2049" in seiner eigenen Schrift über dem Hintergrundbild statt in der Systemschrift. **Alles in einer Anfrage.** `append_to_response` hängt Besetzung, Fremdkennungen, Freigaben und Bilder an den Einzelabruf. Vier getrennte Anfragen je Titel wären bei vierhundert Filmen sechzehnhundert, und TMDB begrenzt, wie oft man fragen darf. Der eigene Abruf der IMDb-Kennung ist dabei entfallen — sie hängt jetzt mit dran. Freigaben sind national: die FSK gilt in Deutschland, die MPAA in den USA, und TMDB führt beide nebeneinander. Genommen wird die des eingestellten Landes. Beim Schriftzug entscheidet zuerst die Sprache und erst danach die Bildbewertung — ein deutscher Titel in deutscher Schrift schlägt den besser bewerteten englischen. Vom Stab nur Regie und Drehbuch. TMDB führt dort auch Beleuchter und Caterer; eine Detailseite, die alle nennt, nennt nichts. **Genres und Personen als eigene Tabellen**, nicht als Text im Film. Sonst: filtern über `LIKE`, Tippfehler als eigenes Genre, und bei einer Umbenennung vierhundert Zeilen anfassen. Personen über die Kennung der Quelle geführt, nicht über den Namen — es gibt zwei Schauspieler namens „Chris Evans". Darauf sitzen zwei neue Endpunkte: ein Filter nach Genre (nur die, die in der Mediathek auch vorkommen — ein Knopf zu einer leeren Liste ist schlimmer als kein Knopf) und **Vorschläge** über die Genres des zuletzt Gesehenen. Keine Empfehlungsmaschine: ein Haushaltsserver hat keine Millionen Sehverläufe, aus denen sich etwas lernen liesse. Eine schlichte Regel ist nachvollziehbar, was eine undurchschaubare Empfehlung nie ist. --- **Zwei Fehler, beide fand erst der echte Lauf.** `UNIQUE constraint failed: Genres.Name`, und damit scheiterte der ganze Scan — in der Mediathek erschien kein einziger Titel. Vier Bibliotheken scannen gleichzeitig, jede mit eigenem Datenbankkontext; zwei stossen auf „Drama", keine sieht die ungespeicherte Zeile der anderen. Statt die Läufe zu serialisieren — das kostete bei zehn Bibliotheken das Zehnfache an Zeit — wird der Fehlschlag hingenommen und die Zeile des anderen benutzt. Sie steht ja genau dafür da. Und: **eine geänderte Sprache erreichte vorhandene Titel nie.** Ein zweiter Scan fragt nichts erneut, das ist Absicht. Wer aber von Englisch auf Deutsch stellt, bekam deutsche Titel erst beim nächsten neuen Film. Dafür gibt es jetzt „Metadaten auffrischen" je Bibliothek — geholt über die bekannte Kennung, nicht über eine neue Suche, damit eine Zuordnung von Hand stehenbleibt. 368 Tests grün, zehn davon neu. Am Container nachgewiesen: „Der Untergang", 156 Minuten, FSK 12, Bewertung 7,9, Genres Drama/Historie/Kriegsfilm, 22 Mitwirkende mit Rollennamen, Schriftzug und Hintergrund da — und nach dem Umstellen auf de-DE heisst er nicht mehr „Downfall". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c4081ff251 |
Stufe 4: Fortschritt ab der ersten Sekunde, ohne Schwelle
Der Anlass für diesen Server, jetzt als Code. Fortschritt, Gesehen-Status, Weiterschauen, Nächste Folge, Favoriten und Bewertungen — alles je Benutzer. **Die Jellyfin-Werte sind jetzt belegt statt behauptet.** Das Entwurfsdokument hatte das ausdrücklich offengelassen („aus dem Gedächtnis"); hier stehen sie aus `MediaBrowser.Model/Configuration/ServerConfiguration.cs` und `Emby.Server.Implementations/Library/UserDataManager.cs`: | | Vorgabe | Was passiert | |---|---|---| | `MinResumePct` | 5 | darunter `positionTicks = 0` — Kommentar im Quelltext: „ignore progress during the beginning" | | `MaxResumePct` | 90 | darüber gesehen, Position **auf 0** | | `MinResumeDurationSeconds` | 300 | alles unter fünf Minuten gilt nach dem ersten Lebenszeichen als gesehen | Bei einem Zweistünder sind die ersten sechs Minuten damit weg. Eine vierminütige Folge gilt nach dreissig Sekunden als vollständig gesehen. Und fehlt die Laufzeit, nimmt Jellyfin an, der Titel sei durch — wörtlich: „we'll just have to assume it was fully played". **Flaro legt jede Meldung ab und wirft nie eine Position weg.** Eine Grenze fürs Häkchen gibt es trotzdem — 90 %, sonst stünde jeder zu Ende geschaute Film für immer bei 98 % in Weiterschauen. Der Unterschied ist nicht, *dass* es die Grenze gibt, sondern was sie anrichtet: hier wird ein Häkchen gesetzt, dort zusätzlich die Stelle vernichtet. Wer einen gesehenen Film noch einmal anfängt, hat beides — das Häkchen und den Punkt, an dem er steht. Ohne bekannte Laufzeit wird nichts vermutet. Das ist der Fehler, den man nicht zurücknehmen kann, ohne ihn zu bemerken. --- **Eine Spalte statt einer zweiten Regel.** „Gehört in Weiterschauen" vergleicht die Stelle mit einem Anteil der Laufzeit, und diese Rechnung lässt sich nicht nach SQL übersetzen. Die Regel daneben noch einmal als Abfrage zu schreiben wäre die Variante, bei der beide irgendwann auseinanderlaufen — unbemerkt, weil keine von beiden dabei falsch aussieht. Stattdessen hält `InProgress` das Ergebnis fest, geschrieben an genau einer Stelle. Eine Prüfung hält Reihe und Regel über vier Stände gegeneinander. **„Weiterschauen" und „Nächste Folge" überschneiden sich nicht.** Was angefangen ist, steht links; was ansteht, rechts. Jellyfin zeigt beides doppelt, und auf einer Startseite mit zwei Reihen nebeneinander sieht das nach einem Fehler aus. Dazu, weil die App sie braucht: Einzelabruf für Film und Serie, die nächste Folge nach einer gegebenen, und der Zustand hängt an jeder Liste mit dran — in einer Abfrage je Seite, nicht in einer je Titel. Ein Titel wird über seine Kennung allein angesprochen, ohne dass der Aufrufer sagen muss, ob es ein Film oder eine Folge ist. Die App hat diese Auskunft an der Stelle nicht. 348 Tests grün. Im Container nachgewiesen: fünf Minuten „Der Untergang" von 2:36 bleiben stehen, bei Minute 150 kommt das Häkchen und die Stelle bleibt, beim zweiten Anlauf steht der Film mit beidem wieder in der Reihe — und nach Folge 1 von Dark zeigt „Nächste Folge" S01E02. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
a7cf6c5def |
Halo heisst ab hier Flaro — die Marke stand im Weg
Der Upload zu App Store Connect scheiterte am Namen. „Halo" ist eine eingetragene Marke von Microsoft; im App Store heisst zwar keine App exakt so, aber reservierte und markenrechtlich belegte Namen tauchen in keiner Suche auf. Der einzige verlässliche Test war die Eingabe dort, und die ging daneben. **Der Name wurde diesmal vorher geprüft.** Zwanzig Kandidaten gegen den deutschen und amerikanischen App Store, auf exakte Treffer und auf ähnliche Namen. „Kavo" wäre dieselbe Wand gewesen — exakt belegt in beiden Stores, in Deutschland von KaVo Dental GmbH. „Flare" ist mit 42 ähnlichen Apps je Store der am dichtesten besetzte Name der ganzen Runde. **Flaro** ist in beiden frei und liest sich als eigenes Wort, nicht als Flare mit Tippfehler. Das bleibt eine Store-Suche und keine Markenrecherche — reservierte Namen ohne veröffentlichte App sieht sie nicht. Aber es ist mehr Prüfung, als beim letzten Mal stattfand. --- 2160 Textvorkommen in 273 Dateien, 49 Pfade. Betroffen ist diesmal auch der Server: `Flaro.Api`, `Flaro.Core`, `Flaro.Data`, `Flaro.Media`, `Flaro.Metadata`, `FlaroContext`, `FlaroPaths`, `flaro.db`, die Variablen `FLARO_DATA`, `FLARO_CACHE`, `FLARO_TRANSCODE`, `FLARO_WRITE_SIDECARS`, und das Image. **Vor dem Ersetzen geprüft**, ob „halo" irgendwo als Teil eines anderen Wortes steckt — und ob es im TMDB-Token vorkommt. Tat es nicht; ein blindes Ersetzen hätte den sonst zerlegt. `docs/superpowers/specs/` bleibt wie beim letzten Mal unangetastet: datierte Entwurfsdokumente sind ein Protokoll getroffener Entscheidungen. Das Server-Dokument hat stattdessen einen Nachtrag bekommen, damit es niemanden in die Irre führt. **Die Bundle-ID wandert mit**, zum zweiten Mal an einem Tag: `com.scarriffleservices.flaro`. Wer die vorige Fassung installiert hat, hat jetzt zwei Karteileichen auf dem Gerät — beide löschen, dann ist Ruhe. 308 Server-Tests grün, 368 im Swift-Paket, null Warnungen. iOS und tvOS bauen, das Image baut, und ein frischer Container läuft durch Einrichtung und Anmeldung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |