From 16200f547aa72183b6041aad3929bc4481aa303f Mon Sep 17 00:00:00 2001
From: tobias <tobias@thecodedev.de>
Date: Sun, 8 Sep 2019 21:37:03 +0200
Subject: [PATCH] Fixed #122 - Add csv playout log export

---
 PlayWallCore/pom.xml                          | 10 +++
 .../PlayWallPluginPlayoutLog/pom.xml          | 11 ++++
 .../PlayoutLogViewController.java             | 42 ++++++++++++
 .../resources/lang/playoutlog_de.properties   |  1 +
 .../view/dialog/PlayoutLogDialog.fxml         |  3 +
 .../playout/export/CsvPlayoutLogExport.scala  | 64 +++++++++++++++++++
 PlayWallPlugins/pom.xml                       |  2 +-
 pom.xml                                       |  1 +
 8 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/scala/de/tobias/playpad/plugin/playout/export/CsvPlayoutLogExport.scala

diff --git a/PlayWallCore/pom.xml b/PlayWallCore/pom.xml
index 7bb61491..df0279f9 100644
--- a/PlayWallCore/pom.xml
+++ b/PlayWallCore/pom.xml
@@ -117,6 +117,16 @@
             <artifactId>itextpdf</artifactId>
             <version>${itextpdf.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-csv</artifactId>
+            <version>${jackson-dataformat-csv.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-scala_2.13</artifactId>
+            <version>${jackson-dataformat-csv.version}</version>
+        </dependency>
 
         <!--Spark-->
         <dependency>
diff --git a/PlayWallPlugins/PlayWallPluginPlayoutLog/pom.xml b/PlayWallPlugins/PlayWallPluginPlayoutLog/pom.xml
index 881f0df2..b31db58f 100644
--- a/PlayWallPlugins/PlayWallPluginPlayoutLog/pom.xml
+++ b/PlayWallPlugins/PlayWallPluginPlayoutLog/pom.xml
@@ -30,6 +30,17 @@
             <artifactId>itextpdf</artifactId>
             <version>${itextpdf.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-csv</artifactId>
+            <version>${jackson-dataformat-csv.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-scala_2.13</artifactId>
+            <version>${jackson-dataformat-csv.version}</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/java/de/tobias/playpad/plugin/playout/viewcontroller/PlayoutLogViewController.java b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/java/de/tobias/playpad/plugin/playout/viewcontroller/PlayoutLogViewController.java
index 427edbe1..ab69f867 100644
--- a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/java/de/tobias/playpad/plugin/playout/viewcontroller/PlayoutLogViewController.java
+++ b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/java/de/tobias/playpad/plugin/playout/viewcontroller/PlayoutLogViewController.java
@@ -1,5 +1,9 @@
 package de.tobias.playpad.plugin.playout.viewcontroller;
 
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import com.fasterxml.jackson.module.scala.DefaultScalaModule;
 import com.itextpdf.text.DocumentException;
 import de.thecodelabs.logger.Logger;
 import de.thecodelabs.storage.proxy.SettingsProxy;
@@ -8,6 +12,7 @@ import de.thecodelabs.utils.ui.NVCStage;
 import de.thecodelabs.utils.util.Localization;
 import de.tobias.playpad.PlayPadPlugin;
 import de.tobias.playpad.plugin.playout.Strings;
+import de.tobias.playpad.plugin.playout.export.CsvPlayoutLogExport;
 import de.tobias.playpad.plugin.playout.export.PlayoutLogPdfExport;
 import de.tobias.playpad.plugin.playout.log.LogSeason;
 import de.tobias.playpad.plugin.playout.log.LogSeasons;
@@ -27,6 +32,8 @@ import javafx.stage.Window;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Optional;
 
 public class PlayoutLogViewController extends NVC {
@@ -126,6 +133,41 @@ public class PlayoutLogViewController extends NVC {
 		});
 	}
 
+	@FXML
+	private void exportMultipleCsvHandler(ActionEvent event) {
+		FileChooser fileChooser = new FileChooser();
+		FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("CSV", "*.csv");
+		fileChooser.getExtensionFilters().add(extensionFilter);
+
+		File file = fileChooser.showSaveDialog(getContainingWindow());
+		if (file == null) {
+			return;
+		}
+		Path path = file.toPath();
+
+		final LogSeason[] logSeasons = LogSeasons.getAllLogSeasonsLazy()
+				.parallelStream()
+				.map(logSeason -> LogSeasons.getLogSeason(logSeason.getId()))
+				.toArray(LogSeason[]::new);
+
+		final CsvPlayoutLogExport.CsvColumn[] export = CsvPlayoutLogExport.export(logSeasons);
+
+		// create mapper and schema
+		CsvMapper mapper = new CsvMapper();
+		mapper.registerModule(new DefaultScalaModule());
+
+		CsvSchema schema = mapper.schemaFor(CsvPlayoutLogExport.CsvColumn.class);
+		schema = schema.withColumnSeparator(';').withHeader();
+
+		// output writer
+		ObjectWriter objectWriter = mapper.writer(schema);
+		try {
+			objectWriter.writeValue(Files.newBufferedWriter(path), export);
+		} catch (IOException e) {
+			Logger.error(e);
+		}
+	}
+
 	@FXML
 	private void deleteButtonHandler(ActionEvent event) {
 		getSelectedLogSeason().ifPresent(season -> { // Lazy Season
diff --git a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/lang/playoutlog_de.properties b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/lang/playoutlog_de.properties
index 8ec96c7c..edec851f 100644
--- a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/lang/playoutlog_de.properties
+++ b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/lang/playoutlog_de.properties
@@ -6,4 +6,5 @@ PlayoutLogDialog.Checkbox.AutoStart=Automatisch starten bei Programmstart
 PlayoutLogDialog.Button.Start=Starten
 PlayoutLogDialog.Button.Stop=Stoppen
 PlayoutLogDialog.Button.Export=Exportieren...
+PlayoutLogDialog.Button.ExportAll=Alle Exportieren...
 PlayoutLogDialog.Button.Delete=L\u00F6schen...
\ No newline at end of file
diff --git a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/view/dialog/PlayoutLogDialog.fxml b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/view/dialog/PlayoutLogDialog.fxml
index 5a6e94f2..f1d29cdf 100644
--- a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/view/dialog/PlayoutLogDialog.fxml
+++ b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/resources/view/dialog/PlayoutLogDialog.fxml
@@ -25,6 +25,9 @@
                         <Button fx:id="exportButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
                                 onAction="#exportButtonHandler" prefWidth="100.0" text="%PlayoutLogDialog.Button.Export"
                                 VBox.vgrow="ALWAYS"/>
+                        <Button fx:id="exportAllButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
+                                onAction="#exportMultipleCsvHandler" prefWidth="100.0" text="%PlayoutLogDialog.Button.ExportAll"
+                                VBox.vgrow="ALWAYS"/>
                         <Button fx:id="deleteButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false"
                                 onAction="#deleteButtonHandler" prefWidth="100.0" text="%PlayoutLogDialog.Button.Delete"
                                 VBox.vgrow="ALWAYS"/>
diff --git a/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/scala/de/tobias/playpad/plugin/playout/export/CsvPlayoutLogExport.scala b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/scala/de/tobias/playpad/plugin/playout/export/CsvPlayoutLogExport.scala
new file mode 100644
index 00000000..b8f322ab
--- /dev/null
+++ b/PlayWallPlugins/PlayWallPluginPlayoutLog/src/main/scala/de/tobias/playpad/plugin/playout/export/CsvPlayoutLogExport.scala
@@ -0,0 +1,64 @@
+package de.tobias.playpad.plugin.playout.export
+
+import java.util.UUID
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder
+import de.tobias.playpad.plugin.playout.log.LogSeason
+
+import scala.jdk.CollectionConverters._
+
+object CsvPlayoutLogExport {
+
+	@JsonPropertyOrder(value = Array("name", "count", "seasonCount", "firstTime", "lastTime"))
+	class CsvColumn
+	(
+		var id: UUID,
+		var name: String,
+		var count: Int,
+		var seasonCount: Int,
+		var firstTime: Long,
+		var lastTime: Long
+	) {
+	}
+
+	def export(sessions: Array[LogSeason]): Array[CsvColumn] = {
+		val items = sessions
+			.map(_.getLogItems.asScala)
+			.flatten
+			.distinctBy(_.getUuid)
+			.map(entry => new CsvColumn(entry.getUuid, entry.getName, 0, 0, 0, 0))
+
+		sessions
+			.map(_.getLogItems.asScala)
+			.flatten
+			.foreach(item => {
+				val entry = items.filter(i => i.id == item.getUuid).head
+				entry.count = entry.count + item.getPlayOutItems.size()
+			})
+
+		sessions
+			.map(_.getLogItems.asScala.distinctBy(_.getUuid))
+			.flatten
+			.foreach(item => {
+				val entry = items.filter(i => i.id == item.getUuid).head
+				entry.seasonCount = entry.seasonCount + 1
+			})
+
+		val timeMapping = sessions
+			.map(_.getLogItems.asScala)
+			.flatten
+			.map(i => i.getPlayOutItems.asScala)
+			.flatten
+			.map(i => i.getPathUuid -> i.getTime)
+
+		items.foreach(item => {
+			val min: Long = timeMapping.filter(i => i._1 == item.id).minByOption(_._2).map(_._2).getOrElse(0)
+			val max: Long = timeMapping.filter(i => i._1 == item.id).maxByOption(_._2).map(_._2).getOrElse(0)
+
+			item.firstTime = min
+			item.lastTime = max
+		})
+
+		items
+	}
+}
diff --git a/PlayWallPlugins/pom.xml b/PlayWallPlugins/pom.xml
index 5ecdd6e1..ed31c86f 100644
--- a/PlayWallPlugins/pom.xml
+++ b/PlayWallPlugins/pom.xml
@@ -3,8 +3,8 @@
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <artifactId>PlayWallDesktop</artifactId>
         <groupId>de.tobias.playpad</groupId>
+        <artifactId>PlayWallDesktop</artifactId>
         <version>6.2.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index 7f547e3a..a2dd6861 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,7 @@
         <jlayer.version>1.0.1</jlayer.version>
 
         <itextpdf.version>5.5.13</itextpdf.version>
+        <jackson-dataformat-csv.version>2.9.9</jackson-dataformat-csv.version>
 
         <spark-core.version>[2.9.0,)</spark-core.version>
 
-- 
GitLab