diff --git a/services/search/pkg/content/tika.go b/services/search/pkg/content/tika.go index 43cc0d7ee0..25e733ff65 100644 --- a/services/search/pkg/content/tika.go +++ b/services/search/pkg/content/tika.go @@ -90,10 +90,7 @@ func (t Tika) Extract(ctx context.Context, ri *provider.ResourceInfo) (Document, doc.Location = t.getLocation(meta) doc.Image = t.getImage(meta) doc.Photo = t.getPhoto(meta) - - if contentType, err := getFirstValue(meta, "Content-Type"); err == nil && strings.HasPrefix(contentType, "audio/") { - doc.Audio = t.getAudio(meta) - } + doc.Audio = t.getAudio(meta) } if langCode, _ := t.tika.LanguageString(ctx, doc.Content); langCode != "" && t.CleanStopWords { diff --git a/services/search/pkg/content/tika_audio.go b/services/search/pkg/content/tika_audio.go index 7a89e3e225..59e79404ab 100644 --- a/services/search/pkg/content/tika_audio.go +++ b/services/search/pkg/content/tika_audio.go @@ -30,9 +30,23 @@ func (t Tika) getAudio(meta map[string][]string) *libregraph.Audio { audio.SetArtist(v) } - // TODO: audio.Bitrate: not provided by tika - // TODO: audio.Composers: not provided by tika - // TODO: audio.Copyright: not provided by tika for audio files? + if v, err := getFirstValue(meta, "audio:bitrate"); err == nil { + // tika emits bits per second, graph wants kbps + if bps, err := strconv.ParseInt(v, 10, 64); err == nil { + initAudio() + audio.SetBitrate(bps / 1000) + } + } + + if v, err := getFirstValue(meta, "xmpDM:composer"); err == nil { + initAudio() + audio.SetComposers(v) + } + + if v, err := getFirstValue(meta, "xmpDM:copyright"); err == nil { + initAudio() + audio.SetCopyright(v) + } if v, err := getFirstValue(meta, "xmpDM:discNumber"); err == nil { if i, err := strconv.ParseInt(v, 10, 32); err == nil { @@ -42,7 +56,12 @@ func (t Tika) getAudio(meta map[string][]string) *libregraph.Audio { } - // TODO: audio.DiscCount: not provided by tika + if v, err := getFirstValue(meta, "audio:disc-count"); err == nil { + if i, err := strconv.ParseInt(v, 10, 32); err == nil { + initAudio() + audio.SetDiscCount(int32(i)) + } + } if v, err := getFirstValue(meta, "xmpDM:duration"); err == nil { // Tika emits fractional seconds. @@ -57,8 +76,19 @@ func (t Tika) getAudio(meta map[string][]string) *libregraph.Audio { audio.SetGenre(v) } - // TODO: audio.HasDrm: not provided by tika - // TODO: audio.IsVariableBitrate: not provided by tika + if v, err := getFirstValue(meta, "audio:has-drm"); err == nil { + if b, err := strconv.ParseBool(v); err == nil { + initAudio() + audio.SetHasDrm(b) + } + } + + if v, err := getFirstValue(meta, "audio:is-variable-bitrate"); err == nil { + if b, err := strconv.ParseBool(v); err == nil { + initAudio() + audio.SetIsVariableBitrate(b) + } + } if v, err := getFirstValue(meta, "dc:title"); err == nil { initAudio() @@ -72,7 +102,12 @@ func (t Tika) getAudio(meta map[string][]string) *libregraph.Audio { } } - // TODO: audio.TrackCount: not provided by tika + if v, err := getFirstValue(meta, "audio:track-count"); err == nil { + if i, err := strconv.ParseInt(v, 10, 32); err == nil { + initAudio() + audio.SetTrackCount(int32(i)) + } + } if v, err := getFirstValue(meta, "xmpDM:releaseDate"); err == nil { if i, err := strconv.ParseInt(v, 10, 32); err == nil { diff --git a/services/search/pkg/content/tika_audio_test.go b/services/search/pkg/content/tika_audio_test.go index 7c81f3b6c9..65576fcc46 100644 --- a/services/search/pkg/content/tika_audio_test.go +++ b/services/search/pkg/content/tika_audio_test.go @@ -9,15 +9,22 @@ import ( var _ = Describe("getAudio", func() { It("maps the audio metadata to the audio facet", func() { meta := map[string][]string{ - "xmpDM:genre": {"Some Genre"}, - "xmpDM:album": {"Some Album"}, - "xmpDM:trackNumber": {"7"}, - "xmpDM:discNumber": {"4"}, - "xmpDM:releaseDate": {"2004"}, - "xmpDM:artist": {"Some Artist"}, - "xmpDM:albumArtist": {"Some AlbumArtist"}, - "dc:title": {"Some Title"}, - "xmpDM:duration": {"225.5"}, + "xmpDM:genre": {"Some Genre"}, + "xmpDM:album": {"Some Album"}, + "xmpDM:trackNumber": {"7"}, + "xmpDM:discNumber": {"4"}, + "xmpDM:releaseDate": {"2004"}, + "xmpDM:artist": {"Some Artist"}, + "xmpDM:albumArtist": {"Some AlbumArtist"}, + "dc:title": {"Some Title"}, + "xmpDM:duration": {"225.5"}, + "xmpDM:composer": {"Some Composers"}, + "xmpDM:copyright": {"Some Copyright"}, + "audio:bitrate": {"192000"}, + "audio:is-variable-bitrate": {"true"}, + "audio:has-drm": {"false"}, + "audio:track-count": {"9"}, + "audio:disc-count": {"5"}, } audio := Tika{}.getAudio(meta) @@ -26,11 +33,18 @@ var _ = Describe("getAudio", func() { Expect(audio.Album).To(Equal(libregraph.PtrString("Some Album"))) Expect(audio.AlbumArtist).To(Equal(libregraph.PtrString("Some AlbumArtist"))) Expect(audio.Artist).To(Equal(libregraph.PtrString("Some Artist"))) + Expect(audio.Bitrate).To(Equal(libregraph.PtrInt64(192))) + Expect(audio.Composers).To(Equal(libregraph.PtrString("Some Composers"))) + Expect(audio.Copyright).To(Equal(libregraph.PtrString("Some Copyright"))) Expect(audio.Disc).To(Equal(libregraph.PtrInt32(4))) + Expect(audio.DiscCount).To(Equal(libregraph.PtrInt32(5))) Expect(audio.Duration).To(Equal(libregraph.PtrInt64(225500))) Expect(audio.Genre).To(Equal(libregraph.PtrString("Some Genre"))) + Expect(audio.HasDrm).To(Equal(libregraph.PtrBool(false))) + Expect(audio.IsVariableBitrate).To(Equal(libregraph.PtrBool(true))) Expect(audio.Title).To(Equal(libregraph.PtrString("Some Title"))) Expect(audio.Track).To(Equal(libregraph.PtrInt32(7))) + Expect(audio.TrackCount).To(Equal(libregraph.PtrInt32(9))) Expect(audio.Year).To(Equal(libregraph.PtrInt32(2004))) }) diff --git a/services/search/pkg/content/tika_location.go b/services/search/pkg/content/tika_location.go index 2334c53afe..d7b489daab 100644 --- a/services/search/pkg/content/tika_location.go +++ b/services/search/pkg/content/tika_location.go @@ -6,6 +6,9 @@ import ( libregraph "github.com/opencloud-eu/libre-graph-api-go" ) +// graph geoCoordinates.altitude is in feet, exif GPS altitude (geo:alt) in metres. +const metresToFeet = 3.280839895 + func (t Tika) getLocation(meta map[string][]string) *libregraph.GeoCoordinates { var location *libregraph.GeoCoordinates initLocation := func() { @@ -14,10 +17,6 @@ func (t Tika) getLocation(meta map[string][]string) *libregraph.GeoCoordinates { } } - // TODO: location.Altitute: transform the following data to … feet above sea level. - // "GPS:GPS Altitude": []string{"227.4 metres"}, - // "GPS:GPS Altitude Ref": []string{"Sea level"}, - if v, err := getFirstValue(meta, "geo:lat"); err == nil { if i, err := strconv.ParseFloat(v, 64); err == nil { initLocation() @@ -32,5 +31,13 @@ func (t Tika) getLocation(meta map[string][]string) *libregraph.GeoCoordinates { } } + // tika emits metres (negative below sea level), graph wants feet + if v, err := getFirstValue(meta, "geo:alt"); err == nil { + if metres, err := strconv.ParseFloat(v, 64); err == nil { + initLocation() + location.SetAltitude(metres * metresToFeet) + } + } + return location } diff --git a/services/search/pkg/content/tika_location_test.go b/services/search/pkg/content/tika_location_test.go index 38bb9ef705..067d06e4f8 100644 --- a/services/search/pkg/content/tika_location_test.go +++ b/services/search/pkg/content/tika_location_test.go @@ -7,14 +7,24 @@ import ( ) var _ = Describe("getLocation", func() { - It("maps latitude and longitude to the location facet", func() { + It("maps lat/long and converts altitude from metres to feet", func() { + metres := 227.4 location := Tika{}.getLocation(map[string][]string{ "geo:lat": {"49.48675890884328"}, "geo:long": {"11.103870357204285"}, + "geo:alt": {"227.4"}, }) Expect(location).ToNot(BeNil()) Expect(location.Latitude).To(Equal(libregraph.PtrFloat64(49.48675890884328))) Expect(location.Longitude).To(Equal(libregraph.PtrFloat64(11.103870357204285))) + Expect(location.Altitude).To(Equal(libregraph.PtrFloat64(metres * metresToFeet))) + }) + + It("keeps below-sea-level altitude negative", func() { + metres := -227.4 + location := Tika{}.getLocation(map[string][]string{"geo:alt": {"-227.4"}}) + Expect(location).ToNot(BeNil()) + Expect(location.Altitude).To(Equal(libregraph.PtrFloat64(metres * metresToFeet))) }) It("returns nil when no location metadata is present", func() {