photoprism/internal/config/client.go

270 lines
8.5 KiB
Go
Raw Normal View History

package config
import (
"strings"
"time"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/pkg/capture"
"github.com/photoprism/photoprism/pkg/colors"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
// ClientConfig contains HTTP client / Web UI config values
type ClientConfig struct {
Flags string `json:"flags"`
Name string `json:"name"`
URL string `json:"url"`
Title string `json:"title"`
Subtitle string `json:"subtitle"`
Description string `json:"description"`
Author string `json:"author"`
Version string `json:"version"`
Copyright string `json:"copyright"`
Debug bool `json:"debug"`
ReadOnly bool `json:"readonly"`
UploadNSFW bool `json:"uploadNSFW"`
Public bool `json:"public"`
Experimental bool `json:"experimental"`
DisableSettings bool `json:"disableSettings"`
Albums []entity.Album `json:"albums"`
Cameras []entity.Camera `json:"cameras"`
Lenses []entity.Lens `json:"lenses"`
Countries []entity.Country `json:"countries"`
Thumbnails []Thumbnail `json:"thumbnails"`
DownloadToken string `json:"downloadToken"`
PreviewToken string `json:"previewToken"`
JSHash string `json:"jsHash"`
CSSHash string `json:"cssHash"`
Settings Settings `json:"settings"`
Count ClientCounts `json:"count"`
Pos ClientPosition `json:"pos"`
Years []int `json:"years"`
Colors []map[string]string `json:"colors"`
Categories []CategoryLabel `json:"categories"`
Clip int `json:"clip"`
Server RuntimeInfo `json:"server"`
}
type ClientCounts struct {
Photos uint `json:"photos"`
Videos uint `json:"videos"`
Hidden uint `json:"hidden"`
Favorites uint `json:"favorites"`
Private uint `json:"private"`
Review uint `json:"review"`
Stories uint `json:"stories"`
Albums uint `json:"albums"`
Folders uint `json:"folders"`
Files uint `json:"files"`
Moments uint `json:"moments"`
Countries uint `json:"countries"`
Places uint `json:"places"`
Labels uint `json:"labels"`
LabelMaxPhotos uint `json:"labelMaxPhotos"`
}
type CategoryLabel struct {
LabelUID string `json:"UID"`
CustomSlug string `json:"Slug"`
LabelName string `json:"Name"`
}
type ClientPosition struct {
PhotoUID string `json:"uid"`
LocUID string `json:"loc"`
TakenAt time.Time `json:"utc"`
PhotoLat float64 `json:"lat"`
PhotoLng float64 `json:"lng"`
}
// Flags returns config flags as string slice.
func (c *Config) Flags() (flags []string) {
if c.Public() {
flags = append(flags, "public")
}
if c.Debug() {
flags = append(flags, "debug")
}
if c.Experimental() {
flags = append(flags, "experimental")
}
if c.ReadOnly() {
flags = append(flags, "readonly")
}
if !c.DisableSettings() {
flags = append(flags, "settings")
}
return flags
}
// PublicClientConfig returns reduced config values for non-public sites.
func (c *Config) PublicClientConfig() ClientConfig {
if c.Public() {
return c.ClientConfig()
}
settings := c.Settings()
result := ClientConfig{
Settings: Settings{Language: settings.Language, Theme: settings.Theme},
Flags: strings.Join(c.Flags(), " "),
Name: c.Name(),
URL: c.Url(),
Title: c.Title(),
Subtitle: c.Subtitle(),
Description: c.Description(),
Author: c.Author(),
Version: c.Version(),
Copyright: c.Copyright(),
Debug: c.Debug(),
ReadOnly: c.ReadOnly(),
Public: c.Public(),
Experimental: c.Experimental(),
Thumbnails: Thumbnails,
Colors: colors.All.List(),
JSHash: fs.Checksum(c.HttpStaticBuildPath() + "/app.js"),
CSSHash: fs.Checksum(c.HttpStaticBuildPath() + "/app.css"),
Clip: txt.ClipDefault,
PreviewToken: "public",
DownloadToken: "public",
}
return result
}
// ClientConfig returns a loaded and set configuration entity.
func (c *Config) ClientConfig() ClientConfig {
defer log.Debug(capture.Time(time.Now(), "config: client config created"))
result := ClientConfig{
Settings: *c.Settings(),
Flags: strings.Join(c.Flags(), " "),
Name: c.Name(),
URL: c.Url(),
Title: c.Title(),
Subtitle: c.Subtitle(),
Description: c.Description(),
Author: c.Author(),
Version: c.Version(),
Copyright: c.Copyright(),
Debug: c.Debug(),
ReadOnly: c.ReadOnly(),
UploadNSFW: c.UploadNSFW(),
DisableSettings: c.DisableSettings(),
Public: c.Public(),
Experimental: c.Experimental(),
Colors: colors.All.List(),
Thumbnails: Thumbnails,
DownloadToken: c.DownloadToken(),
PreviewToken: c.PreviewToken(),
JSHash: fs.Checksum(c.HttpStaticBuildPath() + "/app.js"),
CSSHash: fs.Checksum(c.HttpStaticBuildPath() + "/app.css"),
Clip: txt.ClipDefault,
Server: NewRuntimeInfo(),
}
db := c.Db()
db.Table("photos").
Select("photo_uid, loc_uid, photo_lat, photo_lng, taken_at").
Where("deleted_at IS NULL AND photo_lat != 0 AND photo_lng != 0").
Order("taken_at DESC").
Limit(1).Offset(0).
Take(&result.Pos)
var count = struct {
Photos uint `json:"photos"`
Videos uint `json:"videos"`
Hidden uint `json:"hidden"`
Favorites uint `json:"favorites"`
Private uint `json:"private"`
Review uint `json:"review"`
Albums uint `json:"albums"`
Folders uint `json:"folders"`
Files uint `json:"files"`
Moments uint `json:"moments"`
Countries uint `json:"countries"`
Places uint `json:"places"`
Labels uint `json:"labels"`
LabelMaxPhotos uint `json:"labelMaxPhotos"`
}{}
db.Table("photos").
Select("SUM(photo_type = 'video' AND photo_quality >= 0 AND photo_private = 0) AS videos, SUM(photo_type IN ('image','raw','live') AND photo_quality < 3 AND photo_quality >= 0 AND photo_private = 0) AS review, SUM(photo_quality = -1) AS hidden, SUM(photo_type IN ('image','raw','live') AND photo_private = 0 AND photo_quality >= 0) AS photos, SUM(photo_favorite = 1 AND photo_quality >= 0) AS favorites, SUM(photo_private = 1 AND photo_quality >= 0) AS private").
Where("photos.id NOT IN (SELECT photo_id FROM files WHERE file_primary = 1 AND (file_missing = 1 OR file_error <> ''))").
Where("deleted_at IS NULL").
Take(&result.Count)
db.Table("labels").
Select("MAX(photo_count) as label_max_photos, COUNT(*) AS labels").
Where("photo_count > 0").
Where("deleted_at IS NULL").
Where("(label_priority >= 0 || label_favorite = 1)").
Take(&result.Count)
db.Table("albums").
Select("SUM(album_type = '') AS albums, SUM(album_type = 'moment') AS moments, SUM(album_type = 'folder') AS folders").
Where("deleted_at IS NULL").
Take(&result.Count)
db.Table("folders").
Select("COUNT(*) AS folders").
Where("folder_ignore = 0").
Where("deleted_at IS NULL").
Take(&result.Count)
db.Table("files").
Select("COUNT(*) AS files").
Where("file_missing = 0").
Where("deleted_at IS NULL").
Take(&result.Count)
db.Table("countries").
Select("(COUNT(*) - 1) AS countries").
Take(&result.Count)
db.Table("places").
Select("SUM(photo_count > 0) AS places").
Where("id != 'zz'").
Take(&count)
db.Order("country_slug").
Find(&result.Countries)
db.Where("deleted_at IS NULL").
Limit(10000).Order("camera_slug").
Find(&result.Cameras)
db.Where("deleted_at IS NULL").
Limit(10000).Order("lens_slug").
Find(&result.Lenses)
db.Where("deleted_at IS NULL AND album_favorite = 1").
Limit(20).Order("album_title").
Find(&result.Albums)
db.Table("photos").
Where("photo_year > 0").
Order("photo_year DESC").
Pluck("DISTINCT photo_year", &result.Years)
db.Table("categories").
Select("l.label_uid, l.custom_slug, l.label_name").
Joins("JOIN labels l ON categories.category_id = l.id").
Where("l.deleted_at IS NULL").
Group("l.custom_slug").
Order("l.custom_slug").
Limit(1000).Offset(0).
Scan(&result.Categories)
return result
}