photoprism/internal/entity/search/batch.go
Ömer Duran 1e00d1f52e
UX: Add batch edit dialog and API endpoints #271 #5324
Signed-off-by: Michael Mayer <michael@photoprism.app>
Co-authored-by: Michael Mayer <michael@photoprism.app>
Co-authored-by: graciousgrey <theresagresch@gmail.com>
2025-11-19 11:20:34 +01:00

105 lines
6.4 KiB
Go

package search
import (
"strings"
"time"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/txt"
)
// BatchResult represents a photo geo search result.
type BatchResult struct {
ID uint `json:"-" select:"photos.id"`
CompositeID string `json:"ID,omitempty" select:"files.photo_id AS composite_id"`
UUID string `json:"DocumentID,omitempty" select:"photos.uuid"`
PhotoUID string `json:"UID" select:"photos.photo_uid"`
PhotoType string `json:"Type" select:"photos.photo_type"`
TypeSrc string `json:"TypeSrc" select:"photos.taken_src"`
PhotoTitle string `json:"Title" select:"photos.photo_title"`
PhotoCaption string `json:"Caption,omitempty" select:"photos.photo_caption"`
TakenAt time.Time `json:"TakenAt" select:"photos.taken_at"`
TakenAtLocal time.Time `json:"TakenAtLocal" select:"photos.taken_at_local"`
TimeZone string `json:"TimeZone" select:"photos.time_zone"`
PhotoYear int `json:"Year" select:"photos.photo_year"`
PhotoMonth int `json:"Month" select:"photos.photo_month"`
PhotoDay int `json:"Day" select:"photos.photo_day"`
PhotoCountry string `json:"Country" select:"photos.photo_country"`
PhotoStack int8 `json:"Stack" select:"photos.photo_stack"`
PhotoFavorite bool `json:"Favorite" select:"photos.photo_favorite"`
PhotoPrivate bool `json:"Private" select:"photos.photo_private"`
PhotoIso int `json:"Iso" select:"photos.photo_iso"`
PhotoFocalLength int `json:"FocalLength" select:"photos.photo_focal_length"`
PhotoFNumber float32 `json:"FNumber" select:"photos.photo_f_number"`
PhotoExposure string `json:"Exposure" select:"photos.photo_exposure"`
PhotoFaces int `json:"Faces,omitempty" select:"photos.photo_faces"`
PhotoQuality int `json:"Quality" select:"photos.photo_quality"`
PhotoResolution int `json:"Resolution" select:"photos.photo_resolution"`
PhotoDuration time.Duration `json:"Duration,omitempty" select:"photos.photo_duration"`
PhotoColor int16 `json:"Color" select:"photos.photo_color"`
PhotoScan bool `json:"Scan" select:"photos.photo_scan"`
PhotoPanorama bool `json:"Panorama" select:"photos.photo_panorama"`
CameraID uint `json:"CameraID" select:"photos.camera_id"` // Camera
CameraSrc string `json:"CameraSrc,omitempty" select:"photos.camera_src"`
CameraSerial string `json:"CameraSerial,omitempty" select:"photos.camera_serial"`
CameraMake string `json:"CameraMake,omitempty" select:"cameras.camera_make"`
CameraModel string `json:"CameraModel,omitempty" select:"cameras.camera_model"`
CameraType string `json:"CameraType,omitempty" select:"cameras.camera_type"`
LensID uint `json:"LensID" select:"photos.lens_id"` // Lens
LensMake string `json:"LensMake,omitempty" select:"lenses.lens_model"`
LensModel string `json:"LensModel,omitempty" select:"lenses.lens_make"`
PhotoAltitude int `json:"Altitude,omitempty" select:"photos.photo_altitude"`
PhotoLat float64 `json:"Lat" select:"photos.photo_lat"`
PhotoLng float64 `json:"Lng" select:"photos.photo_lng"`
FileID uint `json:"-" select:"files.id AS file_id"` // File
FileUID string `json:"FileUID" select:"files.file_uid"`
FileRoot string `json:"FileRoot" select:"files.file_root"`
FileName string `json:"FileName" select:"files.file_name"`
OriginalName string `json:"OriginalName" select:"files.original_name"`
FileHash string `json:"Hash" select:"files.file_hash"`
FileWidth int `json:"Width" select:"files.file_width"`
FileHeight int `json:"Height" select:"files.file_height"`
FilePortrait bool `json:"Portrait" select:"files.file_portrait"`
FilePrimary bool `json:"-" select:"files.file_primary"`
FileSidecar bool `json:"-" select:"files.file_sidecar"`
FileMissing bool `json:"-" select:"files.file_missing"`
FileVideo bool `json:"-" select:"files.file_video"`
FileDuration time.Duration `json:"-" select:"files.file_duration"`
FileFPS float64 `json:"-" select:"files.file_fps"`
FileFrames int `json:"-" select:"files.file_frames"`
FilePages int `json:"-" select:"files.file_pages"`
FileCodec string `json:"-" select:"files.file_codec"`
FileType string `json:"-" select:"files.file_type"`
MediaType string `json:"-" select:"files.media_type"`
FileMime string `json:"-" select:"files.file_mime"`
FileSize int64 `json:"-" select:"files.file_size"`
FileOrientation int `json:"-" select:"files.file_orientation"`
FileProjection string `json:"-" select:"files.file_projection"`
FileAspectRatio float32 `json:"-" select:"files.file_aspect_ratio"`
DetailsKeywords string `json:"DetailsKeywords" select:"details.keywords AS details_keywords"`
DetailsSubject string `json:"DetailsSubject" select:"details.subject AS details_subject"`
DetailsArtist string `json:"DetailsArtist" select:"details.artist AS details_artist"`
DetailsCopyright string `json:"DetailsCopyright" select:"details.copyright AS details_copyright"`
DetailsLicense string `json:"DetailsLicense" select:"details.license AS details_license"`
}
// BatchCols contains the result column names necessary for the photo viewer.
var BatchCols = SelectString(BatchResult{}, SelectCols(BatchResult{}, []string{"*"}))
// BatchPhotos finds PhotoResults based on the search form without checking rights or permissions.
func BatchPhotos(uids []string, sess *entity.Session) (results PhotoResults, count int, err error) {
frm := form.SearchPhotos{
UID: strings.Join(uids, txt.Or),
Quality: 0, // Don't filter by quality.
Review: false, // Don't limit search to photos in review.
Details: true, // Include values from details table.
Merged: true, // Group files by photo.
Count: MaxResults,
Offset: 0,
}
return searchPhotos(frm, sess, BatchCols)
}