2019-12-05 19:21:35 +01:00
package form
2018-08-15 09:59:51 +02:00
import (
"time"
2022-08-31 16:22:28 +02:00
"github.com/photoprism/photoprism/pkg/fs"
2018-08-15 09:59:51 +02:00
)
2021-11-26 13:59:10 +01:00
// SearchPhotos represents search form fields for "/api/v1/photos".
type SearchPhotos struct {
2020-12-19 19:15:32 +01:00
Query string ` form:"q" `
2022-09-30 19:15:10 +02:00
Scope string ` form:"s" serialize:"-" example:"s:ariqwb43p5dh9h13" notes:"Limits the results to one album or another scope, if specified" `
2022-09-30 00:42:19 +02:00
Filter string ` form:"filter" serialize:"-" notes:"-" `
UID string ` form:"uid" example:"uid:pqbcf5j446s0futy" notes:"Search for specific files or photos, only exact matches" `
2022-04-18 12:24:15 +02:00
Type string ` form:"type" example:"type:raw" notes:"Media Type (image, video, raw, live, animated); OR search with |" `
Path string ` form:"path" example:"path:2020/Holiday" notes:"Path Name, OR search with |, supports * wildcards" `
Folder string ` form:"folder" example:"folder:\"*/2020\"" notes:"Path Name, OR search with |, supports * wildcards" ` // Alias for Path
Name string ` form:"name" example:"name:\"IMG_9831-112*\"" notes:"File Name without path and extension, OR search with |" `
Filename string ` form:"filename" example:"filename:\"2021/07/12345.jpg\"" notes:"File Name with path and extension, OR search with |" `
Original string ` form:"original" example:"original:\"IMG_9831-112*\"" notes:"Original file name of imported files, OR search with |" `
Title string ` form:"title" example:"title:\"Lake*\"" notes:"Title, OR search with |" `
Hash string ` form:"hash" example:"hash:2fd4e1c67a2d" notes:"SHA1 File Hash, OR search with |" `
Primary bool ` form:"primary" notes:"Finds primary JPEG files only" `
Stack bool ` form:"stack" notes:"Finds pictures with more than one media file" `
Unstacked bool ` form:"unstacked" notes:"Finds pictures with a file that has been removed from a stack" `
Stackable bool ` form:"stackable" notes:"Finds pictures that can be stacked with additional media files" `
Video bool ` form:"video" notes:"Finds video files only" `
Vector bool ` form:"vector" notes:"Finds vector graphics only" `
Animated bool ` form:"animated" notes:"Finds animated GIFs" `
Photo bool ` form:"photo" notes:"Finds only photos, no videos" `
Raw bool ` form:"raw" notes:"Finds pictures with RAW image file" `
Live bool ` form:"live" notes:"Finds Live Photos and short videos" `
Scan bool ` form:"scan" notes:"Finds scanned images and documents" `
Panorama bool ` form:"panorama" notes:"Finds pictures with an aspect ratio > 1.9:1" `
Portrait bool ` form:"portrait" notes:"Finds pictures in portrait format" `
Landscape bool ` form:"landscape" notes:"Finds pictures in landscape format" `
Square bool ` form:"square" notes:"Finds images with an aspect ratio of 1:1" `
Error bool ` form:"error" notes:"Finds pictures with errors" `
Hidden bool ` form:"hidden" notes:"Finds hidden pictures (broken or unsupported)" `
Archived bool ` form:"archived" notes:"Finds archived pictures" `
Public bool ` form:"public" notes:"Excludes private pictures" `
Private bool ` form:"private" notes:"Finds private pictures" `
Favorite bool ` form:"favorite" notes:"Finds pictures marked as favorite" `
Unsorted bool ` form:"unsorted" notes:"Finds pictures not in an album" `
Lat float32 ` form:"lat" notes:"Latitude (GPS Position)" `
Lng float32 ` form:"lng" notes:"Longitude (GPS Position)" `
Dist uint ` form:"dist" example:"dist:5" notes:"Distance in km in combination with lat/lng" `
Fmin float32 ` form:"fmin" notes:"F-number (min)" `
Fmax float32 ` form:"fmax" notes:"F-number (max)" `
2022-06-16 06:30:59 +02:00
Chroma int16 ` form:"chroma" example:"chroma:70" notes:"Chroma (0-100)" `
2022-04-18 12:24:15 +02:00
Diff uint32 ` form:"diff" notes:"Differential Perceptual Hash (000000-FFFFFF)" `
Mono bool ` form:"mono" notes:"Finds pictures with few or no colors" `
Geo bool ` form:"geo" notes:"Finds pictures with GPS location" `
Keywords string ` form:"keywords" example:"keywords:\"buffalo&water\"" notes:"Keywords, can be combined with & and |" ` // Filter by keyword(s)
Label string ` form:"label" example:"label:cat|dog" notes:"Label Name, OR search with |" ` // Label name
Category string ` form:"category" notes:"Location Category Name" ` // Moments
Country string ` form:"country" example:"country:\"de|us\"" notes:"Country Code, OR search with |" ` // Moments
State string ` form:"state" example:"state:\"Baden-Württemberg\"" notes:"Name of State (Location), OR search with |" ` // Moments
2022-08-31 23:04:00 +02:00
City string ` form:"city" example:"city:\"Berlin\"" notes:"Name of City (Location), OR search with |" ` // Moments
2022-04-18 12:24:15 +02:00
Year string ` form:"year" example:"year:1990|2003" notes:"Year Number, OR search with |" ` // Moments
Month string ` form:"month" example:"month:7|10" notes:"Month (1-12), OR search with |" ` // Moments
Day string ` form:"day" example:"day:3|13" notes:"Day of Month (1-31), OR search with |" ` // Moments
2022-04-21 16:23:54 +02:00
Face string ` form:"face" example:"face:PN6QO5INYTUSAATOFL43LL2ABAV5ACZG" notes:"Face ID" ` // UIDs
2022-04-18 12:24:15 +02:00
Subject string ` form:"subject" example:"subject:\"Jane Doe & John Doe\"" notes:"Alias for person" ` // UIDs
Person string ` form:"person" example:"person:\"Jane Doe & John Doe\"" notes:"Subject Names, exact matches, can be combined with & and |" ` // Alias for Subject
Subjects string ` form:"subjects" example:"subjects:\"Jane & John\"" notes:"Alias for people" ` // People names
People string ` form:"people" example:"people:\"Jane & John\"" notes:"Subject Names, can be combined with & and |" ` // Alias for Subjects
Album string ` form:"album" example:"album:berlin" notes:"Album UID or Name, supports * wildcards" ` // Album UIDs or name
Albums string ` form:"albums" example:"albums:\"South Africa & Birds\"" notes:"Album Names, can be combined with & and |" ` // Multi search with and/or
Color string ` form:"color" example:"color:\"red|blue\"" notes:"Color Name (purple, magenta, pink, red, orange, gold, yellow, lime, green, teal, cyan, blue, brown, white, grey, black), OR search with |" ` // Main color
Faces string ` form:"faces" example:"faces:yes faces:3" notes:"Minimum number of Faces (yes = 1)" ` // Find or exclude faces if detected.
Quality int ` form:"quality" notes:"Quality Score (0-7)" ` // Photo quality score
Review bool ` form:"review" notes:"Finds pictures in review" ` // Find photos in review
Camera string ` form:"camera" example:"camera:canon" notes:"Camera Make/Model Name" ` // Camera UID or name
Lens string ` form:"lens" example:"lens:ef24" notes:"Lens Make/Model Name" ` // Lens UID or name
Before time . Time ` form:"before" time_format:"2006-01-02" notes:"Finds pictures taken before this date" ` // Finds images taken before date
After time . Time ` form:"after" time_format:"2006-01-02" notes:"Finds pictures taken after this date" ` // Finds images taken after date
Count int ` form:"count" binding:"required" serialize:"-" ` // Result FILE limit
Offset int ` form:"offset" serialize:"-" ` // Result FILE offset
Order string ` form:"order" serialize:"-" ` // Sort order
Merged bool ` form:"merged" serialize:"-" ` // Merge FILES in response
2019-05-15 21:51:00 +02:00
}
2021-11-26 13:59:10 +01:00
func ( f * SearchPhotos ) GetQuery ( ) string {
2020-01-15 04:04:33 +01:00
return f . Query
}
2019-05-15 21:51:00 +02:00
2021-11-26 13:59:10 +01:00
func ( f * SearchPhotos ) SetQuery ( q string ) {
2020-01-15 04:04:33 +01:00
f . Query = q
}
2019-05-15 23:07:25 +02:00
2021-11-26 13:59:10 +01:00
func ( f * SearchPhotos ) ParseQueryString ( ) error {
2020-05-30 01:41:47 +02:00
if err := ParseQueryString ( f ) ; err != nil {
return err
}
2020-05-21 16:46:22 +02:00
2022-08-01 15:57:19 +02:00
if f . Path != "" {
f . Folder = ""
} else if f . Folder != "" {
2020-05-21 16:46:22 +02:00
f . Path = f . Folder
2021-09-20 12:36:59 +02:00
f . Folder = ""
2020-05-21 16:46:22 +02:00
}
2022-08-01 15:57:19 +02:00
if f . Subject != "" {
f . Person = ""
} else if f . Person != "" {
2021-09-20 12:36:59 +02:00
f . Subject = f . Person
f . Person = ""
}
2022-08-01 15:57:19 +02:00
if f . Subjects != "" {
f . People = ""
} else if f . People != "" {
2021-08-29 16:16:49 +02:00
f . Subjects = f . People
2021-09-20 12:36:59 +02:00
f . People = ""
2021-08-29 16:16:49 +02:00
}
2020-05-30 01:41:47 +02:00
if f . Filter != "" {
if err := Unserialize ( f , f . Filter ) ; err != nil {
return err
}
}
2022-08-31 16:22:28 +02:00
// Strip file extensions if any.
if f . Name != "" {
f . Name = fs . StripKnownExt ( f . Name )
}
2020-05-30 01:41:47 +02:00
return nil
2018-08-15 09:59:51 +02:00
}
2020-02-02 13:01:26 +01:00
2020-05-23 20:58:58 +02:00
// Serialize returns a string containing non-empty fields and values of a struct.
2021-11-26 13:59:10 +01:00
func ( f * SearchPhotos ) Serialize ( ) string {
2020-05-23 20:58:58 +02:00
return Serialize ( f , false )
}
// SerializeAll returns a string containing all non-empty fields and values of a struct.
2021-11-26 13:59:10 +01:00
func ( f * SearchPhotos ) SerializeAll ( ) string {
2020-05-23 20:58:58 +02:00
return Serialize ( f , true )
}
2022-09-30 00:42:19 +02:00
// FindUidOnly checks if search filters other than UID may be skipped to improve performance.
func ( f * SearchPhotos ) FindUidOnly ( ) bool {
2022-09-30 19:15:10 +02:00
return f . UID != "" && f . Query == "" && f . Scope == "" && f . Filter == "" && f . Album == "" && f . Albums == ""
2022-09-30 00:42:19 +02:00
}
2022-09-30 19:15:10 +02:00
func NewSearchPhotos ( query string ) SearchPhotos {
2021-11-26 13:59:10 +01:00
return SearchPhotos { Query : query }
2020-02-02 13:01:26 +01:00
}