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 7670218..0f56a68 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 @@ -7,6 +7,7 @@ import org.texttechnologylab.project.gruppe_05_1.nlp.XmiExtractor; import org.texttechnologylab.project.gruppe_05_1.rest.RESTHandler; import org.texttechnologylab.project.gruppe_05_1.util.Logger; import org.texttechnologylab.project.gruppe_05_1.util.PPRUtils; +import org.texttechnologylab.project.gruppe_05_1.util.SpeechVideoUpdater; import org.texttechnologylab.project.gruppe_05_1.xml.FileObjectFactory; import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Session; import org.texttechnologylab.project.gruppe_05_1.xml.speeches.SpeechParser; @@ -148,6 +149,7 @@ public class Main { Logger.pink("Uploading Member Photos to DB..."); mongoDBHandler.uploadMemberPhotos(); } + SpeechVideoUpdater.init(); ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); scheduler.scheduleAtFixedRate(() -> { try { diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoDBHandler.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoDBHandler.java index e266fcd..672cbb3 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoDBHandler.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/database/MongoDBHandler.java @@ -800,4 +800,7 @@ public class MongoDBHandler { mongoClient.close(); } + public Document getSpeech(Document filter) { + return speechesCollection.find(filter).first(); + } } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/domain/html/HtmlSpeech.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/domain/html/HtmlSpeech.java index accc14e..9a33b72 100644 --- a/src/main/java/org/texttechnologylab/project/gruppe_05_1/domain/html/HtmlSpeech.java +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/domain/html/HtmlSpeech.java @@ -19,6 +19,8 @@ public class HtmlSpeech { String agendaTitle; // aus "agendaItems" Collection List content = new ArrayList<>(); NlpInfo nlp = null; + String video = null; + String videoData; public HtmlSpeech() { } @@ -27,7 +29,7 @@ public class HtmlSpeech { setSpeechKey(doc.getString("speechKey")); setSpeakerName(doc.getString("speakerName")); setFraction(doc.getString("fraction")); - + setVideo(doc.getString("video")); List contentDocList = doc.get("speechContents", MongoDBHandler.DOC_LIST_CLASS); if (contentDocList == null) { setContent(new ArrayList<>()); @@ -51,6 +53,7 @@ public class HtmlSpeech { // Ergänzung um NLP-Informationen Document nlpDoc = (Document) doc.get("analysisResults"); nlp = readNlpInfo(nlpDoc); + } private NlpInfo readNlpInfo(Document nlpDoc) { @@ -157,4 +160,20 @@ public class HtmlSpeech { .add("nlp=" + nlp) .toString(); } + + public void setVideo(String video) { + this.video = video; + } + + public void setVideoData(String videoData) { + this.videoData = videoData; + } + + public String getVideo() { + return video; + } + + public String getVideoData() { + return videoData; + } } 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 5b80639..a8b30f0 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 @@ -64,6 +64,7 @@ public class RESTHandler { 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 + app.get("/reden", SpeechController::listAllSpeeches); // zeige alle Reden an (Filtern möglich) // Charts 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 c91a08e..f7252e3 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 @@ -1,7 +1,11 @@ package org.texttechnologylab.project.gruppe_05_1.rest; +import com.mongodb.client.gridfs.GridFSBucket; +import com.mongodb.client.gridfs.GridFSBuckets; import io.javalin.http.Context; import io.javalin.openapi.*; +import org.bson.types.ObjectId; +import org.texttechnologylab.project.gruppe_05_1.database.MongoDBHandler; import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils; import org.texttechnologylab.project.gruppe_05_1.domain.html.HtmlSpeech; import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails; @@ -14,6 +18,7 @@ import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData; import org.texttechnologylab.project.gruppe_05_1.util.Logger; import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Speech; +import java.io.ByteArrayOutputStream; import java.util.*; import java.util.stream.Collectors; @@ -79,6 +84,26 @@ public class SpeechController { } attributes.put("s", speech); + // Falls ein Video (GridFS-ID) vorhanden ist, abrufen und in Base64 konvertieren + if (speech.getVideo() != null && !speech.getVideo().trim().isEmpty()) { + MongoDBHandler mongoDBHandler = new MongoDBHandler(); + try { + GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDBHandler.getDatabase(), "videos"); + ObjectId fileId = new ObjectId(speech.getVideo()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + gridFSBucket.downloadToStream(fileId, baos); + byte[] videoBytes = baos.toByteArray(); + String base64Video = Base64.getEncoder().encodeToString(videoBytes); + // Speichere den Base64-String als neues Feld im Speech-Objekt oder als separates Attribut + speech.setVideoData(base64Video); + // Alternativ: attributes.put("videoData", base64Video); + } catch (Exception e) { + System.err.println("Error fetching video from GridFS: " + e.getMessage()); + } finally { + mongoDBHandler.close(); + } + } + // Foto des Abgeordnetes String picture = MongoPprUtils.getParlamentarierPictureByID(parlamentarierId); attributes.put("picture", picture); @@ -238,4 +263,5 @@ public class SpeechController { ctx.render("showAllSpeechesList.ftl", attributes); } + } diff --git a/src/main/java/org/texttechnologylab/project/gruppe_05_1/util/SpeechVideoUpdater.java b/src/main/java/org/texttechnologylab/project/gruppe_05_1/util/SpeechVideoUpdater.java new file mode 100644 index 0000000..80ce882 --- /dev/null +++ b/src/main/java/org/texttechnologylab/project/gruppe_05_1/util/SpeechVideoUpdater.java @@ -0,0 +1,122 @@ +package org.texttechnologylab.project.gruppe_05_1.util; + +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.gridfs.GridFSBucket; +import com.mongodb.client.gridfs.GridFSBuckets; +import com.mongodb.client.gridfs.model.GridFSUploadOptions; +import com.mongodb.client.model.UpdateOneModel; +import com.mongodb.client.model.WriteModel; +import org.apache.commons.logging.Log; +import org.bson.Document; +import org.bson.types.ObjectId; +import org.texttechnologylab.project.gruppe_05_1.database.MongoDBHandler; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +public class SpeechVideoUpdater { + + + private static final int BASE_VIDEO_ID = 7615435; + 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"; + + + public static void init() { + MongoDBHandler mongoDBHandler = new MongoDBHandler(); + try { + + Document filter = new Document("sessionId", 187) + .append("agendaItemId", 4) + .append("speechId", 0); + Document firstSpeech = mongoDBHandler.getSpeech(filter); + if (firstSpeech != null && firstSpeech.containsKey("video") + && firstSpeech.getString("video") != null + && !firstSpeech.getString("video").trim().isEmpty()) { + Logger.info("Videos sind bereits vorhanden. Kein Download notwendig."); + } else { + Logger.info("Keine Videos gefunden. Starte Download für die Reden der Session 187, AgendaItem 4..."); + findVideos(); + } + } catch (Exception e) { + System.err.println("Fehler beim Prüfen der Video-Felder: " + e.getMessage()); + e.printStackTrace(); + } finally { + mongoDBHandler.close(); + } + } + + public static void findVideos() throws Exception { + + MongoDBHandler mongoDBHandler = new MongoDBHandler(); + MongoDatabase db = mongoDBHandler.getDatabase(); + + + GridFSBucket gridFSBucket = GridFSBuckets.create(db, "videos"); + + List> bulkOperations = new ArrayList<>(); + + + for (int speechId = 0; speechId < 9; speechId++) { + int videoId = BASE_VIDEO_ID + speechId; + String videoUrl = BASE_URL + videoId + "/" + videoId + SUFFIX; + Logger.info("Downloading video for speech " + speechId + ": " + videoUrl); + + + File videoFile = downloadVideo(videoUrl, "video_" + videoId + ".mp4"); + + + ObjectId gridFsId = uploadVideoToGridFS(gridFSBucket, videoFile, "video_" + videoId + ".mp4"); + Logger.info("Uploaded video with GridFS ID: " + gridFsId); + + + Document filter = new Document("sessionId", 187) + .append("agendaItemId", 4) + .append("speechId", speechId); + + Document update = new Document("$set", new Document("video", gridFsId.toHexString())); + bulkOperations.add(new UpdateOneModel<>(filter, update)); + + + videoFile.delete(); + } + + if (!bulkOperations.isEmpty()) { + Logger.info("Uploading bulk update for " + bulkOperations.size() + " documents..."); + mongoDBHandler.bulkWriteNlpData(bulkOperations); + Logger.info("Bulk update completed."); + } + + mongoDBHandler.close(); + } + + private static File downloadVideo(String videoUrl, String fileName) throws IOException { + URL url = new URL(videoUrl); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + File tempFile = new File(fileName); + try (InputStream in = connection.getInputStream(); + FileOutputStream out = new FileOutputStream(tempFile)) { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + return tempFile; + } + + private static ObjectId uploadVideoToGridFS(GridFSBucket gridFSBucket, File videoFile, String fileName) throws IOException { + try (InputStream streamToUploadFrom = new FileInputStream(videoFile)) { + GridFSUploadOptions options = new GridFSUploadOptions() + .chunkSizeBytes(358400) + .metadata(new Document("type", "video").append("fileName", fileName)); + ObjectId fileId = gridFSBucket.uploadFromStream(fileName, streamToUploadFrom, options); + return fileId; + } + } +} diff --git a/src/main/resources/templates/speech.ftl b/src/main/resources/templates/speech.ftl index d4a6f31..c7910df 100644 --- a/src/main/resources/templates/speech.ftl +++ b/src/main/resources/templates/speech.ftl @@ -57,7 +57,6 @@ -
@@ -76,6 +75,18 @@ <#include "speechContent.ftl"> + <#-- Video einbinden, falls videoData vorhanden ist --> + <#if s.videoData?? && (s.videoData?trim != "")> +
+ +
+ <#else> +

Kein Video vorhanden.

+ +

<#if s.nlp??>

NLP Information