From ccd92a47151e46189eab5c27a0554877328ba459 Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Wed, 25 Mar 2020 14:14:00 +0100 Subject: [PATCH] Update index after editing photo metadata Signed-off-by: Michael Mayer --- frontend/src/model/photo.js | 4 ++++ internal/classify/rules.go | 8 +++---- internal/classify/rules.yml | 4 +++- internal/entity/location.go | 14 ++++++------- internal/entity/photo.go | 6 +++++- internal/form/photo.go | 1 + internal/photoprism/index_mediafile.go | 29 ++++++++++++++------------ 7 files changed, 40 insertions(+), 26 deletions(-) diff --git a/frontend/src/model/photo.js b/frontend/src/model/photo.js index 65a543456..cc53d3537 100644 --- a/frontend/src/model/photo.js +++ b/frontend/src/model/photo.js @@ -228,6 +228,10 @@ class Photo extends Abstract { values.ModifiedTitle = true } + if(values.PhotoKeywords) { + values.ModifiedKeywords = true + } + if(values.PhotoLat || values.PhotoLng || values.PhotoAltitude) { values.ModifiedLocation = true } diff --git a/internal/classify/rules.go b/internal/classify/rules.go index c6bcfd48e..55ea82b3d 100644 --- a/internal/classify/rules.go +++ b/internal/classify/rules.go @@ -5457,16 +5457,16 @@ var rules = LabelRules{ Categories: []string{}, }, "sunglass": { - Label: "sunshine", + Label: "sunglasses", Threshold: 0.200000, Priority: 2, - Categories: []string{}, + Categories: []string{"portrait"}, }, "sunglasses": { - Label: "sunshine", + Label: "sunglasses", Threshold: 0.200000, Priority: 2, - Categories: []string{}, + Categories: []string{"portrait"}, }, "sunscreen": { Label: "bottle", diff --git a/internal/classify/rules.yml b/internal/classify/rules.yml index 88d1b7b95..85f5be3d6 100644 --- a/internal/classify/rules.yml +++ b/internal/classify/rules.yml @@ -3458,9 +3458,11 @@ ear: see: ignore sunglasses: - label: sunshine + label: sunglasses priority: 2 threshold: 0.2 + categories: + - portrait sunglass: see: sunglasses diff --git a/internal/entity/location.go b/internal/entity/location.go index c684f187c..95fddc3b7 100644 --- a/internal/entity/location.go +++ b/internal/entity/location.go @@ -86,18 +86,18 @@ func (m *Location) Find(db *gorm.DB, api string) error { } // Keywords computes keyword based on a Location -func (m *Location) Keywords() []string { - result := []string{ - strings.ToLower(m.City()), - strings.ToLower(m.State()), - strings.ToLower(m.CountryName()), - strings.ToLower(m.Category()), - } +func (m *Location) Keywords() (result []string) { + result = append(result, txt.Keywords(m.City())...) + result = append(result, txt.Keywords(m.State())...) + result = append(result, txt.Keywords(m.CountryName())...) + result = append(result, txt.Keywords(m.Category())...) result = append(result, txt.Keywords(m.Name())...) result = append(result, txt.Keywords(m.Label())...) result = append(result, txt.Keywords(m.Notes())...) + result = txt.UniqueWords(result) + return result } diff --git a/internal/entity/photo.go b/internal/entity/photo.go index 6d8038244..7cec447ed 100644 --- a/internal/entity/photo.go +++ b/internal/entity/photo.go @@ -51,6 +51,7 @@ type Photo struct { ModifiedTitle bool `json:"ModifiedTitle"` ModifiedDetails bool `json:"ModifiedDetails"` ModifiedLocation bool `json:"ModifiedLocation"` + ModifiedKeywords bool `json:"ModifiedKeywords"` ModifiedDate bool `json:"ModifiedDate"` Camera *Camera `json:"Camera"` Lens *Lens `json:"Lens"` @@ -72,6 +73,8 @@ func SavePhoto(model Photo, form form.Photo, db *gorm.DB) error { return err } + model.IndexKeywords(db) + return db.Save(&model).Error } @@ -114,8 +117,9 @@ func (m *Photo) BeforeSave(scope *gorm.Scope) error { } // IndexKeywords adds given keywords to the photo entry -func (m *Photo) IndexKeywords(keywords []string, db *gorm.DB) { +func (m *Photo) IndexKeywords(db *gorm.DB) { var keywordIds []uint + var keywords []string // Add title, description and other keywords keywords = append(keywords, txt.Keywords(m.PhotoTitle)...) diff --git a/internal/form/photo.go b/internal/form/photo.go index ec1567e10..fdebb0058 100644 --- a/internal/form/photo.go +++ b/internal/form/photo.go @@ -34,6 +34,7 @@ type Photo struct { TimeZone string `json:"TimeZone"` TakenAtLocal time.Time `json:"TakenAtLocal"` ModifiedTitle bool `json:"ModifiedTitle"` + ModifiedKeywords bool `json:"ModifiedKeywords"` ModifiedDetails bool `json:"ModifiedDetails"` ModifiedLocation bool `json:"ModifiedLocation"` ModifiedDate bool `json:"ModifiedDate"` diff --git a/internal/photoprism/index_mediafile.go b/internal/photoprism/index_mediafile.go index b9e76088b..4a95e66ea 100644 --- a/internal/photoprism/index_mediafile.go +++ b/internal/photoprism/index_mediafile.go @@ -36,7 +36,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I var file, primaryFile entity.File var metaData meta.Data var photoQuery, fileQuery *gorm.DB - var keywords []string + var locKeywords []string labels := classify.Labels{} fileBase := m.Base() @@ -179,12 +179,12 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I } if fileChanged || o.UpdateKeywords || o.UpdateLocation || o.UpdateTitle { - locKeywords, locLabels := ind.indexLocation(m, &photo, labels, fileChanged, o) - keywords = append(keywords, locKeywords...) + var locLabels classify.Labels + locKeywords, locLabels = ind.indexLocation(m, &photo, labels, fileChanged, o) labels = append(labels, locLabels...) } - if photo.NoTitle() || (fileChanged || o.UpdateTitle) && photo.ModifiedTitle == false && photo.NoLocation() { + if photo.NoTitle() || (fileChanged || o.UpdateTitle) && !photo.ModifiedTitle && photo.NoLocation() { if len(labels) > 0 && labels[0].Priority >= -1 && labels[0].Uncertainty <= 85 && labels[0].Name != "" { photo.PhotoTitle = fmt.Sprintf("%s / %s", txt.Title(labels[0].Name), m.DateCreated().Format("2006")) } else if !photo.TakenAtLocal.IsZero() { @@ -273,14 +273,17 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I if file.FilePrimary && (fileChanged || o.UpdateKeywords) { w := txt.Keywords(photo.PhotoKeywords) - if NonCanonical(fileBase) { - w = append(w, txt.Keywords(filePath)...) - w = append(w, txt.Keywords(fileBase)...) - } + if !photo.ModifiedKeywords { + if NonCanonical(fileBase) { + w = append(w, txt.Keywords(filePath)...) + w = append(w, txt.Keywords(fileBase)...) + } - w = append(w, txt.Keywords(file.OriginalName)...) - w = append(w, file.FileMainColor) - w = append(w, labels.Keywords()...) + w = append(w, locKeywords...) + w = append(w, txt.Keywords(file.OriginalName)...) + w = append(w, file.FileMainColor) + w = append(w, labels.Keywords()...) + } photo.PhotoKeywords = strings.Join(txt.UniqueWords(w), ", ") @@ -325,7 +328,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I file.PhotoUUID = photo.PhotoUUID if file.FilePrimary && (fileChanged || o.UpdateKeywords) { - photo.IndexKeywords(keywords, ind.db) + photo.IndexKeywords(ind.db) } if fileQuery.Error == nil { @@ -512,7 +515,7 @@ func (ind *Index) indexLocation(mediaFile *MediaFile, photo *entity.Photo, label labels = append(labels, classify.LocationLabel(locCategory, 0, -1)) } - if (fileChanged || o.UpdateTitle) && photo.ModifiedTitle == false { + if (fileChanged || o.UpdateTitle) && !photo.ModifiedTitle { if title := labels.Title(location.Name()); title != "" { // TODO: User defined title format log.Infof("index: using label \"%s\" to create photo title", title) if location.NoCity() || location.LongCity() || location.CityContains(title) {