mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Docs: Add command that generates an overview of YAML config values
see https://docs.photoprism.app/getting-started/config-files/ Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -7,9 +7,10 @@ import (
|
||||
// ShowCommand registers the show subcommands.
|
||||
var ShowCommand = cli.Command{
|
||||
Name: "show",
|
||||
Usage: "Shows supported formats, standards, and features",
|
||||
Usage: "Shows supported formats, features, and config options",
|
||||
Subcommands: []cli.Command{
|
||||
ShowConfigCommand,
|
||||
ShowFlagsCommand,
|
||||
ShowOptionsCommand,
|
||||
ShowFiltersCommand,
|
||||
ShowFormatsCommand,
|
||||
|
||||
112
internal/commands/show_flags.go
Normal file
112
internal/commands/show_flags.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/pkg/report"
|
||||
)
|
||||
|
||||
// ShowFlagsCommand configures the command name, flags, and action.
|
||||
var ShowFlagsCommand = cli.Command{
|
||||
Name: "flags",
|
||||
Usage: "Displays supported environment variables and CLI flags",
|
||||
Flags: report.CliFlags,
|
||||
Action: showFlagsAction,
|
||||
}
|
||||
|
||||
var faceFlagsInfo = `!!! info ""
|
||||
To [recognize faces](https://docs.photoprism.app/user-guide/organize/people/), PhotoPrism first extracts crops from your images using a [library](https://github.com/esimov/pigo) based on [pixel intensity comparisons](https://dl.photoprism.app/pdf/20140820-Pixel_Intensity_Comparisons.pdf). These are then fed into TensorFlow to compute [512-dimensional vectors](https://dl.photoprism.app/pdf/20150101-FaceNet.pdf) for characterization. In the final step, the [DBSCAN algorithm](https://en.wikipedia.org/wiki/DBSCAN) attempts to cluster these so-called face embeddings, so they can be matched to persons with just a few clicks. A reasonable range for the similarity distance between face embeddings is between 0.60 and 0.70, with a higher value being more aggressive and leading to larger clusters with more false positives. To cluster a smaller number of faces, you can reduce the core to 3 or 2 similar faces.
|
||||
|
||||
We recommend that only advanced users change these parameters:`
|
||||
|
||||
// showFlagsAction shows environment variable command-line parameter names.
|
||||
func showFlagsAction(ctx *cli.Context) error {
|
||||
conf := config.NewConfig(ctx)
|
||||
conf.SetLogLevel(logrus.FatalLevel)
|
||||
|
||||
rows, cols := config.Flags.Report()
|
||||
|
||||
// CSV Export?
|
||||
if ctx.Bool("csv") || ctx.Bool("tsv") {
|
||||
result, err := report.RenderFormat(rows, cols, report.CliFormat(ctx))
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
type Section struct {
|
||||
Start string
|
||||
Title string
|
||||
Info string
|
||||
}
|
||||
|
||||
s := []Section{
|
||||
{Start: "PHOTOPRISM_ADMIN_PASSWORD", Title: "Authentication"},
|
||||
{Start: "PHOTOPRISM_LOG_LEVEL", Title: "Logging"},
|
||||
{Start: "PHOTOPRISM_CONFIG_PATH", Title: "Storage"},
|
||||
{Start: "PHOTOPRISM_WORKERS", Title: "Index Workers"},
|
||||
{Start: "PHOTOPRISM_READONLY", Title: "Feature Flags"},
|
||||
{Start: "PHOTOPRISM_DEFAULT_LOCALE", Title: "Customization"},
|
||||
{Start: "PHOTOPRISM_CDN_URL", Title: "Site Information"},
|
||||
{Start: "PHOTOPRISM_TRUSTED_PROXY", Title: "Web Server"},
|
||||
{Start: "PHOTOPRISM_DATABASE_DRIVER", Title: "Database Connection"},
|
||||
{Start: "PHOTOPRISM_DARKTABLE_BIN", Title: "File Converters"},
|
||||
{Start: "PHOTOPRISM_DOWNLOAD_TOKEN", Title: "Security Tokens"},
|
||||
{Start: "PHOTOPRISM_THUMB_COLOR", Title: "Image Quality"},
|
||||
{Start: "PHOTOPRISM_FACE_SIZE", Title: "Face Recognition",
|
||||
Info: faceFlagsInfo},
|
||||
{Start: "PHOTOPRISM_PID_FILENAME", Title: "Daemon Mode",
|
||||
Info: "If you start the server as a *daemon* in the background, you can additionally specify a filename for the log and the process ID:"},
|
||||
}
|
||||
|
||||
j := 0
|
||||
|
||||
for i, sec := range s {
|
||||
fmt.Printf("### %s ###\n\n", sec.Title)
|
||||
if sec.Info != "" && ctx.Bool("md") {
|
||||
fmt.Printf("%s\n\n", sec.Info)
|
||||
}
|
||||
|
||||
secRows := make([][]string, 0, len(rows))
|
||||
|
||||
for {
|
||||
row := rows[j]
|
||||
|
||||
if len(row) < 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
if i < len(s)-1 {
|
||||
if s[i+1].Start == row[0] {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
secRows = append(secRows, row)
|
||||
j++
|
||||
|
||||
if j >= len(rows) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
result, err := report.RenderFormat(secRows, cols, report.CliFormat(ctx))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
|
||||
if j >= len(rows) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -12,24 +12,18 @@ import (
|
||||
|
||||
// ShowOptionsCommand configures the command name, flags, and action.
|
||||
var ShowOptionsCommand = cli.Command{
|
||||
Name: "options",
|
||||
Aliases: []string{"flags"},
|
||||
Usage: "Displays supported config flags and variable names",
|
||||
Flags: report.CliFlags,
|
||||
Action: showOptionsAction,
|
||||
Name: "options",
|
||||
Usage: "Displays supported YAML config options and CLI flags",
|
||||
Flags: report.CliFlags,
|
||||
Action: showOptionsAction,
|
||||
}
|
||||
|
||||
var faceOptionsInfo = `!!! info ""
|
||||
To [recognize faces](https://docs.photoprism.app/user-guide/organize/people/), PhotoPrism first extracts crops from your images using a [library](https://github.com/esimov/pigo) based on [pixel intensity comparisons](https://dl.photoprism.app/pdf/20140820-Pixel_Intensity_Comparisons.pdf). These are then fed into TensorFlow to compute [512-dimensional vectors](https://dl.photoprism.app/pdf/20150101-FaceNet.pdf) for characterization. In the final step, the [DBSCAN algorithm](https://en.wikipedia.org/wiki/DBSCAN) attempts to cluster these so-called face embeddings, so they can be matched to persons with just a few clicks. A reasonable range for the similarity distance between face embeddings is between 0.60 and 0.70, with a higher value being more aggressive and leading to larger clusters with more false positives. To cluster a smaller number of faces, you can reduce the core to 3 or 2 similar faces.
|
||||
|
||||
We recommend that only advanced users change these parameters:`
|
||||
|
||||
// showOptionsAction shows environment variable command-line parameter names.
|
||||
// showOptionsAction shows supported YAML config file options.
|
||||
func showOptionsAction(ctx *cli.Context) error {
|
||||
conf := config.NewConfig(ctx)
|
||||
conf.SetLogLevel(logrus.FatalLevel)
|
||||
conf.SetLogLevel(logrus.TraceLevel)
|
||||
|
||||
rows, cols := config.Flags.Report()
|
||||
rows, cols := conf.Options().Report()
|
||||
|
||||
// CSV Export?
|
||||
if ctx.Bool("csv") || ctx.Bool("tsv") {
|
||||
@@ -47,21 +41,19 @@ func showOptionsAction(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
s := []Section{
|
||||
{Start: "PHOTOPRISM_ADMIN_PASSWORD", Title: "Authentication"},
|
||||
{Start: "PHOTOPRISM_LOG_LEVEL", Title: "Logging"},
|
||||
{Start: "PHOTOPRISM_CONFIG_PATH", Title: "Storage"},
|
||||
{Start: "PHOTOPRISM_WORKERS", Title: "Index Workers"},
|
||||
{Start: "PHOTOPRISM_READONLY", Title: "Feature Flags"},
|
||||
{Start: "PHOTOPRISM_DEFAULT_LOCALE", Title: "Customization"},
|
||||
{Start: "PHOTOPRISM_CDN_URL", Title: "Site Information"},
|
||||
{Start: "PHOTOPRISM_TRUSTED_PROXY", Title: "Web Server"},
|
||||
{Start: "PHOTOPRISM_DATABASE_DRIVER", Title: "Database Connection"},
|
||||
{Start: "PHOTOPRISM_DARKTABLE_BIN", Title: "File Converters"},
|
||||
{Start: "PHOTOPRISM_DOWNLOAD_TOKEN", Title: "Security Tokens"},
|
||||
{Start: "PHOTOPRISM_THUMB_COLOR", Title: "Image Quality"},
|
||||
{Start: "PHOTOPRISM_FACE_SIZE", Title: "Face Recognition",
|
||||
Info: faceOptionsInfo},
|
||||
{Start: "PHOTOPRISM_PID_FILENAME", Title: "Daemon Mode",
|
||||
{Start: "AuthMode", Title: "Authentication"},
|
||||
{Start: "LogLevel", Title: "Logging"},
|
||||
{Start: "ConfigPath", Title: "Storage"},
|
||||
{Start: "Workers", Title: "Index Workers"},
|
||||
{Start: "ReadOnly", Title: "Feature Flags"},
|
||||
{Start: "DefaultTheme", Title: "Customization"},
|
||||
{Start: "CdnUrl", Title: "Site Information"},
|
||||
{Start: "TrustedProxies", Title: "Web Server"},
|
||||
{Start: "DatabaseDriver", Title: "Database Connection"},
|
||||
{Start: "DarktableBin", Title: "File Converters"},
|
||||
{Start: "DownloadToken", Title: "Security Tokens"},
|
||||
{Start: "ThumbColor", Title: "Image Quality"},
|
||||
{Start: "PIDFilename", Title: "Daemon Mode",
|
||||
Info: "If you start the server as a *daemon* in the background, you can additionally specify a filename for the log and the process ID:"},
|
||||
}
|
||||
|
||||
|
||||
@@ -451,6 +451,22 @@ var Flags = CliFlags{
|
||||
Usage: "disable HTTPS even if a certificate is available",
|
||||
EnvVar: "PHOTOPRISM_DISABLE_TLS",
|
||||
}}, {
|
||||
Flag: cli.StringFlag{
|
||||
Name: "tls-email",
|
||||
Usage: "`EMAIL` address to enable automatic HTTPS via Let's Encrypt",
|
||||
EnvVar: "PHOTOPRISM_TLS_EMAIL",
|
||||
Hidden: true,
|
||||
}}, {
|
||||
Flag: cli.StringFlag{
|
||||
Name: "tls-cert",
|
||||
Usage: "public HTTPS certificate `FILE` (.crt)",
|
||||
EnvVar: "PHOTOPRISM_TLS_CERT",
|
||||
}}, {
|
||||
Flag: cli.StringFlag{
|
||||
Name: "tls-key",
|
||||
Usage: "private HTTPS key `FILE` (.key)",
|
||||
EnvVar: "PHOTOPRISM_TLS_KEY",
|
||||
}}, {
|
||||
Flag: cli.StringFlag{
|
||||
Name: "database-driver, db",
|
||||
Usage: "database `DRIVER` (sqlite, mysql)",
|
||||
|
||||
@@ -38,10 +38,8 @@ type Options struct {
|
||||
Trace bool `yaml:"Trace" json:"Trace" flag:"trace"`
|
||||
Test bool `yaml:"-" json:"Test,omitempty" flag:"test"`
|
||||
Unsafe bool `yaml:"-" json:"-" flag:"unsafe"`
|
||||
Demo bool `yaml:"Demo" json:"-" flag:"demo"`
|
||||
Demo bool `yaml:"-" json:"-" flag:"demo"`
|
||||
Sponsor bool `yaml:"-" json:"-" flag:"sponsor"`
|
||||
ReadOnly bool `yaml:"ReadOnly" json:"ReadOnly" flag:"read-only"`
|
||||
Experimental bool `yaml:"Experimental" json:"Experimental" flag:"experimental"`
|
||||
ConfigPath string `yaml:"ConfigPath" json:"-" flag:"config-path"`
|
||||
DefaultsYaml string `json:"-" yaml:"-" flag:"defaults-yaml"`
|
||||
OriginalsPath string `yaml:"OriginalsPath" json:"-" flag:"originals-path"`
|
||||
@@ -61,6 +59,8 @@ type Options struct {
|
||||
WakeupInterval time.Duration `yaml:"WakeupInterval" json:"WakeupInterval" flag:"wakeup-interval"`
|
||||
AutoIndex int `yaml:"AutoIndex" json:"AutoIndex" flag:"auto-index"`
|
||||
AutoImport int `yaml:"AutoImport" json:"AutoImport" flag:"auto-import"`
|
||||
ReadOnly bool `yaml:"ReadOnly" json:"ReadOnly" flag:"read-only"`
|
||||
Experimental bool `yaml:"Experimental" json:"Experimental" flag:"experimental"`
|
||||
DisableWebDAV bool `yaml:"DisableWebDAV" json:"DisableWebDAV" flag:"disable-webdav"`
|
||||
DisableBackups bool `yaml:"DisableBackups" json:"DisableBackups" flag:"disable-backups"`
|
||||
DisableSettings bool `yaml:"DisableSettings" json:"-" flag:"disable-settings"`
|
||||
@@ -102,7 +102,7 @@ type Options struct {
|
||||
HttpHost string `yaml:"HttpHost" json:"-" flag:"http-host"`
|
||||
HttpPort int `yaml:"HttpPort" json:"-" flag:"http-port"`
|
||||
DisableTLS bool `yaml:"DisableTLS" json:"DisableTLS" flag:"disable-tls"`
|
||||
TLSEmail string `yaml:"TLSEmail" json:"TLSEmail" flag:"tls-email"` // TLSEmail enabled automatic HTTPS via Let's Encrypt if set a valid email address.
|
||||
TLSEmail string `yaml:"TLSEmail" json:"TLSEmail" flag:"tls-email"`
|
||||
TLSCert string `yaml:"TLSCert" json:"TLSCert" flag:"tls-cert"`
|
||||
TLSKey string `yaml:"TLSKey" json:"TLSKey" flag:"tls-key"`
|
||||
DatabaseDriver string `yaml:"DatabaseDriver" json:"-" flag:"database-driver"`
|
||||
@@ -126,7 +126,6 @@ type Options struct {
|
||||
FFmpegEncoder string `yaml:"FFmpegEncoder" json:"FFmpegEncoder" flag:"ffmpeg-encoder"`
|
||||
FFmpegBitrate int `yaml:"FFmpegBitrate" json:"FFmpegBitrate" flag:"ffmpeg-bitrate"`
|
||||
ExifToolBin string `yaml:"ExifToolBin" json:"-" flag:"exiftool-bin"`
|
||||
DetachServer bool `yaml:"DetachServer" json:"-" flag:"detach-server"`
|
||||
DownloadToken string `yaml:"DownloadToken" json:"-" flag:"download-token"`
|
||||
PreviewToken string `yaml:"PreviewToken" json:"-" flag:"preview-token"`
|
||||
ThumbColor string `yaml:"ThumbColor" json:"ThumbColor" flag:"thumb-color"`
|
||||
@@ -146,6 +145,7 @@ type Options struct {
|
||||
FaceMatchDist float64 `yaml:"-" json:"-" flag:"face-match-dist"`
|
||||
PIDFilename string `yaml:"PIDFilename" json:"-" flag:"pid-filename"`
|
||||
LogFilename string `yaml:"LogFilename" json:"-" flag:"log-filename"`
|
||||
DetachServer bool `yaml:"DetachServer" json:"-" flag:"detach-server"`
|
||||
}
|
||||
|
||||
// NewOptions creates a new configuration entity by using two methods:
|
||||
|
||||
32
internal/config/options_report.go
Normal file
32
internal/config/options_report.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Report returns global config values as a table for reporting.
|
||||
func (c Options) Report() (rows [][]string, cols []string) {
|
||||
v := reflect.ValueOf(c)
|
||||
|
||||
cols = []string{"Name", "Type", "CLI Flag"}
|
||||
rows = make([][]string, 0, v.NumField())
|
||||
|
||||
// Iterate through all config fields.
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
fieldValue := v.Field(i)
|
||||
|
||||
yamlName := v.Type().Field(i).Tag.Get("yaml")
|
||||
flagName := v.Type().Field(i).Tag.Get("flag")
|
||||
|
||||
if yamlName == "" || yamlName == "-" || flagName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldType := fmt.Sprintf("%T", fieldValue.Interface())
|
||||
|
||||
rows = append(rows, []string{yamlName, fieldType, "--" + flagName})
|
||||
}
|
||||
|
||||
return rows, cols
|
||||
}
|
||||
Reference in New Issue
Block a user