diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/Main.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/Main.java index 85aeddb..b022cc3 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/Main.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/Main.java @@ -34,11 +34,13 @@ public class Main { private static final FileObjectFactory xmlFactory = FileObjectFactory.getFactory(); private static final MongoObjectFactory mongoFactory = MongoObjectFactory.getFactory(); + public static final String RESOURCES_DIR = "src/main/resources"; public static final String CONFIG_DIR = "src/main/resources/config"; public static final String JAVALIN_TEMPLATE_DIR = "src/main/resources/templates"; public static final String JAVALIN_STATIC_FILES_DIR = "src/main/resources/static"; public static final String JCAS_SPEECHES_TYPESYSTEM_DIR = "src/main/resources/speeches/TypeSystem"; public static final String MEMBER_IMAGES_DIR = "src/main/resources/membersOfParliamentImages/"; + public static final String TEMP_EXPORT_DIR = "src/main/resources/tempExport/"; public static void main(String[] args) throws Exception { UPLOAD_MEMBER_PHOTOS = Arrays.asList(args).contains("uploadMemberPhotos"); diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoPprUtils.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoPprUtils.java index 73c6d90..d056d92 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoPprUtils.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoPprUtils.java @@ -11,6 +11,7 @@ import com.mongodb.client.model.Projections; import io.javalin.http.Context; import org.bson.Document; import org.bson.conversions.Bson; +import org.texttechnologylab.project.gruppe_05_1.database.domainimpl.mdb.Speaker_MongoDB_Impl; import org.texttechnologylab.project.gruppe_05_1.database.domainimpl.mdb.Speech_MongoDB_Impl; import org.texttechnologylab.project.gruppe_05_1.domain.html.HtmlSpeech; import org.texttechnologylab.project.gruppe_05_1.domain.html.Parlamentarier; @@ -297,6 +298,15 @@ public class MongoPprUtils { return readParlamentarierDetailsFromSpeaker(doc); } + public static Speaker_MongoDB_Impl getSpeakerById(String id) { + Logger.debug("ID: " + id); + Document doc = MongoDBHandler.findFirstDocumentInCollection(getSpeakerCollection(), "_id", id); + Logger.debug("Speaker: " + doc); + Speaker_MongoDB_Impl speaker = new Speaker_MongoDB_Impl().createSpeakerMongoDBImpl(doc); + Logger.debug("Speaker parsed" + speaker); + return speaker; + } + /** * Holt die Details eines Parlamentariers @@ -623,7 +633,7 @@ public class MongoPprUtils { * @param key: Rede ID * @return */ - public static HtmlSpeech getSpeechByKey(String key) { + public static HtmlSpeech getHTMLSpeechByKey(String key) { Document filter = new Document("speechKey", key); Document speechDoc = getSpeechCollection().find(filter).first(); if (speechDoc == null) { @@ -634,6 +644,18 @@ public class MongoPprUtils { return new HtmlSpeech(speechDoc); } + public static Speech getSpeechByKey(String key) { + Document filter = new Document("speechKey", key); + Document speechDoc = getSpeechCollection().find(filter).first(); + + if (speechDoc == null) { + Logger.error("Rede " + key + " nicht gefunden"); + return null; + } + + return new Speech_MongoDB_Impl(speechDoc, true); + } + // getMemberPhoto /** diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/domainimpl/mdb/Speaker_MongoDB_Impl.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/domainimpl/mdb/Speaker_MongoDB_Impl.java index 5c357e0..e2b625e 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/domainimpl/mdb/Speaker_MongoDB_Impl.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/domainimpl/mdb/Speaker_MongoDB_Impl.java @@ -5,15 +5,60 @@ import org.texttechnologylab.project.gruppe_05_1.database.MongoDBHandler; import org.texttechnologylab.project.gruppe_05_1.database.MongoOperations; import org.texttechnologylab.project.gruppe_05_1.domain.speaker.Membership; import org.texttechnologylab.project.gruppe_05_1.domain.speaker.Speaker; +import org.texttechnologylab.project.gruppe_05_1.util.Logger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.time.LocalDate; +import java.util.*; +import static org.texttechnologylab.project.gruppe_05_1.Main.TEMP_EXPORT_DIR; import static org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils.getMemberPhoto; public class Speaker_MongoDB_Impl extends Speaker implements MongoOperations { + public Speaker_MongoDB_Impl createSpeakerMongoDBImpl(Document mongoDocument) { + this.setId(mongoDocument.getString("_id")); + this.setName(mongoDocument.getString("name")); + this.setFirstName(mongoDocument.getString("firstName")); + this.setTitle(mongoDocument.getString("title")); + Logger.debug("First part parsed succesfully"); + this.setGeburtsdatum(parseTimestampSafely(mongoDocument.getDate("geburtsdatum"))); + this.setGeburtsort(mongoDocument.getString("geburtsort")); + this.setSterbedatum(parseTimestampSafely(mongoDocument.getDate("sterbedatum"))); + this.setGeschlecht(mongoDocument.getString("geschlecht")); + this.setBeruf(mongoDocument.getString("beruf")); + this.setAkademischertitel(mongoDocument.getString("akademischertitel")); + this.setFamilienstand(mongoDocument.getString("familienstand")); + this.setReligion(mongoDocument.getString("religion")); + this.setVita(mongoDocument.getString("vita")); + this.setParty(mongoDocument.getString("party")); + + List memberships = (List) mongoDocument.get("memberships"); + List membershipList = new ArrayList<>(); + for (Document membership : memberships) { + Membership membershipObj = new Membership(); + membershipObj.setRole(membership.getString("role")); + membershipObj.setMember(membership.getString("member")); + membershipObj.setBegin(parseTimestampSafely(membership.getDate("begin"))); + membershipObj.setEnd(parseTimestampSafely(membership.getDate("end"))); + membershipObj.setLabel(membership.getString("label")); + membershipObj.setWp(membership.getInteger("wp")); + membershipList.add(membershipObj); + } + this.setMemberships(membershipList); + + return this; + } + + public LocalDate parseTimestampSafely(Date timestamp) { + try { + Logger.debug("Parsing timestamp: " + timestamp); + return LocalDate.parse(timestamp.toString()); + } catch (Exception e) { + return null; + } + } @Override public Document createEntity(Speaker entity) { @@ -48,4 +93,42 @@ public class Speaker_MongoDB_Impl extends Speaker implements MongoOperations() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + // Delete file + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + // Delete the directory after its contents are deleted + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } +} diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/RESTHandler.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/RESTHandler.java index 2d50db1..8ffa4e8 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/RESTHandler.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/RESTHandler.java @@ -65,5 +65,9 @@ public class RESTHandler { app.get("/reden/{id}/{redeId}", SpeechController::showSpeech); // zeige eine bestimmte Rede des Parlamentariers an app.get("/reden", SpeechController::listAllSpeeches); // zeige alle Reden an (Filtern möglich) + + app.get("/export/speech/{id}", SpeechesExportController::exportSpeech); // exportiere eine Rede als PDF + //app.get("/portfolio/{id}/export", SpeechesExportController::exportSpeechesFromParlamentarier); // exportiere alle Reden eines Parlamentariers als PDF + //app.get("/topic/{topic}/export", SpeechesExportController::exportSpeechesWithTopic); // exportiere alle Reden zu einem Thema als PDF } } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechController.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechController.java index 85e5d19..74e2dfe 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechController.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechController.java @@ -72,7 +72,7 @@ public class SpeechController { Map attributes = new HashMap<>(); - HtmlSpeech speech = MongoPprUtils.getSpeechByKey(redeId); + HtmlSpeech speech = MongoPprUtils.getHTMLSpeechByKey(redeId); if (speech == null) { attributes.put("error", "Rede " + redeId + " nicht vorhanden"); ctx.render("speech.ftl", attributes); diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechesExportController.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechesExportController.java new file mode 100644 index 0000000..f56a12a --- /dev/null +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/rest/SpeechesExportController.java @@ -0,0 +1,44 @@ +package org.texttechnologylab.project.gruppe_05_1.rest; + +import io.javalin.http.Context; +import io.javalin.openapi.HttpMethod; +import io.javalin.openapi.OpenApi; +import io.javalin.openapi.OpenApiResponse; +import org.texttechnologylab.project.gruppe_05_1.util.Logger; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Base64; + +import static org.texttechnologylab.project.gruppe_05_1.export.TeXUtil.*; + +public class SpeechesExportController { + @OpenApi( + summary = "Get a speech as a PDF", + description = "Returns a LaTeX generated pdf of a selected speech", + operationId = "getSpeechExport", + path = "/export/speech/{id}", + methods = HttpMethod.GET, + tags = {"Export", "Speeches", "PDF"}, + responses = { + @OpenApiResponse(status = "200") + }) + public static void exportSpeech(Context ctx) throws IOException { + byte[] pdfBytes = new byte[0]; + try { + pdfBytes = Base64.getDecoder().decode(getExportedSpeechBase64StringBySpeechId(ctx.pathParam("id"))); + } catch (Exception e) { + Logger.error("Failed to generate Export of Speech with ID " + ctx.pathParam("id")); + Logger.error(e.getMessage()); + } + + // Set the response content type to PDF + ctx.contentType("application/pdf"); + + // Send the PDF as a response + ctx.result(new ByteArrayInputStream(pdfBytes)); + + // delete the temporary folder + deleteTeXTempDirContents(); + } +} diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Comment_File_Impl.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Comment_File_Impl.java index 036b204..96b802b 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Comment_File_Impl.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Comment_File_Impl.java @@ -42,4 +42,9 @@ public class Comment_File_Impl implements Content, Comment { public MongoDBEntryType getType() { return MongoDBEntryType.SPEECH_COMMENT; } + + @Override + public String toTeX() { + return "\\textcolor{blue}{Kommentar}: " + this.getComment() + "\\\n"; + } } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Line_File_Impl.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Line_File_Impl.java index d230aaf..f9baea5 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Line_File_Impl.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Line_File_Impl.java @@ -34,4 +34,9 @@ public class Line_File_Impl implements Content, Line { public MongoDBEntryType getType() { return MongoDBEntryType.SPEECH_LINE; } + + @Override + public String toTeX() { + return this.getContent() + "\\\n"; + } } \ No newline at end of file diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speaker_File_Impl.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speaker_File_Impl.java index a71b8c1..4dfe625 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speaker_File_Impl.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speaker_File_Impl.java @@ -49,4 +49,9 @@ public class Speaker_File_Impl implements Content, Speaker { public MongoDBEntryType getType() { return MongoDBEntryType.SPEECH_SPEAKER; } + + @Override + public String toTeX() { + return "\\textcolor{blue}{Redner/Rednerin}: " + this.getSpeakerName() + "\\\n"; + } } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speech_File_Impl.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speech_File_Impl.java index fa765c5..2a3a412 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speech_File_Impl.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Impls/Speech_File_Impl.java @@ -103,4 +103,22 @@ public class Speech_File_Impl implements Speech { return null; } + @Override + public String toTeX() { + StringBuilder tex = new StringBuilder(); + + tex.append("\\NLP Metadata\\\n"); + + tex.append("[Graphs] //TODO: Implement\n"); + + tex.append("\\subsection*{Speech Content}\n"); + + // Add content block of speeches + for (Content content: this.getSpeechContents()) { + tex.append(content.toTeX()); + } + + + return tex.toString(); + } } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Content.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Content.java index 1138cb7..5543428 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Content.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Content.java @@ -24,4 +24,11 @@ public interface Content { * @return The speech ID. */ int getSpeechId(); + + /** + * Returns the content as LaTeX. + * + * @return The content. + */ + String toTeX(); } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Speech.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Speech.java index 642a24c..75032ab 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Speech.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/xml/speeches/Interfaces/Speech.java @@ -85,4 +85,6 @@ public interface Speech { String getFullText(); JCas toCas() throws UIMAException; + + String toTeX(); }