2019-05-06 23:18:10 +02:00
|
|
|
package config
|
2019-05-03 18:57:28 +02:00
|
|
|
|
|
|
|
import (
|
2019-06-03 22:58:15 +02:00
|
|
|
"context"
|
2020-01-02 00:03:07 +01:00
|
|
|
"runtime"
|
2020-01-13 11:07:09 +01:00
|
|
|
"strings"
|
2020-01-31 15:29:06 +01:00
|
|
|
"sync"
|
2019-05-03 18:57:28 +02:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
|
|
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
2019-12-02 00:30:58 +01:00
|
|
|
gc "github.com/patrickmn/go-cache"
|
|
|
|
"github.com/photoprism/photoprism/internal/event"
|
2020-01-19 12:50:44 +01:00
|
|
|
"github.com/photoprism/photoprism/internal/mutex"
|
2020-01-06 14:32:15 +01:00
|
|
|
"github.com/photoprism/photoprism/internal/thumb"
|
2019-12-02 00:30:58 +01:00
|
|
|
"github.com/sirupsen/logrus"
|
2019-05-03 18:57:28 +02:00
|
|
|
"github.com/urfave/cli"
|
|
|
|
)
|
|
|
|
|
2019-12-02 00:30:58 +01:00
|
|
|
var log = event.Log
|
|
|
|
|
2020-02-21 01:14:45 +01:00
|
|
|
// Config holds database, cache and all parameters of photoprism
|
2019-05-06 23:18:10 +02:00
|
|
|
type Config struct {
|
2019-05-03 18:57:28 +02:00
|
|
|
db *gorm.DB
|
2019-12-02 00:30:58 +01:00
|
|
|
cache *gc.Cache
|
2019-05-06 23:18:10 +02:00
|
|
|
config *Params
|
2019-05-03 18:57:28 +02:00
|
|
|
}
|
|
|
|
|
2020-01-06 14:32:15 +01:00
|
|
|
func init() {
|
2020-02-21 01:14:45 +01:00
|
|
|
// initialize the Thumbnails global variable
|
2020-01-06 14:32:15 +01:00
|
|
|
for name, t := range thumb.Types {
|
|
|
|
if t.Public {
|
|
|
|
thumbnail := Thumbnail{Name: name, Width: t.Width, Height: t.Height}
|
|
|
|
Thumbnails = append(Thumbnails, thumbnail)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-04 09:11:33 +02:00
|
|
|
func initLogger(debug bool) {
|
2020-01-31 15:29:06 +01:00
|
|
|
var once sync.Once
|
|
|
|
|
|
|
|
once.Do(func() {
|
|
|
|
log.SetFormatter(&logrus.TextFormatter{
|
|
|
|
DisableColors: false,
|
|
|
|
FullTimestamp: true,
|
|
|
|
})
|
|
|
|
|
|
|
|
if debug {
|
|
|
|
log.SetLevel(logrus.DebugLevel)
|
|
|
|
} else {
|
|
|
|
log.SetLevel(logrus.InfoLevel)
|
|
|
|
}
|
2019-05-03 18:57:28 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-02-21 01:14:45 +01:00
|
|
|
// NewConfig initialises a new configuration file
|
2019-05-06 23:18:10 +02:00
|
|
|
func NewConfig(ctx *cli.Context) *Config {
|
2019-05-04 05:25:00 +02:00
|
|
|
initLogger(ctx.GlobalBool("debug"))
|
2019-05-03 18:57:28 +02:00
|
|
|
|
2019-05-14 16:04:17 +02:00
|
|
|
c := &Config{
|
|
|
|
config: NewParams(ctx),
|
|
|
|
}
|
2019-05-03 18:57:28 +02:00
|
|
|
|
|
|
|
log.SetLevel(c.LogLevel())
|
|
|
|
|
2020-01-06 14:32:15 +01:00
|
|
|
thumb.JpegQuality = c.ThumbQuality()
|
2020-01-13 11:07:09 +01:00
|
|
|
thumb.PreRenderSize = c.ThumbSize()
|
|
|
|
thumb.MaxRenderSize = c.ThumbLimit()
|
2020-01-13 13:46:05 +01:00
|
|
|
thumb.Filter = c.ThumbFilter()
|
2020-01-06 14:32:15 +01:00
|
|
|
|
2019-05-03 18:57:28 +02:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
// Name returns the application name.
|
2019-05-06 23:18:10 +02:00
|
|
|
func (c *Config) Name() string {
|
2019-05-03 18:57:28 +02:00
|
|
|
return c.config.Name
|
|
|
|
}
|
|
|
|
|
2019-12-11 14:10:20 +01:00
|
|
|
// Url returns the public server URL (default is "http://localhost:2342/").
|
|
|
|
func (c *Config) Url() string {
|
|
|
|
if c.config.Url == "" {
|
|
|
|
return "http://localhost:2342/"
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.config.Url
|
|
|
|
}
|
|
|
|
|
|
|
|
// Title returns the site title (default is application name).
|
|
|
|
func (c *Config) Title() string {
|
|
|
|
if c.config.Title == "" {
|
|
|
|
return c.Name()
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.config.Title
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subtitle returns the site title.
|
|
|
|
func (c *Config) Subtitle() string {
|
|
|
|
return c.config.Subtitle
|
|
|
|
}
|
|
|
|
|
|
|
|
// Description returns the site title.
|
|
|
|
func (c *Config) Description() string {
|
|
|
|
return c.config.Description
|
|
|
|
}
|
|
|
|
|
|
|
|
// Author returns the site author / copyright.
|
|
|
|
func (c *Config) Author() string {
|
|
|
|
return c.config.Author
|
|
|
|
}
|
|
|
|
|
2020-02-21 01:14:45 +01:00
|
|
|
// Twitter returns the twitter handle for sharing.
|
2019-12-11 14:10:20 +01:00
|
|
|
func (c *Config) Twitter() string {
|
|
|
|
return c.config.Twitter
|
|
|
|
}
|
|
|
|
|
2019-05-03 18:57:28 +02:00
|
|
|
// Version returns the application version.
|
2019-05-06 23:18:10 +02:00
|
|
|
func (c *Config) Version() string {
|
2019-05-03 18:57:28 +02:00
|
|
|
return c.config.Version
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copyright returns the application copyright.
|
2019-05-06 23:18:10 +02:00
|
|
|
func (c *Config) Copyright() string {
|
2019-05-03 18:57:28 +02:00
|
|
|
return c.config.Copyright
|
|
|
|
}
|
|
|
|
|
|
|
|
// Debug returns true if Debug mode is on.
|
2019-05-06 23:18:10 +02:00
|
|
|
func (c *Config) Debug() bool {
|
2019-05-03 18:57:28 +02:00
|
|
|
return c.config.Debug
|
|
|
|
}
|
|
|
|
|
2019-11-11 21:10:41 +01:00
|
|
|
// Public returns true if app requires no authentication.
|
|
|
|
func (c *Config) Public() bool {
|
|
|
|
return c.config.Public
|
|
|
|
}
|
|
|
|
|
2019-12-30 12:38:11 +01:00
|
|
|
// Experimental returns true if experimental features should be enabled.
|
|
|
|
func (c *Config) Experimental() bool {
|
|
|
|
return c.config.Experimental
|
|
|
|
}
|
|
|
|
|
2019-05-04 09:11:33 +02:00
|
|
|
// ReadOnly returns true if photo directories are write protected.
|
2019-05-06 23:18:10 +02:00
|
|
|
func (c *Config) ReadOnly() bool {
|
2019-05-04 09:11:33 +02:00
|
|
|
return c.config.ReadOnly
|
|
|
|
}
|
|
|
|
|
2020-01-13 16:48:32 +01:00
|
|
|
// DetectNSFW returns true if NSFW photos should be detected and flagged.
|
|
|
|
func (c *Config) DetectNSFW() bool {
|
|
|
|
return c.config.DetectNSFW
|
2019-12-15 17:19:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// UploadNSFW returns true if NSFW photos can be uploaded.
|
|
|
|
func (c *Config) UploadNSFW() bool {
|
|
|
|
return c.config.UploadNSFW
|
|
|
|
}
|
|
|
|
|
2019-11-08 06:53:40 +01:00
|
|
|
// AdminPassword returns the admin password.
|
|
|
|
func (c *Config) AdminPassword() string {
|
|
|
|
if c.config.AdminPassword == "" {
|
|
|
|
return "photoprism"
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.config.AdminPassword
|
|
|
|
}
|
|
|
|
|
2020-02-21 04:23:16 +01:00
|
|
|
// WebDAVPassword returns the WebDAV password for remote access.
|
|
|
|
func (c *Config) WebDAVPassword() string {
|
|
|
|
return c.config.WebDAVPassword
|
|
|
|
}
|
|
|
|
|
2019-05-03 18:57:28 +02:00
|
|
|
// LogLevel returns the logrus log level.
|
2019-12-02 00:30:58 +01:00
|
|
|
func (c *Config) LogLevel() logrus.Level {
|
2019-05-03 18:57:28 +02:00
|
|
|
if c.Debug() {
|
|
|
|
c.config.LogLevel = "debug"
|
|
|
|
}
|
|
|
|
|
2019-12-02 00:30:58 +01:00
|
|
|
if logLevel, err := logrus.ParseLevel(c.config.LogLevel); err == nil {
|
2019-05-03 18:57:28 +02:00
|
|
|
return logLevel
|
|
|
|
} else {
|
2019-12-02 00:30:58 +01:00
|
|
|
return logrus.InfoLevel
|
2019-05-03 18:57:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-08 06:53:40 +01:00
|
|
|
// Cache returns the in-memory cache.
|
|
|
|
func (c *Config) Cache() *gc.Cache {
|
|
|
|
if c.cache == nil {
|
|
|
|
c.cache = gc.New(336*time.Hour, 30*time.Minute)
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.cache
|
|
|
|
}
|
|
|
|
|
2019-06-03 22:58:15 +02:00
|
|
|
// Init initialises the Database.
|
|
|
|
func (c *Config) Init(ctx context.Context) error {
|
|
|
|
return c.connectToDatabase(ctx)
|
|
|
|
}
|
|
|
|
|
2020-01-19 12:50:44 +01:00
|
|
|
// Shutdown services and workers.
|
2019-05-06 23:18:10 +02:00
|
|
|
func (c *Config) Shutdown() {
|
2020-01-19 12:50:44 +01:00
|
|
|
mutex.Worker.Cancel()
|
|
|
|
|
2019-05-04 17:34:51 +02:00
|
|
|
if err := c.CloseDb(); err != nil {
|
|
|
|
log.Errorf("could not close database connection: %s", err)
|
|
|
|
} else {
|
|
|
|
log.Info("closed database connection")
|
|
|
|
}
|
|
|
|
}
|
2019-11-12 04:34:37 +01:00
|
|
|
|
2020-01-02 00:03:07 +01:00
|
|
|
// Workers returns the number of workers e.g. for indexing files.
|
2020-01-02 04:08:33 +01:00
|
|
|
func (c *Config) Workers() int {
|
2020-03-09 00:51:10 +01:00
|
|
|
numCPU := runtime.NumCPU()
|
|
|
|
|
|
|
|
if c.config.Workers > 0 && c.config.Workers <= numCPU {
|
2020-01-06 23:43:19 +01:00
|
|
|
return c.config.Workers
|
|
|
|
}
|
|
|
|
|
2020-03-09 00:51:10 +01:00
|
|
|
if numCPU > 1 {
|
|
|
|
return numCPU - 1
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1
|
2019-11-12 04:34:37 +01:00
|
|
|
}
|
2020-01-06 06:59:35 +01:00
|
|
|
|
2020-01-06 14:32:15 +01:00
|
|
|
// ThumbQuality returns the thumbnail jpeg quality setting (25-100).
|
2020-01-06 06:59:35 +01:00
|
|
|
func (c *Config) ThumbQuality() int {
|
2020-01-06 14:32:15 +01:00
|
|
|
if c.config.ThumbQuality > 100 {
|
|
|
|
return 100
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.config.ThumbQuality < 25 {
|
|
|
|
return 25
|
|
|
|
}
|
|
|
|
|
2020-01-06 06:59:35 +01:00
|
|
|
return c.config.ThumbQuality
|
|
|
|
}
|
|
|
|
|
2020-01-13 11:07:09 +01:00
|
|
|
// ThumbSize returns the pre-rendered thumbnail size limit in pixels (720-3840).
|
2020-01-06 06:59:35 +01:00
|
|
|
func (c *Config) ThumbSize() int {
|
2020-01-13 11:07:09 +01:00
|
|
|
if c.config.ThumbSize > 3840 {
|
|
|
|
return 3840
|
2020-01-06 14:32:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if c.config.ThumbSize < 720 {
|
|
|
|
return 720
|
|
|
|
}
|
|
|
|
|
2020-01-06 06:59:35 +01:00
|
|
|
return c.config.ThumbSize
|
|
|
|
}
|
|
|
|
|
2020-01-13 11:07:09 +01:00
|
|
|
// ThumbLimit returns the on-demand thumbnail size limit in pixels (720-3840).
|
|
|
|
func (c *Config) ThumbLimit() int {
|
|
|
|
if c.config.ThumbLimit > 3840 {
|
|
|
|
return 3840
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.config.ThumbLimit < 720 {
|
|
|
|
return 720
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.config.ThumbLimit
|
|
|
|
}
|
|
|
|
|
2020-01-13 13:46:05 +01:00
|
|
|
// ThumbFilter returns the thumbnail resample filter (blackman, lanczos, cubic or linear).
|
|
|
|
func (c *Config) ThumbFilter() thumb.ResampleFilter {
|
|
|
|
switch strings.ToLower(c.config.ThumbFilter) {
|
2020-01-13 12:25:16 +01:00
|
|
|
case "blackman":
|
|
|
|
return thumb.ResampleBlackman
|
2020-01-13 11:07:09 +01:00
|
|
|
case "lanczos":
|
|
|
|
return thumb.ResampleLanczos
|
|
|
|
case "cubic":
|
|
|
|
return thumb.ResampleCubic
|
|
|
|
case "linear":
|
|
|
|
return thumb.ResampleLinear
|
|
|
|
default:
|
2020-01-13 12:25:16 +01:00
|
|
|
return thumb.ResampleCubic
|
2020-01-13 11:07:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 06:59:35 +01:00
|
|
|
// GeoCodingApi returns the preferred geo coding api (none, osm or places).
|
|
|
|
func (c *Config) GeoCodingApi() string {
|
|
|
|
switch c.config.GeoCodingApi {
|
|
|
|
case "places":
|
|
|
|
return "places"
|
|
|
|
case "osm":
|
|
|
|
return "osm"
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|