2022-04-22 17:38:40 +02:00
|
|
|
package commands
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/urfave/cli"
|
|
|
|
|
|
|
|
"github.com/photoprism/photoprism/internal/config"
|
|
|
|
"github.com/photoprism/photoprism/pkg/report"
|
|
|
|
)
|
|
|
|
|
2022-05-10 20:47:45 +02:00
|
|
|
// 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,
|
2022-04-22 17:38:40 +02:00
|
|
|
}
|
|
|
|
|
2022-05-10 20:47:45 +02:00
|
|
|
var faceOptionsInfo = `!!! info ""
|
|
|
|
To [recognize faces](https://docs.photoprism.app/user-guide/organize/people/), PhotoPrism first extracts crops from your images using a
|
2022-04-22 17:38:40 +02:00
|
|
|
[library](https://github.com/esimov/pigo) based on [pixel intensity comparisons](https://arxiv.org/pdf/1305.4537.pdf).
|
|
|
|
These are then fed into TensorFlow to compute [512-dimensional vectors](https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Schroff_FaceNet_A_Unified_2015_CVPR_paper.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:`
|
|
|
|
|
2022-05-10 20:47:45 +02:00
|
|
|
// showOptionsAction shows environment variable command-line parameter names.
|
|
|
|
func showOptionsAction(ctx *cli.Context) error {
|
2022-04-22 17:38:40 +02:00
|
|
|
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.Render(rows, cols, report.CliFormat(ctx))
|
|
|
|
|
|
|
|
fmt.Println(result)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
type Section struct {
|
|
|
|
Start string
|
|
|
|
Caption string
|
|
|
|
Info string
|
|
|
|
}
|
|
|
|
|
|
|
|
s := []Section{
|
|
|
|
{Start: "PHOTOPRISM_ADMIN_PASSWORD", Caption: "Authentication"},
|
|
|
|
{Start: "PHOTOPRISM_LOG_LEVEL", Caption: "Logging"},
|
|
|
|
{Start: "PHOTOPRISM_CONFIG_PATH", Caption: "Storage"},
|
|
|
|
{Start: "PHOTOPRISM_WORKERS", Caption: "Index Workers"},
|
|
|
|
{Start: "PHOTOPRISM_READONLY", Caption: "Feature Flags"},
|
|
|
|
{Start: "PHOTOPRISM_DEFAULT_LOCALE", Caption: "Customization"},
|
|
|
|
{Start: "PHOTOPRISM_CDN_URL", Caption: "Site Information"},
|
|
|
|
{Start: "PHOTOPRISM_HTTP_PORT", Caption: "Web Server"},
|
|
|
|
{Start: "PHOTOPRISM_DATABASE_DRIVER", Caption: "Database Connection"},
|
|
|
|
{Start: "PHOTOPRISM_DARKTABLE_BIN", Caption: "File Converters"},
|
|
|
|
{Start: "PHOTOPRISM_DOWNLOAD_TOKEN", Caption: "Security Tokens"},
|
|
|
|
{Start: "PHOTOPRISM_THUMB_COLOR", Caption: "Image Quality"},
|
|
|
|
{Start: "PHOTOPRISM_FACE_SIZE", Caption: "Face Recognition",
|
2022-05-10 20:47:45 +02:00
|
|
|
Info: faceOptionsInfo},
|
2022-04-22 17:38:40 +02:00
|
|
|
{Start: "PHOTOPRISM_PID_FILENAME", Caption: "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.Caption)
|
|
|
|
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.Render(secRows, cols, report.CliFormat(ctx))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(result)
|
|
|
|
|
|
|
|
if j >= len(rows) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|