Frontend: List of Speeches is now displayed
This commit is contained in:
parent
c64a280405
commit
8439b52f65
8 changed files with 407 additions and 13 deletions
|
@ -1,14 +1,22 @@
|
|||
package org.texttechnologylab.project.gruppe_05_1.database;
|
||||
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import org.bson.Document;
|
||||
import org.texttechnologylab.project.gruppe_05_1.database.domainimp.speeches.Speech_MongoDB_Impl;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.html.Parlamentarier;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.speaker.Membership;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData;
|
||||
import org.texttechnologylab.project.gruppe_05_1.util.GeneralUtils;
|
||||
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Impls.Speech_File_Impl;
|
||||
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Speech;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -32,6 +40,8 @@ public class MongoPprUtils {
|
|||
|
||||
private static MongoCollection<Document> speakerCollection = null;
|
||||
private static MongoCollection<Document> speechCollection = null;
|
||||
private static MongoCollection<Document> sessionCollection = null;
|
||||
private static MongoCollection<Document> agendaItemsCollection = null;
|
||||
private static MongoCollection<Document> picturesCollection = null;
|
||||
private static MongoCollection<Document> commentCollection = null;
|
||||
|
||||
|
@ -45,6 +55,15 @@ public class MongoPprUtils {
|
|||
return speechCollection;
|
||||
}
|
||||
|
||||
public static MongoCollection<Document> getSessionCollection() {
|
||||
if (sessionCollection == null) sessionCollection = MongoDBHandler.getMongoDatabase().getCollection(SESSION_COLLECTION_NAME);
|
||||
return sessionCollection;
|
||||
}
|
||||
|
||||
public static MongoCollection<Document> getAgendaItemsCollection() {
|
||||
if (agendaItemsCollection == null) agendaItemsCollection = MongoDBHandler.getMongoDatabase().getCollection(AGENDA_ITEMS_COLLECTION_NAME);
|
||||
return agendaItemsCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Speaker Collection and useful indices for it
|
||||
|
@ -259,4 +278,114 @@ public class MongoPprUtils {
|
|||
}
|
||||
|
||||
// TODO: kopiere die Speech-Sachen von Übung 4 hierher!
|
||||
|
||||
/**
|
||||
* Aufzählen, wie viele Reden eines bestimmten Redners gespeichert sind
|
||||
* @param speakerId
|
||||
* @return Anzahl Reden
|
||||
*/
|
||||
public static Long countSpeechesOfSpeaker(String speakerId) {
|
||||
return getSpeechCollection().countDocuments(new Document("speakerId", Integer.parseInt(speakerId)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert alle Reden eines Redners zurück
|
||||
* @param speakerId
|
||||
* @return Alle Reden eines Redners
|
||||
*/
|
||||
public static List<Speech> getSpeechesOfSpeaker(String speakerId) {
|
||||
List<Speech> speeches = new ArrayList<>();
|
||||
|
||||
Document filter = new Document("speakerId", Integer.parseInt(speakerId));
|
||||
List<Document> docs = getSpeechCollection().find(filter).into(new ArrayList<>());
|
||||
|
||||
for (Document doc : docs) {
|
||||
speeches.add(new Speech_MongoDB_Impl(doc));
|
||||
}
|
||||
|
||||
return speeches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert Metadaten (aber keine Inhalte!) für alle Reden eines Redners zurück.
|
||||
* Als Metadaten zählen das Datum, Agenda-ID etc.
|
||||
* @param speakerId
|
||||
* @return
|
||||
*/
|
||||
public static List<SpeechMetaData> getSpeechesMetadataForSeaker(String speakerId) {
|
||||
|
||||
List<SpeechMetaData> speechMetaDataList = new ArrayList<>();
|
||||
List<Speech> speeches = MongoPprUtils.getSpeechesOfSpeaker(speakerId);
|
||||
for (Speech speech : speeches) {
|
||||
SpeechMetaData md = new SpeechMetaData();
|
||||
|
||||
md.setSpeechKey(speech.getSpeechKey());
|
||||
md.setSpeechId(speech.getSpeechId());
|
||||
md.setSpeakerId(speech.getSpeakerId());
|
||||
int sessionId = speech.getSessionId();
|
||||
md.setSessionId(sessionId);
|
||||
|
||||
|
||||
// aus "sessions" Collection
|
||||
String dateTimeString = getSessionDateTime(sessionId);
|
||||
if (dateTimeString != null) {
|
||||
md.setDateTimeString(dateTimeString);
|
||||
LocalDateTime tmp = GeneralUtils.parseDateTime(dateTimeString, "dd.MM.yyyy HH:mm");
|
||||
if (tmp == null) {
|
||||
tmp = GeneralUtils.parseDateTime(dateTimeString, "dd.MM.yyyy H:mm");
|
||||
if (tmp == null) {
|
||||
System.out.println(dateTimeString + " could not be parsed");
|
||||
}
|
||||
}
|
||||
md.setDateTime(tmp);
|
||||
}
|
||||
|
||||
// aus "agendaItems" Collection
|
||||
int agendaItemId = speech.getAgendaItemId();
|
||||
String agendaTitel = getAgendaTitle(sessionId, agendaItemId);
|
||||
md.setAgendaTitle(agendaTitel);
|
||||
|
||||
speechMetaDataList.add(md);
|
||||
|
||||
}
|
||||
|
||||
// Sortiere nach Datum, absteigend
|
||||
speechMetaDataList.sort((md1, md2) -> {
|
||||
return md2.getDateTime().compareTo(md1.getDateTime());
|
||||
});
|
||||
|
||||
return speechMetaDataList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert das Datum und die Uhrzeit einer Sitzung zurück
|
||||
* @param sessionId
|
||||
* @return
|
||||
*/
|
||||
public static String getSessionDateTime(int sessionId) {
|
||||
Document filter = new Document("sessionId", sessionId);
|
||||
Object dateTime = getSessionCollection().find(filter).first().get("dateTime");
|
||||
if (dateTime == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (String) dateTime;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Agenda-Titel zurück
|
||||
* @param sessionId
|
||||
* @return
|
||||
*/
|
||||
public static String getAgendaTitle(int sessionId, int agendaItemId) {
|
||||
Document filter = new Document("sessionId", sessionId).append("id", agendaItemId);
|
||||
FindIterable<Document> iter = getAgendaItemsCollection().find(filter);
|
||||
if ((iter == null || (iter.first() == null))) {
|
||||
return "(kein Agendatitel)";
|
||||
} else {
|
||||
return (String) iter.first().get("title");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
package org.texttechnologylab.project.gruppe_05_1.domain.speech;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* Diese Klasse dient der Darstellung aller Reden eines Parlamentariers.
|
||||
*/
|
||||
public class SpeechMetaData {
|
||||
// aus "speech" Collection
|
||||
String speechKey; // z.B. "ID2011400300"
|
||||
int speechId; // TODO: nötig?
|
||||
int speakerId;
|
||||
int sessionId; // TODO: nötig?
|
||||
|
||||
// aus "sessions" Collection
|
||||
LocalDateTime dateTime;
|
||||
String dateTimeString;
|
||||
|
||||
// aus "agendaItems" Collection
|
||||
String agendaTitle;
|
||||
|
||||
public String getSpeechKey() {
|
||||
return speechKey;
|
||||
}
|
||||
|
||||
public void setSpeechKey(String speechKey) {
|
||||
this.speechKey = speechKey;
|
||||
}
|
||||
|
||||
public int getSpeechId() {
|
||||
return speechId;
|
||||
}
|
||||
|
||||
public void setSpeechId(int speechId) {
|
||||
this.speechId = speechId;
|
||||
}
|
||||
|
||||
public int getSpeakerId() {
|
||||
return speakerId;
|
||||
}
|
||||
|
||||
public void setSpeakerId(int speakerId) {
|
||||
this.speakerId = speakerId;
|
||||
}
|
||||
|
||||
public int getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public void setSessionId(int sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
public LocalDateTime getDateTime() {
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
public void setDateTime(LocalDateTime dateTime) {
|
||||
this.dateTime = dateTime;
|
||||
}
|
||||
|
||||
public String getDateTimeString() {
|
||||
return dateTimeString;
|
||||
}
|
||||
|
||||
public void setDateTimeString(String dateTimeString) {
|
||||
this.dateTimeString = dateTimeString;
|
||||
}
|
||||
|
||||
public String getAgendaTitle() {
|
||||
return agendaTitle;
|
||||
}
|
||||
|
||||
public void setAgendaTitle(String agendaTitle) {
|
||||
this.agendaTitle = agendaTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof SpeechMetaData that)) return false;
|
||||
return speechId == that.speechId && speakerId == that.speakerId && sessionId == that.sessionId && Objects.equals(speechKey, that.speechKey) && Objects.equals(dateTime, that.dateTime) && Objects.equals(dateTimeString, that.dateTimeString) && Objects.equals(agendaTitle, that.agendaTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(speechKey, speechId, speakerId, sessionId, dateTime, dateTimeString, agendaTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", SpeechMetaData.class.getSimpleName() + "[", "]")
|
||||
.add("speechKey='" + speechKey + "'")
|
||||
.add("speechId=" + speechId)
|
||||
.add("speakerId=" + speakerId)
|
||||
.add("sessionId=" + sessionId)
|
||||
.add("dateTime=" + dateTime)
|
||||
.add("dateTimeString='" + dateTimeString + "'")
|
||||
.add("agendaTitle='" + agendaTitle + "'")
|
||||
.toString();
|
||||
}
|
||||
}
|
|
@ -6,7 +6,9 @@ import org.texttechnologylab.project.gruppe_05_1.domain.html.Parlamentarier;
|
|||
import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails;
|
||||
import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils;
|
||||
import org.texttechnologylab.project.gruppe_05_1.util.PPRUtils;
|
||||
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Speech;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -31,6 +33,8 @@ public class ParlamentarierController {
|
|||
* @param ctx JavaLin-Context
|
||||
*/
|
||||
|
||||
private static List<Integer> emptyList = new ArrayList<>(); // passed as an indicator if a certain list exists or not (in latter case: pass null)
|
||||
|
||||
@OpenApi(
|
||||
summary = "Get alle Parlamentarier. Man kann nach Vor-, Nachname oder Partei filtern.",
|
||||
description = "Listet alle Parlamentarier bzw. diejenige, welche den Filter entsprechen",
|
||||
|
@ -88,7 +92,16 @@ public class ParlamentarierController {
|
|||
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("p", pd);
|
||||
attributes.put("speechesCount", pd.getReden() == null ? 0 : pd.getReden().size());
|
||||
Long speechCount = MongoPprUtils.countSpeechesOfSpeaker(pd.getId());
|
||||
attributes.put("speechesCount", speechCount);
|
||||
if (speechCount == 0) {
|
||||
attributes.put("speechesPlaceholder", null);
|
||||
} else {
|
||||
attributes.put("speechesPlaceholder", emptyList);
|
||||
}
|
||||
|
||||
|
||||
List<Speech> speeches = MongoPprUtils.getSpeechesOfSpeaker(pd.getId());
|
||||
ctx.render("parlamentarierDetails.ftl", attributes);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,17 +57,9 @@ public class RESTHandler {
|
|||
app.get("/portfolio/{id}", ParlamentarierController::getParlamentarierDetails);
|
||||
app.delete("/deleteParlamentarier", ParlamentarierController::deleteAllParlamentarier);
|
||||
|
||||
/* - TODO
|
||||
// Fotos
|
||||
app.get("/editFoto/{id}", FotosController::editFotos);
|
||||
app.post("/editFoto/updateFotoUrl/{id}/{pictureId}", FotosController::updateFotoUrl);
|
||||
app.post("/editFoto/defineFotoAsPrimary/{id}", FotosController::defineFotoAsPrimary);
|
||||
|
||||
// Reden
|
||||
app.get("/reden/{id}", RedenController::listSpeeches); // zeige Reden eines Parlamentariers an
|
||||
app.get("/reden/{id}/{redeId}", RedenController::showSpeech); // zeige eine bestimmte Rede des Parlamentariers an
|
||||
app.post("/reden/updateComment/{id}/{speechId}/{commentId}", RedenController::updateComment); // aktualisiere Änderung an einer Kommentar
|
||||
app.get("/reden/{id}", SpeechController::listSpeeches); // zeige Reden eines Parlamentariers an
|
||||
app.get("/reden/{id}/{redeId}", SpeechController::showSpeech); // zeige eine bestimmte Rede des Parlamentariers an
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package org.texttechnologylab.project.gruppe_05_1.rest;
|
||||
|
||||
import io.javalin.http.Context;
|
||||
import io.javalin.openapi.*;
|
||||
import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.speech.Protocol;
|
||||
import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData;
|
||||
import org.texttechnologylab.project.gruppe_05_1.util.GeneralUtils;
|
||||
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Comment;
|
||||
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Speech;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SpeechController {
|
||||
/**
|
||||
* Liste alle Reden eines Parlamentariers an
|
||||
* @param ctx Javalin Context
|
||||
*/
|
||||
@OpenApi(
|
||||
summary = "Liste alle Reden eines Parlamentariers an",
|
||||
description = "Liste alle Reden eines Parlamentariers an",
|
||||
operationId = "listSpeeches",
|
||||
path = "/reden/{id}",
|
||||
methods = HttpMethod.GET,
|
||||
tags = {"Rede"},
|
||||
pathParams = {
|
||||
@OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
|
||||
},
|
||||
responses = {
|
||||
@OpenApiResponse(status = "200", content = {@OpenApiContent(from = Speech[].class)})
|
||||
})
|
||||
public static void listSpeeches(Context ctx) {
|
||||
String parlamentarierId = ctx.pathParam("id");
|
||||
|
||||
ParlamentarierDetails p = MongoPprUtils.getParlamentarierDetailsByID(parlamentarierId);
|
||||
List<SpeechMetaData> speechMetaDataList = MongoPprUtils.getSpeechesMetadataForSeaker(parlamentarierId);
|
||||
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("p", p);
|
||||
attributes.put("speechesMetaDataList", speechMetaDataList);
|
||||
ctx.render("showSpeechesList.ftl", attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeige eine bestimmte Rede des Parlamentariers an
|
||||
* @param ctx Javalin Context
|
||||
*/
|
||||
@OpenApi(
|
||||
summary = "Zeige eine bestimmte Rede des Parlamentariers an",
|
||||
description = "Zeige eine bestimmte Rede des Parlamentariers an",
|
||||
operationId = "showSpeech",
|
||||
path = "/reden/{id}/{redeID}",
|
||||
methods = HttpMethod.GET,
|
||||
tags = {"Rede"},
|
||||
pathParams = {
|
||||
@OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
|
||||
@OpenApiParam(name = "redeId", description = "id der Rede", required = true),
|
||||
},
|
||||
responses = {
|
||||
@OpenApiResponse(status = "200", content = {@OpenApiContent(from = Speech.class)})
|
||||
})
|
||||
public static void showSpeech(Context ctx) {
|
||||
String parlamentarierId = ctx.pathParam("id");
|
||||
String redeId = ctx.pathParam("redeId");
|
||||
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
|
||||
/*
|
||||
Speech rede = MongoPprUtils.getSpeechesById(redeId);
|
||||
List<Comment> comments = MongoPprUtils.getCommentsForSpeech(redeId);
|
||||
ParlamentarierDetails p = MongoPprUtils.getParlamentarierDetailsByID(parlamentarierId);
|
||||
|
||||
|
||||
attributes.put("p", p);
|
||||
attributes.put("rede", rede);
|
||||
attributes.put("comments", comments.size() > 0 ? comments : null);
|
||||
Protocol protocol = rede.getProtocol();
|
||||
if (protocol == null) {
|
||||
attributes.put("date", "(keine Angaben)");
|
||||
attributes.put("time", "(keine Angaben)");
|
||||
} else {
|
||||
LocalDate date = protocol.getDate();
|
||||
LocalTime time = protocol.getStarttime();
|
||||
if (date == null) {
|
||||
attributes.put("date", "(keine Angaben)");
|
||||
} else {
|
||||
attributes.put("date", GeneralUtils.formatDate(date));
|
||||
}
|
||||
if (time == null) {
|
||||
attributes.put("time", "(keine Angaben)");
|
||||
} else {
|
||||
attributes.put("time", GeneralUtils.formatTime(time));
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
ctx.render("speechWithComments.ftl", attributes);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.texttechnologylab.project.gruppe_05_1.util;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
@ -74,4 +75,11 @@ public abstract class GeneralUtils {
|
|||
return time.format(DateTimeFormatter.ofPattern("HH.mm"));
|
||||
}
|
||||
|
||||
public static LocalDateTime parseDateTime(String dateTime, String timeFormat) {
|
||||
try {
|
||||
return LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern(timeFormat));
|
||||
} catch (DateTimeParseException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
<main>
|
||||
<section>
|
||||
<h2>Reden</h2>
|
||||
<#if p.reden??>
|
||||
<#if speechesPlaceholder??>
|
||||
<a href="/reden/${p.id}">${speechesCount} Reden vorhanden</a>
|
||||
<#else>
|
||||
Keine Reden
|
||||
Keine Reden vorhanden
|
||||
</#if>
|
||||
<br> <br>
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Reden von ${p.vorname} ${p.nachname} (${p.partei})</title>
|
||||
<style type="text/css">
|
||||
th, td {
|
||||
padding: 12px;
|
||||
text-align: center; /* Center-aligns both header and data cells */
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Reden von ${p.vorname} ${p.nachname} (${p.partei})</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Sitzung / Agenda</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<#list speechesMetaDataList as redeMd>
|
||||
<tr>
|
||||
<td>${redeMd.dateTimeString}</td>
|
||||
<td><a href="/reden/${p.id}/${redeMd.speechKey}">${redeMd.sessionId} / ${redeMd.agendaTitle}</a></td>
|
||||
</tr>
|
||||
</#list>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</main>
|
||||
<body>
|
Loading…
Add table
Add a link
Reference in a new issue