This commit is contained in:
Gökçe Dilek 2023-12-05 05:35:30 +00:00 committed by GitHub
commit 282aa8a258
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 200 additions and 9 deletions

View file

@ -52,6 +52,8 @@ type Album struct {
AlbumYear int `gorm:"index:idx_albums_ymd;index:idx_albums_country_year_month;" json:"Year" yaml:"Year,omitempty"`
AlbumMonth int `gorm:"index:idx_albums_ymd;index:idx_albums_country_year_month;" json:"Month" yaml:"Month,omitempty"`
AlbumDay int `gorm:"index:idx_albums_ymd;" json:"Day" yaml:"Day,omitempty"`
AlbumOldest time.Time `json:"Oldest" yaml:"Oldest"`
AlbumNewest time.Time `json:"Newest" yaml:"Newest"`
AlbumFavorite bool `json:"Favorite" yaml:"Favorite,omitempty"`
AlbumPrivate bool `json:"Private" yaml:"Private,omitempty"`
Thumb string `gorm:"type:VARBINARY(128);index;default:'';" json:"Thumb" yaml:"Thumb,omitempty"`
@ -137,8 +139,42 @@ func AddPhotoToUserAlbums(photoUid string, albums []string, userUid string) (err
log.Errorf("album: %s (add photo %s to albums)", err.Error(), photoUid)
}
// Refresh updated timestamp.
err = UpdateAlbum(albumUid, Values{"updated_at": TimePointer()})
// update the oldest or newest date of the album, if needed
var photo Photo
var album Album
var albumOldest time.Time
var albumNewest time.Time
if err := Db().Model(&Photo{}).Where("photo_uid = ?",
photoUid).First(&photo).Error; err == nil && photo.PhotoUID != "" {
takenAt := photo.TakenAt
if err := Db().Model(&Album{}).Where("album_uid = ?",
albumUid).First(&album).Error; err == nil && album.
AlbumUID != "" {
albumOldest = album.AlbumOldest
albumNewest = album.AlbumNewest
if before := takenAt.Before(albumOldest); before {
albumOldest = takenAt
} else if zero := albumOldest.IsZero(); zero {
albumOldest = takenAt
}
if after := takenAt.After(albumNewest); after {
albumNewest = takenAt
}
}
}
if !albumOldest.Equal(album.AlbumOldest) || !albumNewest.Equal(album.AlbumNewest) {
// Refresh updated timestamp and album oldest/newest values.
err = UpdateAlbum(
albumUid, Values{
"updated_at": TimePointer(),
"albumOldest": albumOldest, "albumNewest": albumNewest,
},
)
}
}
}
@ -788,6 +824,9 @@ func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
return added
}
albumOldest := m.AlbumOldest
albumNewest := m.AlbumNewest
// Add album entries.
for _, uid := range UIDs {
if !rnd.IsUID(uid, PhotoUID) {
@ -801,11 +840,34 @@ func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
} else {
added = append(added, entry)
}
// update the oldest or newest date of the album, if needed
var photo Photo
if err := Db().Model(&Photo{}).Where("photo_uid = ?",
uid).First(&photo).Error; err == nil && photo.PhotoUID != "" {
takenAt := photo.TakenAt
if before := takenAt.Before(albumOldest); before {
albumOldest = takenAt
} else if zero := albumOldest.IsZero(); zero {
albumOldest = takenAt
}
if after := takenAt.After(albumNewest); after {
albumNewest = takenAt
}
}
}
// Refresh updated timestamp.
if err := UpdateAlbum(m.AlbumUID, Values{"updated_at": TimePointer()}); err != nil {
log.Errorf("album: %s (update %s)", err.Error(), m)
// Refresh updated timestamp and album oldest/newest values.
if !albumOldest.Equal(m.AlbumOldest) || !albumNewest.Equal(m.AlbumNewest) {
if err := UpdateAlbum(
m.AlbumUID, Values{
"updated_at": TimePointer(),
"albumOldest": albumOldest, "albumNewest": albumNewest,
},
); err != nil {
log.Errorf("album: %s (update %s)", err.Error(), m)
}
}
return added
@ -817,6 +879,9 @@ func (m *Album) RemovePhotos(UIDs []string) (removed PhotoAlbums) {
return removed
}
updatedAlbumOldest := m.AlbumOldest
updatedAlbumNewest := m.AlbumNewest
for _, uid := range UIDs {
if !rnd.IsUID(uid, PhotoUID) {
continue
@ -829,11 +894,37 @@ func (m *Album) RemovePhotos(UIDs []string) (removed PhotoAlbums) {
} else {
removed = append(removed, entry)
}
// update the oldest or newest date of the album, if needed
var photo Photo
if err := Db().Model(&Photo{}).Where("photo_uid = ?", uid).First(&photo).Error; err == nil &&
photo.PhotoUID != "" {
takenAt := photo.TakenAt
if isOldest := takenAt.Equal(m.AlbumOldest); isOldest {
if oldestPhoto, err := AlbumOldestOrNewest(m.AlbumUID, true, ""); err == nil {
// update the oldest of the album
updatedAlbumOldest = oldestPhoto.TakenAt
}
}
if isNewest := takenAt.Equal(m.AlbumNewest); isNewest {
if newestPhoto, err := AlbumOldestOrNewest(m.AlbumUID, false, ""); err == nil {
// update the newest of the album
updatedAlbumNewest = newestPhoto.TakenAt
}
}
}
}
// Refresh updated timestamp.
if err := UpdateAlbum(m.AlbumUID, Values{"updated_at": TimePointer()}); err != nil {
log.Errorf("album: %s (update %s)", err.Error(), m)
if !updatedAlbumOldest.Equal(m.AlbumOldest) || !updatedAlbumNewest.Equal(m.AlbumNewest) {
if err := UpdateAlbum(
m.AlbumUID, Values{
"updated_at": TimePointer(), "albumOldest": updatedAlbumOldest,
"albumNewest": updatedAlbumNewest,
},
); err != nil {
log.Errorf("album: %s (update %s)", err.Error(), m)
}
}
return removed
@ -843,3 +934,54 @@ func (m *Album) RemovePhotos(UIDs []string) (removed PhotoAlbums) {
func (m *Album) Links() Links {
return FindLinks("", m.AlbumUID)
}
func AlbumOldestOrNewest(albumUid string, isOldest bool, exceptPhotoUid string) (Photo, error) {
var photo Photo
var orderDirection string
if isOldest {
orderDirection = "ASC"
} else {
orderDirection = "DESC"
}
stmt := Db().Table("photos").Select("photos.*").Joins(
"JOIN photos_albums ON photos.photo_uid = "+
"photos_albums.photo_uid",
).Joins("JOIN albums ON photos_albums.album_uid = albums.album_uid").
Where("photos.photo_uid != ?", exceptPhotoUid).
Where("albums.album_uid = ?", albumUid).
Where("photos_albums.hidden = 0").
Order(
fmt.Sprintf(
"photos.taken_at %s, photos.photo_uid",
orderDirection,
),
)
if r := stmt.First(&photo); r.RecordNotFound() {
return Photo{}, nil
} else if r.Error != nil {
return Photo{}, r.Error
}
return photo, nil
}
func AlbumsOfPhoto(photoUid string) ([]Album, error) {
var albums []Album
stmt := Db().Table("albums").Select("albums.*").Joins(
"JOIN photos_albums ON albums.album_uid = "+
"photos_albums.album_uid",
).Joins("JOIN photos ON photos_albums.photo_uid = photos.photo_uid").
Where("photos.photo_uid = ?", photoUid).
Where("photos_albums.hidden = 0")
if r := stmt.Find(&albums); r.RecordNotFound() {
return albums, nil
} else if r.Error != nil {
return albums, r.Error
}
return albums, nil
}

View file

@ -155,6 +155,9 @@ func NewUserPhoto(stackable bool, userUid string) Photo {
// SavePhotoForm saves a model in the database using form data.
func SavePhotoForm(model Photo, form form.Photo) error {
locChanged := model.PhotoLat != form.PhotoLat || model.PhotoLng != form.PhotoLng || model.PhotoCountry != form.PhotoCountry
oldTakenAt := model.TakenAt
oldTakenAtLocal := model.TakenAtLocal
takenAtChanged := oldTakenAt != form.TakenAt || oldTakenAtLocal != form.TakenAtLocal
if err := deepcopier.Copy(&model).From(form); err != nil {
return err
@ -173,6 +176,10 @@ func SavePhotoForm(model Photo, form form.Photo) error {
model.UpdateDateFields()
if takenAtChanged {
model.UpdateDateFieldsOfAlbums(oldTakenAt)
}
details := model.GetDetails()
if form.Details.PhotoID == model.ID {

View file

@ -128,3 +128,43 @@ func (m *Photo) UpdateDateFields() {
Updates(File{PhotoTakenAt: m.TakenAtLocal}).Error,
)
}
// UpdateDateFieldsOfAlbums updates the oldest or newest date of the albums the photo is in, if needed.
func (m *Photo) UpdateDateFieldsOfAlbums(oldTakenAt time.Time) {
if albums, err := AlbumsOfPhoto(m.PhotoUID); err == nil {
for _, album := range albums {
albumOldest := album.AlbumOldest
albumNewest := album.AlbumNewest
updatedAlbumOldest := albumOldest
updatedAlbumNewest := albumNewest
takenAt := m.TakenAt
if wasOldest := oldTakenAt.Equal(albumOldest); wasOldest {
if oldestPhoto, err := AlbumOldestOrNewest(album.AlbumUID, true, m.PhotoUID); err == nil {
// find the oldest of the album
updatedAlbumOldest = oldestPhoto.TakenAt
}
}
if wasNewest := oldTakenAt.Equal(albumNewest); wasNewest {
if newestPhoto, err := AlbumOldestOrNewest(album.AlbumUID, false, m.PhotoUID); err == nil {
// find the newest of the album
updatedAlbumNewest = newestPhoto.TakenAt
}
}
if before := takenAt.Before(updatedAlbumOldest); before {
updatedAlbumOldest = takenAt
} else if after := takenAt.After(updatedAlbumNewest); after {
updatedAlbumNewest = takenAt
}
// Refresh updated timestamp and album oldest/newest values.
if !updatedAlbumOldest.Equal(album.AlbumOldest) || !updatedAlbumNewest.Equal(album.AlbumNewest) {
if err := UpdateAlbum(
album.AlbumUID, Values{
"albumOldest": updatedAlbumOldest, "albumNewest": updatedAlbumNewest,
},
); err != nil {
log.Errorf("album: %s (update %s)", err.Error(), album)
}
}
}
}
}

View file

@ -148,6 +148,8 @@ CREATE TABLE `albums` (
`album_day` int(11) DEFAULT NULL,
`album_favorite` tinyint(1) DEFAULT NULL,
`album_private` tinyint(1) DEFAULT NULL,
`album_oldest` datetime DEFAULT NULL,
`album_newest` datetime DEFAULT NULL,
`thumb` varbinary(128) DEFAULT '',
`thumb_src` varbinary(8) DEFAULT '',
`created_at` datetime DEFAULT NULL,

View file

@ -81,7 +81,7 @@ func UserAlbums(f form.SearchAlbums, sess *entity.Session) (results AlbumResults
s = s.Order("photo_count DESC, albums.album_title, albums.album_uid DESC")
case sortby.Moment, sortby.Newest:
if f.Type == entity.AlbumManual || f.Type == entity.AlbumState {
s = s.Order("albums.album_uid DESC")
s = s.Order("albums.album_newest DESC")
} else if f.Type == entity.AlbumMoment {
s = s.Order("has_year, albums.album_year DESC, albums.album_month DESC, albums.album_day DESC, albums.album_title, albums.album_uid DESC")
} else {
@ -89,7 +89,7 @@ func UserAlbums(f form.SearchAlbums, sess *entity.Session) (results AlbumResults
}
case sortby.Oldest:
if f.Type == entity.AlbumManual || f.Type == entity.AlbumState {
s = s.Order("albums.album_uid ASC")
s = s.Order("albums.album_oldest ASC")
} else if f.Type == entity.AlbumMoment {
s = s.Order("has_year, albums.album_year ASC, albums.album_month ASC, albums.album_day ASC, albums.album_title, albums.album_uid ASC")
} else {