-
Notifications
You must be signed in to change notification settings - Fork 121
/
FileMetadata.scala
73 lines (64 loc) · 2.86 KB
/
FileMetadata.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.gu.mediaservice.model
import com.gu.mediaservice.lib.logging.{LogMarker, MarkerMap}
import net.logstash.logback.marker.Markers
import play.api.libs.json._
import play.api.libs.functional.syntax._
import scala.collection.JavaConverters._
case class FileMetadata(
iptc: Map[String, String] = Map(),
exif: Map[String, String] = Map(),
exifSub: Map[String, String] = Map(),
xmp: Map[String, JsValue] = Map(),
icc: Map[String, String] = Map(),
getty: Map[String, String] = Map(),
colourModel: Option[String] = None,
colourModelInformation: Map[String, String] = Map()
) {
def toLogMarker: LogMarker = {
val fieldCountMarkers = Map (
"iptcFieldCount" -> iptc.size,
"exifFieldCount" -> exif.size,
"exifSubFieldCount" -> exifSub.size,
"xmpFieldCount" -> xmp.size,
"iccFieldCount" -> icc.size,
"gettyFieldCount" -> getty.size,
"colourModelInformationFieldCount" -> colourModelInformation.size
)
val totalFieldCount = fieldCountMarkers.foldLeft(0)(_ + _._2)
val markers = fieldCountMarkers + ("totalFieldCount" -> totalFieldCount)
MarkerMap(markers)
}
}
object FileMetadata {
// TODO: reindex all images to make the getty map always present
// for data consistency, so we can fallback to use the default Reads
implicit val ImageMetadataReads: Reads[FileMetadata] = (
(__ \ "iptc").read[Map[String,String]] ~
(__ \ "exif").read[Map[String,String]] ~
(__ \ "exifSub").read[Map[String,String]] ~
(__ \ "xmp").read[Map[String,JsValue]] ~
(__ \ "icc").readNullable[Map[String,String]].map(_ getOrElse Map()).map(removeLongValues) ~
(__ \ "getty").readNullable[Map[String,String]].map(_ getOrElse Map()) ~
(__ \ "colourModel").readNullable[String] ~
(__ \ "colourModelInformation").readNullable[Map[String,String]].map(_ getOrElse Map())
)(FileMetadata.apply _)
private val maximumValueLengthBytes = 5000
private def removeLongValues = { m:Map[String, String] => {
val (short, long) = m.partition(_._2.length <= maximumValueLengthBytes)
if (long.size>0) {
short + ("removedFields" -> long.map(_._1).mkString(", "))
} else {
m
}
} }
implicit val FileMetadataWrites: Writes[FileMetadata] = (
(JsPath \ "iptc").write[Map[String,String]] and
(JsPath \ "exif").write[Map[String,String]] and
(JsPath \ "exifSub").write[Map[String,String]] and
(JsPath \ "xmp").write[Map[String,JsValue]] and
(JsPath \ "icc").write[Map[String,String]].contramap[Map[String, String]](removeLongValues) and
(JsPath \ "getty").write[Map[String,String]] and
(JsPath \ "colourModel").writeNullable[String] and
(JsPath \ "colourModelInformation").write[Map[String,String]]
)(unlift(FileMetadata.unapply))
}