From 2636255c952267314d4caa268fad104651baa8e0 Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Thu, 16 Dec 2021 11:42:57 +0100 Subject: [PATCH] Search: Add uid:... search filter #1820 --- internal/api/event.go | 8 ++++---- internal/api/face.go | 2 +- internal/api/search_albums.go | 2 +- internal/form/search_albums.go | 2 +- internal/form/search_faces.go | 2 +- internal/form/search_labels.go | 2 +- internal/form/search_photos.go | 2 +- internal/form/search_subjects.go | 2 +- internal/form/serialize.go | 4 +++- internal/search/albums.go | 4 ++-- internal/search/albums_test.go | 2 +- internal/search/faces.go | 4 ++-- internal/search/faces_test.go | 2 +- internal/search/labels.go | 4 ++-- internal/search/labels_test.go | 2 +- internal/search/photos.go | 31 +++++++++++++++++-------------- internal/search/photos_test.go | 4 ++-- internal/search/subjects.go | 4 ++-- internal/search/subjects_test.go | 2 +- 19 files changed, 45 insertions(+), 40 deletions(-) diff --git a/internal/api/event.go b/internal/api/event.go index d00491747..41d7533b0 100644 --- a/internal/api/event.go +++ b/internal/api/event.go @@ -17,7 +17,7 @@ const ( ) func PublishPhotoEvent(e EntityEvent, uid string, c *gin.Context) { - f := form.SearchPhotos{ID: uid, Merged: true} + f := form.SearchPhotos{UID: uid, Merged: true} result, _, err := search.Photos(f) if err != nil { @@ -30,7 +30,7 @@ func PublishPhotoEvent(e EntityEvent, uid string, c *gin.Context) { } func PublishAlbumEvent(e EntityEvent, uid string, c *gin.Context) { - f := form.SearchAlbums{ID: uid} + f := form.SearchAlbums{UID: uid} result, err := search.Albums(f) if err != nil { @@ -43,7 +43,7 @@ func PublishAlbumEvent(e EntityEvent, uid string, c *gin.Context) { } func PublishLabelEvent(e EntityEvent, uid string, c *gin.Context) { - f := form.SearchLabels{ID: uid} + f := form.SearchLabels{UID: uid} result, err := search.Labels(f) if err != nil { @@ -56,7 +56,7 @@ func PublishLabelEvent(e EntityEvent, uid string, c *gin.Context) { } func PublishSubjectEvent(e EntityEvent, uid string, c *gin.Context) { - f := form.SearchSubjects{ID: uid} + f := form.SearchSubjects{UID: uid} result, err := search.Subjects(f) if err != nil { diff --git a/internal/api/face.go b/internal/api/face.go index 01951f5af..60d028979 100644 --- a/internal/api/face.go +++ b/internal/api/face.go @@ -28,7 +28,7 @@ func GetFace(router *gin.RouterGroup) { return } - f := form.SearchFaces{ID: c.Param("id"), Markers: true} + f := form.SearchFaces{UID: c.Param("id"), Markers: true} if results, err := search.Faces(f); err != nil || len(results) < 1 { Abort(c, http.StatusNotFound, i18n.ErrFaceNotFound) diff --git a/internal/api/search_albums.go b/internal/api/search_albums.go index 0ee46c1a4..427cb7501 100644 --- a/internal/api/search_albums.go +++ b/internal/api/search_albums.go @@ -35,7 +35,7 @@ func SearchAlbums(router *gin.RouterGroup) { // Guest permissions are limited to shared albums. if s.Guest() { - f.ID = s.Shares.Join(txt.Or) + f.UID = s.Shares.Join(txt.Or) } result, err := search.Albums(f) diff --git a/internal/form/search_albums.go b/internal/form/search_albums.go index b9abac0ee..953ce731a 100644 --- a/internal/form/search_albums.go +++ b/internal/form/search_albums.go @@ -3,7 +3,7 @@ package form // SearchAlbums represents search form fields for "/api/v1/albums". type SearchAlbums struct { Query string `form:"q"` - ID string `form:"id"` + UID string `form:"uid"` Type string `form:"type"` Location string `form:"location"` Category string `form:"category"` diff --git a/internal/form/search_faces.go b/internal/form/search_faces.go index f16337023..5847175fc 100644 --- a/internal/form/search_faces.go +++ b/internal/form/search_faces.go @@ -3,7 +3,7 @@ package form // SearchFaces represents search form fields for "/api/v1/faces". type SearchFaces struct { Query string `form:"q"` - ID string `form:"id"` + UID string `form:"uid"` Subject string `form:"subject"` Unknown string `form:"unknown"` Hidden string `form:"hidden"` diff --git a/internal/form/search_labels.go b/internal/form/search_labels.go index 2e1cf8203..ab150c1cb 100644 --- a/internal/form/search_labels.go +++ b/internal/form/search_labels.go @@ -3,7 +3,7 @@ package form // SearchLabels represents search form fields for "/api/v1/labels". type SearchLabels struct { Query string `form:"q"` - ID string `form:"id"` + UID string `form:"uid"` Slug string `form:"slug"` Name string `form:"name"` All bool `form:"all"` diff --git a/internal/form/search_photos.go b/internal/form/search_photos.go index 8a7524e75..7061fd4f7 100644 --- a/internal/form/search_photos.go +++ b/internal/form/search_photos.go @@ -8,7 +8,7 @@ import ( type SearchPhotos struct { Query string `form:"q"` Filter string `form:"filter"` - ID string `form:"id"` + UID string `form:"uid"` Type string `form:"type"` Path string `form:"path"` Folder string `form:"folder"` // Alias for Path diff --git a/internal/form/search_subjects.go b/internal/form/search_subjects.go index b9de97188..5710b2792 100644 --- a/internal/form/search_subjects.go +++ b/internal/form/search_subjects.go @@ -3,7 +3,7 @@ package form // SearchSubjects represents search form fields for "/api/v1/subjects". type SearchSubjects struct { Query string `form:"q"` - ID string `form:"id"` + UID string `form:"uid"` Type string `form:"type"` Name string `form:"name"` All bool `form:"all"` diff --git a/internal/form/serialize.go b/internal/form/serialize.go index e46be7ece..3c3c4f408 100644 --- a/internal/form/serialize.go +++ b/internal/form/serialize.go @@ -94,7 +94,9 @@ func Unserialize(f SearchForm, q string) (result error) { if unicode.IsSpace(char) && !escaped { if isKeyValue { fieldName := strings.Title(string(key)) - field := formValues.FieldByName(fieldName) + field := formValues.FieldByNameFunc(func(name string) bool { + return strings.EqualFold(name, fieldName) + }) stringValue := string(value) if field.CanSet() { diff --git a/internal/search/albums.go b/internal/search/albums.go index a169021c2..b33c9ad10 100644 --- a/internal/search/albums.go +++ b/internal/search/albums.go @@ -91,8 +91,8 @@ func Albums(f form.SearchAlbums) (results AlbumResults, err error) { s = s.Order("albums.album_favorite DESC, albums.album_title ASC, albums.album_uid DESC") } - if f.ID != "" { - s = s.Where("albums.album_uid IN (?)", strings.Split(f.ID, txt.Or)) + if f.UID != "" { + s = s.Where("albums.album_uid IN (?)", strings.Split(strings.ToLower(f.UID), txt.Or)) if result := s.Scan(&results); result.Error != nil { return results, result.Error diff --git a/internal/search/albums_test.go b/internal/search/albums_test.go index d5547bdde..378ceb4ba 100644 --- a/internal/search/albums_test.go +++ b/internal/search/albums_test.go @@ -96,7 +96,7 @@ func TestAlbums(t *testing.T) { t.Run("search for existing ID", func(t *testing.T) { f := form.SearchAlbums{ Query: "", - ID: "at9lxuqxpogaaba7", + UID: "at9lxuqxpogaaba7", Slug: "", Title: "", Favorite: false, diff --git a/internal/search/faces.go b/internal/search/faces.go index cea18bddf..08d12f057 100644 --- a/internal/search/faces.go +++ b/internal/search/faces.go @@ -72,8 +72,8 @@ func Faces(f form.SearchFaces) (results FaceResults, err error) { } // Find specific IDs? - if f.ID != "" { - s = s.Where(fmt.Sprintf("%s.id IN (?)", facesTable), strings.Split(strings.ToUpper(f.ID), txt.Or)) + if f.UID != "" { + s = s.Where(fmt.Sprintf("%s.id IN (?)", facesTable), strings.Split(strings.ToUpper(f.UID), txt.Or)) if result := s.Scan(&results); result.Error != nil { return results, result.Error diff --git a/internal/search/faces_test.go b/internal/search/faces_test.go index c7653ff5f..25e798bc0 100644 --- a/internal/search/faces_test.go +++ b/internal/search/faces_test.go @@ -26,7 +26,7 @@ func TestFaces(t *testing.T) { assert.LessOrEqual(t, 1, len(results)) }) t.Run("Find specific id", func(t *testing.T) { - results, err := Faces(form.SearchFaces{ID: "PN6QO5INYTUSAATOFL43LL2ABAV5ACZK", Markers: true}) + results, err := Faces(form.SearchFaces{UID: "PN6QO5INYTUSAATOFL43LL2ABAV5ACZK", Markers: true}) assert.NoError(t, err) t.Logf("Faces: %#v", results) assert.LessOrEqual(t, 1, len(results)) diff --git a/internal/search/labels.go b/internal/search/labels.go index 78b8bf1e4..a5a5658dd 100644 --- a/internal/search/labels.go +++ b/internal/search/labels.go @@ -41,8 +41,8 @@ func Labels(f form.SearchLabels) (results []Label, err error) { s = s.Order("labels.label_favorite DESC, custom_slug ASC") } - if f.ID != "" { - s = s.Where("labels.label_uid IN (?)", strings.Split(f.ID, txt.Or)) + if f.UID != "" { + s = s.Where("labels.label_uid IN (?)", strings.Split(strings.ToLower(f.UID), txt.Or)) if result := s.Scan(&results); result.Error != nil { return results, result.Error diff --git a/internal/search/labels_test.go b/internal/search/labels_test.go index 2a9c3991f..cb050c2ab 100644 --- a/internal/search/labels_test.go +++ b/internal/search/labels_test.go @@ -111,7 +111,7 @@ func TestLabels(t *testing.T) { t.Run("search for ID", func(t *testing.T) { f := form.SearchLabels{ Query: "", - ID: "lt9k3pw1wowuy3c4", + UID: "lt9k3pw1wowuy3c4", Slug: "", Name: "", All: false, diff --git a/internal/search/photos.go b/internal/search/photos.go index 6d1254fbd..47aab9b1d 100644 --- a/internal/search/photos.go +++ b/internal/search/photos.go @@ -93,22 +93,25 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) { s = s.Where("files.file_primary = 1") } - // Shortcut for known photo ids. - if f.ID != "" { - s = s.Where("photos.photo_uid IN (?)", strings.Split(f.ID, txt.Or)) - s = s.Order("files.file_primary DESC") + if f.UID != "" { + s = s.Where("photos.photo_uid IN (?)", strings.Split(strings.ToLower(f.UID), txt.Or)) - if result := s.Scan(&results); result.Error != nil { - return results, 0, result.Error + // Take shortcut? + if f.Album == "" && f.Albums == "" && f.Label == "" && f.Query == "" { + s = s.Order("files.file_primary DESC") + + if result := s.Scan(&results); result.Error != nil { + return results, 0, result.Error + } + + log.Infof("photos: found %s for %s [%s]", english.Plural(len(results), "result", "results"), f.SerializeAll(), time.Since(start)) + + if f.Merged { + return results.Merged() + } + + return results, len(results), nil } - - log.Infof("photos: found %s for %s [%s]", english.Plural(len(results), "result", "results"), f.SerializeAll(), time.Since(start)) - - if f.Merged { - return results.Merged() - } - - return results, len(results), nil } // Filter by label, label category and keywords. diff --git a/internal/search/photos_test.go b/internal/search/photos_test.go index cb3bc6d70..1c80f14eb 100644 --- a/internal/search/photos_test.go +++ b/internal/search/photos_test.go @@ -68,7 +68,7 @@ func TestPhotos(t *testing.T) { frm.Query = "" frm.Count = 5000 frm.Offset = 0 - frm.ID = "pt9jtdre2lvl0yh7" + frm.UID = "pt9jtdre2lvl0yh7" frm.Merged = true photos, _, err := Photos(frm) @@ -84,7 +84,7 @@ func TestPhotos(t *testing.T) { frm.Query = "" frm.Count = 5000 frm.Offset = 0 - frm.ID = "pt9jtdre2lvl0yh7" + frm.UID = "pt9jtdre2lvl0yh7" frm.Merged = false photos, _, err := Photos(frm) diff --git a/internal/search/subjects.go b/internal/search/subjects.go index be2d9badc..2decb9d07 100644 --- a/internal/search/subjects.go +++ b/internal/search/subjects.go @@ -46,8 +46,8 @@ func Subjects(f form.SearchSubjects) (results SubjectResults, err error) { s = s.Order("subj_favorite DESC, subj_name") } - if f.ID != "" { - s = s.Where(fmt.Sprintf("%s.subj_uid IN (?)", subjTable), strings.Split(f.ID, txt.Or)) + if f.UID != "" { + s = s.Where(fmt.Sprintf("%s.subj_uid IN (?)", subjTable), strings.Split(strings.ToLower(f.UID), txt.Or)) if result := s.Scan(&results); result.Error != nil { return results, result.Error diff --git a/internal/search/subjects_test.go b/internal/search/subjects_test.go index 63e46f4bc..eacf93344 100644 --- a/internal/search/subjects_test.go +++ b/internal/search/subjects_test.go @@ -77,7 +77,7 @@ func TestSubjects(t *testing.T) { assert.LessOrEqual(t, 1, len(results)) }) t.Run("search for ID", func(t *testing.T) { - results, err := Subjects(form.SearchSubjects{Type: entity.SubjPerson, ID: "jqy3y652h8njw0sx"}) + results, err := Subjects(form.SearchSubjects{Type: entity.SubjPerson, UID: "jqy3y652h8njw0sx"}) assert.NoError(t, err) //t.Logf("Subjects: %#v", results) assert.Equal(t, "Joe Biden", results[0].SubjName)