Fotoverwaltung und Galerien – Teil 3: Automatisch erzeugte Fotogalerien

Keine Kommentare

In diesem letzten Teil meiner Blogserie zum Thema Fotoverwaltung und Galerien wird es endlich etwas technischer. Nachdem ich beschrieben habe, wie ich meine Fotos verwalte und meine Fotogalerien manuell erzeuge, fehlt noch der letzte logische Schritt: die Automatisierung des gesamten Prozesses. Ansatzpunkt der Automatisierung war der Ort, an dem ich auch den Inhalt meiner Galerien verwalte: in meiner NextCloud.

NextCloud als Bildquelle für die Galerien

Zunächst habe ich überlegt, wie man die Fotos am besten markiert, die zusammen in einer Galerie landen sollen. Das Kopieren von Bildern in einen expliziten „Galerie“-Ordner kam von Anfang an aufgrund der redundanten Datenspeicherung für mich nicht in Frage und auch die Verwendung von Verknüpfungen fällt weg, da NextCloud diese nicht verarbeiten kann. Jedoch ist es dank der in NextCloud integrierten Tagging-Erweiterung möglich, Dateien und Ordner mit Schlagworten zu versehen und nach diesen zu Suchen. Mein Ansatz war es also, alle Bilder mit dem Schlagwort „galerie“ zu versehen, welche später veröffentlich werden sollen. Wie bereits im ersten Teil beschrieben, sind die Ordner jeweils mit dem entsprechenden Datum sowie einem Titel der Aktivität versehen, sodass diese als Galerieüberschrift herangezogen werden sollten. Was fehlte, war das Auslesen der einzelnen Ordner bzw. Bilder und das Generieren der Galerien.

Auslesen der Bilder

Um alle Bilder bzw. ganze Ordner für eine Galerie zu markieren, habe ich das Schlagwort „galerie“ angelegt und mir die entsprechende Id herausgesucht. Die ID ist in der URL zu finden, wenn man im Tag-Bereich der NextCloud das entsprechende Tag als Filter verwendet (siehe Screenshot; hier:  „?dir=9“, ergo ist die Id 9). Die ID wird für die programmatische Suche nach den markierten Elementen benötigt, da eine Suche über den Namen nicht möglich ist.
Suchergebnisanzeige in NextCloud

NextCloud bietet eine WebDAV-Schnittstelle an, über die man auf die gespeicherten Dateien und Ordner zugreifen kann. Das Filtern bzw. Suchen nach Tags ist mittels der WebDAV-API ebenfalls möglich, indem man folgende Anfrage an die NextCloud-Instanz schickt, die als filter-rule die Id enthält, nach der gesucht werden soll:

REPORT /remote.php/dav/files/boromir

<?xml version="1.0"?>
<oc:filter-files xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns" xmlns:ocs="http://open-collaboration-services.org/ns">
    <d:prop>
        <d:getcontenttype />
    </d:prop>
    <oc:filter-rules>
        <oc:systemtag>9</oc:systemtag>
    </oc:filter-rules>
</oc:filter-files>

Als Antwort erhält man alle Dateien bzw. Ordner, welche der Tag-Id zugeordnet sind und es werden die im Bereich <d:prop> angegebenen Attribute in der Antwort zurückgegeben. Benötigt man also mehr als nur den contenttype, können in der Anfrage weitere Properties spezifiziert werden. Für unsere Zwecke ist der contenttype aber ausreichend, da wir anhand des contenttype bestimmen können, ob das Element eine Datei oder ein Ordner ist: Handelt es sich um eine Datei, ist der contenttype gesetzt, andernfalls nicht vorhanden bzw. leer:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
    <d:response>
        <d:status>HTTP/1.1 200 OK</d:status>
        <d:href>/remote.php/dav/files/boromir/Pictures/2019.07%20Minas%20Tirith/1.jpg</d:href>
        <d:propstat>
            <d:prop>
                <d:getcontenttype>image/jpeg</d:getcontenttype>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
    </d:response>
    <d:response>
        <d:status>HTTP/1.1 200 OK</d:status>
        <d:href>/remote.php/dav/files/boromir/Pictures/2019.06%20Minas%20Tirith</d:href>
        <d:propstat>
            <d:prop>
                <d:getcontenttype/>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
    </d:response>
</d:multistatus>

Sollten im Suchergebnis Ordner enthalten sein, möchte ich alle enthaltenen Bilder als Galerie exportieren. Folglich muss jeder Ordner gegen seinen Inhalt ersetzt werden, sodass letztlich eine Liste mit (Bild-)Dateien entsteht. Um den Inhalt der Ordner aufzulösen, wird pro Ordner nochmals eine Abfrage gesendet, die den Inhalt des jeweiligen Ordners abruft. Die Abfrage des Inhalts eines Ordners via WebDAV sieht wie folgt aus:

PROPFIND /remote.php/dav/files/boromir/2019.06%20Minas%20Tirith

<?xml version="1.0"?>
<d:propfind  xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns" xmlns:ocs="http://open-collaboration-services.org/ns">
    <d:prop>
        <d:getcontenttype />
    </d:prop>
</d:propfind>

Auch hier fragen wir wieder den contenttype ab, da ein Ordner auch weitere Unterordner enthalten kann.

Sicherheit und „Datenschutz“

Das von mir implementierte Skript, das die Bilder und aus meiner NextCloud extrahiert, benötigt natürlich Zugangsdaten, da die von mir gespeicherten Daten in der NextCloud unter meinem Benutzerprofil hochgeladen wurden. Da mein Benutzer jedoch Zugriff auf sämtliche Daten hat, habe ich eigens für das Skript einen neuen Benutzer mit entsprechend sicherem Passwort angelegt und diesem Benutzer Zugriff auf die Bilder gegeben. Hierdurch kann das Skript zwar meine Bilder durchforsten und herunterladen, diese aber nicht verändern bzw. andere Daten lesen. Auch wenn dies etwas übervorsichtig erscheint, möchte ich an dieser Stelle darauf hinweisen, dass auch im Privaten das Thema Sicherheit nicht vernachlässigt werden sollte. Erneut sei gesagt, dass Phrasen wie „Was habe ich schon zu verbergen?“ oder „Macht nichts, wenn das veröffentlicht wird“ immer mit Vorsicht zu genießen sind.

Automatisiert erzeugte Galerien

Herunterladen der Bilder

Die Implementierung meines Galerie-Generators habe ich in Node.JS vorgenommen. Die Kommunikation zur NextCloud wird mithilfe einer webdav-Bibliothek realisiert. Die erste Aufgabe des Skripts ist es, eine Liste der Bilder zu erzeugen, die in der NextCloud als für die Galerie relevant markiert wurden. Da sowohl einzelne Bilder als auch ganze Ordner für Galerien markiert werden können, muss die Liste der direkt markierten Bilder mit den Bildern vereinigt werden, die indirekt über ihren Ordner markiert sind. Anschließend kann diese Liste in ein Nested Set umgewandelt werden, die den Namen der Galerie als Schlüssel sowie alle in ihr enthaltenen Bilder als Liste führt:

{
    "2019.06 Minas Tirith" => ["1.jpg", "2.jpg", "3.jpg", ...],
    "2017.02 Gondor" => ["faramir.jpg", "gandalf.jpg", ...],
    ...
}

Die Zuordnung von Ordnernamen zu Bildern stellt die Grundlage für alle folgenden Operationen dar. Da die Bilder teils sehr groß sind (sowohl in ihrer Dimension als auch Dateigröße) und sich daher nur bedingt bzw. gar nicht für die Verwendung im Web eignen, werden die Bilder nicht nur stumpf heruntergeladen, sondern mithilfe von ImageMagick auf verschiedene Anzeigegrößen heruntergerechnet (large: 1024x1024px, medium: 512x512px, small: 256x256px). Das Reduzieren der Dateigröße soll nicht nur die Ladezeit der Galerien verringern, sondern auch den CO2-Abdruck der Webseite reduzieren. Zwar steigt die Geschwindigkeit der Internetanschlüsse stetig und es ist nicht zwingend notwendig, auf ein oder zwei Kilobyte mehr zu achten, dennoch liegt es meiner Meinung nach in der Verantwortung eines jeden Entwicklers, Ressourcen bewusst einzusetzen und diese nicht einfach auszureizen, nur weil sie verfügbar sind.

Behandlung von EXIF-Metainformationen

Sind die Bilder heruntergeladen und auf kleinere Größen heruntergerechnet, kann der Blick erneut auf das Thema Sicherheit bzw. Datenschutz gelegt werden: Da die Bilder in meiner NextCloud teils direkt von der Kamera kommen, enthalten diese noch EXIF-Informationen, die mitunter Daten enthalten, die so nicht im Web landen sollen. Dies reicht von harmlosen Informationen wie dem Kameramodell bis hin zu Standortdaten. Um diese Meta-Informationen zu entfernen, verwende ich das ExifTool und entferne die Daten über den Befehl exiftool -all= <pfad>. Natürlich handelt es sich hier nicht zwingend um „brisante“ oder „sehr persönliche“ Daten, dennoch denke ich, dass je weniger Informationen man im Internet verteilt, desto ruhiger lässt es sich schlafen.

Galerien aus der eigenen Feder – ganz automatisch

Bis hierher haben wir nun unsere Bilder sortiert, markiert, heruntergeladen und für die Anzeige im Web optimiert. Letztlich fehlt nur noch das Gewand für die Bilder: eine Webseite, die die Bilder präsentiert. Anstatt hier einen eigenen statischen Website-Generator zu implementieren, habe ich bereits früh auf einen bekannten Kandidaten gesetzt: Jekyll! Durch den hohen Verbreitungsgrad von Jekyll kann man aus einer Vielzahl an bereits vorgefertigten Templates wählen und diese an die eigenen Bedürfnisse anpassen. Da Jekyll „blog-aware“ ist, nutzen wir dieses Feature und betrachten jede Galerie als einen Blogpost, der ausschließlich aus Bildern besteht. Für den hier beschriebenen Anwendungsfall sieht die (gekürzte) Jekyll-Ordner-Struktur wie folgt aus:

  • _layouts/
    • default.html
    • galerie.html
  • gallery/
    • 2017.02-gondor/
      • faramir.jpg
      • gandalf.jpg
      • index.md
    • 2019.06-minas-tirith/
      • 1.jpg
      • 2.jpg
      • index.md
  • index.html

Im _layouts-Ordner befinden sich die wiederverwendbaren Templates für die Startseite sowie für die Galerien. Im gallery-Ordner findet sich für jede Galerie ein eigener Ordner, der sowohl die anzuzeigenden Bilder als auch eine Markdown-Datei enthält, die wiederum den Titel der Galerie enthält, das Header-Bild definiert und eine Liste von anzuzeigenden Bildern vorgibt:

---
layout: galerie
title: "2017.02 Gondor"
header-img: "/gallery/2017.02-gondor/faramir.jpg"
images:
- image_path: /gallery/2017.02-gondor/faramir.jpg
  image_path_m: /gallery/2017.02-gondor/faramir_m.jpg
  image_path_s: /gallery/2017.02-gondor/faramir_s.jpg
- image_path: /gallery/2017.02-gondor/gandalf.jpg
  image_path_m: /gallery/2017.02-gondor/gandalf_m.jpg
  image_path_s: /gallery/2017.02-gondor/gandalf_s.jpg
---

Durch diese Markdown-Datei weiß Jekyll, welches Layout zum Rendern verwendet werden soll und erzeugt basierend auf den gegebenen Informationen die statische HTML-Datei im konfigurierten Ausgabeordner (Standard: _site). Wird dieser Ordner nun auf einem Webserver platziert, kann die erzeugte Webseite im Browser aufgerufen werden.

Fazit

Mithilfe von NextCloud lassen sich Fotos ausreichend gut verwalten und organisieren. Dank der vorhandenen WebDAV-Schnittstelle ist es zudem möglich, auf die Daten zuzugreifen und diese im Rahmen automatisierter Prozesse zu verwenden. Im Rahmen dieser Blog-Beteitragsserie wollte ich zeigen, dass auch – oder vielleicht gerade – im privaten Bereich einige Erleichterungen möglich sind. Vor allem aber wollte ich zeigen, wie man sich mit etwas Aufwand und Geduld vorhandene Systeme zunutze machen kann, um daraus schöne Resultate zu generieren, die einem am Ende das Leben sogar einfacher machen. Durch das Markieren von Bildern und anschließend automatisierte Generieren von Galerien kann ich nun schneller und gezielter meine Bilder teilen und verbleibe dabei in meinem kleinen Ökosystem: Ich brauche keinen weiteren Dienstleister als einen Serverbetreiber (sofern dieser nicht bei mir daheim steht) sowie eine Domain, um mit meinen Daten nach Belieben Inhalte zu erzeugen.

Stephan Köninger

Stephan arbeitet als Software-Entwickler mit dem Schwerpunkt Web-Frontend-Entwicklung für die codecentric. Themen wie Java, Spring und Hibernate sind ihm nicht fremd, was ihn zu einem Full-Stack-Entwickler macht. Zudem ist das Thema Automatisierung sowie Testing ebenfalls wichtiger Bestandteil seines täglichen Arbeitens.

Über 1.000 Abonnenten sind up to date!

Die neuesten Tipps, Tricks, Tools und Technologien. Jede Woche direkt in deine Inbox.

Kostenfrei anmelden und immer auf dem neuesten Stand bleiben!
(Keine Sorge, du kannst dich jederzeit abmelden.)

* Hiermit willige ich in die Erhebung und Verarbeitung der vorstehenden Daten für das Empfangen des monatlichen Newsletters der codecentric AG per E-Mail ein. Ihre Einwilligung können Sie per E-Mail an datenschutz@codecentric.de, in der Informations-E-Mail selbst per Link oder an die im Impressum genannten Kontaktdaten jederzeit widerrufen. Von der Datenschutzerklärung der codecentric AG habe ich Kenntnis genommen und bestätige dies mit Absendung des Formulars.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.