Bratzell
I'm new here

Liste aller PDF-Dokumente in den Medien

Jump to solution

Hallo Zusammen,

Ich muss eine Liste aller Namen der PDF Dokumente die in den Medien liegen erstellen.

Das ganze soll als dynamische CSV-Tabelle dargestellt werden.

Dazu sollen noch mehrere Spalten hinzugefügt werden wie die MD5-Prüfsumme, Dateigröße .... und weiteres.

Ich bin noch relativ unvertraut mit Firstspirit.

Dank der Hilfe hier im Forum wurde mir gesagt das ich den Ausgabekanal des Seitentemplates mit csv überschreiben kann.

Die Frage wäre wie ich eine Solche CSV-Tabelle in Firstspirit erstelle. Kann mir da wer helfen?

Wenn ihr irgendwas unklar beschrieben haben sollte oder ihr mehr informationen braucht sagt bescheid.

Grüße

Artur

0 Kudos
1 Solution

Accepted Solutions
mbergmann
Crownpeak employee

Hallo Artur,

am einfachsten wäre es wohl tatsächlich, das über ein entsprechendes Seitentemplate zu erledigen und darauf basierend eine Inhaltsseite und Seitenreferenz anzulegen. Am besten nimmst Du hierfür den HTML-Ausgabekanal und änderst hierfür die Dateierweiterung auf csv (bzw. txt - siehe Hinweis unten).

Der Template-Code wäre dann z.B. so:

$CMS_TRIM(level:3)$

$CMS_SET(set_mediastoreRoot, #global.project.userService

  .getStore(

    class("de.espirit.firstspirit.access.store.Store$Type").MEDIASTORE,

    !#global.preview

  )

)$

UID,Name,CRC,Size

$CMS_SET(Media, class("de.espirit.firstspirit.access.store.mediastore.Media"))$

$CMS_FOR(for_media,set_mediastoreRoot.getChildren(Media,true))$

  $CMS_IF(for_media.getType()==Media.FILE)$

       $CMS_SET(set_file,for_media.getFile(#global.language))$

       $CMS_IF(set_file.extension=="pdf")$

            $CMS_TRIM(level:4)$

                 $-- media info --$

                 $CMS_VALUE(for_media.uid)$,

                 $CMS_VALUE(for_media.getDisplayName(#global.language))$,

                 $CMS_VALUE(set_file.getCrc())$,

                 $CMS_VALUE(set_file.getSize())$

            $CMS_END_TRIM$

       $CMS_END_IF$

  $CMS_END_IF$

$CMS_END_FOR$

$CMS_END_TRIM$

An die einzelnen Informationen kommst Du hier über zwei Stellen: Einmal das Medienobjekt selbst (im Beispiel ist dies die Variable for_media). Hier kannst Du alle Methoden des interfaces Media nutzen. Für Informationen der hinterlegten Datei (im Beispiel die Variable set_file) stehen die Methoden des Interfaces File zur Verfügung.

Kleiner Hinweis: Wenn Du die Erweiterung auf "csv" setzt, bekommst Du in der SA-Vorschau ggf. einen Download-Dialog wenn der Erweiterung "csv" kein Mime-Type zugeordnet ist (z.B. falls der interne Jetty verwendet wird). Zum Testen ist es darum hilfreich, die Erweiterung erstmal auf txt zu setzen.

Im Code sind jetzt Feinheiten wie Escaping von Kommata / Anführungszeichen noch nicht enthalten, aber vielleicht reicht es ja als Starthilfe.

Viele Grüße

Michael

View solution in original post

0 Kudos
9 Replies
mbergmann
Crownpeak employee

Hallo Artur,

am einfachsten wäre es wohl tatsächlich, das über ein entsprechendes Seitentemplate zu erledigen und darauf basierend eine Inhaltsseite und Seitenreferenz anzulegen. Am besten nimmst Du hierfür den HTML-Ausgabekanal und änderst hierfür die Dateierweiterung auf csv (bzw. txt - siehe Hinweis unten).

Der Template-Code wäre dann z.B. so:

$CMS_TRIM(level:3)$

$CMS_SET(set_mediastoreRoot, #global.project.userService

  .getStore(

    class("de.espirit.firstspirit.access.store.Store$Type").MEDIASTORE,

    !#global.preview

  )

)$

UID,Name,CRC,Size

$CMS_SET(Media, class("de.espirit.firstspirit.access.store.mediastore.Media"))$

$CMS_FOR(for_media,set_mediastoreRoot.getChildren(Media,true))$

  $CMS_IF(for_media.getType()==Media.FILE)$

       $CMS_SET(set_file,for_media.getFile(#global.language))$

       $CMS_IF(set_file.extension=="pdf")$

            $CMS_TRIM(level:4)$

                 $-- media info --$

                 $CMS_VALUE(for_media.uid)$,

                 $CMS_VALUE(for_media.getDisplayName(#global.language))$,

                 $CMS_VALUE(set_file.getCrc())$,

                 $CMS_VALUE(set_file.getSize())$

            $CMS_END_TRIM$

       $CMS_END_IF$

  $CMS_END_IF$

$CMS_END_FOR$

$CMS_END_TRIM$

An die einzelnen Informationen kommst Du hier über zwei Stellen: Einmal das Medienobjekt selbst (im Beispiel ist dies die Variable for_media). Hier kannst Du alle Methoden des interfaces Media nutzen. Für Informationen der hinterlegten Datei (im Beispiel die Variable set_file) stehen die Methoden des Interfaces File zur Verfügung.

Kleiner Hinweis: Wenn Du die Erweiterung auf "csv" setzt, bekommst Du in der SA-Vorschau ggf. einen Download-Dialog wenn der Erweiterung "csv" kein Mime-Type zugeordnet ist (z.B. falls der interne Jetty verwendet wird). Zum Testen ist es darum hilfreich, die Erweiterung erstmal auf txt zu setzen.

Im Code sind jetzt Feinheiten wie Escaping von Kommata / Anführungszeichen noch nicht enthalten, aber vielleicht reicht es ja als Starthilfe.

Viele Grüße

Michael

0 Kudos

Hallo Michael,

danke für die schnelle Hilfe, wenn ich auf weitere Probleme treffe melde ich mich nochmals.

Ich versuch mich mal damit ^^.

Grüße

Artur

0 Kudos

Ok ich verzweifle weiterhin Smiley Sad

ich hab mich mit den Interfaces von Media und File auseinandergesetzt aber ich glaube mir fehlt da grundsätzliches Wissen.

Ich hab gerade Schwierigkeiten den Ablageort (Referenzname des Baumes) der Dokumente zu ermitteln,

auf welchen Seiten das Dokument referenziert ist und die MD5-Prüfsumme zu errechnen.

Ich weiß das CrC möglich ist hast du ja auch in dem Beispiel schon implementiert aber mein Chef will MD5 haben.

Den Ablageort kann man doch über getStoredUrl kriegen oder?

Die Seiten auf dehnen das Dokument referenziert ist kriegt man über eine Verschachtelung von CMS_VALUE und CMS_REF oder?

Grüße

Artur

0 Kudos

Hallo Artur,

in FS gibt es ja erstmal keinen "Ablageort" für Medien im Dateisystem, sondern die liegen im internen Berkeley Repository. Erst bei der Generierung werden die Dateien wirklich geschrieben - und je nach Deployment-Mechanismus (z.B. FTB) nichtmal unbedingt dann.

Was ist denn genau der Anwendungsfall hinter der Anforderung?

Wenn Du hier wirklich "eigene Operationen" auf den Daten ausführen willst, müsstest Du ein Modul in Java implementieren, dass die MD5 berechnet.

Theoretisch kannst Du natürlich auch nach der Generierung auf den generierten Files arbeiten (aber letztlich brauchst Du auch da ein Stück Java-Code). Und hier hast Du dann natürlich die Objektinfos nicht mehr bzw. müsstest eine entsprechende Zuprdnungsmöglichkeit bauen...

Viele Grüße

Michael

0 Kudos

Hallo Michael,

Mit Ablageort meine ich den root folder des Dokuments in Firstspirit.

Ich weiß leider nicht was der Anwendungsfall ist. Ich glaube es soll einfach eine CSV Tabelle mit den hier schon genanten werten sein damit diese Intern Sinn und Zweck erfüllt.

Das hilft mir jetzt in die richtige Richtung  ^^.

Grüße

Artur

0 Kudos

Hallo Artur,

ohne den Anwendungsfall genauer zu kennen ist es natürlich schwierig hier eine sinnvolle Vorgehensweise zu empfehlen...

Es geht z.B. um Fragen wie:

  • Geht es um eine Liste aller Publizierten PDFs oder ist das eher ein "Redakteurs-Tool"?
  • Wer braucht die Checksumme für welchen Zweck?
  • Soll die Prüfsumme auf dem freigegebenen oder dem current Stand durchgeführt werden?
  • Von wievielen PDFs mit welcher Größe reden wir hier? Das hat z.B. Einfluss auf die Umsetzung - für 10.000 größere PDFs jedes Mal ein MD5 berechnen zu wollen wäre wohl z.B. keine so gute Idee - hier müsste man sich über ein Caching bzw. eine Speicherung inkl. Einbindung der Berechnung in den Freigabeworkflow Gedanken machen.

Selbst die von mir vorgeschlagene Variante der sog. "Full Store Iteration" ist nicht in jedem Fall (=bei vielen Medien) empfehlenswert.

Vor der eigentlichen Generierung sind die PDFs nicht über das Dateisystem zugreifbar, weil sie in der internen Berkeley-DB liegen.

Viele Grüße

Michael

0 Kudos

Hallo Michael,

es geht um eine Liste aller Publizierten PDFs.

Für welchen Zweck ich diese MD5 Prüfsumme benötige wüsste ich gerne selber, aber in die Gründe bin ich nicht eingeweiht.

Die Prüfsumme soll auf den freigegebenen Stand sein.

Es handelt sich um weniger als 4000 Dokumente die alle von unterschiedlicher größe sind, eher kleiner als groß.

Grüße

Artur

0 Kudos

Hallo Artur,

hmm, 4000 ist schon ne Hausnummer. Wieviele Medien habt ihr denn insgesamt? Also Anzahl aller Objekte im Mediastore?

Da könnte sich nämlich allein schon die von mir initial vorgeschlagene Full-Store-Iteration ungünstig auswirken - und die MD5 müsste ja auch noch berechnet werden. Ich weiß jetzt nicht, wie schnell so eine MD5-Berechnung ist, aber es muss ja zumindest mal die ganze Datei eingelesen werden.

Wie generiert bzw. publiziert ihr denn aktuell? (Teil-/Voll-/Delta-Generierung?)

Was man generell machen könnte (zumindest einige Ansätze - nicht unbedingt vollständig!) wäre Folgendes:

a) Full-Store-Iteration + Modulcode zur Berechnung von MD5, Generierung der CSV über "technische Seite" (mein initialer Vorschlag)

Vorteile:

  • Recht einfach zu bauen (Utility-Klasse mit Modul, ggf. ein bisschen Tricksen um da im Template ranzukommen)
  • Anpassungen / Hinzufügen von Infos (zumindest solcher für die nicht weiterer Modul-Code geschrieben werden muss, die sich also direkt aus dem FS-Medienobjekt abgreifen lassen) durch Template-Entwickler möglich

Nachteile:

  • Full-Store-Iteration bei großem Store ungünstig was die Performance betrifft.
  • MD5 würde ggf. - je nach Generierungsmodell - "unnötig" mehrfach berechnet
  • Sonderfälle wie Escaping müssen "manuell" im Template gemacht werden

b) Einbau der Berechnung in den Freigabeworkflow, Speicherung an den FirstSpirit-Metadaten, Ausgabe über "technische Seite"

Vorteile:

  • Performancetechnisch optimal, da nur dann gerechnet wird wenn es sein muss
  • Ausgabe komplett über Template, Erweiterung für Template-Entwickler möglich
  • MD5 würde im Metadaten-Formular stehen und somit sichtbar sein (da wir den Anwendungsfall ja beide nicht genau kennen - wer weiß ob das nicht praktisch ist)

Nachteile:

  • Full-Store-Iteration notwendig um "alle PDFs" zu finden
  • Sonderfälle wie Escaping müssen "manuell" im Template gemacht werden
  • Mehr Modul-Implementierung - hier sollte man sich schon ein bisschen in der API auskennen
  • Für bereits freigegebene PDFs müsste das Ganze einmal "nachgeholt" werden (das dann wieder über Full-Store-Iteration, Berechnung, Merken in den Metadaten und erneute Freigabe). Wobei "irgendwann" muss es halt eh gemacht werden. Theoretischer Problemfall (=etwas mehr Aufwand): Bereits einmal freigegebene, inzwischen aber geänderte und nicht wieder freigegebene Medien, die aber aus irgendwelchen Gründen (noch) nicht wieder freigegeben werden sollen

c) Erzeugung der CSV komplett über ein Modul nach der Generierung basierend auf den tatsächlich generierten PDFs (also quasi auf Dateisystem-Ebene)

Vorteile:

  • Hier gibt es eine Hilfsklasse (CsvWriter) in der FS-API, die einem das Escaping abnimmt

Nachteile:

  • Man müsste sich hier eine Art "Übergabemöglichkeit" schaffen, um die Infos die sich nicht allein aus dem Dateisystem ermitteln lassen (z.B. Anzeigename) bei der Erstellung auch zur Verfügung zu haben.
  • Zwar keine Full-Store-Iteration - aber dafür würde man im Filesystem suchen müssen
  • Auch hier wird die MD5 - je nach Generierungsmechanismus - ggf. unnötig oft durchgeführt
  • Allgemein stärkere Abhängigkeit vom Generierungsmechanismus, falls ihr z.B. keine Vollgenerierung macht, wird es etwas auswendiger das für bereits publizierte Medien nachzuholen weil man sie ja auf jeden Fall einmal generieren müsste

Alternative zur jeweiligen Full-Store-Iteration um die PDFs zu finden wäre noch die Nutzung des QueryAgent möglich - der aber nur auf dem Current-Stand arbeitet. D.h. man müsste dann im Current-Stand suchen (was hier sehr einfach und effizient möglich ist per Suche nach fs.extension=pdf), die Daten dann aber aus dem Release-Stand nehmen bzw. erstmal schauen ob das jew. PDF schon freigegeben ist (letzteres ist aber einfach). Theoretisch Gefahr höchstens, dass man publizierte PDFs "nicht erwischt", die in FS gelöscht wurden aber deren Löschung noch nicht freigegeben wurde.

Es gibt bestimmt noch weitere Varianten bzw. Kombinationsmöglichkeiten... Für die eigentliche Berechnung der MD5 wirst Du aber in jedem Fall ein Modul bauen müssen, weil es da eben keine fertige Lösung in FS gibt.

Variante c) könnte höchstens noch interessant sein, wenn man alle Infos auch rein in den generierten Dateien hat, also keine Infos aus FS und dem Filesystem "zusammenführen" muss - dann wird es einfacher.

Persönlich würde ich eher zu Variante b) tendieren.

Du könntest es natürlich auch erstmal mit a) versuchen und schauen wie die Performance ist und ob man sich da überhaupt Gedanken machen muss. Ein Modul brauchst Du ja eh und auch den Code um die MD5 zu erzeugen - d.h. es wäre zumindest mal keine Zeitverschwendung 😉

Viele Grüße

Michael

0 Kudos

Hallo Michael,

tut mir Leid für die späte Antwort. Das ist mir eine große Hilfe, danke dir vielmals.

Ich setzt mich nochmal ran und guck mal wofür ich mich Entscheide.

Falls nochmal was sein sollte wodurch sich ein spezifisches Problem ergibt eröffne ich einen neuen post.

Mit freundlichen Grüßen

Artur Kammerloch

0 Kudos