Homelab 11 Min Read

Meine erste App

Ich habe schon viel Code geschrieben. Skripte, die einen Server aufräumen. Cronjobs, die nachts etwas umrechnen. Kleine Helfer, die genau eine Sache machen und sonst nichts. Aber nie eine App.…

Ich habe schon viel Code geschrieben. Skripte, die einen Server aufräumen. Cronjobs, die nachts etwas umrechnen. Kleine Helfer, die genau eine Sache machen und sonst nichts. Aber nie eine App. Nie etwas mit einem Gesicht, das man aufmacht, das andere installieren können, das einen Namen hat und ein Zuhause im Internet.

Jetzt schon. Sie heißt Regalratte, sie verwaltet meine Film-Sammlung, und seit heute steht sie unter einer freien Lizenz auf GitHub, wo sie sich jeder ziehen kann.

Angefangen hat das damit, dass ich Blade Runner 2049 zum zweiten Mal gekauft habe. Aus einem Doppelkauf wurden zwei Tage Coden. Aus zwei Tagen Coden wurde eine Datenbank mit vierhundert Filmen. Und aus der Datenbank wurde die erste Software, bei der ich sagen würde: Das ist eine App, keine Bastelei.

Dieser Text ist die Bestandsaufnahme. Was das Ding kann, wie es aussieht, wo es wehgetan hat, und warum ich es verschenke.

Das Regal, aber durchsuchbar

Die Idee ist banal: Ich fotografiere eine Hülle mit dem Handy, den Rest macht die App. Sie erkennt den Film, holt Cover und Daten von TMDB und sagt mir, wo er im Regal steht. Ein Foto vom Regalbrett genügt, um abzugleichen, was tatsächlich drinsteht.

Das Ergebnis ist mein Regal, nur eben als Bildschirm. Türme, Ebenen, Fächer — mit den echten Covern.

Dreihundertachtundachtzig Plätze belegt, hundertachtzehn frei. Jedes Fach mit Cover und einem kleinen Kennzeichen, ob 4K oder Blu-ray. Das ist der Punkt, an dem eine Datenbank aufhört, sich wie eine Tabelle anzufühlen, und anfängt, sich wie ein Regal anzufühlen.

Fahr über ein Cover, und es wird groß.

Klick drauf, und du landest auf der Detailseite. Poster, Beschreibung, Laufzeit, die Tonspuren im Vergleich Deutsch gegen Original — und, das ist mir am wichtigsten, der genaue Standort: Wohnzimmer, Turm 3, Ebene 1, Platz 2, zwischen Gladiator II und Godzilla II.

Der letzte Satz ist der eigentliche Sinn der ganzen Sache. Ich will im Regal nicht Fächer abzählen, ich lese Rücken. Also sagt mir die App, zwischen wem der Film liegt. Steht er mal falsch, findet man ihn trotzdem.

Und wenn ich gar nicht weiß, wonach ich suche, sondern nur blättern will, gibt es die Cover-Wand mit Volltextsuche über Titel, Regie, Schauspieler, Genre und Strichcode.

Warum eine Box kein Film ist

Die Frage, an der jede fertige Lösung scheitert, ist unscheinbar: Was ist eine Hülle?

Für die meisten Apps ist eine Hülle ein Film. Ein Cover, ein Titel, ein Eintrag. Bei mir ist das für ein Drittel der Sammlung schlicht falsch. In der Bud-Spencer-Box stecken siebzehn Filme. Die Daniel-Craig-Collection sind vier. Herr der Ringe sind drei, und wenn man die Extended Editions dazurechnet, wird es unübersichtlich.

Eine Hülle ist also ein Regalplatz und gleichzeitig beliebig viele Filme. Wer das nicht sauber trennt, zählt entweder die Regalplätze falsch oder findet einen Film nicht, weil er in einer Box steckt, die anders heißt.

Deshalb liegt unter der App keine Tabelle, sondern ein Datenmodell mit drei Ebenen: die Hülle, die Disc darin, und der Film auf der Disc. Eine Hülle hat eine oder mehrere Discs, eine Disc trägt einen oder mehrere Filme. Klingt nach Overkill für „ich will meine Blu-rays sortieren”. Ist aber der einzige Weg, bei dem am Ende die Zahl stimmt — und bei dem die Suche nach „Casino Royale” auch dann trifft, wenn er nur als Teil der Craig-Collection im Regal steht.

Das ist der unsichtbare Teil, der aus einer Liste eine App macht. Man sieht ihn nie. Man merkt ihn nur, wenn er fehlt.

Ein Bildschirm, zwei Knöpfe

Beim Erfassen entscheidet sich, ob so ein Projekt durchgezogen wird oder nach dreißig Hüllen im Sand verläuft. Vierhundert Mal etwas eintippen macht niemand.

Die erste Fassung hatte ein Formular. Nach zwei Regalbrettern war klar, dass das nicht geht. Die zweite ist ein einziger Bildschirm: Kamerabild formatfüllend, unten drei Knöpfe. Auslöser, Fertig, Fotomediathek. Ich knipse Vorder- und Rückseite, drücke Fertig, greife zur nächsten Hülle. Was das ist und wohin es gehört, entscheidet der Server später.

Zwei Details haben mehr gebracht als alles andere. Erstens: Die Fotos gehen in eine lokale Warteschlange im Browser. Im Keller bricht das WLAN weg — statt einer Fehlermeldung landen die Bilder zwischengespeichert und gehen hoch, sobald wieder Netz da ist. Zweitens: ein Schalter für ganze Regalbretter, weil Mediabooks und Steelbooks bei mir beieinanderstehen und auf der Rückseite oft gar nichts Brauchbares steht. Einmal oben antippen, das Brett durchknipsen, fertig.

Vierhundert Hüllen erfasst man so an zwei Abenden. Ohne diesen Bildschirm hätte ich nach dreißig aufgegeben.

Warum es sich wie eine App anfühlt und nicht wie ein Skript

Der Unterschied zwischen einem Skript und einer App sind nicht die Features. Es ist die Frage, ob jemand anderes es benutzen kann, ohne dass ich danebensitze.

Genau da hakte es lange. Der Erkennungsteil lief bei mir zu Hause über einen Mac mini mit Apple Vision und meinem Claude-Abo auf der Kommandozeile. Charmant für mich, unbrauchbar für alle anderen. Wer keinen Mac und kein Abo hat, hatte eine schöne leere Hülle.

Also habe ich die App aufgemacht. Es gibt jetzt ein Einstellungs-Menü, in dem man alles selbst festlegt, statt einer Black-Box zu vertrauen.

KI-Zugang, Prompts, die angebundenen Dienste — steht alles da, und man trägt seine eigenen Schlüssel ein. Secrets werden verschlüsselt gespeichert und nie im Klartext zurückgegeben. Das ist die Zeile, die aus meinem Werkzeug eine Software für andere macht.

Erkennung: drei Wege, von gratis bis pixelgenau

Die spannendste Frage beim Aufmachen war die Bilderkennung. Bei mir lief sie über den Mac. Für die Allgemeinheit brauchte es Wege, die ohne meinen Mac funktionieren.

Es sind drei geworden.

Ohne KI, kostenlos. Ein Barcode-Leser liest den Strichcode auf der Rückseite und schlägt ihn über jpc.de nach. Dazu Tesseract als Texterkennung im Container. Kein Schlüssel, keine laufenden Kosten.

Hier war ich ehrlich zu mir selbst und habe es gemessen. Reines Texterkennen auf glänzenden UHD-Covern mit ihren Künstler-Schriften ist grottig — in einem Test mit sechs Hüllen: null von sechs richtig. Gemini Man wurde zu „HIGH FRAME RATE”, Barbie zu Kauderwelsch. Der Barcode rettet das: Wo der Strichcode auf dem Foto scharf genug war, sprang das Ergebnis auf drei von sechs, exakt richtig. Der Rest scheiterte nicht an der Logik, sondern an unscharfen Strichcodes.

Die Lehre steht so auch im Handbuch: Ohne KI taugt es für saubere Cover und lesbare Barcodes. Wer es zuverlässig über die ganze Sammlung will, hinterlegt eine KI.

Mit eigener KI. Anthropic, OpenAI, Google oder ein lokales Ollama-Modell. Schlüssel eintragen, ein Knopf testet die Verbindung, und der Container erledigt die Bilderkennung selbst. Kein Mac nötig, keine fremde Hardware.

Der Nerd-Weg. Wer wie ich einen Mac und ein Claude-Abo hat, kann Apple Vision fürs Lesen und die Claude-Kommandozeile fürs Verstehen nehmen und spart die API-Kosten komplett. Steht dokumentiert dabei, für die, die es reizt.

Die Hardware gehört dazu

Eine Film-Datenbank, die nicht weiß, wie das Regal aussieht, beantwortet die falsche Frage. Meine Halter drucke ich selbst — acht Fächer pro Modul, Module stapeln sich zu Türmen. Die App weiß das und rechnet damit: Sie sagt mir nicht nur, wo ein Film steht, sondern auch, wie viele Halter ich noch drucken muss.

Die Module liegen bei MakerWorld, verlinkt in der App und im Handbuch. Wer die App nachbaut, kann sich dasselbe Regal drucken.

Der Wächter, der auf Angebote wartet

Der Auslöser war ja ein Doppelkauf. Also gehört zur App der Teil, der sich im Laden bezahlt macht — und zwar auf dem Handy, nicht am Schreibtisch.

Im Laden fotografiere ich die Hülle. Ein Tipp, den Titel sucht der Rechner zu Hause nach, während ich weiterlaufe. Die Antwort auf der Karte ist nicht „hast du schon” — das wäre falsch, wenn ich die UHD suche und nur die Blu-ray im Regal steht. Die Antwort ist: „Hast du als Blu-ray, die UHD fehlt dir. Steht in Keller, Turm 3, Ebene 3, Platz 5.” Ein Upgrade ist kein Doppelkauf.

Wenn ich nicht kaufe, sondern nur will, trage ich einen Zielpreis ein. Jeden Morgen sieht ein Skript nach, was die beobachteten Filme kosten. Es liest keine Shop-Seiten mit einem eigenen Scraper je Laden — das bricht bei jedem Relaunch. Es liest die Daten, die praktisch jeder Shop freiwillig ausliefert, weil Google sie will. Funktioniert bei JPC, MediaMarkt, Saturn, Thalia. Amazon blockt, da bleibt das Feld ehrlich leer statt falsch gefüllt.

Das eigentlich Nützliche sind aber nicht einzelne Preise, sondern Aktionen. Drei für zwei. Bei drei für zwei ist der günstigste Artikel gratis — man will also drei möglichst gleich teure Titel bündeln, nicht den Acht-Euro-Ramsch mit der Dreißig-Euro-Neuheit mischen. Das ist ein kleines Rechenproblem, und genau dafür ist eine Datenbank da, in der jeder Preis der letzten Monate steht. Die Meldung kommt dann nicht als „Preis gefallen”, sondern als „aus deiner Wunschliste passen drei, nimm die und die, dann ist der teuerste geschenkt”.

Der Teil, der wehgetan hat

Zur ehrlichen Bestandsaufnahme gehört der Tag, an dem ich meine eigene Synology umgelegt habe.

Der Docker-Build auf der NAS wollte plötzlich nicht mehr. Ursache war banal und fies zugleich: Die Build-Container bekamen keine funktionierende Namensauflösung, apt hing endlos. Auf der Suche nach dem Fix habe ich den Container-Manager neu gestartet — und der hat beim Neustart den Docker-Socket und ein paar Symlinks mitgerissen und schließlich den ganzen Docker-Dienst hängen lassen. Für einen Moment waren nicht nur die Regalratte weg, sondern auch Jellyfin, Home Assistant, der Passwort-Manager, alles.

Die NAS selbst war die ganze Zeit gesund, kein Byte verloren. Ein sauberer Neustart hat alles wieder hochgezogen, ein paar Container musste ich von Hand nachstarten. Aber die Lektion sitzt: Auf dieser Synology fasse ich den Container-Manager nicht mehr über die Kommandozeile an. Und neue Versionen der App spiele ich jetzt per Datei-Kopie in den laufenden Container statt über einen Neu-Bau, weil der Bau an genau dem DNS-Problem hängt.

Das ist der Teil, den man in Release-Ankündigungen nie liest. Zwischen „läuft bei mir” und „läuft veröffentlicht” liegt ein Nachmittag, an dem gar nichts läuft.

Und jetzt kann es sich jeder holen

Der Code steht auf GitHub, unter der AGPL. Die Regal-Module unter einer Creative-Commons-Lizenz, Namensnennung, nicht kommerziell. Ein Handbuch liegt dabei, samt Anleitung, wie man iOS die Kamera per HTTPS-Zertifikat freischaltet — denn ohne HTTPS gibt das iPhone die Kamera nicht her, und ohne Kamera kein Live-Sucher.

Es gibt sogar einen kleinen Selbstbedienungs-Teil, den ich zuletzt gebaut habe: Wenn ein Regal-Scan einen Film erkennt, den es in der Sammlung noch gar nicht gibt, kann man ihn direkt aus der Oberfläche über TMDB nachtragen und ins Fach setzen. Genau der Fall „das Ding steht im Regal, aber die App kennt es nicht” — ohne Umweg.

Warum verschenken? Weil ich von genau solchen Projekten anderer seit Jahren lebe. Meine halbe Homelab besteht aus Software, die jemand gebaut und rausgestellt hat, ohne dafür Geld zu wollen. Regalratte ist nichts Weltbewegendes. Aber es ist mein Beitrag zurück in denselben Topf.

Was ich mitgenommen habe

Der Sprung vom Werkzeug zur App ist eine Zeile. Nicht ein Feature, sondern der Moment, in dem die Konfiguration aus meinem Kopf in ein Menü wandert. Solange die Zugangsdaten bei mir im Schlüsselbund liegen, ist es meins. Sobald sie in einem Feld stehen, das jeder ausfüllen kann, ist es Software.

Ehrlich messen schlägt schön behaupten. Null von sechs ohne KI klingt nach einem Armutszeugnis. Aber es ist die Wahrheit, und die Wahrheit gehört ins Handbuch, damit niemand sich wundert. Eine App, die verspricht was sie nicht hält, ist schlimmer als eine, die ihre Grenzen kennt.

Veröffentlichen ist ein eigenes Projekt. Der Code war fertig. Trotzdem lag zwischen „fertig” und „online” ein Tag mit Sicherheitsprüfung, generischen Beispieldaten statt meiner echten, einer aufgeräumten Migrationskette und der Frage, welche interne IP versehentlich im Quelltext steht. Ein öffentliches Repo ist keine Kopie deines Ordners. Es ist eine bewusste Entscheidung, was drin sein darf und was nicht.

Und die banalste Erkenntnis zum Schluss: Meine erste App löst kein großes Problem. Sie sagt mir, ob ich Blade Runner 2049 schon habe. Aber sie tut es gut, sie sieht ordentlich aus, und ab heute kann es jeder nachbauen. Für eine erste App nehme ich das.


Regalratte auf GitHub: github.com/DarkRudolf/regalratte

Die Regal-Module: makerworld.com — „Stackable Blu-ray / DVD Case Shelves”