wie PDF-Metadaten bearbeiten?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
EmmJott
Beiträge: 66
Registriert: 25.10.2024 12:23

wie PDF-Metadaten bearbeiten?

Beitrag von EmmJott »

Guude!

Ich habe über die Jahre eine ganze Menge PDFs gesammelt, die ich gerne in einer selfhosted Library (beispielsweise Booklore) organisieren würde. Habe dabei festgestellt, dass ein Großteil der PDFs falsche, fehlerhafte oder gar keine Metadaten enthält. Leider hat meine Suche nach vernünftiger Software nichts Brauchbares ergeben.

Hat jemand zufällig Infos, wie man mit PB Metadaten von PDFs ausliest bzw. geänderte Metadaten speichert und könnte mir da weiterhelfen?
Hauptsache: Niveau! Bin beim Pogrammieren seit Jahrzehnten konstant auf Anfängerniveau!
Benutzeravatar
Kiffi
Beiträge: 10724
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: wie PDF-Metadaten bearbeiten?

Beitrag von Kiffi »

Eine Möglichkeit wäre die Nutzung von exiftool (https://exiftool.org/), die man von PB aus mittels RunProgram() aufrufen könnte.
a²+b²=mc²
Axolotl
Beiträge: 319
Registriert: 31.12.2008 16:34

Re: wie PDF-Metadaten bearbeiten?

Beitrag von Axolotl »

Ich nutze (immer) die xpdf-tools um an Teile des Textes zu kommen. Evtl. bieten die anderen Tools noch mehr/was du suchst.
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
EmmJott
Beiträge: 66
Registriert: 25.10.2024 12:23

Re: wie PDF-Metadaten bearbeiten?

Beitrag von EmmJott »

Besten Dank für die Beiträge. Exiftool scheint das zu können, bin mir aber nicht sicher, ob ich mich da wirklich reinfuchsen will.

Wenn man sich PDFs mit einem HexEditor anschaut, kann man am Ende der Dateien folgendes finden:

Code: Alles auswählen

<dc:title>" + Chr(10) + Space(n) + "<rdf:Alt>" + Chr(10) + Space(n) + "<rdf:li xml:lang=" + #DQUOTE$ + "x-Default" + #DQUOTE$ + ">"
hier stünde der Titeltext
</rdf:li>" + Chr(10) + Space(n) + "</rdf:Alt>" + Chr(10) + Space(n) + "</dc:title>"
Space(n) soll hier bedeuten, dass die Anzahl an CHR(32) variiert, offenbar abhängig von der zur Erstellung der PDF verwendeten Software. Das mit den variablen Abständen zwischen den "Tags" (in Ermangelung eines geeigneten Fachbegriffes) ist auch bei

Code: Alles auswählen

<dc:description>    <rdf:Alt>     <rdf:li xml:lang="x-default">
hier stünde die Beschreibung
</rdf:li>    </rdf:Alt>   </dc:description>
oder
<dc:contributor>    <rdf:Bag>     <rdf:li>
Text
</rdf:li>    </rdf:Bag>   </dc:contributor>
oder
<dc:publisher>    <rdf:Bag>     <rdf:li>
Text
</rdf:li>    </rdf:Bag>   </dc:publisher>
oder
<dc:relation>    <rdf:Bag>     <rdf:li>
Text
</rdf:li>    </rdf:Bag>   </dc:relation>
oder
<dc:rights>    <rdf:Alt>     <rdf:li xml:lang="x-default">
Text
</rdf:li>    </rdf:Alt>   </dc:rights>
Weitere "Tags" wären beispielsweise

Code: Alles auswählen

<dc:coverage></dc:coverage>
<dc:identifier></dc:identifier>
<dc:source></dc:source>
<dc:type></dc:type>
<pdf:Producer></pdf:Producer>
<pdf:Keywords></pdf:Keywords>
Ich würde gerne bei meinen PDF-Dateien (einige recht große darunter) einige Metadaten auslesen und in eine CSV-Datei schreiben, die CSV-Datei dann bearbeiten (z. B. in LibreOffice) und dann die geänderten Metadaten in die PDFs zurückschreiben.

Erste Hürde dabei: Wie finde ich in (theoretisch beliebig großen) Dateien den Text, der zwischen <dc:title> und </dc:title> steht?
Hauptsache: Niveau! Bin beim Pogrammieren seit Jahrzehnten konstant auf Anfängerniveau!
Benutzeravatar
H.Brill
Beiträge: 521
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: wie PDF-Metadaten bearbeiten?

Beitrag von H.Brill »

der zwischen <dc:title> und </dc:title> steht?
Ist doch eine typische Aufgabe für die Regulären Ausdrücke (RegularExpressions).
PB 6.10
Benutzeravatar
EmmJott
Beiträge: 66
Registriert: 25.10.2024 12:23

Re: wie PDF-Metadaten bearbeiten?

Beitrag von EmmJott »

Hallo H.Brill,

der erste Teil der Frage, nämlich "Wie finde ich in (theoretisch beliebig großen) Dateien ..." bereitet mir erstmal mehr Schwierigkeiten. Liest man die häppchenweise ein , durchsucht, und bei Erfolglosigkeit das nächste Häppchen?
Hauptsache: Niveau! Bin beim Pogrammieren seit Jahrzehnten konstant auf Anfängerniveau!
Axolotl
Beiträge: 319
Registriert: 31.12.2008 16:34

Re: wie PDF-Metadaten bearbeiten?

Beitrag von Axolotl »

Moin,
ja, kann man so machen, allerdings würde ich es erstmal einfacher machen.... (Ohne gleich auf Speicher oder Geschwindigkeitsoptimierung zu gehen)
Wenn die Logik fehlerfrei funktioniert kannste die Optimierungen für (riesige) pdf dateien immer noch vornehmen.

Wenn ich dich richtig verstanden habe, willst du sowas machen, oder? (Datei lesen geht so natürlich nur mit ReadString, wenn da keine NULL-Zeichen enthalten sind. Dann brauchste dafür ReadData (usw.)

Code: Alles auswählen

EnableExplicit 

Global PDFEntireText$ = " Der Text, der zwischen <dc:title> und </dc:title> steht? " 

Procedure ReadPDF(File$) ; BOOL 
  Protected result 
  
  If ReadFile(0, File$) 
    While Eof(0) = 0 
      PDFEntireText$ = ReadString(0, #PB_File_IgnoreEOL) 
    Wend
    CloseFile(0) 
    result = #True 
  Else   
    PDFEntireText$ = ""   
  EndIf 
  ProcedureReturn result 
EndProcedure  

Procedure.s ExtractValue(Tag$, Title$)  ; STR 
  Protected result$, searchBegin$, searchEnd$, pBegin, pEnd 
  
  If PDFEntireText$ 
    searchBegin$ = "<" + Tag$ + ":" + Title$ + ">"  
    searchEnd$   = "</" + Tag$ + ":" + Title$ + ">" 
    pBegin = FindString(PDFEntireText$, searchBegin$, 1) 
    If pBegin 
      pBegin + Len(searchBegin$)
      pEnd = FindString(PDFEntireText$, searchEnd$, pBegin) 
      If pEnd 
        result$ = Mid(PDFEntireText$, pBegin, pEnd - pBegin) 
      EndIf 
    EndIf
  EndIf
  ProcedureReturn result$ 
EndProcedure 

Debug "=>" + ExtractValue("dc", "title") + "<" 

Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
dige
Beiträge: 1247
Registriert: 08.09.2004 08:53

Re: wie PDF-Metadaten bearbeiten?

Beitrag von dige »

Hi EmmJott, falls es um die Verwaltung von mehr als 100 Pdf's geht, würde ich das gleich größer aufziehen und das mit einer Kombination aus PDF CLI Tool und AI angehen.
Also Meta Daten und Text über eine CLI Tool auslesen und mit AI eine Zusammenfassung und ggf. neue Metadaten generieren lassen.
Falls dein PDF Scans bzw. Bilder enthält kannst du diese mit Tesseract oder einen Visionmodell auch daraus die Texte holen.

Wenn deine Grafikkarte mehr als 8GB VRAM hat, kann man mit Ollama und LLMs wie llama und qwen schon ziemlich gut arbeiten.

Richtig Spaß macht das ganze dann aber erst, wenn du AI dann auch in deine Suche integrierst. Das erhöht signifikant die Trefferquote. Stichwort RAG (Retrieval-Augmented Generation)
"Papa, ich laufe schneller - dann ist es nicht so weit."
Benutzeravatar
EmmJott
Beiträge: 66
Registriert: 25.10.2024 12:23

Re: wie PDF-Metadaten bearbeiten?

Beitrag von EmmJott »

Hallo Dige,

mit AI und so ein interessanter Ansatz, für meinen Bedarf allerdings weit über das Ziel hinausgeschossen. Werde auch das Programm-Projekt nicht weiter verfolgen, da es wahrscheinlich mehr Zeit zum Programmieren benötigt, als die Daten (soweit überhaupt erforderlich) gleich richtig zu stellen. Habe mich übrigens für "Booklore" entschieden, das auch eine brauchbare Metadaten-Bearbeitung bietet.
Hauptsache: Niveau! Bin beim Pogrammieren seit Jahrzehnten konstant auf Anfängerniveau!
Benutzeravatar
Kiffi
Beiträge: 10724
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: wie PDF-Metadaten bearbeiten?

Beitrag von Kiffi »

Hier ein Beispielcode zum Auslesen und Anzeigen der PDF-Metadaten via ExifTool. Du musst lediglich [PfadZuDeinemExifTool] und [DeinPdf] anpassen (auf evtl. vorhandene Leerzeichen in den Pfaden achten!).

Code: Alles auswählen

EnableExplicit

Procedure.s GetMetaDataFromFile(filename.s)
  
  Protected cmd.s   = "[PfadZuDeinemExifTool]"
  Protected exiftool.i, line.s, result.s
  
  exiftool = RunProgram(cmd, "-j " + filename, "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
  
  If exiftool
    
    While ProgramRunning(exiftool)
      If AvailableProgramOutput(exiftool)
        line = ReadProgramString(exiftool)
        result + line + #LF$
      EndIf
    Wend
    
    CloseProgram(exiftool)
    
  Else
    
    Debug "ExifTool not found"
    
  EndIf
  
  ProcedureReturn result
  
EndProcedure

Define jsonString.s
Define Xml.s
Define ObjectValue

jsonString = GetMetaDataFromFile([DeinPdf])

If jsonString = ""
  Debug "No MetaData found!"
  End
EndIf

#Dialog = 0
#Xml = 0

Xml = "<window id='#PB_Any' name='test' text='test' width='800' height='800' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
      "  <scrollarea>" +
      "    <gridbox colexpand='item:2'>"

ParseJSON(0, jsonString)

ObjectValue = GetJSONElement(JSONValue(0), 0)

If ExamineJSONMembers(ObjectValue)
  While NextJSONMember(ObjectValue)
    Xml + "<text text='" + JSONMemberKey(ObjectValue) + "' />"
    Select JSONType(JSONMemberValue(ObjectValue))
      Case #PB_JSON_Number
        Xml + "<string text='" + Str(GetJSONInteger(JSONMemberValue(ObjectValue))) + "' />"
      Case #PB_JSON_String
        Xml + "<string text='" + GetJSONString(JSONMemberValue(ObjectValue)) + "' />"
    EndSelect
  Wend
EndIf

Xml + "    </gridbox>" +
      "  </scrollarea>" +
      "</window>"

FreeJSON(0)

If ParseXML(#Xml, Xml) And XMLStatus(#Xml) = #PB_XML_Success
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow 
  Else  
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf
a²+b²=mc²
Antworten