2020-05-08 15:41:01 +02:00
|
|
|
package query
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gosimple/slug"
|
|
|
|
"github.com/photoprism/photoprism/internal/entity"
|
|
|
|
"github.com/photoprism/photoprism/pkg/rnd"
|
|
|
|
"github.com/ulule/deepcopier"
|
|
|
|
)
|
|
|
|
|
2020-05-11 14:49:00 +02:00
|
|
|
// PhotosResult contains found photos and their main file plus other meta data.
|
|
|
|
type PhotosResult struct {
|
2020-05-08 15:41:01 +02:00
|
|
|
// Photo
|
|
|
|
ID uint
|
|
|
|
CreatedAt time.Time
|
|
|
|
UpdatedAt time.Time
|
|
|
|
DeletedAt time.Time
|
|
|
|
TakenAt time.Time
|
|
|
|
TakenAtLocal time.Time
|
|
|
|
TakenSrc string
|
|
|
|
TimeZone string
|
|
|
|
PhotoUUID string
|
|
|
|
PhotoPath string
|
|
|
|
PhotoName string
|
|
|
|
PhotoTitle string
|
|
|
|
PhotoYear int
|
|
|
|
PhotoMonth int
|
|
|
|
PhotoCountry string
|
|
|
|
PhotoFavorite bool
|
|
|
|
PhotoPrivate bool
|
2020-05-13 15:36:42 +02:00
|
|
|
PhotoVideo bool
|
2020-05-08 15:41:01 +02:00
|
|
|
PhotoLat float32
|
|
|
|
PhotoLng float32
|
|
|
|
PhotoAltitude int
|
|
|
|
PhotoIso int
|
|
|
|
PhotoFocalLength int
|
|
|
|
PhotoFNumber float32
|
|
|
|
PhotoExposure string
|
|
|
|
PhotoQuality int
|
|
|
|
PhotoResolution int
|
|
|
|
Merged bool
|
|
|
|
|
|
|
|
// Camera
|
|
|
|
CameraID uint
|
|
|
|
CameraModel string
|
|
|
|
CameraMake string
|
|
|
|
|
|
|
|
// Lens
|
|
|
|
LensID uint
|
|
|
|
LensModel string
|
|
|
|
LensMake string
|
|
|
|
|
|
|
|
// Location
|
|
|
|
LocationID string
|
|
|
|
PlaceID string
|
|
|
|
LocLabel string
|
|
|
|
LocCity string
|
|
|
|
LocState string
|
|
|
|
LocCountry string
|
|
|
|
|
|
|
|
// File
|
|
|
|
FileID uint
|
|
|
|
FileUUID string
|
|
|
|
FilePrimary bool
|
|
|
|
FileMissing bool
|
2020-05-13 15:36:42 +02:00
|
|
|
FileVideo bool
|
|
|
|
FileLength time.Duration
|
2020-05-08 15:41:01 +02:00
|
|
|
FileName string
|
|
|
|
FileHash string
|
|
|
|
FileType string
|
|
|
|
FileMime string
|
|
|
|
FileWidth int
|
|
|
|
FileHeight int
|
2020-05-14 11:57:26 +02:00
|
|
|
FileSize int64
|
2020-05-08 15:41:01 +02:00
|
|
|
FileOrientation int
|
|
|
|
FileAspectRatio float32
|
|
|
|
FileColors string // todo: remove from result?
|
|
|
|
FileChroma uint8 // todo: remove from result?
|
|
|
|
FileLuminance string // todo: remove from result?
|
|
|
|
FileDiff uint32 // todo: remove from result?
|
|
|
|
|
|
|
|
Files []entity.File
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:49:00 +02:00
|
|
|
type PhotosResults []PhotosResult
|
2020-05-08 15:41:01 +02:00
|
|
|
|
2020-05-11 14:49:00 +02:00
|
|
|
func (m PhotosResults) Merged() (PhotosResults, int, error) {
|
2020-05-08 15:41:01 +02:00
|
|
|
count := len(m)
|
2020-05-11 14:49:00 +02:00
|
|
|
merged := make([]PhotosResult, 0, count)
|
2020-05-08 15:41:01 +02:00
|
|
|
|
|
|
|
var lastId uint
|
|
|
|
var i int
|
|
|
|
|
|
|
|
for _, res := range m {
|
|
|
|
file := entity.File{}
|
|
|
|
|
|
|
|
if err := deepcopier.Copy(&file).From(res); err != nil {
|
|
|
|
return merged, count, err
|
|
|
|
}
|
|
|
|
|
|
|
|
file.ID = res.FileID
|
|
|
|
|
|
|
|
if lastId == res.ID && i > 0 {
|
|
|
|
merged[i-1].Files = append(merged[i-1].Files, file)
|
|
|
|
merged[i-1].Merged = true
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
lastId = res.ID
|
|
|
|
|
|
|
|
res.Files = append(res.Files, file)
|
|
|
|
merged = append(merged, res)
|
|
|
|
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
|
|
|
|
return merged, count, nil
|
|
|
|
}
|
|
|
|
|
2020-05-11 14:49:00 +02:00
|
|
|
func (m *PhotosResult) ShareFileName() string {
|
2020-05-08 15:41:01 +02:00
|
|
|
var name string
|
|
|
|
|
|
|
|
if m.PhotoTitle != "" {
|
|
|
|
name = strings.Title(slug.MakeLang(m.PhotoTitle, "en"))
|
|
|
|
} else {
|
|
|
|
name = m.PhotoUUID
|
|
|
|
}
|
|
|
|
|
|
|
|
taken := m.TakenAtLocal.Format("20060102-150405")
|
|
|
|
token := rnd.Token(3)
|
|
|
|
|
|
|
|
result := fmt.Sprintf("%s-%s-%s.%s", taken, name, token, m.FileType)
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|