parent
df1ffc68cf
commit
06c23b0cb3
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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,23 +50,15 @@ 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 {
|
||||
return nil
|
||||
} else {
|
||||
return &place
|
||||
}
|
||||
}
|
||||
|
||||
// Find fetches entity values from the database the primary key.
|
||||
|
@ -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)
|
||||
|
|
|
@ -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: "",
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -6,13 +6,14 @@ 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())
|
||||
|
||||
t.Run("Start", func(t *testing.T) {
|
||||
updated, err := w.Start()
|
||||
|
||||
if err != nil {
|
||||
|
@ -20,14 +21,9 @@ func TestPlaces_Start(t *testing.T) {
|
|||
}
|
||||
|
||||
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()
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue