From 76ade2404115bd65d99ead41aac01167aed52cc1 Mon Sep 17 00:00:00 2001
From: viktorstrate <viktorstrate@gmail.com>
Date: Fri, 15 May 2020 15:23:21 +0200
Subject: [PATCH] start on executable worker

---
 api/scanner/encode_photo.go      | 11 +++------
 api/scanner/executable_worker.go | 41 ++++++++++++++++++++++++++++++++
 api/scanner/process_photo.go     | 18 ++++++++++----
 3 files changed, 58 insertions(+), 12 deletions(-)
 create mode 100644 api/scanner/executable_worker.go

diff --git a/api/scanner/encode_photo.go b/api/scanner/encode_photo.go
index 2dd0b4f..d2588c2 100644
--- a/api/scanner/encode_photo.go
+++ b/api/scanner/encode_photo.go
@@ -21,18 +21,13 @@ type EncodeImageData struct {
 	_contentType    *ImageType
 }
 
-func (img *EncodeImageData) EncodeImageJPEG(tx *sql.Tx, path string, jpegQuality int) error {
-	photo_file, err := os.Create(path)
+func EncodeImageJPEG(image image.Image, outputPath string, jpegQuality int) error {
+	photo_file, err := os.Create(outputPath)
 	if err != nil {
-		return errors.Wrapf(err, "could not create file: %s", path)
+		return errors.Wrapf(err, "could not create file: %s", outputPath)
 	}
 	defer photo_file.Close()
 
-	image, err := img.PhotoImage(tx)
-	if err != nil {
-		return err
-	}
-
 	err = jpeg.Encode(photo_file, image, &jpeg.Options{Quality: jpegQuality})
 	if err != nil {
 		return err
diff --git a/api/scanner/executable_worker.go b/api/scanner/executable_worker.go
new file mode 100644
index 0000000..97f5c91
--- /dev/null
+++ b/api/scanner/executable_worker.go
@@ -0,0 +1,41 @@
+package scanner
+
+import "os/exec"
+
+import "log"
+
+import "fmt"
+
+import "github.com/pkg/errors"
+
+type ExecutableWorker struct {
+	Name    string
+	Path    string
+	argsFmt string
+}
+
+func newExecutableWorker(name string, argsFmt string) ExecutableWorker {
+	path, err := exec.LookPath(name)
+	if err != nil {
+		log.Printf("WARN: Darktable was not found, RAW conversion will be disabled")
+	}
+
+	return ExecutableWorker{
+		Name:    name,
+		Path:    path,
+		argsFmt: argsFmt,
+	}
+}
+
+func (execWorker *ExecutableWorker) EncodeJpeg(inputPath string, outputPath string, jpegQuality int) error {
+	args := fmt.Sprintf(execWorker.argsFmt, inputPath, outputPath, jpegQuality)
+	cmd := exec.Command(execWorker.Path, args)
+
+	if err := cmd.Run(); err != nil {
+		return errors.Wrapf(err, "error encoding image using '%s'", execWorker.Name)
+	}
+
+	return nil
+}
+
+var DarktableCli = newExecutableWorker("darktable-cli", "%s %s --core --conf plugins/imageio/format/jpeg/quality=%d")
diff --git a/api/scanner/process_photo.go b/api/scanner/process_photo.go
index 8cea3c0..da87e32 100644
--- a/api/scanner/process_photo.go
+++ b/api/scanner/process_photo.go
@@ -120,7 +120,7 @@ func ProcessPhoto(tx *sql.Tx, photo *models.Photo) error {
 			return err
 		}
 
-		err = imageData.EncodeImageJPEG(tx, path.Join(*photoCachePath, thumbnail_name), 70)
+		err = EncodeImageJPEG(thumbnailImage, path.Join(*photoCachePath, thumbnail_name), 70)
 		if err != nil {
 			return errors.Wrap(err, "could not create thumbnail cached image")
 		}
@@ -137,7 +137,12 @@ func ProcessPhoto(tx *sql.Tx, photo *models.Photo) error {
 		if _, err := os.Stat(thumbPath); os.IsNotExist(err) {
 			fmt.Printf("Thumbnail photo found in database but not in cache, re-encoding photo to cache: %s\n", thumbURL.PhotoName)
 
-			err = imageData.EncodeImageJPEG(tx, thumbPath, 70)
+			thumbnailImage, err := imageData.ThumbnailImage(tx)
+			if err != nil {
+				return err
+			}
+
+			err = EncodeImageJPEG(thumbnailImage, thumbPath, 70)
 			if err != nil {
 				log.Println("ERROR: creating thumbnail cached image")
 				return err
@@ -172,7 +177,7 @@ func ProcessPhoto(tx *sql.Tx, photo *models.Photo) error {
 				return err
 			}
 
-			err = imageData.EncodeImageJPEG(tx, path.Join(*photoCachePath, highres_name), 70)
+			err = EncodeImageJPEG(photoImage, path.Join(*photoCachePath, highres_name), 70)
 			if err != nil {
 				return errors.Wrap(err, "creating high-res cached image")
 			}
@@ -191,7 +196,12 @@ func ProcessPhoto(tx *sql.Tx, photo *models.Photo) error {
 		if _, err := os.Stat(highResPath); os.IsNotExist(err) {
 			fmt.Printf("High-res photo found in database but not in cache, re-encoding photo to cache: %s\n", highResURL.PhotoName)
 
-			err = imageData.EncodeImageJPEG(tx, highResPath, 70)
+			photoImage, err := imageData.PhotoImage(tx)
+			if err != nil {
+				return err
+			}
+
+			err = EncodeImageJPEG(photoImage, highResPath, 70)
 			if err != nil {
 				return errors.Wrap(err, "could create high-res cached image")
 			}
