Erste eigene Nextcloud App – Metafetch

Seitdem Nextcloud die Funktion den Download Managers entfernt hatte, hat mir immer ein Download Manager für meine Dateien gefehlt. Entfernt hatte Nextcloud diese Funktion vor sechs bis sieben Jahren. Seitdem hatte ich die App NCDownloader genutzt. Nun wurde die aber seit mehr als 2 Jahren nicht mehr aktualisiert, dann hab ich mich selbst an die Weiterentwicklung gemacht. 

Eigentlich fehlte mir nur ein Download-Manager

Die ganze Geschichte mit MediaFetch hat ziemlich unspektakulär angefangen. Ich wollte für meine eigene Nextcloud schlichtweg einen vernünftigen Download-Manager haben.

Nicht mehr und nicht weniger.

Ich wollte Links direkt in der Nextcloud anwerfen können, normale Dateien herunterladen, Torrents und Magnet-Links nutzen und bei Bedarf auch Medien über yt-dlp holen. Das Ganze bitte möglichst so, dass ich nicht jedes Mal auf den Server springen oder irgendeine zusätzliche Weboberfläche öffnen muss. Und weil ich Nextcloud auch ziemlich oft auf dem Smartphone nutze, sollte das dort ebenfalls vernünftig funktionieren.

Es gibt natürlich andere Projekte und Ansätze. Unter anderem hatte ich mir auch Vedor angesehen. Ich möchte daraus aber keinen künstlichen Konkurrenzvergleich machen. Andere Apps verfolgen andere Ziele und können für viele Nutzer vollkommen ausreichend sein. Mir fehlte für meinen eigenen Einsatz schlicht die Kombination, die ich haben wollte: klassischer HTTP-Download, Torrent, Magnet-Links und yt-dlp innerhalb von Nextcloud – und das Ganze bitte auch auf einem Smartphone benutzbar.

Also habe ich weitergesucht.

Dabei bin ich wieder bei NCDownloader gelandet. Ganz unbekannt war mir die App nicht. Ich hatte bereits 2024 darüber geschrieben, als NCDownloader wieder funktionsfähig war. Die grundsätzliche Idee hinter der App fand ich damals schon ziemlich gut.

Nur war inzwischen das Problem da, das man bei älteren Open-Source-Projekten irgendwann bekommt: Die Software stammte aus einer anderen Nextcloud-Generation.

Im offiziellen Nextcloud App Store wird NCDownloader derzeit nur bis Nextcloud 31 angeboten. Zusätzlich gibt es inzwischen Berichte über Probleme mit Nextcloud 32 und 33. Deshalb wäre es unfair zu behaupten, das Projekt sei einfach „seit Jahren tot“. Aber für aktuelle Installationen war eben einiges an Arbeit nötig. (apps.nextcloud.com)

Warum alles neu schreiben, wenn schon eine gute Basis da ist?

An dem Punkt hätte ich natürlich sagen können: Gut, dann programmiere ich eben meinen eigenen Download-Manager komplett von null.

Das wäre allerdings ziemlich größenwahnsinnig gewesen.

Ich bin kein klassischer Softwareentwickler. Ich administriere meine Systeme, beschäftige mich gern mit Linux, Docker, Nextcloud und Open Source und kann mich auch durch Code und Logs arbeiten. Aber ich setze mich nicht morgens hin und schreibe mal eben eine komplette Nextcloud-App aus dem Kopf.

Dazu kam noch etwas anderes: NCDownloader war freie Software. Die grundlegende Arbeit war bereits gemacht worden. Warum sollte ich eine gute Idee wegwerfen und alles noch einmal neu erfinden?

Also habe ich angefangen, die bestehende Codebasis weiterzuentwickeln.

Zwischenzeitlich lief das Ganze bei mir unter dem Namen Net Loader. Im April hatte ich schon ausführlicher darüber geschrieben, warum ich NCDownloader als Nextcloud-App weiterentwickeln wollte. Aus diesem Versuch, die bestehende App wieder vernünftig auf aktuellen Nextcloud-Versionen zum Laufen zu bekommen, wurde mit der Zeit aber immer mehr.

Und irgendwann war der Punkt erreicht, an dem eine bloße Reparatur oder ein anderer Name eigentlich nicht mehr passend war.

Daraus entstand MediaFetch.

Wichtig ist mir dabei eine Sache: MediaFetch ist nicht plötzlich aus dem Nichts entstanden und ich stelle mich auch nicht hin und behaupte, die gesamte Anwendung selbst erfunden zu haben.

Das Repository ist weiterhin als Fork der ursprünglichen NCDownloader-Codebasis erkennbar. MediaFetch basiert auf NCDownloader und damit auf der Arbeit von Jiaxin Huang und weiteren früheren Mitwirkenden. Die bestehende Copyright- und Lizenzhistorie wurde beibehalten. Auch MediaFetch steht unter AGPL-3.0-or-later. Das ist für mich bei Open Source schlicht der saubere Weg. (GitHub)

ChatGPT war dabei mein Entwicklungsassistent

Ein weiterer Teil der Geschichte gehört für mich genauso offen dazu: Bei der Entwicklung habe ich sehr intensiv ChatGPT verwendet.

Und nein, das bedeutet nicht, dass ich einen Satz wie „Programmier mir eine Nextcloud-App“ eingegeben habe und danach MediaFetch fertig vom Himmel gefallen ist.

Schön wär’s gewesen.

In der Realität sah das eher so aus:

Idee → vorhandenen Code ansehen → verstehen, was dort überhaupt passiert → Änderung umsetzen → App installieren → Fehler bekommen → Logs ansehen → nächsten Fehler finden → korrigieren → wieder installieren → testen → nächste Baustelle.

Und dann das Ganze noch einmal.

Und noch einmal.

Meine Aufgabe war dabei vor allem zu wissen, was ich überhaupt haben wollte. Ich habe die Anwendung auf meiner eigenen Nextcloud installiert, praktisch benutzt, Fehler gefunden, Funktionen ausprobiert und entschieden, was sinnvoll ist und was nicht. Wenn etwas nach einer Änderung zwar technisch irgendwie funktionierte, aber im Alltag Blödsinn war, ging es eben zurück an die nächste Runde.

ChatGPT hat mir dabei geholfen, bestehenden PHP- und JavaScript-Code zu analysieren, Änderungen umzusetzen und Fehlermeldungen auseinanderzunehmen. Gerade bei den Nextcloud-APIs war das hilfreich, weil sich über mehrere Nextcloud-Generationen einiges verändert hat. Auch beim Aufspüren möglicher Sicherheitsprobleme, beim Umbau einzelner Abläufe und bei der Vorbereitung von Pull Requests war das Werkzeug für mich sehr nützlich.

Die Anforderungen, Entscheidungen und Tests verschwinden dadurch aber nicht. Im Gegenteil: Gerade wenn man sich Code generieren oder verändern lässt, muss man ziemlich genau prüfen, was danach tatsächlich passiert.

Ich hatte mehr als einmal den Moment, dass etwas auf den ersten Blick gut aussah und beim ersten echten Test dann doch irgendwo gegen die Wand lief.

Dann hieß es wieder: Logs auf, Ursache suchen, ändern, neu testen.

Das war eigentlich der normale Entwicklungsprozess von MediaFetch.

Was MediaFetch 1.0.0 inzwischen kann

Aus dem ursprünglichen „ich brauche da einen Download-Button“ ist inzwischen ein ziemlich umfangreicher Download-Manager geworden.

MediaFetch verwendet aria2 und yt-dlp als eigentliche Download-Backends. aria2 kümmert sich um klassische HTTP- und HTTPS-Downloads und unterstützt außerdem Torrent-Dateien sowie Magnet-Links. Für Mediendownloads kommt yt-dlp zum Einsatz. Mit ffmpeg sind zusätzlich Audioextraktion und Medienkonvertierung möglich. Die aktuelle erste öffentliche Version ist MediaFetch 1.0.0. (GitHub)

Mir war dabei wichtig, dass mehrere Nextcloud-Nutzer nicht zwangsläufig dieselbe Konfiguration verwenden müssen. Jeder Benutzer kann einen eigenen Downloadordner festlegen. Für Torrents gibt es einen separaten Zielordner. Auch bestimmte aria2- und yt-dlp-Einstellungen können pro Benutzer angepasst werden.

Die grundlegende Kontrolle über die eigentlichen Programme bleibt dagegen beim Administrator.

Der Administrator legt fest, wo aria2 und yt-dlp liegen beziehungsweise welche ausführbaren Dateien MediaFetch starten darf. Dabei können statt der eigentlichen Programme auch kontrollierte Wrapper-Skripte verwendet werden.

Das klingt zunächst nach einem ziemlich speziellen Detail, ist für Selfhosting aber durchaus praktisch.

So lässt sich beispielsweise ein Downloader in einem eigenen Network-Namespace oder über ein VPN starten, ohne deshalb die komplette Nextcloud durch dieses VPN schicken zu müssen. Ich hatte in der Vergangenheit selbst schon mit solchen Netzwerkkonstruktionen gearbeitet – meine ältere Nextcloud-Anleitung mit Docker und Gluetun geht noch deutlich radikaler vor und routet die Cloud entsprechend über das VPN.

Bei MediaFetch wollte ich das sauberer trennen können: Nextcloud bleibt Nextcloud, während der Administrator festlegen kann, wie der eigentliche Downloader ins Netz geht.

Dazu kommt die Statusanzeige direkt innerhalb von MediaFetch. Gerade bei yt-dlp war mir wichtig, nicht einfach nur irgendeinen drehenden Kreis zu zeigen. Der Download durchläuft erkennbare Phasen. MediaFetch kann anzeigen, dass ein Auftrag vorbereitet wird, dass tatsächlich heruntergeladen wird, dass die fertigen Dateien anschließend in Nextcloud übernommen werden und dass der Vorgang abgeschlossen ist. (GitHub)

Einer der größeren Umbauten: yt-dlp und das Nextcloud-Datenverzeichnis

Eine der Stellen, an denen aus einer kleinen Anpassung eine größere Baustelle wurde, war der yt-dlp-Workflow.

Die ursprüngliche Anwendung konnte Dateien direkt in Bereiche des Nextcloud-Datenverzeichnisses schreiben und anschließend versuchen, Nextcloud über einen Dateiscan dazu zu bringen, diese Dateien zu erkennen.

Das funktionierte früher vielleicht halbwegs brauchbar. Bei modernen Nextcloud-Versionen ist das aber kein besonders schöner Weg mehr.

Nextcloud verwaltet seine Dateien nicht einfach nur als beliebige Dateien auf einer Festplatte. Dahinter hängen unter anderem die eigene Storage-Schicht, Dateisperren und Metadaten. Wenn eine Anwendung an diesen Mechanismen vorbei direkt in das Datenverzeichnis schreibt und anschließend sinngemäß sagt „such das mal“, kann es unschöne Effekte geben.

Bei meinen Tests waren gerade Dateisperren eine Baustelle.

Deshalb funktioniert der yt-dlp-Ablauf in MediaFetch 1.0.0 anders.

yt-dlp lädt zunächst in einen privaten temporären Arbeitsbereich außerhalb des eigentlichen Nextcloud-Datenverzeichnisses. Dort kann yt-dlp seine Arbeit erledigen, inklusive der Verarbeitung durch ffmpeg, ohne gleichzeitig im Datenbestand eines Nextcloud-Benutzers herumzuschreiben.

Erst wenn der eigentliche Download abgeschlossen ist, übernimmt MediaFetch die fertigen Dateien über die öffentlichen Nextcloud Files APIs in den gewünschten Benutzerordner.

Das ist ein ziemlich wichtiger Unterschied.

Die Datei wird damit nicht mehr an Nextcloud vorbeigeschmuggelt und anschließend durch einen erzwungenen Scan bekannt gemacht. Sie wird über die von Nextcloud vorgesehene Dateischnittstelle in den Storage übernommen. Nextcloud kennt die Datei damit direkt über seine eigene Storage-Schicht.

Der alte erzwungene Folder-Scan konnte dadurch aus diesem Workflow verschwinden. Genau dieser Umbau ist auch im Changelog der Version 1.0.0 dokumentiert. (GitHub)

Nebenbei wurde der Ablauf dadurch für den Benutzer verständlicher. MediaFetch weiß jetzt besser, in welchem Abschnitt sich ein Auftrag befindet. Deshalb gibt es diese Zustände wie „wird vorbereitet“, „wird heruntergeladen“, „wird in Nextcloud übernommen“ und schließlich „fertig“.

Das sind Kleinigkeiten, bis man einen größeren Download startet und wissen möchte, warum die Datei noch nicht im Zielordner liegt.

Auf dem Smartphone sollte es bitte nicht wehtun

Ein Punkt hat mich bei älteren Lösungen immer wieder gestört: Auf dem Desktop waren sie irgendwie bedienbar, auf einem Smartphone wurde es teilweise abenteuerlich.

Und ich möchte einen Download-Manager gerade unterwegs benutzen.

Wenn mir auf dem Smartphone ein Link begegnet, möchte ich ihn an meine Nextcloud schicken können und fertig. Dafür will ich nicht erst einen Desktop-Rechner suchen oder auf einer Webseite horizontal durch eine Navigation schieben, die eigentlich für einen 27-Zoll-Monitor gedacht war.

Deshalb bekam MediaFetch ausdrücklich eine responsive Navigation mit einem mobilen Drawer.

Das war für mich keine Funktion, die irgendwo in einem Frontend-Framework auf dem Papier „responsive“ heißt und dann abgehakt wird. Ich habe die Oberfläche tatsächlich auf dem Smartphone benutzt und angepasst.

Menü auf. Download anlegen. Zwischen den Bereichen wechseln. Einstellungen erreichen. Status kontrollieren.

Es muss nicht aussehen wie eine native Smartphone-App. Aber es muss benutzbar sein.

Die mobile Navigation gehört deshalb für mich tatsächlich zu den Dingen, auf die ich bei Version 1.0 mehr Wert gelegt habe, als man beim Stichwort „Download-Manager“ vielleicht zuerst erwarten würde. Im Changelog wird die mobile Navigation ausdrücklich als Bestandteil des 1.0.0-Umbaus für aktuelle Nextcloud-Versionen geführt. (GitHub)

Aus alter Codebasis wurde auch eine Sicherheitsbaustelle

Je länger ich mich mit dem Projekt beschäftigt habe, desto klarer wurde auch: Für eine App, die nur privat auf meinem eigenen Server herumliegt, kann man manche Dinge vielleicht noch pragmatisch sehen. Sobald man so etwas öffentlich anbietet, sieht die Sache anders aus.

Ein Download-Manager startet schließlich externe Programme und verarbeitet Eingaben von Benutzern. Das ist genau die Kombination, bei der man nicht einfach alles durchreichen sollte, was irgendwo in einem Textfeld landet.

Deshalb wurden die erlaubten yt-dlp-Optionen für normale Benutzer über eine Allowlist eingeschränkt. Gefährliche aria2-Optionen wurden ebenfalls aus den persönlichen Einstellungen herausgenommen.

Ein Benutzer soll nicht über irgendeine vermeintlich harmlose Downloader-Option plötzlich beliebige lokale Befehle auf dem Server starten können.

Genauso wenig darf ein normaler Benutzer einfach sagen: „Mein yt-dlp liegt übrigens unter /irgendwo/mein-eigenes-programm“ und MediaFetch führt das dann brav aus.

Welche Downloader-Binaries oder Wrapper tatsächlich verwendet werden dürfen, entscheidet deshalb der Administrator.

Auch Zielpfade und Output-Templates mussten eingeschränkt werden. Ein Benutzer soll über ein geschickt formuliertes Template nicht aus seinem vorgesehenen Downloadbereich heraus navigieren können.

Eine weitere Altlast waren frei konfigurierbare Shellbefehle zum Starten und Stoppen einer VPN-Verbindung. Das habe ich entfernt. Wenn Downloads über ein VPN oder einen speziellen Network-Namespace laufen sollen, ist das Sache des Administrators. Dafür gibt es die kontrollierten Wrapper.

Das ist etwas weniger „mach einfach alles möglich“, dafür kann ich bei einer öffentlich veröffentlichten App wesentlich besser damit leben.

Projektlinks: GitHub: [GitHub-Link einfügen] · Nextcloud App Store: [Nextcloud-App-Store-Link einfügen]

Die Einschränkungen für yt-dlp und aria2, die Entfernung der alten VPN-Shellbefehle und die Kontrolle der Downloader-Pfade sind für MediaFetch 1.0.0 dokumentierte Sicherheitsänderungen. (GitHub)

MediaFetch ist mehr als ein neuer Name

Zwischendurch hätte ich das Projekt theoretisch einfach weiter NCDownloader nennen und ein neues Logo darüberkleben können.

Das wollte ich nicht.

MediaFetch bekam deshalb die eigene App-ID mediafetch. Auch Routen, Übersetzungsdomains und andere Stellen wurden entsprechend von NCDownloader auf MediaFetch umgestellt. Dazu kam ein neues Icon und der Wechsel auf aktuelle Nextcloud-Frontend-Komponenten. Unter anderem verwendet MediaFetch inzwischen den modernen Nextcloud-Dateiauswahldialog. (GitHub)

Der Haken an einer neuen App-ID ist allerdings offensichtlich: Nextcloud behandelt die Anwendung damit als andere App.

Blöd, wenn jemand vorher NCDownloader genutzt und dort bereits alles eingestellt hat.

Deshalb habe ich versucht, diesen Wechsel nicht unnötig brutal zu machen. MediaFetch kann vorhandene App- und Benutzereinstellungen aus dem alten ncdownloader-Namensraum übernehmen. Dazu gehören unter anderem Download- und Torrent-Ordner sowie persönliche aria2- und yt-dlp-Einstellungen.

Auch vorhandene Download-Datensätze können übernommen werden.

Wichtig fand ich dabei, bei der ersten Migration nicht gleich hinter mir die Brücke anzuzünden. Die alten Daten werden deshalb nicht einfach sofort gelöscht. MediaFetch übernimmt, was benötigt wird, während die Legacy-Daten zunächst erhalten bleiben. (GitHub)

Warum ich nicht einfach Vedoa oder etwas anderes genommen habe

Die Frage ist vollkommen berechtigt.

Warum dieser ganze Aufwand, wenn es andere Downloader gibt?

Weil Software am Ende immer zum eigenen Workflow passen muss.

Ich möchte Vedoa oder irgendeine andere Alternative überhaupt nicht schlechtreden. Ein anderes Projekt kann für einen anderen Anwender genau richtig sein. Man muss auch nicht jedes Problem mit einem neuen Fork beantworten.

Bei mir war es einfach die Kombination.

Ich wollte normale HTTP- und HTTPS-Downloads, Torrents, Magnet-Links und yt-dlp in einer Nextcloud-App haben. Dazu individuelle Ordner und Einstellungen, eine vernünftige mobile Oberfläche und die Möglichkeit, den eigentlichen Downloader auf Serverseite kontrolliert in ein anderes Netzwerk oder VPN zu schicken.

Und ich hatte mit NCDownloader bereits eine freie Codebasis vor mir, deren Grundidee ziemlich genau in diese Richtung ging.

Aus „ich passe mir da mal etwas an“ wurde dann eben Stück für Stück ein eigenes Projekt.

Oder um es schlichtweg zu sagen:

Eigentlich wollte ich nur einen Download-Manager für meine Nextcloud. Irgendwann saß ich dann da und beantragte bei Nextcloud ein Code-Signing-Zertifikat für meine eigene App.

Damit hatte ich am Anfang nun wirklich nicht gerechnet.

Der Weg zur ersten Version im App Store

Mit der Zeit ging es deshalb nicht mehr nur darum, ob MediaFetch auf meinem Server irgendwie startet.

Die PHP-Abhängigkeiten mussten aktualisiert werden. Der Code musste mit PHP 8.2 bis 8.4 klarkommen. Anpassungen für aktuelle Nextcloud-Versionen waren nötig. Das Frontend wurde modernisiert, alte APIs flogen raus oder wurden ersetzt und die verschiedenen Stellen mit dem alten NCDownloader-Namen mussten auf MediaFetch umgestellt werden.

Dazu kamen GitHub Actions.

Damit werden unter anderem PHP-Syntax, App-Metadaten und der Frontend-Build geprüft. Ein automatischer Check ersetzt keine echten Tests, aber er verhindert zumindest einige ziemlich dumme Fehler, bevor sie in einem Release landen. (GitHub)

Und dann habe ich getestet.

Nicht nur irgendeinen theoretischen Build, sondern die App auf einer echten Nextcloud-Installation. Einstellungen öffnen, Download starten, yt-dlp verwenden, Dateien importieren, aria2 testen, Navigation ausprobieren und das Ganze auch auf dem Smartphone.

Der für MediaFetch 1.0.0 dokumentierte öffentliche Kompatibilitätsbereich liegt bei Nextcloud 32 bis 34 und PHP 8.2 bis 8.4. In den Release-Tests wurde unter anderem Nextcloud 34.0.2 mit PHP 8.4 verwendet. (GitHub)

Irgendwann kam dann der Teil, den ich Monate vorher überhaupt nicht auf dem Schirm hatte: offizielles Code Signing.

Zertifikat beantragen, App für den Store vorbereiten, Release bauen und signieren.

Und schließlich Version 1.0.0 veröffentlichen.

Das GitHub-Release vom 26. August 2026 bezeichnet MediaFetch 1.0.0 ausdrücklich als erste öffentliche Version. Für mich ist es gleichzeitig noch etwas anderes: Es ist meine erste veröffentlichte Nextcloud-App. (GitHub)

Das macht die Sache für mich tatsächlich etwas besonders.

Nicht weil MediaFetch jetzt angeblich die beste Download-App aller Zeiten wäre. Das wäre Quatsch. Version 1.0.0 ist der erste öffentliche Stand eines Projekts, das aus einer älteren Codebasis entstanden ist und an dem sicher noch genug Stellen auftauchen werden, die verbessert werden können.

Aber aus einem Problem auf meinem eigenen Server ist ein Open-Source-Projekt geworden, das jetzt auch andere installieren können.

Das fühlt sich schon ziemlich gut an.

Und jetzt?

Mit Version 1.0.0 ist MediaFetch für mich nicht fertig.

Das wäre bei Software vermutlich sowieso eine gefährliche Aussage.

Als Nächstes möchte ich vor allem weiter an der Bedienung arbeiten. Gerade kleine Dinge fallen meistens erst auf, wenn mehrere Leute eine App anders benutzen als man selbst. Auch Performance und Ressourcensteuerung sind Themen, die ich weiter verbessern möchte.

Dazu können später weitere Download-Funktionen kommen. Was davon tatsächlich sinnvoll ist, möchte ich aber nicht jetzt schon als riesige Roadmap versprechen.

Erst einmal interessiert mich, wie MediaFetch außerhalb meiner eigenen Nextcloud läuft.

Andere Installationen, andere Server, andere Konfigurationen und andere Gewohnheiten finden erfahrungsgemäß ziemlich schnell Stellen, an die man selbst nie gedacht hat.

Und genau dafür ist Open Source ja am Ende auch da.

Was als „ich brauche für meine Nextcloud einen Download-Manager“ angefangen hat, liegt jetzt als meine erste App öffentlich vor.

Mal sehen, welche Baustelle als Nächstes aufploppt.

Quellen

  • MediaFetch – Repository und README – GitHub / Happyfeet01 – Direkt zur Quelle
  • MediaFetch CHANGELOG.md, Version 1.0.0 – GitHub / Happyfeet01 – Direkt zur Quelle
  • MediaFetch 1.0.0 – First Public Release – GitHub Releases / Happyfeet01 – Direkt zur Quelle
  • MediaFetch appinfo/info.xml – GitHub / Happyfeet01 – Direkt zur Quelle
  • NCDownloader – Nextcloud App Store – Direkt zur Quelle
  • NCDownloader – ursprüngliches Repository – GitHub / shiningw – Direkt zur Quelle
  • NCDownloader is broken on Nextcloud 33 due to deprecated API calls – Nextcloud Community – Direkt zur Quelle

Download: MediaFetch im App Store

Wie ist deine Meinung?
Schreib gern einen Kommentar unter dem Artikel oder diskutiere mit anderen im Matrix-Kanal: #dasnetzundich:matrix.org