2021-09-18 15:32:39 +02:00
package search
import (
"strings"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/txt"
)
// Albums searches albums based on their name.
2021-11-26 14:28:50 +01:00
func Albums ( f form . SearchAlbums ) ( results AlbumResults , err error ) {
2021-09-18 15:32:39 +02:00
if err := f . ParseQueryString ( ) ; err != nil {
return results , err
}
2021-11-18 12:54:26 +01:00
// Clip and normalize search query.
f . Query = txt . NormalizeQuery ( f . Query )
2021-09-18 15:32:39 +02:00
// Base query.
s := UnscopedDb ( ) . Table ( "albums" ) .
2021-11-18 00:46:34 +01:00
Select ( "albums.*, cp.photo_count, cl.link_count, CASE WHEN albums.album_year = 0 THEN 0 ELSE 1 END AS has_year" ) .
2021-09-18 15:32:39 +02:00
Joins ( "LEFT JOIN (SELECT album_uid, count(photo_uid) AS photo_count FROM photos_albums WHERE hidden = 0 AND missing = 0 GROUP BY album_uid) AS cp ON cp.album_uid = albums.album_uid" ) .
Joins ( "LEFT JOIN (SELECT share_uid, count(share_uid) AS link_count FROM links GROUP BY share_uid) AS cl ON cl.share_uid = albums.album_uid" ) .
Where ( "albums.album_type <> 'folder' OR albums.album_path IN (SELECT photo_path FROM photos WHERE photo_private = 0 AND photo_quality > -1 AND deleted_at IS NULL)" ) .
Where ( "albums.deleted_at IS NULL" )
// Limit result count.
if f . Count > 0 && f . Count <= MaxResults {
s = s . Limit ( f . Count ) . Offset ( f . Offset )
} else {
s = s . Limit ( MaxResults ) . Offset ( f . Offset )
}
2021-11-18 12:54:26 +01:00
// Filter by storage path?
if f . Query != "" && f . Type == entity . AlbumFolder {
f . Order = entity . SortOrderPath
p := f . Query
if strings . HasPrefix ( p , "/" ) {
p = p [ 1 : ]
}
if strings . HasSuffix ( p , "/" ) {
s = s . Where ( "albums.album_path = ?" , p [ : len ( p ) - 1 ] )
} else {
p = p + "*"
where , values := OrLike ( "albums.album_path" , p )
if w , v := OrLike ( "albums.album_title" , p ) ; len ( v ) > 0 {
where = where + " OR " + w
values = append ( values , v ... )
}
s = s . Where ( where , values ... )
}
} else if f . Query != "" {
likeString := "%" + f . Query + "%"
s = s . Where ( "albums.album_title LIKE ? OR albums.album_location LIKE ?" , likeString , likeString )
}
2021-09-18 15:32:39 +02:00
// Set sort order.
switch f . Order {
2021-11-18 00:46:34 +01:00
case entity . SortOrderCount :
s = s . Order ( "photo_count DESC, albums.album_title, albums.album_uid DESC" )
case entity . SortOrderRelevance :
s = s . Order ( "albums.album_favorite DESC, albums.updated_at DESC, albums.album_uid DESC" )
case entity . SortOrderNewest :
s = s . Order ( "albums.album_favorite DESC, albums.album_year DESC, albums.album_month DESC, albums.album_day DESC, albums.album_title, albums.album_uid DESC" )
case entity . SortOrderOldest :
s = s . Order ( "albums.album_favorite DESC, albums.album_year ASC, albums.album_month ASC, albums.album_day ASC, albums.album_title, albums.album_uid ASC" )
case entity . SortOrderAdded :
s = s . Order ( "albums.album_uid DESC" )
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 :
2021-11-20 16:36:34 +01:00
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" )
2021-11-18 00:46:34 +01:00
case entity . SortOrderName :
s = s . Order ( "albums.album_title ASC, albums.album_uid DESC" )
case entity . SortOrderPath :
2021-11-18 12:54:26 +01:00
s = s . Order ( "albums.album_path, albums.album_uid DESC" )
2021-11-18 00:46:34 +01:00
case entity . SortOrderCategory :
s = s . Order ( "albums.album_category, albums.album_title, albums.album_uid DESC" )
case entity . SortOrderSlug :
s = s . Order ( "albums.album_favorite DESC, albums.album_slug ASC, albums.album_uid DESC" )
2021-09-18 15:32:39 +02:00
default :
2021-11-18 00:46:34 +01:00
s = s . Order ( "albums.album_favorite DESC, has_year, albums.album_title ASC, albums.album_uid DESC" )
2021-09-18 15:32:39 +02:00
}
if f . ID != "" {
s = s . Where ( "albums.album_uid IN (?)" , strings . Split ( f . ID , txt . Or ) )
if result := s . Scan ( & results ) ; result . Error != nil {
return results , result . Error
}
return results , nil
}
if f . Type != "" {
s = s . Where ( "albums.album_type IN (?)" , strings . Split ( f . Type , txt . Or ) )
}
if f . Category != "" {
s = s . Where ( "albums.album_category IN (?)" , strings . Split ( f . Category , txt . Or ) )
}
if f . Location != "" {
s = s . Where ( "albums.album_location IN (?)" , strings . Split ( f . Location , txt . Or ) )
}
if f . Country != "" {
s = s . Where ( "albums.album_country IN (?)" , strings . Split ( f . Country , txt . Or ) )
}
if f . Favorite {
s = s . Where ( "albums.album_favorite = 1" )
}
if ( f . Year > 0 && f . Year <= txt . YearMax ) || f . Year == entity . UnknownYear {
s = s . Where ( "albums.album_year = ?" , f . Year )
}
if ( f . Month >= txt . MonthMin && f . Month <= txt . MonthMax ) || f . Month == entity . UnknownMonth {
s = s . Where ( "albums.album_month = ?" , f . Month )
}
if ( f . Day >= txt . DayMin && f . Month <= txt . DayMax ) || f . Day == entity . UnknownDay {
s = s . Where ( "albums.album_day = ?" , f . Day )
}
if result := s . Scan ( & results ) ; result . Error != nil {
return results , result . Error
}
return results , nil
}