Compare commits

..

No commits in common. "67e117b6471c0fe1cf3065a4170694ff7c75ef34" and "e7eb638e29ab02d66f78c05e54383befb7a13b25" have entirely different histories.

21 changed files with 3898 additions and 4207 deletions

View file

@ -1,38 +0,0 @@
BENUTZERHANDBUCH MULTIMODAL PARLIAMENT EXPLORER
GRUPPE_05_01
Der Multimodal Parliament Explorer ist eine client-server basierte Anwendung zum automatischen abrufen, analysieren, visualisieren und exportieren aller Reden des Bundestags der aktuellen Legislaturperiode.
Mit unserem Programm kann man Reden des Bundestags interaktiv erkunden, Statistiken zu den zugehörigen Reden einsehen und diese selbst weiterverwenden.
1. Systemanforderungen
- Java 17+
- Maven
- Einen modernen Webbrowser (Chrome, Firefox, Edge)
- Einen Internetzugang
2. Hauptfunktionen
Datenimport:
Automatischer Download der XML Protokolle inklusive Videos
NLP-Analyse:
Analyse der Reden durch einen NLP-Docker
Datenexploration:
Filterbar nach Redner, Thema und Datum
Visualisierung der analysierten Daten:
Durch verschiedene Charts werden die Analysedaten anschaulich und verdaubar wiedergegeben
Export:
Alle Reden können als PDF und XML exportiert werden.
3. Support und Weiterführende Dokumentation
Detaillierte Entwicklungs und Nutzungsanleitungen finden Sie im Repository unter /doc oder auf unserer GitLab-Page bei https://ppr.gitlab.texttechnologylab.org/leonkastner/multimodal-parliament-explorer-docu
Bei Fragen oder Fehlern können sie sich gerne bei uns melden.

View file

@ -154,7 +154,6 @@ Folgende Informationen werden angezeigt:
- Informationen zum Redner (Name, Partei, Foto).
- Informationen zur Rede (Datum, Uhrzeit, Agendapunkt).
- Redetext. Vorstellung und Kommentare werden farblich gekennzeichnet.
- Video bei Reden der Sitzung 187 Tagesordnungspunkt 4
- NLP Informationen.
Der NLP-Abschnitt beinhaltet folgende Informationen:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

View file

@ -1,77 +0,0 @@
@startuml
left to right direction
actor Admin
actor Nutzer
actor SystemScheduler as "Zeitgesteuerter Dienst"
rectangle "Multimodal Parliament Explorer" {
package "Datenimport" {
usecase "XML Protokolle herunterladen" as UC1
usecase "XML verarbeiten & speichern" as UC2
usecase "Videos herunterladen & speichern" as UC3
usecase "Fotos der Abgeordneten speichern" as UC4
usecase "NLP-Daten einlesen & verarbeiten" as UC5
}
package "NLP Verarbeitung" {
usecase "NLP Analyse mit DUUI durchführen" as UC6
usecase "NLP-Resultate serialisieren\n& in DB speichern" as UC7
}
package "Export / Serialisierung" {
usecase "Rede als PDF exportieren" as UC8
usecase "Rede als XML exportieren" as UC9
usecase "Rede als XMI exportieren" as UC10
}
package "Visualisierung & UI" {
usecase "Reden durchsuchen" as UC11
usecase "Rede anzeigen (HTML, NLP, Video)" as UC12
usecase "POS / Sentiment / NER / Topics visualisieren" as UC13
}
package "Datenbankoperationen" {
usecase "Reden / Sessions / AgendaItems\nin MongoDB speichern" as UC14
usecase "Metadaten zu Reden abfragen" as UC15
usecase "Video-Referenzen zu Reden abfragen" as UC16
}
package "Systemdienste" {
usecase "Auf neue Protokolle automatisch prüfen und herunterladen" as UC17
usecase "Neue NLP-Reden automatisch analysieren" as UC18
}
' Verbindungen
Admin--> UC1
Admin--> UC2
Admin--> UC3
Admin--> UC4
Admin--> UC5
Admin--> UC6
Admin--> UC7
Admin--> UC8
Admin--> UC9
Admin--> UC10
Nutzer--> UC8
Nutzer--> UC9
Nutzer--> UC10
Nutzer --> UC11
Nutzer --> UC12
Nutzer --> UC13
UC6 --> UC7
UC5 --> UC6
UC2 --> UC14
UC3 --> UC14
UC4 --> UC14
UC14 --> UC15
UC14 --> UC16
UC12 --> UC13
UC12 --> UC16
SystemScheduler --> UC17
SystemScheduler --> UC18
}
@enduml

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Before After
Before After

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

File diff suppressed because it is too large Load diff

View file

@ -331,46 +331,6 @@ public class MongoPprUtils {
return result;
}
/**
* Implementiert von Valentin
* Holt alle Reden eines Parlamentariers
* @param speakerId
* @return
*/
public static List<SpeechOverview> getSpeechesOverviewForSpeaker(Integer speakerId) {
List<SpeechOverview> result = new ArrayList<>();
MongoCollection<Document> collection = getSpeechCollection();
Document projection = new Document("speechKey", 1)
.append("speakerId", 1)
.append("dateTimeString", 1)
.append("speakerName", 1)
.append("fraction", 1)
.append("agendaTitel", 1);
Bson filter = Filters.eq("speakerId", speakerId);
List<Document> docs = collection.find(filter)
.projection(projection)
.sort(Sorts.descending("dateTime"))
.into(new ArrayList<>());
for (Document doc : docs) {
result.add(new SpeechOverview(
doc.getString("speechKey"),
doc.getInteger("speakerId"),
doc.getString("dateTimeString"),
doc.getString("speakerName"),
doc.getString("fraction"),
doc.getString("agendaTitel")
));
}
return result;
}
/**
* Implementiert von Valentin

View file

@ -42,20 +42,6 @@ public class FrontEndController {
ctx.render("home.ftl");
}
@OpenApi(
summary = "Get the about page.",
description = "Get the about",
operationId = "getAbout",
path = "/about",
methods = HttpMethod.GET,
tags = {"About"},
responses = {
@OpenApiResponse(status = "200")
})
public static void getAbout(Context ctx) {
ctx.render("about.ftl");
}
/*
TODO: getAllParlamentarier gibt es hier UND im ParlamentarierController (etwas unterschiedliche Implementierungen)
--> konsolidieren!
@ -84,34 +70,6 @@ public class FrontEndController {
ctx.render("parlamentarier.ftl", attributes);
}
@OpenApi(
summary = "Get the export page.",
description = "Get the export page",
operationId = "getExportPage",
path = "/export",
methods = HttpMethod.GET,
tags = {"Export"},
responses = {
@OpenApiResponse(status = "200")
})
public static void getExportPage(Context ctx) {
ctx.render("export.ftl");
}
@OpenApi(
summary = "Get the about page.",
description = "Get the about page",
operationId = "getAboutPage",
path = "/about",
methods = HttpMethod.GET,
tags = {"About"},
responses = {
@OpenApiResponse(status = "200")
})
public static void getAboutPage(Context ctx) {
ctx.render("about.ftl");
}
/**
* Aggregiert für alle Reden die NLPErgebnisse (Topics, POS, Named Entities, erste SentimentObjekte)
* und liefert die zusammengefassten Daten an die ChartsAnsicht.

View file

@ -62,8 +62,6 @@ public class RESTHandler {
app.get("/", FrontEndController::getHomepage);
app.get("/members", FrontEndController::getAllParlamentarier);
app.get("/portfolio/{id}", ParlamentarierController::getParlamentarierDetails);
app.get("/export", FrontEndController::getExportPage);
app.get("/about", FrontEndController::getAboutPage);
// Reden
app.get("/reden/{id}", SpeechController::listSpeeches); // zeige Reden eines Parlamentariers an
@ -76,14 +74,12 @@ public class RESTHandler {
app.get("/charts", FrontEndController::getCharts);
app.get("/export/pdf/speech/{id}", SpeechesLatexExportController::exportSpeech); // exportiere eine Rede als PDF
app.get("/export/pdf/speech", SpeechesLatexExportController::exportSpeech); // exportiere eine Rede als PDF
app.get("/export/pdf/speaker/{id}", SpeechesLatexExportController::exportSpeechesFromSpeaker); // exportiere alle Reden eines Parlamentariers als PDF
app.get("/export/pdf/topic/{topic}", SpeechesLatexExportController::exportSpeechesWithTopic); // exportiere alle Reden zu einem Thema als PDF
app.get("/export/pdf/all", SpeechesLatexExportController::exportAllSpeeches); // exportiere alle Reden als PDF CAUTION!!!: This will take forever but is required in the exercise
app.get("/export/pdf/speeches/{speechIds}", SpeechesLatexExportController::exportSpeeches); // exportiere eine Liste von Reden als PDF
app.get("/export/xml/speech/{id}", SpeechesXMLExportController::exportSpeech); // exportiere eine Rede als XML
app.get("/export/xml/speech", SpeechesXMLExportController::exportSpeech); // exportiere eine Rede als XML
app.get("/export/xml/speaker/{id}", SpeechesXMLExportController::exportSpeechesFromSpeaker); // exportiere alle Reden eines Parlamentariers als XML
app.get("/export/xml/topic/{topic}", SpeechesXMLExportController::exportSpeechesWithTopic); // exportiere alle Reden zu einem Thema als XML
app.get("/export/xml/all", SpeechesXMLExportController::exportAllSpeeches); // exportiere alle Reden als XML

View file

@ -45,7 +45,8 @@ public class SpeechController {
String parlamentarierId = ctx.pathParam("id");
ParlamentarierDetails p = MongoPprUtils.getParlamentarierDetailsByID(parlamentarierId);
List<SpeechOverview> speechMetaDataList = MongoPprUtils.getSpeechesOverviewForSpeaker(Integer.parseInt(parlamentarierId));
List<SpeechMetaData> speechMetaDataList = MongoPprUtils.getSpeechesMetadataForSpeaker(parlamentarierId);
Map<String, Object> attributes = new HashMap<>();
attributes.put("p", p);
attributes.put("speechesMetaDataList", speechMetaDataList);

View file

@ -30,18 +30,11 @@ public class SpeechesLatexExportController {
@OpenApiResponse(status = "200")
})
public static void exportSpeech(Context ctx) {
String speechId = null;
try {
speechId = ctx.pathParam("id");
} catch (Exception e) {
// check query param
speechId = ctx.queryParam("speechId");
}
byte[] pdfBytes = new byte[0];
try {
pdfBytes = Base64.getDecoder().decode(getExportedSpeechBase64StringBySpeechId(speechId));
pdfBytes = Base64.getDecoder().decode(getExportedSpeechBase64StringBySpeechId(ctx.pathParam("id")));
} catch (Exception e) {
Logger.error("Failed to generate Export of Speech with ID " + speechId);
Logger.error("Failed to generate Export of Speech with ID " + ctx.pathParam("id"));
Logger.error(e.getMessage());
Logger.debug(Arrays.toString(e.getStackTrace()));
}

View file

@ -32,16 +32,9 @@ public class SpeechesXMLExportController {
@OpenApiResponse(status = "200")
})
public static void exportSpeech(Context ctx) {
String speechId = null;
try {
speechId = ctx.pathParam("id");
} catch (Exception e) {
// check query param
speechId = ctx.queryParam("speechId");
}
String xmlContent;
try {
xmlContent = getExportedSpeechById(speechId);
xmlContent = getExportedSpeechById(ctx.pathParam("id"));
ByteArrayInputStream stream = new ByteArrayInputStream(xmlContent.getBytes());
if (stream.available() == 0) {
Logger.error("XML stream is empty.");
@ -52,7 +45,7 @@ public class SpeechesXMLExportController {
ctx.contentType("application/xml");
ctx.result(stream);
} catch (Exception e) {
Logger.error("Failed to generate Export of Speech with ID " + speechId);
Logger.error("Failed to generate Export of Speech with ID " + ctx.pathParam("id"));
Logger.error(e.getMessage());
Logger.debug(Arrays.toString(e.getStackTrace()));
ctx.result("Internal Server Error");

View file

@ -2,9 +2,5 @@
<link rel="stylesheet" href="index.css">
</head>
<#include "header.ftl">
<h1>Über</h1>
<p>Alle Infos zur Nutzung und die Dokumentation kann auf der <a href="https://ppr.gitlab.texttechnologylab.org/leonkastner/multimodal-parliament-explorer-docu">Doku GitLab Repository eingesehen werden</a></p>
<br>
<br>
<p>PPR WS24/25 - Gruppe_05_1</p>
<h1>About</h1>
<#include "footer.ftl">

View file

@ -1,43 +0,0 @@
<head>
<link rel="stylesheet" href="index.css">
<title>Parliament Explorer</title>
</head>
<#include "header.ftl">
<body>
<main>
<h2>Export von Reden</h2>
<p>Export von allen Reden (Dieser Prozess kanne einige Zeit dauern):</p>
<div class="export-button centered-flex-button">
<div class="red-button centered-flex-button">
<a href="/export/pdf/all" target="_blank">PDF Export</a>
</div>
<br>
<div class="red-button centered-flex-button">
<a href="/export/xml/all" target="_blank">XML Export</a>
</div>
<br>
<br>
<p>Export von allen Reden eines Parlamentariers.</p>
</div>
<#assign formAction = "/members">
<#include "filterForm.ftl">
<br>
<br>
<p>Export einer bestimmten Rede nach ID</p>
<div class="filter-form">
<form name="searchForm" action="/export/pdf/speech" method="GET">
<input type="text" name="speechId" placeholder="Reden ID">
<button type="submit">Als PDF Exportieren</button>
</form>
</div>
<div class="filter-form">
<form name="searchForm" action="/export/xml/speech" method="GET">
<input type="text" name="speechId" placeholder="Reden ID">
<button type="submit">Als XML Exportieren</button>
</form>
</div>
</main>
</body>
<#include "footer.ftl">

View file

@ -36,11 +36,11 @@
<h2>Reden Export von allen Reden von ${p.vorname} ${p.nachname}</h2>
<div class="export-button centered-flex-button">
<div class="red-button centered-flex-button">
<a href="/export/pdf/speaker/${p.id}" target="_blank">PDF Export</a>
<a href="/export/pdf/speaker/${p.id}">PDF Export</a>
</div>
<br>
<div class="red-button centered-flex-button">
<a href="/export/xml/speaker/${p.id}" target="_blank">XML Export</a>
<a href="/export/xml/speaker/${p.id}">XML Export</a>
</div>
</div>

View file

@ -32,7 +32,7 @@
<#list speechesMetaDataList as redeMd>
<tr>
<td>${redeMd.dateTimeString}</td>
<td><a href="/reden/${p.id}/${redeMd.speechKey}">${redeMd.agendaTitel}</a></td>
<td><a href="/reden/${p.id}/${redeMd.speechKey}">${redeMd.agendaTitle}</a></td>
</tr>
</#list>

View file

@ -51,11 +51,11 @@
<h2>Reden Export von dieser Rede</h2>
<div class="export-button centered-flex-button">
<div class="red-button centered-flex-button">
<a href="/export/pdf/speech/${s.speechKey}" target="_blank">PDF Export</a>
<a href="/export/pdf/speech/${s.speechKey}">PDF Export</a>
</div>
<br>
<div class="red-button centered-flex-button">
<a href="/export/xml/speech/${s.speechKey}" target="_blank">XML Export</a>
<a href="/export/xml/speech/${s.speechKey}">XML Export</a>
</div>
</div>