From 06c23b0cb37348cd651666ae2a90da5759c6393a Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Sat, 20 Nov 2021 16:36:34 +0100 Subject: [PATCH] Places: Sort States by Country Name and Title #1608 #1740 --- internal/config/config.go | 3 ++ internal/entity/album.go | 67 +++++++++++++++++++++++++- internal/entity/album_test.go | 33 +++++++++++-- internal/entity/cell.go | 9 ++-- internal/entity/photo_estimate.go | 14 +++++- internal/entity/photo_estimate_test.go | 19 ++++++-- internal/entity/photo_location_test.go | 6 +-- internal/entity/place.go | 22 +++------ internal/entity/place_fixtures.go | 13 ++--- internal/entity/place_test.go | 18 +++---- internal/maps/location.go | 6 +-- internal/maps/location_test.go | 10 ++-- internal/photoprism/moments.go | 4 ++ internal/photoprism/places_test.go | 22 ++++----- internal/search/albums.go | 2 +- 15 files changed, 175 insertions(+), 73 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 47d8a7207..e7faa8291 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -206,6 +206,9 @@ func (c *Config) Init() error { log.Infof("config: make sure your server has enough swap configured to prevent restarts when there are memory usage spikes") } + // Set User Agent for HTTP requests. + places.UserAgent = fmt.Sprintf("%s/%s", c.Name(), c.Version()) + c.initSettings() c.initHub() diff --git a/internal/entity/album.go b/internal/entity/album.go index 7a1c8e449..64e7690d9 100644 --- a/internal/entity/album.go +++ b/internal/entity/album.go @@ -9,6 +9,8 @@ import ( "github.com/gosimple/slug" "github.com/jinzhu/gorm" + + "github.com/photoprism/photoprism/internal/maps" "github.com/photoprism/photoprism/internal/event" "github.com/photoprism/photoprism/internal/form" "github.com/photoprism/photoprism/pkg/rnd" @@ -308,7 +310,7 @@ func (m *Album) SetTitle(title string) { m.AlbumTitle = txt.Clip(title, txt.ClipDefault) - if m.AlbumType == AlbumDefault { + if m.AlbumType == AlbumDefault || m.AlbumSlug == "" { if len(m.AlbumTitle) < txt.ClipSlug { m.AlbumSlug = txt.Slug(m.AlbumTitle) } else { @@ -321,6 +323,39 @@ func (m *Album) SetTitle(title string) { } } +// UpdateState updates the album location. +func (m *Album) UpdateState(stateName, countryCode string) error { + if stateName == "" || countryCode == "" { + return nil + } + + changed := false + countryName := maps.CountryName(countryCode) + + if m.AlbumCountry != countryCode { + m.AlbumCountry = countryCode + changed = true + } + + if changed || m.AlbumLocation == "" { + m.AlbumLocation = countryName + changed = true + } + + if m.AlbumState != stateName { + m.AlbumState = stateName + changed = true + } + + if !changed { + return nil + } + + m.AlbumTitle = stateName + + return m.Updates(Values{"album_title": m.AlbumTitle, "album_location": m.AlbumLocation, "album_country": m.AlbumCountry, "album_state": m.AlbumState}) +} + // SaveForm updates the entity using form data and stores it in the database. func (m *Album) SaveForm(f form.Album) error { if err := deepcopier.Copy(m).From(f); err != nil { @@ -343,6 +378,11 @@ func (m *Album) Update(attr string, value interface{}) error { return UnscopedDb().Model(m).UpdateColumn(attr, value).Error } +// Updates multiple columns in the database. +func (m *Album) Updates(values interface{}) error { + return UnscopedDb().Model(m).UpdateColumns(values).Error +} + // UpdateFolder updates the path, filter and slug for a folder album. func (m *Album) UpdateFolder(albumPath, albumFilter string) error { albumPath = strings.Trim(albumPath, string(os.PathSeparator)) @@ -413,6 +453,31 @@ func (m *Album) Delete() error { return nil } +// DeletePermanently permanently removes an album from the index. +func (m *Album) DeletePermanently() error { + albumType := m.AlbumType + wasDeleted := m.Deleted() + + if err := UnscopedDb().Delete(m).Error; err != nil { + return err + } + + if !wasDeleted { + switch albumType { + case AlbumDefault: + event.Publish("count.albums", event.Data{"count": -1}) + case AlbumMoment: + event.Publish("count.moments", event.Data{"count": -1}) + case AlbumMonth: + event.Publish("count.months", event.Data{"count": -1}) + case AlbumFolder: + event.Publish("count.folders", event.Data{"count": -1}) + } + } + + return nil +} + // Deleted tests if the entity is deleted. func (m *Album) Deleted() bool { return m.DeletedAt != nil diff --git a/internal/entity/album_test.go b/internal/entity/album_test.go index 8d1a9bf0d..96295dbf7 100644 --- a/internal/entity/album_test.go +++ b/internal/entity/album_test.go @@ -4,11 +4,11 @@ import ( "testing" "time" - "github.com/photoprism/photoprism/internal/form" - "github.com/gosimple/slug" - "github.com/photoprism/photoprism/pkg/txt" "github.com/stretchr/testify/assert" + + "github.com/photoprism/photoprism/internal/form" + "github.com/photoprism/photoprism/pkg/txt" ) func TestNewAlbum(t *testing.T) { @@ -69,6 +69,33 @@ is an oblate spheroid.` }) } +func TestAlbum_UpdateState(t *testing.T) { + t.Run("success", func(t *testing.T) { + album := NewAlbum("Any State", AlbumState) + + assert.Equal(t, "Any State", album.AlbumTitle) + assert.Equal(t, "any-state", album.AlbumSlug) + + if err := album.Create(); err != nil { + t.Fatal(err) + } + + if err := album.UpdateState("Alberta", "ca"); err != nil { + t.Fatal(err) + } + + assert.Equal(t, "Alberta", album.AlbumTitle) + assert.Equal(t, "", album.AlbumDescription) + assert.Equal(t, "Canada", album.AlbumLocation) + assert.Equal(t, "Alberta", album.AlbumState) + assert.Equal(t, "ca", album.AlbumCountry) + + if err := album.DeletePermanently(); err != nil { + t.Fatal(err) + } + }) +} + func TestAlbum_SaveForm(t *testing.T) { t.Run("success", func(t *testing.T) { album := NewAlbum("Old Name", AlbumDefault) diff --git a/internal/entity/cell.go b/internal/entity/cell.go index 810f38ae9..80d205620 100644 --- a/internal/entity/cell.go +++ b/internal/entity/cell.go @@ -7,14 +7,13 @@ import ( "github.com/photoprism/photoprism/internal/event" "github.com/photoprism/photoprism/internal/maps" - "github.com/photoprism/photoprism/pkg/s2" "github.com/photoprism/photoprism/pkg/txt" ) var cellMutex = sync.Mutex{} -// Cell represents a S2 cell with location data. +// Cell represents an S2 cell with metadata and reference to a place. type Cell struct { ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"` CellName string `gorm:"type:VARCHAR(200);" json:"Name" yaml:"Name,omitempty"` @@ -142,14 +141,14 @@ func (m *Cell) Find(api string) error { } l := &maps.Location{ - ID: s2.NormalizeToken(m.ID), + ID: m.ID, } if err := l.QueryApi(api); err != nil { return err } - if found := FindPlace(l.PlaceID(), l.Label()); found != nil { + if found := FindPlace(l.PlaceID()); found != nil { m.Place = found } else { place := &Place{ @@ -171,7 +170,7 @@ func (m *Cell) Find(api string) error { log.Infof("place: added %s [%s]", place.ID, time.Since(start)) m.Place = place - } else if found := FindPlace(l.PlaceID(), l.Label()); found != nil { + } else if found := FindPlace(l.PlaceID()); found != nil { m.Place = found } else { log.Errorf("place: %s (create %s)", createErr, place.ID) diff --git a/internal/entity/photo_estimate.go b/internal/entity/photo_estimate.go index bbc838325..f729d902f 100644 --- a/internal/entity/photo_estimate.go +++ b/internal/entity/photo_estimate.go @@ -4,6 +4,7 @@ import ( "time" "github.com/jinzhu/gorm" + "github.com/photoprism/photoprism/pkg/fs" "github.com/photoprism/photoprism/pkg/txt" ) @@ -55,10 +56,19 @@ func (m *Photo) EstimatePlace(force bool) { return } + // Only estimate country if date isn't known with certainty. + if m.TakenSrc == SrcAuto { + m.PlaceID = UnknownPlace.ID + m.PlaceSrc = SrcEstimate + m.EstimateCountry() + m.EstimatedAt = TimePointer() + return + } + var err error - rangeMin := m.TakenAt.AddDate(0, 0, -1) - rangeMax := m.TakenAt.AddDate(0, 0, 1) + rangeMin := m.TakenAt.Add(-1 * time.Hour * 72) + rangeMax := m.TakenAt.Add(time.Hour * 72) // Find photo with location info taken at a similar time... var recentPhoto Photo diff --git a/internal/entity/photo_estimate_test.go b/internal/entity/photo_estimate_test.go index 464216627..48585189d 100644 --- a/internal/entity/photo_estimate_test.go +++ b/internal/entity/photo_estimate_test.go @@ -63,7 +63,7 @@ func TestPhoto_EstimateCountry(t *testing.T) { func TestPhoto_EstimatePlace(t *testing.T) { t.Run("photo already has location", func(t *testing.T) { p := &Place{ID: "1000000001", PlaceCountry: "mx"} - m := Photo{PhotoName: "PhotoWithLocation", OriginalName: "demo/xyz.jpg", Place: p, PlaceID: "1000000001", PlaceSrc: SrcManual, PhotoCountry: "mx"} + m := Photo{TakenSrc: SrcMeta, PhotoName: "PhotoWithLocation", OriginalName: "demo/xyz.jpg", Place: p, PlaceID: "1000000001", PlaceSrc: SrcManual, PhotoCountry: "mx"} assert.True(t, m.HasPlace()) assert.Equal(t, "mx", m.CountryCode()) assert.Equal(t, "Mexico", m.CountryName()) @@ -72,7 +72,7 @@ func TestPhoto_EstimatePlace(t *testing.T) { assert.Equal(t, "Mexico", m.CountryName()) }) t.Run("RecentlyEstimates", func(t *testing.T) { - m2 := Photo{PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", EstimatedAt: TimePointer(), TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} + m2 := Photo{TakenSrc: SrcMeta, PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", EstimatedAt: TimePointer(), TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} assert.Equal(t, UnknownID, m2.CountryCode()) m2.EstimatePlace(false) assert.Equal(t, "zz", m2.CountryCode()) @@ -80,7 +80,7 @@ func TestPhoto_EstimatePlace(t *testing.T) { assert.Equal(t, SrcAuto, m2.PlaceSrc) }) t.Run("ForceEstimate", func(t *testing.T) { - m2 := Photo{PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", EstimatedAt: TimePointer(), TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} + m2 := Photo{TakenSrc: SrcMeta, PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", EstimatedAt: TimePointer(), TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} assert.Equal(t, UnknownID, m2.CountryCode()) m2.EstimatePlace(true) assert.Equal(t, "mx", m2.CountryCode()) @@ -88,15 +88,24 @@ func TestPhoto_EstimatePlace(t *testing.T) { assert.Equal(t, SrcEstimate, m2.PlaceSrc) }) t.Run("recent photo has place", func(t *testing.T) { - m2 := Photo{PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} + m2 := Photo{TakenSrc: SrcMeta, PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} assert.Equal(t, UnknownID, m2.CountryCode()) m2.EstimatePlace(false) assert.Equal(t, "mx", m2.CountryCode()) assert.Equal(t, "Mexico", m2.CountryName()) assert.Equal(t, SrcEstimate, m2.PlaceSrc) }) + t.Run("SrcAuto", func(t *testing.T) { + m2 := Photo{TakenSrc: SrcAuto, PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", TakenAt: time.Date(2016, 11, 11, 8, 7, 18, 0, time.UTC)} + assert.Equal(t, UnknownID, m2.CountryCode()) + m2.EstimatePlace(false) + assert.Equal(t, "zz", m2.CountryCode()) + assert.Equal(t, "Unknown", m2.CountryName()) + assert.Equal(t, "zz", m2.PlaceID) + assert.Equal(t, SrcEstimate, m2.PlaceSrc) + }) t.Run("cant estimate - out of scope", func(t *testing.T) { - m2 := Photo{PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", TakenAt: time.Date(2016, 11, 13, 8, 7, 18, 0, time.UTC)} + m2 := Photo{TakenSrc: SrcMeta, PhotoName: "PhotoWithoutLocation", OriginalName: "demo/xyy.jpg", TakenAt: time.Date(2016, 11, 13, 8, 7, 18, 0, time.UTC)} assert.Equal(t, UnknownID, m2.CountryCode()) m2.EstimatePlace(true) assert.Equal(t, UnknownID, m2.CountryCode()) diff --git a/internal/entity/photo_location_test.go b/internal/entity/photo_location_test.go index 7d0d76a1d..51ab7663d 100644 --- a/internal/entity/photo_location_test.go +++ b/internal/entity/photo_location_test.go @@ -140,7 +140,7 @@ func TestUpdateLocation(t *testing.T) { PhotoCountry: UnknownID, PhotoLat: 0.0, PhotoLng: 0.0, - PlaceID: "s2:85d1ea7d3278", + PlaceID: "mx:VvfNBpFegSCr", PlaceSrc: SrcEstimate, } @@ -152,7 +152,7 @@ func TestUpdateLocation(t *testing.T) { assert.Equal(t, "mx", m.PhotoCountry) assert.Equal(t, float32(0.0), m.PhotoLat) assert.Equal(t, float32(0.0), m.PhotoLng) - assert.Equal(t, "s2:85d1ea7d3278", m.PlaceID) + assert.Equal(t, "mx:VvfNBpFegSCr", m.PlaceID) assert.Equal(t, SrcEstimate, m.PlaceSrc) }) @@ -162,7 +162,7 @@ func TestUpdateLocation(t *testing.T) { PhotoCountry: "de", PhotoLat: 0.0, PhotoLng: 0.0, - PlaceID: "s2:85d1ea7d3278", + PlaceID: "de:HFqPHxa2Hsol", PlaceSrc: SrcManual, } diff --git a/internal/entity/place.go b/internal/entity/place.go index 76b8b8572..61eb93222 100644 --- a/internal/entity/place.go +++ b/internal/entity/place.go @@ -11,10 +11,10 @@ import ( var placeMutex = sync.Mutex{} -// Place used to associate photos to places +// Place represents a distinct region identified by city, district, state, and country. type Place struct { ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"PlaceID" yaml:"PlaceID"` - PlaceLabel string `gorm:"type:VARCHAR(400);unique_index;" json:"Label" yaml:"Label"` + PlaceLabel string `gorm:"type:VARCHAR(400);" json:"Label" yaml:"Label"` PlaceDistrict string `gorm:"type:VARCHAR(100);index;" json:"District" yaml:"District,omitempty"` PlaceCity string `gorm:"type:VARCHAR(100);index;" json:"City" yaml:"City,omitempty"` PlaceState string `gorm:"type:VARCHAR(100);index;" json:"State" yaml:"State,omitempty"` @@ -50,19 +50,11 @@ func CreateUnknownPlace() { } // FindPlace finds a matching place or returns nil. -func FindPlace(id string, label string) *Place { +func FindPlace(id string) *Place { place := Place{} - if label == "" { - if err := Db().Where("id = ?", id).First(&place).Error; err != nil { - log.Debugf("place: %s no found", txt.Quote(id)) - return nil - } else { - return &place - } - } - - if err := Db().Where("id = ? OR place_label = ?", id, label).First(&place).Error; err != nil { + if err := Db().Where("id = ?", id).First(&place).Error; err != nil { + log.Debugf("place: %s no found", txt.Quote(id)) return nil } else { return &place @@ -113,11 +105,11 @@ func FirstOrCreatePlace(m *Place) *Place { result := Place{} - if findErr := Db().Where("id = ? OR place_label = ?", m.ID, m.PlaceLabel).First(&result).Error; findErr == nil { + if findErr := Db().Where("id = ?", m.ID).First(&result).Error; findErr == nil { return &result } else if createErr := m.Create(); createErr == nil { return m - } else if err := Db().Where("id = ? OR place_label = ?", m.ID, m.PlaceLabel).First(&result).Error; err == nil { + } else if err := Db().Where("id = ?", m.ID).First(&result).Error; err == nil { return &result } else { log.Errorf("place: %s (create %s)", createErr, m.ID) diff --git a/internal/entity/place_fixtures.go b/internal/entity/place_fixtures.go index b1af3dfbc..86d958fa5 100644 --- a/internal/entity/place_fixtures.go +++ b/internal/entity/place_fixtures.go @@ -24,8 +24,8 @@ func (m PlacesMap) Pointer(name string) *Place { var PlaceFixtures = PlacesMap{ "mexico": { - ID: s2.TokenPrefix + "85d1ea7d3278", - PlaceLabel: "Teotihuacán, Mexico, Mexico", + ID: "mx:VvfNBpFegSCr", + PlaceLabel: "Teotihuacán, State of Mexico, Mexico", PlaceCity: "Teotihuacán", PlaceState: "State of Mexico", PlaceCountry: "mx", @@ -36,7 +36,7 @@ var PlaceFixtures = PlacesMap{ UpdatedAt: TimeStamp(), }, "zinkwazi": { - ID: s2.TokenPrefix + "1ef744d1e279", + ID: "za:Rc1K7dTWRzBD", PlaceLabel: "KwaDukuza, KwaZulu-Natal, South Africa", PlaceCity: "KwaDukuza", PlaceState: "KwaZulu-Natal", @@ -48,9 +48,10 @@ var PlaceFixtures = PlacesMap{ UpdatedAt: TimeStamp(), }, "holidaypark": { - ID: s2.TokenPrefix + "1ef744d1e280", - PlaceLabel: "Holiday Park, Amusement", - PlaceCity: "", + ID: "de:HFqPHxa2Hsol", + PlaceLabel: "Neustadt an der Weinstraße, Rheinland-Pfalz, Germany", + PlaceDistrict: "Hambach an der Weinstraße", + PlaceCity: "Neustadt an der Weinstraße", PlaceState: "Rheinland-Pfalz", PlaceCountry: "de", PlaceKeywords: "", diff --git a/internal/entity/place_test.go b/internal/entity/place_test.go index e24412355..9b3bbc1b3 100644 --- a/internal/entity/place_test.go +++ b/internal/entity/place_test.go @@ -12,9 +12,9 @@ func TestCreateUnknownPlace(t *testing.T) { assert.True(t, r.Unknown()) } -func TestFindPlaceByLabel(t *testing.T) { - t.Run("find by id", func(t *testing.T) { - r := FindPlace(s2.TokenPrefix+"1ef744d1e280", "") +func TestFindPlace(t *testing.T) { + t.Run("Holiday Park", func(t *testing.T) { + r := FindPlace("de:HFqPHxa2Hsol") if r == nil { t.Fatal("result should not be nil") @@ -22,16 +22,16 @@ func TestFindPlaceByLabel(t *testing.T) { assert.Equal(t, "de", r.PlaceCountry) }) - t.Run("find by id", func(t *testing.T) { - r := FindPlace(s2.TokenPrefix+"85d1ea7d3278", "") + t.Run("Mexico", func(t *testing.T) { + r := FindPlace("mx:VvfNBpFegSCr") if r == nil { t.Fatal("result should not be nil") } assert.Equal(t, "mx", r.PlaceCountry) }) - t.Run("find by label", func(t *testing.T) { - r := FindPlace("", "KwaDukuza, KwaZulu-Natal, South Africa") + t.Run("KwaDukuza", func(t *testing.T) { + r := FindPlace("za:Rc1K7dTWRzBD") if r == nil { t.Fatal("result should not be nil") @@ -40,14 +40,14 @@ func TestFindPlaceByLabel(t *testing.T) { assert.Equal(t, "za", r.PlaceCountry) }) t.Run("not matching", func(t *testing.T) { - r := FindPlace("111", "xxx") + r := FindPlace("111") if r != nil { t.Fatal("result should be nil") } }) t.Run("not matching empty label", func(t *testing.T) { - r := FindPlace("111", "") + r := FindPlace("111") if r != nil { t.Fatal("result should be nil") diff --git a/internal/maps/location.go b/internal/maps/location.go index c99fdae0b..daa3742d1 100644 --- a/internal/maps/location.go +++ b/internal/maps/location.go @@ -78,11 +78,7 @@ func (l *Location) Unknown() bool { } func (l Location) PlaceID() string { - if l.placeID != "" { - return s2.Prefix(l.placeID) - } - - return l.PrefixedToken() + return l.placeID } func (l Location) S2Token() string { diff --git a/internal/maps/location_test.go b/internal/maps/location_test.go index 96c2ac860..147afd090 100644 --- a/internal/maps/location_test.go +++ b/internal/maps/location_test.go @@ -68,12 +68,12 @@ func TestLocation_QueryPlaces(t *testing.T) { t.Fatal(err) } - assert.Equal(t, "", l.LocName) - assert.Equal(t, "ocean", l.LocCategory) - assert.Equal(t, "", l.LocState) - assert.Equal(t, "South Pacific Ocean", l.LocDistrict) + assert.Equal(t, "Puerto Velasco Ibarra", l.LocName) + assert.Equal(t, "", l.LocCategory) + assert.Equal(t, "Galápagos", l.LocState) + assert.Equal(t, "", l.LocDistrict) assert.Equal(t, "ec", l.LocCountry) - assert.Equal(t, "South Pacific Ocean, Ecuador", l.LocLabel) + assert.Equal(t, "Galápagos, Ecuador", l.LocLabel) assert.Equal(t, "places", l.LocSource) }) } diff --git a/internal/photoprism/moments.go b/internal/photoprism/moments.go index 814da9a43..a89cc3d1d 100644 --- a/internal/photoprism/moments.go +++ b/internal/photoprism/moments.go @@ -179,6 +179,10 @@ func (w *Moments) Start() (err error) { } if a := entity.FindAlbumBySlug(mom.Slug(), entity.AlbumState); a != nil { + if err := a.UpdateState(mom.State, mom.Country); err != nil { + log.Errorf("moments: %s (update state)", err.Error()) + } + if !a.Deleted() { log.Tracef("moments: %s already exists (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter) } else if err := a.Restore(); err != nil { diff --git a/internal/photoprism/places_test.go b/internal/photoprism/places_test.go index 55da1b9d4..5d00fdd12 100644 --- a/internal/photoprism/places_test.go +++ b/internal/photoprism/places_test.go @@ -6,28 +6,24 @@ import ( "github.com/photoprism/photoprism/internal/config" ) -func TestPlaces_Start(t *testing.T) { +func TestPlaces(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } w := NewPlaces(config.TestConfig()) - updated, err := w.Start() + t.Run("Start", func(t *testing.T) { + updated, err := w.Start() - if err != nil { - t.Fatal(err) - } + if err != nil { + t.Fatal(err) + } - t.Logf("updated: %#v", updated) -} + t.Logf("updated: %#v", updated) + }) -func TestPlaces_UpdatePhotos(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - - t.Run("success", func(t *testing.T) { + t.Run("UpdatePhotos", func(t *testing.T) { w := NewPlaces(config.TestConfig()) affected, err := w.UpdatePhotos() diff --git a/internal/search/albums.go b/internal/search/albums.go index dd1ac9f01..0117ec7eb 100644 --- a/internal/search/albums.go +++ b/internal/search/albums.go @@ -76,7 +76,7 @@ func Albums(f form.AlbumSearch) (results AlbumResults, err error) { case entity.SortOrderMoment: s = s.Order("albums.album_favorite DESC, has_year, albums.album_year DESC, albums.album_month DESC, albums.album_title ASC, albums.album_uid DESC") case entity.SortOrderPlace: - s = s.Order("albums.album_favorite DESC, albums.album_country, albums.album_state, albums.album_title, albums.album_year DESC, albums.album_month ASC, albums.album_day ASC, albums.album_uid DESC") + s = s.Order("albums.album_favorite DESC, albums.album_location, albums.album_title, albums.album_year DESC, albums.album_month ASC, albums.album_day ASC, albums.album_uid DESC") case entity.SortOrderName: s = s.Order("albums.album_title ASC, albums.album_uid DESC") case entity.SortOrderPath: