From c665c212a0ed948ae24ba5e21bcbc1688825600f Mon Sep 17 00:00:00 2001
From: Eike Kettner <eike.kettner@posteo.de>
Date: Mon, 17 Feb 2020 14:02:23 +0100
Subject: [PATCH] Early draft for running wkhtmltopdf

---
 .../docspell/convert/extern/WkHtmlPdf.scala   | 50 +++++++++++++++++++
 .../convert/extern/WkHtmlPdfConfig.scala      |  7 +++
 2 files changed, 57 insertions(+)
 create mode 100644 modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdf.scala
 create mode 100644 modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdfConfig.scala

diff --git a/modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdf.scala b/modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdf.scala
new file mode 100644
index 00000000..60fa1fb9
--- /dev/null
+++ b/modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdf.scala
@@ -0,0 +1,50 @@
+package docspell.convert.extern
+
+import java.nio.file.Path
+
+import cats.effect._
+import fs2.{Pipe, Stream}
+import docspell.common._
+
+object WkHtmlPdf {
+
+  def toPDF[F[_]: Sync: ContextShift](
+      cfg: WkHtmlPdfConfig,
+      chunkSize: Int,
+      blocker: Blocker,
+      logger: Logger[F]
+  ): Pipe[F, Byte, Byte] =
+    in =>
+      Stream.resource(File.withTempDir[F](cfg.workingDir, "docspell-wkhtmltopdf")).flatMap { dir =>
+        val out = dir.resolve("out.pdf")
+        val sysCfg =
+          cfg.cmd.mapArgs(_.replace("{{outfile}}", out.toAbsolutePath.normalize.toString))
+
+        Stream.eval(logger.info(s"Running ${sysCfg.program}")).drain ++
+          SystemCommand
+            .execSuccess[F](sysCfg, blocker, Some(dir), in)
+            .flatMap(result => readResult[F](out, result, blocker, chunkSize, logger))
+      }
+
+  private def readResult[F[_]: Sync: ContextShift](
+      out: Path,
+      result: SystemCommand.Result,
+      blocker: Blocker,
+      chunkSize: Int,
+      logger: Logger[F]
+  ): Stream[F, Byte] =
+    Stream.eval(File.existsNonEmpty[F](out)).flatMap {
+      case true =>
+        if (result.rc == 0) File.readAll(out, blocker, chunkSize)
+        else
+          Stream
+            .eval(logger.warn(s"Command not successful (rc=${result.rc}), but file exists."))
+            .drain ++
+            File.readAll(out, blocker, chunkSize)
+
+      case false =>
+        Stream.raiseError(
+          new Exception(s"Command result=${result.rc}. No output file found. ${result.stderr}")
+        )
+    }
+}
diff --git a/modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdfConfig.scala b/modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdfConfig.scala
new file mode 100644
index 00000000..11d8aa1c
--- /dev/null
+++ b/modules/convert/src/main/scala/docspell/convert/extern/WkHtmlPdfConfig.scala
@@ -0,0 +1,7 @@
+package docspell.convert.extern
+
+import java.nio.file.Path
+
+import docspell.common.SystemCommand
+
+case class WkHtmlPdfConfig (cmd: SystemCommand.Config, workingDir: Path)