*documentation*

This commit is contained in:
Picman2000 2025-03-23 20:28:13 +01:00
parent 08c8205088
commit 6bec903301
5 changed files with 218 additions and 7 deletions

View file

@ -508,7 +508,11 @@ public class MongoDBHandler {
* Justus Jonas operations
* =======================
*/
/**
* Fügt eine Session in die Datenbank ein.
*
* @param session Das Session-Objekt, das eingefügt werden soll.
*/
public void insertSession(Session session) {
Document sessionDocument = new Document("sessionId", session.getId())
.append("dateTime", session.getDateTime())
@ -518,6 +522,15 @@ public class MongoDBHandler {
sessionsCollection.insertOne(sessionDocument);
}
/**
* Erstellt eine neue Session anhand der übergebenen Parameter, generiert eine eindeutige sessionId,
* fügt sie in die Datenbank ein und gibt die erstellte Session zurück.
*
* @param dateTime Startzeit der Session.
* @param endTime Endzeit der Session.
* @param legislativePeriod Die Legislaturperiode.
* @return Die neu erstellte Session.
*/
public Session insertSession(String dateTime, String endTime, String legislativePeriod) {
// get a new random sessionId that is not already in use
int sessionId = 0;
@ -535,13 +548,22 @@ public class MongoDBHandler {
return session;
}
/**
* Fügt eine Liste von Sessions in die Datenbank ein.
*
* @param sessions Liste der Sessions, die eingefügt werden sollen.
*/
public void insertSessions(List<Session> sessions) {
for (Session session : sessions) {
insertSession(session);
}
}
/**
* Fügt eine Liste von AgendaItems in die Datenbank ein.
*
* @param agendaItems Liste der AgendaItems, die eingefügt werden sollen.
*/
public void insertAgendaItems(List<AgendaItem> agendaItems) {
List<Document> agendaItemDocuments = new ArrayList<>();
for (AgendaItem agendaItem : agendaItems) {
@ -555,7 +577,15 @@ public class MongoDBHandler {
agendaItemsCollection.insertMany(agendaItemDocuments);
}
/**
* Erstellt ein neues AgendaItem für eine bestimmte Session und einen Titel.
*
* @param sessionId Die Session-ID, zu der das AgendaItem gehört.
* @param title Der Titel des AgendaItems.
* @return Das neu erstellte AgendaItem.
* @throws SessionNotFoundException Falls keine Session mit der angegebenen sessionId existiert.
* @throws ServerErrorException Falls ein Serverfehler auftritt.
*/
public AgendaItem insertAgendaItem(int sessionId, String title) throws SessionNotFoundException, ServerErrorException {
// check if session exists
List<Session> sessions = retrieveAllSessions(Filters.eq("sessionId", sessionId));
@ -579,6 +609,11 @@ public class MongoDBHandler {
return agendaItem;
}
/**
* Fügt eine Liste von Speech-Objekten in die Datenbank ein.
*
* @param speeches Liste der Speeches, die eingefügt werden sollen.
*/
public void insertSpeeches(List<Speech> speeches) {
// Convert each Speech to a Document
List<Document> speechDocuments = new ArrayList<>();
@ -629,7 +664,11 @@ public class MongoDBHandler {
speechesCollection.insertMany(speechDocuments);
}
/**
* Ruft alle Speech-Dokumente ohne Filter ab und wandelt sie in eine Liste von Speech-Objekten um.
*
* @return Eine Liste aller Speeches.
*/
public List<Speech> retrieveAllSpeeches() {
List<Document> speeches = speechesCollection.find().into(new ArrayList<>());
List<Speech> result = new ArrayList<>();
@ -640,6 +679,13 @@ public class MongoDBHandler {
return result;
}
/**
* Ruft alle Speech-Dokumente ab, die dem übergebenen Filter entsprechen, und wandelt sie in eine Liste von Speech-Objekten um.
*
* @param filter Der Filter als Bson-Objekt.
* @return Eine Liste der Speeches, die dem Filter entsprechen.
*/
public List<Speech> retrieveAllSpeeches(Bson filter) {
List<Document> speeches = speechesCollection.find(filter).into(new ArrayList<>());
List<Speech> result = new ArrayList<>();
@ -650,6 +696,11 @@ public class MongoDBHandler {
return result;
}
/**
* Ruft alle Session-Dokumente ohne Filter ab und wandelt sie in eine Liste von Session-Objekten um.
*
* @return Eine Liste aller Sessions.
*/
public List<Session> retrieveAllSessions() {
List<Document> sessions = sessionsCollection.find().into(new ArrayList<>());
List<Session> result = new ArrayList<>();
@ -660,6 +711,12 @@ public class MongoDBHandler {
return result;
}
/**
* Ruft alle Session-Dokumente ab, die dem übergebenen Filter entsprechen, und wandelt sie in eine Liste von Session-Objekten um.
*
* @param filter Der Filter als Bson-Objekt.
* @return Eine Liste der Sessions, die dem Filter entsprechen.
*/
public List<Session> retrieveAllSessions(Bson filter) {
List<Document> speeches = sessionsCollection.find(filter).into(new ArrayList<>());
List<Session> result = new ArrayList<>();
@ -670,6 +727,11 @@ public class MongoDBHandler {
return result;
}
/**
* Ruft alle AgendaItem-Dokumente ohne Filter ab und wandelt sie in eine Liste von AgendaItem-Objekten um.
*
* @return Eine Liste aller AgendaItems.
*/
public List<AgendaItem> retrieveAllAgendaItems() {
List<Document> agendaItems = agendaItemsCollection.find().into(new ArrayList<>());
List<AgendaItem> result = new ArrayList<>();
@ -680,6 +742,12 @@ public class MongoDBHandler {
return result;
}
/**
* Ruft alle AgendaItem-Dokumente ab, die dem übergebenen Filter entsprechen, und wandelt sie in eine Liste von AgendaItem-Objekten um.
*
* @param filter Der Filter als Bson-Objekt.
* @return Eine Liste der AgendaItems, die dem Filter entsprechen.
*/
public List<AgendaItem> retrieveAllAgendaItems(Bson filter) {
List<Document> speeches = agendaItemsCollection.find(filter).into(new ArrayList<>());
List<AgendaItem> result = new ArrayList<>();
@ -690,6 +758,13 @@ public class MongoDBHandler {
return result;
}
/**
* Aktualisiert das Speech-Dokument, das durch den speechKey identifiziert wird,
* und setzt das Feld "xmiData" auf den übergebenen xmiContent.
*
* @param speechKey Der Schlüssel der Rede.
* @param xmiContent Der XMI-Inhalt als String.
*/
public void updateXmiData(String speechKey, String xmiContent) {
speechesCollection.updateOne(
Filters.eq("speechKey", speechKey),
@ -697,6 +772,9 @@ public class MongoDBHandler {
);
}
/**
* Löscht alle Dokumente, die mit den Reden, Sessions, AgendaItems (und History) zusammenhängen.
*/
public void deleteSpeechRelatedDocuments() {
speechesCollection.deleteMany(new Document());
sessionsCollection.deleteMany(new Document());
@ -704,6 +782,11 @@ public class MongoDBHandler {
//historyCollection.deleteMany(new Document());
}
/**
* Führt einen Bulk-Write für NLP-bezogene Updates in der Speech-Collection aus.
*
* @param bulkOperations Eine Liste von Bulk-Update-Operationen.
*/
public void bulkWriteNlpData(List<WriteModel<Document>> bulkOperations) {
if (!bulkOperations.isEmpty()) {
BulkWriteOptions options = new BulkWriteOptions().ordered(false);
@ -721,6 +804,11 @@ public class MongoDBHandler {
}
}
/**
* Zählt die Anzahl der Speech-Dokumente, die ein Feld "analysisResults" besitzen.
*
* @return Die Anzahl der Speech-Dokumente mit einem "analysisResults"-Feld.
*/
public long checkAnalysisResultsField() {
return speechesCollection.countDocuments(Filters.exists("analysisResults"));
}
@ -781,7 +869,12 @@ public class MongoDBHandler {
}
}
/**
* Überprüft, ob eine Session mit der angegebenen Session-Nummer in der sessionsCollection existiert.
*
* @param sessionNumber Die Session-Nummer als String.
* @return true, wenn mindestens ein Dokument mit der angegebenen sessionId existiert, andernfalls false.
*/
public boolean sessionExists(String sessionNumber) {
Document filter = new Document("sessionId", Integer.valueOf(sessionNumber));
long count = sessionsCollection.countDocuments(filter);
@ -796,10 +889,19 @@ public class MongoDBHandler {
return photoDocument.getString("base64");
}
/**
* Schließt die MongoDB-Verbindung.
*/
public void close() {
mongoClient.close();
}
/**
* Gibt ein einzelnes Speech-Dokument zurück, das dem angegebenen Filter entspricht.
*
* @param filter Der Filter als Document.
* @return Das erste Speech-Dokument, das dem Filter entspricht, oder null, wenn keines gefunden wird.
*/
public Document getSpeech(Document filter) {
return speechesCollection.find(filter).first();
}

View file

@ -315,6 +315,15 @@ public class NlpUtils {
}
/**
* Führt den Remote-NLP-Driver auf unprozessierten Reden aus und aktualisiert die Datenbank.
* <p>
* Es werden alle Reden ohne "analysisResults" abgerufen, mit den Remote-Komponenten (spaCy und Vader)
* verarbeitet, die NLP-Ergebnisse extrahiert und per Bulk-Update in der Datenbank gespeichert.
* </p>
*
* @throws Exception falls ein Fehler auftritt.
*/
public static void runRemoteDriver() throws Exception {
DUUILuaContext luaContext = new DUUILuaContext().withJsonLibrary();
pComposer = new DUUIComposer()

View file

@ -327,7 +327,19 @@ public abstract class PPRUtils {
});
}
/**
* Liest XML-Protokolle von der Bundestag-OpenData-URL und verarbeitet sie.
*
* <p>
* Diese Methode ruft wiederholt Seiten mit XML-Links (Protokollen) ab, basierend auf einem
* Offset und Limit. Für jeden gefundenen Link wird die XML-Datei heruntergeladen und geparst.
* Einzigartige Protokolle werden anhand des "sitzung-nr"-Attributs identifiziert. Falls ein Protokoll
* bereits verarbeitet wurde (gespeichert in {@code processedProtocols}), wird es übersprungen.
* Die verarbeiteten XML-Dokumente werden in der globalen Menge {@code xmlProtocols} gesammelt.
* </p>
*
* @return Ein Set von {@code org.w3c.dom.Document}, das die verarbeiteten XML-Protokolle enthält.
*/
public static Set<org.w3c.dom.Document> processXML() {
int offset = 0;
int limit = 10;
@ -425,6 +437,24 @@ public abstract class PPRUtils {
return fileNames;
}
/**
* Ruft neue Protokoll-XML-Dokumente von der Bundestag OpenData-API ab und verarbeitet sie.
*
* Diese Methode verwendet eine paginierte Abfrage (über Offset und Limit) der URL
* "https://www.bundestag.de/ajax/filterlist/de/services/opendata/866354-866354".
* Für jeden gefundenen XML-Link wird anhand des Dateinamens (z.B "20212.xml") die Sitzungsnummer extrahiert.
* Protokolle mit den Dateinamen "20007" oder "20212" werden als fehlerhaft erkannt und übersprungen.
* Falls die extrahierte Sitzungsnummer (nach Entfernen eines möglichen "20"-Präfixes) noch nicht in der Datenbank existiert
* (bestimmt durch mongoDBHandler.sessionExists(sessionNumber)), wird das XML-Dokument heruntergeladen und geparst.
* Die neu verarbeiteten XML-Dokumente werden in einem Set gesammelt und zurückgegeben.
*
* Die Pagination erfolgt über das HTML-Element <div class="meta-slider"> mit dem Attribut
* data-nextoffset. Ist kein nächster Offset vorhanden, wird die Schleife beendet.
*
*
* @param mongoDBHandler der MongoDBHandler, der für die Prüfung der Existenz einer Session in der Datenbank verwendet wird
* @return ein Setvon org.w3c.dom.Document, das alle neuen (noch nicht verarbeiteten) Protokoll-XML-Dokumente enthält
*/
public static Set<org.w3c.dom.Document> checkAndProcessNewProtocols(MongoDBHandler mongoDBHandler) {
Set<org.w3c.dom.Document> newProtocols = new HashSet<>();
int offset = 0;

View file

@ -24,7 +24,12 @@ public class SpeechVideoUpdater {
private static final String BASE_URL = "https://cldf-od.r53.cdn.tv1.eu/1000153copo/ondemand/app144277506/145293313/";
private static final String SUFFIX = "_h264_720_400_2000kb_baseline_de_2192.mp4?fdl=1";
/**
* Initialisiert den Video-Upload-Prozess.
* Diese Methode prüft, ob bereits ein Video für die erste Rede (speechId 0) in Session 187 und AgendaItem 4 vorhanden ist.
* Falls ein Video vorhanden ist, wird der Download übersprungen. Andernfalls wird findVideos() aufgerufen,
* um die Videos herunterzuladen und in GridFS hochzuladen sowie die Speech-Dokumente zu aktualisieren.
*/
public static void init() {
MongoDBHandler mongoDBHandler = new MongoDBHandler();
try {
@ -49,6 +54,13 @@ public class SpeechVideoUpdater {
}
}
/**
* Lädt Videos für Reden in Session 187, AgendaItem 4 herunter und lädt diese in GridFS hoch.
* Anschließend wird für jede Rede (speechId 0 bis 8) ein Bulk-Update erstellt, um das Speech-Dokument
* mit dem Videolink (GridFS-ID als Hex-String) zu aktualisieren.
*
* @throws Exception Falls beim Download oder Upload ein Fehler auftritt.
*/
public static void findVideos() throws Exception {
MongoDBHandler mongoDBHandler = new MongoDBHandler();
@ -93,6 +105,14 @@ public class SpeechVideoUpdater {
mongoDBHandler.close();
}
/**
* Lädt das Video von der angegebenen URL herunter und speichert es als temporäre Datei.
*
* @param videoUrl Die URL des Videos.
* @param fileName Der gewünschte Dateiname für die temporäre Datei.
* @return Eine {@code File}-Instanz, die auf die heruntergeladene Datei verweist.
* @throws IOException Falls beim Download oder Schreiben der Datei ein Fehler auftritt.
*/
private static File downloadVideo(String videoUrl, String fileName) throws IOException {
URL url = new URL(videoUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
@ -110,6 +130,15 @@ public class SpeechVideoUpdater {
return tempFile;
}
/**
* Lädt die übergebene Videodatei in GridFS hoch.
*
* @param gridFSBucket Der {@code GridFSBucket}, der für die Collection "videos" in der Datenbank konfiguriert ist.
* @param videoFile Die zu hochladende Videodatei.
* @param fileName Der Name, unter dem die Datei in GridFS gespeichert werden soll.
* @return Die {@code ObjectId} der in GridFS gespeicherten Datei.
* @throws IOException Falls beim Hochladen der Datei ein Fehler auftritt.
*/
private static ObjectId uploadVideoToGridFS(GridFSBucket gridFSBucket, File videoFile, String fileName) throws IOException {
try (InputStream streamToUploadFrom = new FileInputStream(videoFile)) {
GridFSUploadOptions options = new GridFSUploadOptions()

View file

@ -39,6 +39,13 @@ public class SpeechParser {
public void setParseLegislativePeriods(Boolean parseLegislativePeriods) {
}
/**
* Parst alle Sessions aus den globalen XML-Dokumenten, die über PPRUtils.processXML() abgerufen werden.
* Dabei werden auch die zugehörigen Reden und AgendaItems (sowie deren Inhalte) geparst.
* Die temporären Dateien werden nach der Verarbeitung gelöscht.
*
* @return Eine Liste von Session-Objekten, die aus den XML-Dokumenten erstellt wurden.
*/
public List<Session> parseAllSessions() {
List<Session> sessions = new ArrayList<>();
this.speeches = new ArrayList<>();
@ -60,6 +67,15 @@ public class SpeechParser {
}
/**
* Parst alle neuen Sessions aus den übergebenen XML-Dokumenten.
* Diese Methode wird verwendet, wenn bereits ein Set von XML-Dokumenten (z.B. von neuen Protokollen)
* vorliegt. Für jedes XML-Dokument wird eine temporäre Datei erstellt, geparst und anschließend gelöscht.
*
* @param xmlDocuments Ein Set von XML-Dokumenten (als org.w3c.dom.Document),
* die geparst werden sollen.
* @return Eine Liste von Session-Objekten, die aus den XML-Dokumenten erstellt wurden.
*/
public List<Session> parseAllSessions(Set<Document> xmlDocuments) {
List<Session> sessions = new ArrayList<>();
this.speeches = new ArrayList<>();
@ -80,6 +96,21 @@ public class SpeechParser {
}
/**
* Parst eine einzelne Session aus einer XML-Datei.
*
*
* Diese Methode erstellt mithilfe eines DocumentBuilder ein org.w3c.dom.Document aus der übergebenen Datei.
* Anschließend werden die Sitzungsdaten (z.B. Legislaturperiode, Sitzung-Nummer, Datum und Uhrzeit) aus dem Root-Element extrahiert.
* Danach werden die AgendaItems der Session und die zugehörigen Reden (inkl. Redner und Inhalte) geparst.
* Für jeden AgendaItem werden die zugehörigen Reden aus den untergeordneten XML-Elementen ("rede") extrahiert.
* Die geparsten Daten werden in Objekten vom Typ Session_File_Impl und AgendaItem_File_Impl abgelegt.
*
*
* @param file Die temporäre XML-Datei, die die Session-Daten enthält.
* @return Ein Session-Objekt, das aus der XML-Datei erstellt wurde.
* @throws Exception Falls beim Parsen der XML-Datei oder der Konvertierung in ein Session-Objekt ein Fehler auftritt.
*/
private Session parseSessionFile(File file) throws Exception {
//file = removeDoctypeAnnotation(file.getAbsolutePath());
@ -184,6 +215,16 @@ public class SpeechParser {
return session;
}
/**
* Retrieves the text content of the first child element with the specified tag name.
* The method searches for child elements with the given tag name in the provided element.
* If at least one such element is found, its text content is returned after trimming leading and trailing whitespace.
* If no child element with the specified tag name exists, the method returns null.
*
* @param parent the parent XML element in which to search for the child element
* @param tagName the name of the child element whose text content is to be retrieved
* @return the trimmed text content of the first matching child element, or null if no such element is found
*/
private static String getOptionalTextContent(Element parent, String tagName) {
NodeList nodes = parent.getElementsByTagName(tagName);
if (nodes.getLength() > 0) {