From 1193222f92d8097d8f463f0ca298918064650449 Mon Sep 17 00:00:00 2001
From: Kjeldgaard <Kjeldgaard@users.noreply.github.com>
Date: Sun, 28 Mar 2021 23:52:51 +0200
Subject: [PATCH] Update external exif parser method

Exiftool meta data parsed as intergers and not strings. Keep internal
exif parsing functionality.

Signed-off-by: Kjeldgaard <Kjeldgaard@users.noreply.github.com>
---
 api/graphql/generated.go                  |  6 +-
 api/graphql/models/media_exif.go          |  2 +-
 api/graphql/schema.graphql                |  2 +-
 api/scanner/exif/exif_parser_external.go  | 72 ++++-------------------
 api/scanner/exif/exif_parser_internal.go  |  5 +-
 ui/src/components/sidebar/MediaSidebar.js | 51 +++++++++++++++-
 6 files changed, 71 insertions(+), 67 deletions(-)

diff --git a/api/graphql/generated.go b/api/graphql/generated.go
index 3f937ad..e452da2 100644
--- a/api/graphql/generated.go
+++ b/api/graphql/generated.go
@@ -1889,7 +1889,7 @@ type MediaEXIF {
   "The focal length of the lens, when the image was taken"
   focalLength: Float
   "A formatted description of the flash settings, when the image was taken"
-  flash: String
+  flash: Int
   "An index describing the mode for adjusting the exposure of the image"
   exposureProgram: Int
 }
@@ -4584,9 +4584,9 @@ func (ec *executionContext) _MediaEXIF_flash(ctx context.Context, field graphql.
 	if resTmp == nil {
 		return graphql.Null
 	}
-	res := resTmp.(*string)
+	res := resTmp.(*int64)
 	fc.Result = res
-	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+	return ec.marshalOInt2ᚖint64(ctx, field.Selections, res)
 }
 
 func (ec *executionContext) _MediaEXIF_exposureProgram(ctx context.Context, field graphql.CollectedField, obj *models.MediaEXIF) (ret graphql.Marshaler) {
diff --git a/api/graphql/models/media_exif.go b/api/graphql/models/media_exif.go
index 3b15fe5..6b75ab6 100644
--- a/api/graphql/models/media_exif.go
+++ b/api/graphql/models/media_exif.go
@@ -14,7 +14,7 @@ type MediaEXIF struct {
 	Aperture        *float64
 	Iso             *int64
 	FocalLength     *float64
-	Flash           *string
+	Flash           *int64
 	Orientation     *int64
 	ExposureProgram *int64
 	GPSLatitude     *float64
diff --git a/api/graphql/schema.graphql b/api/graphql/schema.graphql
index 15042ad..ff91f54 100644
--- a/api/graphql/schema.graphql
+++ b/api/graphql/schema.graphql
@@ -312,7 +312,7 @@ type MediaEXIF {
   "The focal length of the lens, when the image was taken"
   focalLength: Float
   "A formatted description of the flash settings, when the image was taken"
-  flash: String
+  flash: Int
   "An index describing the mode for adjusting the exposure of the image"
   exposureProgram: Int
 }
diff --git a/api/scanner/exif/exif_parser_external.go b/api/scanner/exif/exif_parser_external.go
index 3111171..5378cd8 100644
--- a/api/scanner/exif/exif_parser_external.go
+++ b/api/scanner/exif/exif_parser_external.go
@@ -14,10 +14,8 @@ type externalExifParser struct{}
 
 func (p *externalExifParser) ParseExif(media *models.Media) (returnExif *models.MediaEXIF, returnErr error) {
 	// Init ExifTool
-
-	et2 := exiftool.Charset("-n")
-
-	et, err := 																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																			.NewExiftool(et2)
+	extraInitArgs := []string{"-n"}
+	et, err := exiftool.NewExiftool(exiftool.AddInitArgs(extraInitArgs))
 	if err != nil {
 		log.Printf("Error initializing ExifTool: %s\n", err)
 		return nil, err
@@ -99,9 +97,9 @@ func (p *externalExifParser) ParseExif(media *models.Media) (returnExif *models.
 		}
 
 		// Get flash info
-		flash, err := fileInfo.GetString("Flash")
+		flash, err := fileInfo.GetInt("Flash")
 		if err == nil {
-			log.Printf("Flash: %s", flash)
+			log.Printf("Flash: %d", flash)
 			newExif.Flash = &flash
 		}
 
@@ -113,71 +111,27 @@ func (p *externalExifParser) ParseExif(media *models.Media) (returnExif *models.
 		}
 
 		// Get exposure program
-		expProgram, err := fileInfo.GetStrings("ExposureProgram")
+		expProgram, err := fileInfo.GetInt("ExposureProgram")
 		if err == nil {
-			for _, value := range expProgram {
-				log.Printf("%s", value)
-			}
-			//log.Printf("Exposure Program: %d", expProgram)
+			log.Printf("Exposure Program: %d", expProgram)
+			newExif.ExposureProgram = &expProgram
 		}
 
 		// GPS coordinates - longitude
-		longitudeRaw, err := fileInfo.GetString("GPSLongitude")
+		longitudeRaw, err := fileInfo.GetFloat("GPSLongitude")
 		if err == nil {
-			log.Printf("GPS longitude: %s", longitudeRaw)
-			value, err := ConvertCoodinateToFloat(longitudeRaw)
-			if err == nil {
-				newExif.GPSLongitude = &value
-			}
+			log.Printf("GPS longitude: %f", longitudeRaw)
+			newExif.GPSLongitude = &longitudeRaw
 		}
 
 		// GPS coordinates - latitude
-		latitudeRaw, err := fileInfo.GetString("GPSLatitude")
+		latitudeRaw, err := fileInfo.GetFloat("GPSLatitude")
 		if err == nil {
-			log.Printf("GPS latitude: %s", latitudeRaw)
-			value, err := ConvertCoodinateToFloat(latitudeRaw)
-			if err == nil {
-				newExif.GPSLatitude = &value
-			}
+			log.Printf("GPS latitude: %f", latitudeRaw)
+			newExif.GPSLatitude = &latitudeRaw
 		}
 	}
 
 	returnExif = &newExif
 	return
 }
-
-func ConvertCoodinateToFloat(coordinate string) (value float64, err error) {
-	reg, err := regexp.Compile("[0-9.]+")
-	if err != nil {
-		return 0, err
-	}
-
-	coordinateStr := reg.FindAllString(coordinate, -1)
-	log.Printf("GPS: %s length: %d\n", coordinateStr, len(coordinateStr))
-	if len(coordinateStr) != 3 {
-		return 0, err
-	}
-
-	deg, err := strconv.ParseFloat(coordinateStr[0], 64)
-	if err != nil {
-		return 0, err
-	}
-
-	minute, err := strconv.ParseFloat(coordinateStr[1], 64)
-	if err != nil {
-		return 0, err
-	}
-
-	second, err := strconv.ParseFloat(coordinateStr[2], 64)
-	if err != nil {
-		return 0, err
-	}
-
-	var multiplier float64 = 1
-	if deg < 0 {
-		multiplier = -1
-	}
-
-	value = (deg + minute / 60 + second / 3600) * multiplier
-	return value, nil
-}
diff --git a/api/scanner/exif/exif_parser_internal.go b/api/scanner/exif/exif_parser_internal.go
index 654ec5f..baacf57 100644
--- a/api/scanner/exif/exif_parser_internal.go
+++ b/api/scanner/exif/exif_parser_internal.go
@@ -106,9 +106,10 @@ func (p *internalExifParser) ParseExif(media *models.Media) (returnExif *models.
 		}
 	}
 
-	flash, err := exifTags.Flash()
+	flash, err := p.readIntegerTag(exifTags, exif.Flash, media)
 	if err == nil {
-		newExif.Flash = &flash
+		flash64 := int64(*flash)
+		newExif.Flash = &flash64
 	}
 
 	orientation, err := p.readIntegerTag(exifTags, exif.Orientation, media)
diff --git a/ui/src/components/sidebar/MediaSidebar.js b/ui/src/components/sidebar/MediaSidebar.js
index 321569b..7914391 100644
--- a/ui/src/components/sidebar/MediaSidebar.js
+++ b/ui/src/components/sidebar/MediaSidebar.js
@@ -148,6 +148,49 @@ const exposurePrograms = {
   9: 'Bulb',
 }
 
+// From https://exiftool.org/TagNames/EXIF.html#Flash
+const flash = {
+  0x0:	'No Flash',
+  0x1:	'Fired',
+  0x5:	'Fired, Return not detected',
+  0x7:	'Fired, Return detected',
+  0x8:	'On, Did not fire',
+  0x9:	'On, Fired',
+  0xd:	'On, Return not detected',
+  0xf:	'On, Return detected',
+  0x10:	'Off, Did not fire',
+  0x14:	'Off, Did not fire, Return not detected',
+  0x18:	'Auto, Did not fire',
+  0x19:	'Auto, Fired',
+  0x1d:	'Auto, Fired, Return not detected',
+  0x1f:	'Auto, Fired, Return detected',
+  0x20:	'No flash function',
+  0x30:	'Off, No flash function',
+  0x41:	'Fired, Red-eye reduction',
+  0x45:	'Fired, Red-eye reduction, Return not detected',
+  0x47:	'Fired, Red-eye reduction, Return detected',
+  0x49:	'On, Red-eye reduction',
+  0x4d:	'On, Red-eye reduction, Return not detected',
+  0x4f:	'On, Red-eye reduction, Return detected',
+  0x50:	'Off, Red-eye reduction',
+  0x58:	'Auto, Did not fire, Red-eye reduction',
+  0x59:	'Auto, Fired, Red-eye reduction',
+  0x5d:	'Auto, Fired, Red-eye reduction, Return not detected',
+  0x5f:	'Auto, Fired, Red-eye reduction, Return detected',
+}
+
+// From https://exiftool.org/TagNames/EXIF.html
+const orientation = {
+  1: 'Horizontal (normal)',
+  2: 'Mirror horizontal',
+  3: 'Rotate 180',
+  4: 'Mirror vertical',
+  5: 'Mirror horizontal and rotate 270 CW',
+  6: 'Rotate 90 CW',
+  7: 'Mirror horizontal and rotate 90 CW',
+  8: 'Rotate 270 CW',
+}
+
 const SidebarContent = ({ media, hidePreview }) => {
   let exifItems = []
 
@@ -165,7 +208,9 @@ const SidebarContent = ({ media, hidePreview }) => {
     )
 
     exif.dateShot = new Date(exif.dateShot).toLocaleString()
-    if (exif.exposureProgram) {
+
+    if (exposurePrograms.hasOwnProperty(exif.exposureProgram))
+    {
       exif.exposureProgram = exposurePrograms[exif.exposureProgram]
     }
 
@@ -177,6 +222,10 @@ const SidebarContent = ({ media, hidePreview }) => {
       exif.focalLength = `${exif.focalLength}mm`
     }
 
+    if (flash.hasOwnProperty(exif.flash)) {
+      exif.flash = flash[exif.flash]
+    }
+
     exifItems = exifKeys.map(key => (
       <SidebarItem key={key} name={exifNameLookup[key]} value={exif[key]} />
     ))
