2020-01-02 00:03:07 +01:00
package config
import (
"strings"
"time"
"github.com/photoprism/photoprism/internal/entity"
2020-01-13 11:07:09 +01:00
"github.com/photoprism/photoprism/pkg/colors"
2020-01-12 14:00:56 +01:00
"github.com/photoprism/photoprism/pkg/fs"
2020-04-26 14:31:33 +02:00
"github.com/photoprism/photoprism/pkg/txt"
2020-01-02 00:03:07 +01:00
)
2020-12-18 20:42:12 +01:00
// ClientConfig represents HTTP client / Web UI config options.
2020-05-27 19:38:40 +02:00
type ClientConfig struct {
2020-12-25 20:30:18 +01:00
Mode string ` json:"mode" `
2020-05-27 19:38:40 +02:00
Name string ` json:"name" `
Version string ` json:"version" `
Copyright string ` json:"copyright" `
2020-05-31 02:09:52 +02:00
Flags string ` json:"flags" `
SiteUrl string ` json:"siteUrl" `
2020-06-26 14:26:36 +02:00
SitePreview string ` json:"sitePreview" `
2020-05-31 02:09:52 +02:00
SiteTitle string ` json:"siteTitle" `
SiteCaption string ` json:"siteCaption" `
SiteDescription string ` json:"siteDescription" `
SiteAuthor string ` json:"siteAuthor" `
2020-05-27 19:38:40 +02:00
Debug bool ` json:"debug" `
2020-12-18 10:59:21 +01:00
Demo bool ` json:"demo" `
2020-05-27 19:38:40 +02:00
ReadOnly bool ` json:"readonly" `
UploadNSFW bool ` json:"uploadNSFW" `
Public bool ` json:"public" `
Experimental bool ` json:"experimental" `
2020-05-30 21:11:56 +02:00
AlbumCategories [ ] string ` json:"albumCategories" `
2020-05-27 19:38:40 +02:00
Albums [ ] entity . Album ` json:"albums" `
Cameras [ ] entity . Camera ` json:"cameras" `
Lenses [ ] entity . Lens ` json:"lenses" `
Countries [ ] entity . Country ` json:"countries" `
2020-07-13 17:25:27 +02:00
Thumbs [ ] Thumb ` json:"thumbs" `
2020-10-04 22:22:53 +02:00
Status string ` json:"status" `
2020-10-04 04:47:54 +02:00
MapKey string ` json:"mapKey" `
2020-05-27 19:38:40 +02:00
DownloadToken string ` json:"downloadToken" `
2020-05-27 19:56:56 +02:00
PreviewToken string ` json:"previewToken" `
2020-05-27 19:38:40 +02:00
JSHash string ` json:"jsHash" `
CSSHash string ` json:"cssHash" `
2021-01-08 18:32:08 +01:00
ManifestHash string ` json:"manifestHash" `
2020-05-27 19:38:40 +02:00
Settings Settings ` json:"settings" `
2020-12-18 09:11:42 +01:00
Disable ClientDisable ` json:"disable" `
2020-05-27 19:38:40 +02:00
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" `
}
2020-12-18 09:11:42 +01:00
// ClientDisable represents disabled client features a user can't turn back on.
type ClientDisable struct {
2020-12-18 20:42:12 +01:00
Backups bool ` json:"backups" `
WebDAV bool ` json:"webdav" `
Settings bool ` json:"settings" `
Places bool ` json:"places" `
ExifTool bool ` json:"exiftool" `
TensorFlow bool ` json:"tensorflow" `
2020-12-18 09:11:42 +01:00
}
// ClientCounts represents photo, video and album counts for the client UI.
2020-05-27 19:38:40 +02:00
type ClientCounts struct {
2021-01-11 14:06:48 +01:00
All int ` json:"all" `
Photos int ` json:"photos" `
Videos int ` json:"videos" `
2020-05-30 01:41:47 +02:00
Cameras int ` json:"cameras" `
Lenses int ` json:"lenses" `
Countries int ` json:"countries" `
Hidden int ` json:"hidden" `
Favorites int ` json:"favorites" `
Private int ` json:"private" `
Review int ` json:"review" `
Stories int ` json:"stories" `
Albums int ` json:"albums" `
Moments int ` json:"moments" `
Months int ` json:"months" `
Folders int ` json:"folders" `
Files int ` json:"files" `
Places int ` json:"places" `
2020-06-08 18:32:51 +02:00
States int ` json:"states" `
2020-05-30 01:41:47 +02:00
Labels int ` json:"labels" `
LabelMaxPhotos int ` json:"labelMaxPhotos" `
2020-05-27 19:38:40 +02:00
}
type CategoryLabel struct {
LabelUID string ` json:"UID" `
CustomSlug string ` json:"Slug" `
LabelName string ` json:"Name" `
}
type ClientPosition struct {
2020-07-11 23:43:29 +02:00
PhotoUID string ` json:"uid" `
2020-07-12 08:27:05 +02:00
CellID string ` json:"cid" `
2020-07-11 23:43:29 +02:00
TakenAt time . Time ` json:"utc" `
PhotoLat float64 ` json:"lat" `
PhotoLng float64 ` json:"lng" `
2020-05-27 19:38:40 +02:00
}
2020-01-02 00:03:07 +01:00
2020-04-12 18:00:31 +02:00
// Flags returns config flags as string slice.
func ( c * Config ) Flags ( ) ( flags [ ] string ) {
2020-01-22 16:54:01 +01:00
if c . Public ( ) {
flags = append ( flags , "public" )
}
2020-04-12 18:00:31 +02:00
2020-01-22 16:54:01 +01:00
if c . Debug ( ) {
flags = append ( flags , "debug" )
}
2020-04-12 18:00:31 +02:00
2020-01-22 16:54:01 +01:00
if c . Experimental ( ) {
flags = append ( flags , "experimental" )
}
2020-04-12 18:00:31 +02:00
2020-01-22 16:54:01 +01:00
if c . ReadOnly ( ) {
flags = append ( flags , "readonly" )
}
2020-12-18 09:11:42 +01:00
if ! c . DisableSettings ( ) {
2020-04-12 18:00:31 +02:00
flags = append ( flags , "settings" )
}
2020-12-13 14:53:26 +01:00
if ! c . Settings ( ) . UI . Scrollbar {
flags = append ( flags , "hide-scrollbar" )
}
2020-04-12 18:00:31 +02:00
return flags
}
2020-12-18 20:42:12 +01:00
// PublicConfig returns public client config options with as little information as possible.
2020-06-22 20:15:08 +02:00
func ( c * Config ) PublicConfig ( ) ClientConfig {
2020-04-12 18:00:31 +02:00
if c . Public ( ) {
2020-06-25 01:20:58 +02:00
return c . UserConfig ( )
2020-04-12 18:00:31 +02:00
}
2020-05-27 19:38:40 +02:00
settings := c . Settings ( )
2020-01-22 16:54:01 +01:00
result := ClientConfig {
2020-06-22 20:41:18 +02:00
Settings : Settings {
2020-12-13 14:53:26 +01:00
UI : settings . UI ,
2020-06-23 12:37:37 +02:00
Maps : settings . Maps ,
Features : settings . Features ,
2020-12-13 14:53:26 +01:00
Share : settings . Share ,
2020-06-22 20:41:18 +02:00
} ,
2020-12-18 09:11:42 +01:00
Disable : ClientDisable {
2020-12-18 20:42:12 +01:00
Backups : true ,
WebDAV : true ,
Settings : c . DisableSettings ( ) ,
Places : c . DisablePlaces ( ) ,
ExifTool : true ,
TensorFlow : true ,
2020-12-18 09:11:42 +01:00
} ,
2020-05-31 02:09:52 +02:00
Flags : strings . Join ( c . Flags ( ) , " " ) ,
2020-12-25 20:30:18 +01:00
Mode : "public" ,
2020-05-31 02:09:52 +02:00
Name : c . Name ( ) ,
SiteUrl : c . SiteUrl ( ) ,
2020-06-26 14:26:36 +02:00
SitePreview : c . SitePreview ( ) ,
2020-05-31 02:09:52 +02:00
SiteTitle : c . SiteTitle ( ) ,
SiteCaption : c . SiteCaption ( ) ,
SiteDescription : c . SiteDescription ( ) ,
SiteAuthor : c . SiteAuthor ( ) ,
Version : c . Version ( ) ,
Copyright : c . Copyright ( ) ,
Debug : c . Debug ( ) ,
2020-12-18 10:59:21 +01:00
Demo : c . Demo ( ) ,
2020-05-31 02:09:52 +02:00
ReadOnly : c . ReadOnly ( ) ,
Public : c . Public ( ) ,
Experimental : c . Experimental ( ) ,
2020-10-04 22:22:53 +02:00
Status : "" ,
2020-10-04 04:47:54 +02:00
MapKey : "" ,
2020-07-13 17:25:27 +02:00
Thumbs : Thumbs ,
2020-05-31 02:09:52 +02:00
Colors : colors . All . List ( ) ,
2020-06-26 16:11:56 +02:00
JSHash : fs . Checksum ( c . BuildPath ( ) + "/app.js" ) ,
CSSHash : fs . Checksum ( c . BuildPath ( ) + "/app.css" ) ,
2021-01-08 18:32:08 +01:00
ManifestHash : fs . Checksum ( c . StaticPath ( ) + "/manifest.json" ) ,
2020-05-31 02:09:52 +02:00
Clip : txt . ClipDefault ,
PreviewToken : "public" ,
DownloadToken : "public" ,
2020-01-22 16:54:01 +01:00
}
return result
}
2020-12-18 20:42:12 +01:00
// GuestConfig returns client config options for the sharing with guests.
2020-06-25 01:20:58 +02:00
func ( c * Config ) GuestConfig ( ) ClientConfig {
2020-06-22 20:15:08 +02:00
settings := c . Settings ( )
result := ClientConfig {
2020-06-22 20:41:18 +02:00
Settings : Settings {
2020-12-13 14:53:26 +01:00
UI : settings . UI ,
2020-06-23 12:37:37 +02:00
Maps : settings . Maps ,
Features : settings . Features ,
2020-12-13 14:53:26 +01:00
Share : settings . Share ,
2020-06-22 20:41:18 +02:00
} ,
2020-12-18 09:11:42 +01:00
Disable : ClientDisable {
2020-12-18 20:42:12 +01:00
Backups : true ,
WebDAV : c . DisableWebDAV ( ) ,
Settings : c . DisableSettings ( ) ,
Places : c . DisablePlaces ( ) ,
ExifTool : true ,
TensorFlow : true ,
2020-12-18 09:11:42 +01:00
} ,
2020-06-22 20:15:08 +02:00
Flags : "readonly public shared" ,
2020-12-25 20:30:18 +01:00
Mode : "guest" ,
2020-06-22 20:15:08 +02:00
Name : c . Name ( ) ,
SiteUrl : c . SiteUrl ( ) ,
2020-06-26 14:26:36 +02:00
SitePreview : c . SitePreview ( ) ,
2020-06-22 20:15:08 +02:00
SiteTitle : c . SiteTitle ( ) ,
SiteCaption : c . SiteCaption ( ) ,
SiteDescription : c . SiteDescription ( ) ,
SiteAuthor : c . SiteAuthor ( ) ,
Version : c . Version ( ) ,
Copyright : c . Copyright ( ) ,
Debug : c . Debug ( ) ,
2020-12-18 10:59:21 +01:00
Demo : c . Demo ( ) ,
2020-06-22 20:15:08 +02:00
ReadOnly : true ,
UploadNSFW : c . UploadNSFW ( ) ,
Public : true ,
Experimental : false ,
Colors : colors . All . List ( ) ,
2020-07-13 17:25:27 +02:00
Thumbs : Thumbs ,
2020-12-04 13:10:32 +01:00
Status : c . Hub ( ) . Status ,
MapKey : c . Hub ( ) . MapKey ( ) ,
2020-06-22 20:15:08 +02:00
DownloadToken : c . DownloadToken ( ) ,
PreviewToken : c . PreviewToken ( ) ,
2020-06-26 16:11:56 +02:00
JSHash : fs . Checksum ( c . BuildPath ( ) + "/share.js" ) ,
CSSHash : fs . Checksum ( c . BuildPath ( ) + "/share.css" ) ,
2021-01-08 18:32:08 +01:00
ManifestHash : fs . Checksum ( c . StaticPath ( ) + "/manifest.json" ) ,
2020-06-22 20:15:08 +02:00
Clip : txt . ClipDefault ,
}
return result
}
2020-12-18 20:42:12 +01:00
// UserConfig returns client configuration options for registered users.
2020-06-25 01:20:58 +02:00
func ( c * Config ) UserConfig ( ) ClientConfig {
2020-05-27 19:38:40 +02:00
result := ClientConfig {
2020-12-18 09:11:42 +01:00
Settings : * c . Settings ( ) ,
Disable : ClientDisable {
2020-12-18 20:42:12 +01:00
Backups : c . DisableBackups ( ) ,
WebDAV : c . DisableWebDAV ( ) ,
Settings : c . DisableSettings ( ) ,
Places : c . DisablePlaces ( ) ,
ExifTool : c . DisableExifTool ( ) ,
TensorFlow : c . DisableTensorFlow ( ) ,
2020-12-18 09:11:42 +01:00
} ,
2020-05-27 19:38:40 +02:00
Flags : strings . Join ( c . Flags ( ) , " " ) ,
2020-12-25 20:30:18 +01:00
Mode : "user" ,
2020-05-27 19:38:40 +02:00
Name : c . Name ( ) ,
2020-05-31 02:09:52 +02:00
SiteUrl : c . SiteUrl ( ) ,
2020-06-26 14:26:36 +02:00
SitePreview : c . SitePreview ( ) ,
2020-05-31 02:09:52 +02:00
SiteTitle : c . SiteTitle ( ) ,
SiteCaption : c . SiteCaption ( ) ,
SiteDescription : c . SiteDescription ( ) ,
SiteAuthor : c . SiteAuthor ( ) ,
2020-05-27 19:38:40 +02:00
Version : c . Version ( ) ,
Copyright : c . Copyright ( ) ,
Debug : c . Debug ( ) ,
2020-12-18 10:59:21 +01:00
Demo : c . Demo ( ) ,
2020-05-27 19:38:40 +02:00
ReadOnly : c . ReadOnly ( ) ,
UploadNSFW : c . UploadNSFW ( ) ,
Public : c . Public ( ) ,
Experimental : c . Experimental ( ) ,
Colors : colors . All . List ( ) ,
2020-07-13 17:25:27 +02:00
Thumbs : Thumbs ,
2020-12-04 13:10:32 +01:00
Status : c . Hub ( ) . Status ,
MapKey : c . Hub ( ) . MapKey ( ) ,
2020-05-27 19:38:40 +02:00
DownloadToken : c . DownloadToken ( ) ,
2020-05-27 19:56:56 +02:00
PreviewToken : c . PreviewToken ( ) ,
2020-06-26 16:11:56 +02:00
JSHash : fs . Checksum ( c . BuildPath ( ) + "/app.js" ) ,
CSSHash : fs . Checksum ( c . BuildPath ( ) + "/app.css" ) ,
2021-01-08 18:32:08 +01:00
ManifestHash : fs . Checksum ( c . StaticPath ( ) + "/manifest.json" ) ,
2020-05-27 19:38:40 +02:00
Clip : txt . ClipDefault ,
Server : NewRuntimeInfo ( ) ,
2020-01-02 00:03:07 +01:00
}
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "photos" ) .
2020-07-12 08:27:05 +02:00
Select ( "photo_uid, cell_id, photo_lat, photo_lng, taken_at" ) .
2020-01-02 00:03:07 +01:00
Where ( "deleted_at IS NULL AND photo_lat != 0 AND photo_lng != 0" ) .
Order ( "taken_at DESC" ) .
Limit ( 1 ) . Offset ( 0 ) .
2020-05-27 19:38:40 +02:00
Take ( & result . Pos )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "cameras" ) .
2020-05-29 18:04:30 +02:00
Where ( "camera_slug <> 'zz' AND camera_slug <> ''" ) .
Select ( "COUNT(*) AS cameras" ) .
Take ( & result . Count )
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "lenses" ) .
2020-05-29 18:04:30 +02:00
Where ( "lens_slug <> 'zz' AND lens_slug <> ''" ) .
Select ( "COUNT(*) AS lenses" ) .
Take ( & result . Count )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "photos" ) .
2020-06-04 17:33:00 +02:00
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_private = 0 AND photo_quality >= 0) AS favorites, SUM(photo_private = 1 AND photo_quality >= 0) AS private" ) .
2020-05-18 15:45:55 +02:00
Where ( "photos.id NOT IN (SELECT photo_id FROM files WHERE file_primary = 1 AND (file_missing = 1 OR file_error <> ''))" ) .
2020-01-02 00:03:07 +01:00
Where ( "deleted_at IS NULL" ) .
2020-05-27 19:38:40 +02:00
Take ( & result . Count )
2020-01-02 00:03:07 +01:00
2021-01-11 14:06:48 +01:00
result . Count . All = result . Count . Photos + result . Count . Videos
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "labels" ) .
2020-05-10 19:43:49 +02:00
Select ( "MAX(photo_count) as label_max_photos, COUNT(*) AS labels" ) .
Where ( "photo_count > 0" ) .
Where ( "deleted_at IS NULL" ) .
2020-06-01 09:45:24 +02:00
Where ( "(label_priority >= 0 OR label_favorite = 1)" ) .
2020-05-27 19:38:40 +02:00
Take ( & result . Count )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "albums" ) .
2020-06-08 18:32:51 +02:00
Select ( "SUM(album_type = ?) AS albums, SUM(album_type = ?) AS moments, SUM(album_type = ?) AS months, SUM(album_type = ?) AS states, SUM(album_type = ?) AS folders" , entity . AlbumDefault , entity . AlbumMoment , entity . AlbumMonth , entity . AlbumState , entity . AlbumFolder ) .
2020-12-14 20:37:54 +01:00
Where ( "deleted_at IS NULL AND (albums.album_type <> 'folder' OR albums.album_path IN (SELECT photos.photo_path FROM photos WHERE photos.deleted_at IS NULL))" ) .
2020-05-27 19:38:40 +02:00
Take ( & result . Count )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "files" ) .
2020-05-24 22:16:06 +02:00
Select ( "COUNT(*) AS files" ) .
Where ( "file_missing = 0" ) .
Where ( "deleted_at IS NULL" ) .
2020-05-27 19:38:40 +02:00
Take ( & result . Count )
2020-05-24 22:16:06 +02:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "countries" ) .
2020-01-02 00:03:07 +01:00
Select ( "(COUNT(*) - 1) AS countries" ) .
2020-05-27 19:38:40 +02:00
Take ( & result . Count )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "places" ) .
2020-05-10 16:12:15 +02:00
Select ( "SUM(photo_count > 0) AS places" ) .
Where ( "id != 'zz'" ) .
2020-05-29 18:04:30 +02:00
Take ( & result . Count )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Order ( "country_slug" ) .
2020-05-27 19:38:40 +02:00
Find ( & result . Countries )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Where ( "id IN (SELECT photos.camera_id FROM photos WHERE photos.photo_quality >= 0 OR photos.deleted_at IS NULL)" ) .
Where ( "deleted_at IS NULL" ) .
2020-04-25 14:22:47 +02:00
Limit ( 10000 ) . Order ( "camera_slug" ) .
2020-05-27 19:38:40 +02:00
Find ( & result . Cameras )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Where ( "deleted_at IS NULL" ) .
2020-04-25 14:22:47 +02:00
Limit ( 10000 ) . Order ( "lens_slug" ) .
2020-05-27 19:38:40 +02:00
Find ( & result . Lenses )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Where ( "deleted_at IS NULL AND album_favorite = 1" ) .
2020-05-26 09:02:19 +02:00
Limit ( 20 ) . Order ( "album_title" ) .
2020-05-27 19:38:40 +02:00
Find ( & result . Albums )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "photos" ) .
Where ( "photo_year > 0 AND (photos.photo_quality >= 0 OR photos.deleted_at IS NULL)" ) .
2020-01-02 00:03:07 +01:00
Order ( "photo_year DESC" ) .
2020-05-27 19:38:40 +02:00
Pluck ( "DISTINCT photo_year" , & result . Years )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "categories" ) .
2020-05-23 20:58:58 +02:00
Select ( "l.label_uid, l.custom_slug, l.label_name" ) .
2020-01-02 00:03:07 +01:00
Joins ( "JOIN labels l ON categories.category_id = l.id" ) .
2020-05-23 20:58:58 +02:00
Where ( "l.deleted_at IS NULL" ) .
Group ( "l.custom_slug" ) .
Order ( "l.custom_slug" ) .
2020-01-02 00:03:07 +01:00
Limit ( 1000 ) . Offset ( 0 ) .
2020-05-27 19:38:40 +02:00
Scan ( & result . Categories )
2020-01-02 00:03:07 +01:00
2020-12-15 20:14:06 +01:00
c . Db ( ) .
Table ( "albums" ) .
2020-05-30 21:11:56 +02:00
Select ( "album_category" ) .
Where ( "deleted_at IS NULL AND album_category <> ''" ) .
Group ( "album_category" ) .
Order ( "album_category" ) .
Limit ( 1000 ) . Offset ( 0 ) .
Pluck ( "album_category" , & result . AlbumCategories )
2020-01-02 00:03:07 +01:00
return result
}