diff --git a/cmd/photoprism/photoprism.go b/cmd/photoprism/photoprism.go index 5d25ce90f..f88634eda 100644 --- a/cmd/photoprism/photoprism.go +++ b/cmd/photoprism/photoprism.go @@ -57,21 +57,21 @@ func main() { commands.StopCommand, commands.IndexCommand, commands.ImportCommand, + commands.CopyCommand, commands.FacesCommand, - commands.MomentsCommand, - commands.OptimizeCommand, + commands.UsersCommand, + commands.PasswdCommand, commands.PurgeCommand, commands.CleanUpCommand, - commands.CopyCommand, commands.ConvertCommand, - commands.ResampleCommand, + commands.ThumbsCommand, + commands.OptimizeCommand, + commands.MomentsCommand, commands.MigrateCommand, commands.BackupCommand, commands.RestoreCommand, commands.ResetCommand, commands.ConfigCommand, - commands.UsersCommand, - commands.PasswdCommand, commands.VersionCommand, commands.StatusCommand, } diff --git a/internal/api/batch.go b/internal/api/batch.go index 580d7cd2e..29a88a8ea 100644 --- a/internal/api/batch.go +++ b/internal/api/batch.go @@ -193,7 +193,7 @@ func BatchPhotosApprove(router *gin.RouterGroup) { }) } -// BatchAlbumsDelete permanently deletes multiple albums. +// BatchAlbumsDelete permanently removes multiple albums. // // POST /api/v1/batch/albums/delete func BatchAlbumsDelete(router *gin.RouterGroup) { @@ -328,7 +328,7 @@ func BatchLabelsDelete(router *gin.RouterGroup) { }) } -// BatchPhotosDelete permanently deletes multiple photos from the archive. +// BatchPhotosDelete permanently removes multiple photos from the archive. // // POST /api/v1/batch/photos/delete func BatchPhotosDelete(router *gin.RouterGroup) { diff --git a/internal/commands/config.go b/internal/commands/config.go index 595ab24f9..74f1dad88 100644 --- a/internal/commands/config.go +++ b/internal/commands/config.go @@ -26,9 +26,12 @@ func configAction(ctx *cli.Context) error { fmt.Printf("%-25s VALUE\n", "NAME") - // Feature flags. + // Feature flags and auth. fmt.Printf("%-25s %t\n", "debug", conf.Debug()) + fmt.Printf("%-25s %s\n", "log-level", conf.LogLevel()) + fmt.Printf("%-25s %s\n", "log-filename", conf.LogFilename()) fmt.Printf("%-25s %t\n", "public", conf.Public()) + fmt.Printf("%-25s %s\n", "admin-password", strings.Repeat("*", utf8.RuneCountInString(conf.AdminPassword()))) fmt.Printf("%-25s %t\n", "read-only", conf.ReadOnly()) fmt.Printf("%-25s %t\n", "experimental", conf.Experimental()) @@ -84,8 +87,8 @@ func configAction(ctx *cli.Context) error { // Site information. fmt.Printf("%-25s %s\n", "site-url", conf.SiteUrl()) fmt.Printf("%-25s %s\n", "site-preview", conf.SitePreview()) - fmt.Printf("%-25s %s\n", "site-title", conf.SiteTitle()) fmt.Printf("%-25s %s\n", "site-author", conf.SiteAuthor()) + fmt.Printf("%-25s %s\n", "site-title", conf.SiteTitle()) fmt.Printf("%-25s %s\n", "site-caption", conf.SiteCaption()) fmt.Printf("%-25s %s\n", "site-description", conf.SiteDescription()) fmt.Printf("%-25s %s\n", "cdn-url", conf.CdnUrl("/")) @@ -94,19 +97,11 @@ func configAction(ctx *cli.Context) error { fmt.Printf("%-25s %s\n", "api-uri", conf.ApiUri()) fmt.Printf("%-25s %s\n", "base-uri", conf.BaseUri("/")) - // Logging. - fmt.Printf("%-25s %s\n", "log-level", conf.LogLevel()) - fmt.Printf("%-25s %s\n", "log-filename", conf.LogFilename()) - fmt.Printf("%-25s %s\n", "pid-filename", conf.PIDFilename()) - // HTTP server configuration. fmt.Printf("%-25s %s\n", "http-host", conf.HttpHost()) fmt.Printf("%-25s %d\n", "http-port", conf.HttpPort()) fmt.Printf("%-25s %s\n", "http-mode", conf.HttpMode()) - // Passwords. - fmt.Printf("%-25s %s\n", "admin-password", strings.Repeat("*", utf8.RuneCountInString(conf.AdminPassword()))) - // Database configuration. fmt.Printf("%-25s %s\n", "database-driver", dbDriver) fmt.Printf("%-25s %s\n", "database-server", conf.DatabaseServer()) @@ -153,5 +148,8 @@ func configAction(ctx *cli.Context) error { fmt.Printf("%-25s %f\n", "face-cluster-dist", conf.FaceClusterDist()) fmt.Printf("%-25s %f\n", "face-match-dist", conf.FaceMatchDist()) + // Other. + fmt.Printf("%-25s %s\n", "pid-filename", conf.PIDFilename()) + return nil } diff --git a/internal/commands/convert.go b/internal/commands/convert.go index 2a9746502..2fc41fa31 100644 --- a/internal/commands/convert.go +++ b/internal/commands/convert.go @@ -16,8 +16,8 @@ import ( // ConvertCommand registers the convert cli command. var ConvertCommand = cli.Command{ Name: "convert", - Usage: "Converts originals in other formats to JPEG and AVC sidecar files", - UsageText: `To limit scope, a sub folder may be passed as first argument.`, + Usage: "Converts media files to JPEG and AVC as needed", + UsageText: `To limit scope, a PATH may be passed as first argument.`, Action: convertAction, } diff --git a/internal/commands/copy.go b/internal/commands/copy.go index 1c4d87efa..0efe9d90b 100644 --- a/internal/commands/copy.go +++ b/internal/commands/copy.go @@ -16,9 +16,9 @@ import ( // CopyCommand registers the copy cli command. var CopyCommand = cli.Command{ - Name: "copy", - Aliases: []string{"cp"}, - Usage: "Copies files to originals folder, converts and indexes them as needed", + Name: "cp", + Aliases: []string{"copy"}, + Usage: "Copies media files to originals", Action: copyAction, } @@ -59,7 +59,7 @@ func copyAction(ctx *cli.Context) error { } if sourcePath == conf.OriginalsPath() { - return errors.New("import folder is identical with originals") + return errors.New("import path is identical with originals") } log.Infof("copying media files from %s to %s", sourcePath, conf.OriginalsPath()) diff --git a/internal/commands/faces.go b/internal/commands/faces.go index 36629c653..ba962beec 100644 --- a/internal/commands/faces.go +++ b/internal/commands/faces.go @@ -21,7 +21,7 @@ import ( // FacesCommand registers the faces cli command. var FacesCommand = cli.Command{ Name: "faces", - Usage: "Facial recognition sub-commands", + Usage: "Facial recognition commands", Subcommands: []cli.Command{ { Name: "stats", @@ -34,18 +34,18 @@ var FacesCommand = cli.Command{ Flags: []cli.Flag{ cli.BoolFlag{ Name: "fix, f", - Usage: "automatically fixes issues", + Usage: "fix discovered issues", }, }, Action: facesAuditAction, }, { Name: "reset", - Usage: "Removes people and faces", + Usage: "Removes people and faces after confirmation", Flags: []cli.Flag{ cli.BoolFlag{ Name: "force, f", - Usage: "removes all people and faces", + Usage: "remove all people and faces", }, }, Action: facesResetAction, @@ -62,7 +62,7 @@ var FacesCommand = cli.Command{ Flags: []cli.Flag{ cli.BoolFlag{ Name: "force, f", - Usage: "updates all faces", + Usage: "update all faces", }, }, Action: facesUpdateAction, @@ -184,7 +184,7 @@ func facesResetAction(ctx *cli.Context) error { // facesResetAllAction removes all people, faces, and face markers. func facesResetAllAction(ctx *cli.Context) error { actionPrompt := promptui.Prompt{ - Label: "Permanently delete all people and faces?", + Label: "Permanently remove all people and faces?", IsConfirm: true, } diff --git a/internal/commands/import.go b/internal/commands/import.go index 55924ce7a..a9d27193f 100644 --- a/internal/commands/import.go +++ b/internal/commands/import.go @@ -16,9 +16,9 @@ import ( // ImportCommand registers the import cli command. var ImportCommand = cli.Command{ - Name: "import", - Aliases: []string{"mv"}, - Usage: "Moves files to originals folder, converts and indexes them as needed", + Name: "mv", + Aliases: []string{"import"}, + Usage: "Moves media files to originals", Action: importAction, } @@ -59,7 +59,7 @@ func importAction(ctx *cli.Context) error { } if sourcePath == conf.OriginalsPath() { - return errors.New("import folder is identical with originals") + return errors.New("import path is identical with originals") } log.Infof("moving media files from %s to %s", sourcePath, conf.OriginalsPath()) diff --git a/internal/commands/index.go b/internal/commands/index.go index fef0dcd23..199806dfe 100644 --- a/internal/commands/index.go +++ b/internal/commands/index.go @@ -20,7 +20,7 @@ import ( // IndexCommand registers the index cli command. var IndexCommand = cli.Command{ Name: "index", - Usage: "indexes media files in the originals folder", + Usage: "Indexes original media files", ArgsUsage: "[path]", Flags: indexFlags, Action: indexAction, diff --git a/internal/commands/migrate.go b/internal/commands/migrate.go index 0a60a74af..7d14e1be9 100644 --- a/internal/commands/migrate.go +++ b/internal/commands/migrate.go @@ -12,7 +12,7 @@ import ( // MigrateCommand registers the migrate cli command. var MigrateCommand = cli.Command{ Name: "migrate", - Usage: "Initializes the index database if needed", + Usage: "Updates the index database schema", Action: migrateAction, } diff --git a/internal/commands/moments.go b/internal/commands/moments.go index e2c51eb99..9ee68de45 100644 --- a/internal/commands/moments.go +++ b/internal/commands/moments.go @@ -13,7 +13,7 @@ import ( // MomentsCommand registers the moments cli command. var MomentsCommand = cli.Command{ Name: "moments", - Usage: "Creates albums based on popular locations, dates, and labels", + Usage: "Creates albums of special moments, trips, and places", Action: momentsAction, } diff --git a/internal/commands/optimize.go b/internal/commands/optimize.go index f9133dc06..b7f9d941c 100644 --- a/internal/commands/optimize.go +++ b/internal/commands/optimize.go @@ -14,7 +14,7 @@ import ( // OptimizeCommand registers the index cli command. var OptimizeCommand = cli.Command{ Name: "optimize", - Usage: "Starts metadata check and optimization", + Usage: "Verifies and optimizes metadata", Action: optimizeAction, } diff --git a/internal/commands/purge.go b/internal/commands/purge.go index 32977916c..0e4c53e5e 100644 --- a/internal/commands/purge.go +++ b/internal/commands/purge.go @@ -20,7 +20,7 @@ import ( // PurgeCommand registers the index cli command. var PurgeCommand = cli.Command{ Name: "purge", - Usage: "Removes missing files from search results", + Usage: "Flags missing files as hidden, updates counts and covers", Flags: purgeFlags, Action: purgeAction, } @@ -28,7 +28,7 @@ var PurgeCommand = cli.Command{ var purgeFlags = []cli.Flag{ cli.BoolFlag{ Name: "hard", - Usage: "permanently delete from database", + Usage: "permanently remove from database", }, cli.BoolFlag{ Name: "dry", diff --git a/internal/commands/start.go b/internal/commands/start.go index c889e332b..49b5fe328 100644 --- a/internal/commands/start.go +++ b/internal/commands/start.go @@ -26,7 +26,7 @@ import ( var StartCommand = cli.Command{ Name: "start", Aliases: []string{"up"}, - Usage: "Starts web server", + Usage: "Starts the web server", Flags: startFlags, Action: startAction, } diff --git a/internal/commands/stop.go b/internal/commands/stop.go index 84ec0d015..64904d842 100644 --- a/internal/commands/stop.go +++ b/internal/commands/stop.go @@ -14,7 +14,7 @@ import ( var StopCommand = cli.Command{ Name: "stop", Aliases: []string{"down"}, - Usage: "Stops web server (only in daemon mode)", + Usage: "Stops the web server when running in daemon mode", Action: stopAction, } diff --git a/internal/commands/resample.go b/internal/commands/thumbs.go similarity index 68% rename from internal/commands/resample.go rename to internal/commands/thumbs.go index c53df0f5a..4ba97c149 100644 --- a/internal/commands/resample.go +++ b/internal/commands/thumbs.go @@ -10,22 +10,22 @@ import ( "github.com/photoprism/photoprism/pkg/txt" ) -// ResampleCommand registers the resample cli command. -var ResampleCommand = cli.Command{ - Name: "resample", - Aliases: []string{"thumbs"}, - Usage: "Pre-caches thumbnail images for improved performance", +// ThumbsCommand registers the resample cli command. +var ThumbsCommand = cli.Command{ + Name: "thumbs", + Aliases: []string{"resample"}, + Usage: "Pre-renders thumbnail images", Flags: []cli.Flag{ cli.BoolFlag{ Name: "force, f", Usage: "replace existing thumbnails", }, }, - Action: resampleAction, + Action: thumbsAction, } -// resampleAction pre-caches default thumbnails. -func resampleAction(ctx *cli.Context) error { +// thumbsAction pre-renders thumbnail images. +func thumbsAction(ctx *cli.Context) error { start := time.Now() conf := config.NewConfig(ctx) diff --git a/internal/commands/users.go b/internal/commands/users.go index b88224510..6c9b69e3b 100644 --- a/internal/commands/users.go +++ b/internal/commands/users.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/dustin/go-humanize/english" - "github.com/manifoldco/promptui" "github.com/urfave/cli" @@ -21,16 +20,16 @@ import ( // UsersCommand registers user management commands. var UsersCommand = cli.Command{ Name: "users", - Usage: "User management sub-commands", + Usage: "User management commands", Subcommands: []cli.Command{ { Name: "list", - Usage: "lists registered users", + Usage: "Lists registered users", Action: usersListAction, }, { Name: "add", - Usage: "adds a new user", + Usage: "Adds a new user", Action: usersAddAction, Flags: []cli.Flag{ cli.StringFlag{ @@ -53,7 +52,7 @@ var UsersCommand = cli.Command{ }, { Name: "update", - Usage: "select user by username and update it's information", + Usage: "Updates user information", Action: usersUpdateAction, Flags: []cli.Flag{ cli.StringFlag{ @@ -72,7 +71,7 @@ var UsersCommand = cli.Command{ }, { Name: "delete", - Usage: "deletes an existing user", + Usage: "Removes an existing user", Action: usersDeleteAction, ArgsUsage: "[username]", }, diff --git a/internal/config/config.go b/internal/config/config.go index 28cc5e3c2..316dc815c 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -322,6 +322,11 @@ func (c *Config) SitePreview() string { return c.options.SitePreview } +// SiteAuthor returns the site author / copyright. +func (c *Config) SiteAuthor() string { + return c.options.SiteAuthor +} + // SiteTitle returns the main site title (default is application name). func (c *Config) SiteTitle() string { if c.options.SiteTitle == "" { @@ -331,11 +336,6 @@ func (c *Config) SiteTitle() string { return c.options.SiteTitle } -// SiteAuthor returns the site author / copyright. -func (c *Config) SiteAuthor() string { - return c.options.SiteAuthor -} - // SiteCaption returns a short site caption. func (c *Config) SiteCaption() string { return c.options.SiteCaption diff --git a/internal/config/disable.go b/internal/config/disable.go index e4e89a64a..7c71abe03 100644 --- a/internal/config/disable.go +++ b/internal/config/disable.go @@ -1,14 +1,5 @@ package config -// DisableBackups tests if photo and album metadata backups should be disabled. -func (c *Config) DisableBackups() bool { - if !c.SidecarWritable() { - return true - } - - return c.options.DisableBackups -} - // DisableWebDAV tests if the built-in WebDAV server should be disabled. func (c *Config) DisableWebDAV() bool { if c.ReadOnly() || c.Demo() { @@ -18,6 +9,15 @@ func (c *Config) DisableWebDAV() bool { return c.options.DisableWebDAV } +// DisableBackups tests if photo and album metadata backups should be disabled. +func (c *Config) DisableBackups() bool { + if !c.SidecarWritable() { + return true + } + + return c.options.DisableBackups +} + // DisableSettings tests if users should not be allowed to change settings. func (c *Config) DisableSettings() bool { return c.options.DisableSettings diff --git a/internal/config/flags.go b/internal/config/flags.go index 7b045995a..eb3db1f12 100644 --- a/internal/config/flags.go +++ b/internal/config/flags.go @@ -11,18 +11,30 @@ import ( var GlobalFlags = []cli.Flag{ cli.BoolFlag{ Name: "debug", - Usage: "enables the debug mode, shows additional log messages", + Usage: "enable debug mode, shows additional log messages", EnvVar: "PHOTOPRISM_DEBUG", }, + cli.StringFlag{ + Name: "log-level, l", + Usage: "log verbosity `LEVEL` (trace, debug, info, warning, error, fatal or panic)", + Value: "info", + EnvVar: "PHOTOPRISM_LOG_LEVEL", + }, + cli.StringFlag{ + Name: "log-filename", + Usage: "optional server log `FILENAME`", + EnvVar: "PHOTOPRISM_LOG_FILENAME", + Value: "", + }, cli.BoolFlag{ Name: "test", Hidden: true, - Usage: "enables the test mode", + Usage: "enable test mode", }, cli.BoolFlag{ Name: "demo", Hidden: true, - Usage: "enables the demo mode", + Usage: "enable demo mode", EnvVar: "PHOTOPRISM_DEMO", }, cli.BoolFlag{ @@ -33,460 +45,448 @@ var GlobalFlags = []cli.Flag{ }, cli.BoolFlag{ Name: "public, p", - Usage: "disables password authentication", + Usage: "disable password authentication", EnvVar: "PHOTOPRISM_PUBLIC", }, + cli.StringFlag{ + Name: "admin-password", + Usage: "initial admin `PASSWORD`, min 4 characters", + EnvVar: "PHOTOPRISM_ADMIN_PASSWORD", + }, cli.BoolFlag{ Name: "read-only, r", - Usage: "disables import, upload, and delete", + Usage: "disable import, upload, and delete", EnvVar: "PHOTOPRISM_READONLY", }, cli.BoolFlag{ Name: "experimental, e", - Usage: "enables experimental features", + Usage: "enable experimental features", EnvVar: "PHOTOPRISM_EXPERIMENTAL", }, - cli.StringFlag{ - Name: "admin-password", - Usage: "sets the initial admin `PASSWORD`, min 4 characters", - EnvVar: "PHOTOPRISM_ADMIN_PASSWORD", - }, cli.StringFlag{ Name: "config-file, c", - Usage: "loads config options from `FILENAME`", + Usage: "load config options from `FILENAME`", EnvVar: "PHOTOPRISM_CONFIG_FILE", }, cli.StringFlag{ Name: "config-path", - Usage: "sets the config `PATH` for storing settings and other config files", + Usage: "config `PATH` where settings and other config files can be found", EnvVar: "PHOTOPRISM_CONFIG_PATH", }, cli.StringFlag{ Name: "originals-path", - Usage: "sets the originals `PATH` containing your photo and video files", + Usage: "photo and video library `PATH` containing your original files", EnvVar: "PHOTOPRISM_ORIGINALS_PATH", }, cli.IntFlag{ Name: "originals-limit", Value: 1000, - Usage: "limits the file size in `MB`", + Usage: "original file size limit in `MB`", EnvVar: "PHOTOPRISM_ORIGINALS_LIMIT", }, cli.StringFlag{ Name: "import-path", - Usage: "sets an optional import `PATH` from which files can be added to originals", + Usage: "optional import `PATH` from which files can be added to originals", EnvVar: "PHOTOPRISM_IMPORT_PATH", }, cli.StringFlag{ Name: "storage-path", - Usage: "sets the storage base `PATH` for cache, database, and sidecar files", + Usage: "writable storage `PATH` for cache, database, and sidecar files", EnvVar: "PHOTOPRISM_STORAGE_PATH", }, cli.StringFlag{ Name: "sidecar-path", - Usage: "sets a custom relative or absolute sidecar `PATH`", + Usage: "optional custom relative or absolute sidecar `PATH`", EnvVar: "PHOTOPRISM_SIDECAR_PATH", }, cli.StringFlag{ Name: "cache-path", - Usage: "sets a custom cache `PATH` for storing sessions and thumbnails", + Usage: "optional custom cache `PATH` for sessions and thumbnail files", EnvVar: "PHOTOPRISM_CACHE_PATH", }, cli.StringFlag{ Name: "temp-path", - Usage: "sets a custom temp `PATH` for storing temporary files", + Usage: "optional custom temporary file `PATH`", EnvVar: "PHOTOPRISM_TEMP_PATH", }, cli.StringFlag{ Name: "backup-path", - Usage: "sets a custom backup `PATH`", + Usage: "optional custom backup file `PATH`", EnvVar: "PHOTOPRISM_BACKUP_PATH", }, cli.StringFlag{ Name: "assets-path", - Usage: "sets the assets `PATH` containing static resources like icons and templates", + Usage: "static assets `PATH` containing resources like icons and templates", EnvVar: "PHOTOPRISM_ASSETS_PATH", }, cli.IntFlag{ Name: "workers, w", - Usage: "limits the `NUMBER` of indexing workers", + Usage: "max `NUMBER` of indexing workers", EnvVar: "PHOTOPRISM_WORKERS", Value: cpuid.CPU.PhysicalCores / 2, }, cli.IntFlag{ Name: "wakeup-interval", - Usage: "adjusts the background worker wakeup interval in `SECONDS`", + Usage: "background worker wakeup interval in `SECONDS`", Value: DefaultWakeupInterval, EnvVar: "PHOTOPRISM_WAKEUP_INTERVAL", }, cli.IntFlag{ Name: "auto-index", - Usage: "adjusts the WebDAV auto indexing safety delay in `SECONDS` (-1 to disable)", + Usage: "WebDAV auto indexing safety delay in `SECONDS` (-1 to disable)", Value: DefaultAutoIndexDelay, EnvVar: "PHOTOPRISM_AUTO_INDEX", }, cli.IntFlag{ Name: "auto-import", - Usage: "adjusts the WebDAV auto import safety delay in `SECONDS` (-1 to disable)", + Usage: "WebDAV auto import safety delay in `SECONDS` (-1 to disable)", Value: DefaultAutoImportDelay, EnvVar: "PHOTOPRISM_AUTO_IMPORT", }, - cli.BoolFlag{ - Name: "disable-backups", - Usage: "disables creating YAML metadata backup sidecar files", - EnvVar: "PHOTOPRISM_DISABLE_BACKUPS", - }, cli.BoolFlag{ Name: "disable-webdav", - Usage: "disables the built-in WebDAV server", + Usage: "disable built-in WebDAV server", EnvVar: "PHOTOPRISM_DISABLE_WEBDAV", }, + cli.BoolFlag{ + Name: "disable-backups", + Usage: "disable creating YAML metadata backup sidecar files", + EnvVar: "PHOTOPRISM_DISABLE_BACKUPS", + }, cli.BoolFlag{ Name: "disable-settings", - Usage: "disables the settings UI and API", + Usage: "disable settings UI and API", EnvVar: "PHOTOPRISM_DISABLE_SETTINGS", }, cli.BoolFlag{ Name: "disable-places", - Usage: "disables reverse geocoding and maps", + Usage: "disable reverse geocoding and maps", EnvVar: "PHOTOPRISM_DISABLE_PLACES", }, cli.BoolFlag{ Name: "disable-exiftool", - Usage: "disables metadata extraction with ExifTool", + Usage: "disable metadata extraction with ExifTool", EnvVar: "PHOTOPRISM_DISABLE_EXIFTOOL", }, cli.BoolFlag{ Name: "disable-ffmpeg", - Usage: "disables video transcoding and thumbnail generation with FFmpeg", + Usage: "disable video transcoding and thumbnail generation with FFmpeg", EnvVar: "PHOTOPRISM_DISABLE_FFMPEG", }, cli.BoolFlag{ Name: "disable-darktable", - Usage: "disables RAW file conversion with Darktable", + Usage: "disable RAW file conversion with Darktable", EnvVar: "PHOTOPRISM_DISABLE_DARKTABLE", }, cli.BoolFlag{ Name: "disable-rawtherapee", - Usage: "disables RAW file conversion with RawTherapee", + Usage: "disable RAW file conversion with RawTherapee", EnvVar: "PHOTOPRISM_DISABLE_RAWTHERAPEE", }, cli.BoolFlag{ Name: "disable-sips", - Usage: "disables RAW file conversion with Sips on macOS", + Usage: "disable RAW file conversion with Sips on macOS", EnvVar: "PHOTOPRISM_DISABLE_SIPS", }, cli.BoolFlag{ Name: "disable-heifconvert", - Usage: "disables HEIC/HEIF file conversion", + Usage: "disable HEIC/HEIF file conversion", EnvVar: "PHOTOPRISM_DISABLE_HEIFCONVERT", }, cli.BoolFlag{ Name: "disable-tensorflow", - Usage: "disables all features depending on TensorFlow", + Usage: "disable all features depending on TensorFlow", EnvVar: "PHOTOPRISM_DISABLE_TENSORFLOW", }, cli.BoolFlag{ Name: "disable-faces", - Usage: "disables facial recognition", + Usage: "disable facial recognition", EnvVar: "PHOTOPRISM_DISABLE_FACES", }, cli.BoolFlag{ Name: "disable-classification", - Usage: "disables image classification", + Usage: "disable image classification", EnvVar: "PHOTOPRISM_DISABLE_CLASSIFICATION", }, cli.BoolFlag{ Name: "detect-nsfw", - Usage: "flags photos as private that may be offensive (requires TensorFlow)", + Usage: "flag photos as private that may be offensive (requires TensorFlow)", EnvVar: "PHOTOPRISM_DETECT_NSFW", }, cli.BoolFlag{ Name: "upload-nsfw", - Usage: "allows uploads that may be offensive", + Usage: "allow uploads that may be offensive", EnvVar: "PHOTOPRISM_UPLOAD_NSFW", }, - cli.StringFlag{ - Name: "log-level, l", - Usage: "adjusts the log level to trace, debug, info, warning, error, fatal or panic", - Value: "info", - EnvVar: "PHOTOPRISM_LOG_LEVEL", - }, - cli.StringFlag{ - Name: "log-filename", - Usage: "sets the server log `FILENAME`", - EnvVar: "PHOTOPRISM_LOG_FILENAME", - Value: "", - }, - cli.StringFlag{ - Name: "pid-filename", - Usage: "sets the server process id `FILENAME`", - EnvVar: "PHOTOPRISM_PID_FILENAME", - }, cli.StringFlag{ Name: "cdn-url", - Usage: "sets an optional content delivery network `URL` (optional)", + Usage: "optional content delivery network `URL` (optional)", EnvVar: "PHOTOPRISM_CDN_URL", }, cli.StringFlag{ Name: "site-url", - Usage: "sets the public site `URL`", + Usage: "public site `URL`", Value: "http://localhost:2342/", EnvVar: "PHOTOPRISM_SITE_URL", }, cli.StringFlag{ Name: "site-preview", - Usage: "sets the public preview image `URL`", + Usage: "public preview image `URL`", EnvVar: "PHOTOPRISM_SITE_PREVIEW", }, + cli.StringFlag{ + Name: "site-author", + Usage: "artist name or copyright", + EnvVar: "PHOTOPRISM_SITE_AUTHOR", + }, cli.StringFlag{ Name: "site-title", - Usage: "sets the site title", + Usage: "site title", Value: "PhotoPrism", EnvVar: "PHOTOPRISM_SITE_TITLE", }, - cli.StringFlag{ - Name: "site-author", - Usage: "sets the artist name or copyright", - EnvVar: "PHOTOPRISM_SITE_AUTHOR", - }, cli.StringFlag{ Name: "site-caption", - Usage: "sets the site caption", + Usage: "site caption", Value: "Browse Your Life", EnvVar: "PHOTOPRISM_SITE_CAPTION", }, cli.StringFlag{ Name: "site-description", - Usage: "sets an optional site description", + Usage: "site description", EnvVar: "PHOTOPRISM_SITE_DESCRIPTION", }, cli.IntFlag{ Name: "http-port", Value: 2342, - Usage: "sets the http server port `NUMBER`", + Usage: "http server port `NUMBER`", EnvVar: "PHOTOPRISM_HTTP_PORT", }, cli.StringFlag{ Name: "http-host", - Usage: "sets the http server `IP` address", + Usage: "http server `IP` address", EnvVar: "PHOTOPRISM_HTTP_HOST", }, cli.StringFlag{ Name: "http-mode, m", - Usage: "selects the http server `MODE` (debug, release, or test)", + Usage: "http server `MODE` (debug, release, or test)", EnvVar: "PHOTOPRISM_HTTP_MODE", }, cli.StringFlag{ Name: "http-compression, z", - Usage: "improves transfer speed and bandwidth utilization (none or gzip)", + Usage: "enable http compression to improve bandwidth utilization (none or gzip)", EnvVar: "PHOTOPRISM_HTTP_COMPRESSION", }, cli.StringFlag{ Name: "database-driver", - Usage: "selects the database `DRIVER` (sqlite or mysql)", + Usage: "database `DRIVER` (sqlite or mysql)", Value: "sqlite", EnvVar: "PHOTOPRISM_DATABASE_DRIVER", }, cli.StringFlag{ Name: "database-dsn", - Usage: "sets the sqlite file name, specifying a `DSN` is optional other drivers", + Usage: "sqlite file name, specifying a `DSN` is optional other drivers", EnvVar: "PHOTOPRISM_DATABASE_DSN", }, cli.StringFlag{ Name: "database-server", - Usage: "sets the database server `HOST` and port e.g. mysql:3306", + Usage: "database server `HOST` and port e.g. mysql:3306", EnvVar: "PHOTOPRISM_DATABASE_SERVER", }, cli.StringFlag{ Name: "database-name", Value: "photoprism", - Usage: "sets the database schema `NAME`", + Usage: "database schema `NAME`", EnvVar: "PHOTOPRISM_DATABASE_NAME", }, cli.StringFlag{ Name: "database-user", Value: "photoprism", - Usage: "sets the database user `NAME`", + Usage: "database user `NAME`", EnvVar: "PHOTOPRISM_DATABASE_USER", }, cli.StringFlag{ Name: "database-password", - Usage: "sets the database user `PASSWORD`", + Usage: "database user `PASSWORD`", EnvVar: "PHOTOPRISM_DATABASE_PASSWORD", }, cli.IntFlag{ Name: "database-conns", - Usage: "limits the `NUMBER` of open database connections", + Usage: "max `NUMBER` of open database connections", EnvVar: "PHOTOPRISM_DATABASE_CONNS", }, cli.IntFlag{ Name: "database-conns-idle", - Usage: "limits the `NUMBER` of idle database connections", + Usage: "max `NUMBER` of idle database connections", EnvVar: "PHOTOPRISM_DATABASE_CONNS_IDLE", }, cli.BoolFlag{ Name: "raw-presets", - Usage: "enables RAW file converter presets (may reduce performance)", + Usage: "enable RAW file converter presets (may reduce performance)", EnvVar: "PHOTOPRISM_RAW_PRESETS", }, cli.StringFlag{ Name: "darktable-bin", - Usage: "sets the Darktable CLI `COMMAND` for RAW file conversion", + Usage: "Darktable CLI `COMMAND` for RAW file conversion", Value: "darktable-cli", EnvVar: "PHOTOPRISM_DARKTABLE_BIN", }, cli.StringFlag{ Name: "darktable-blacklist", - Usage: "disables using Darktable for specific file `EXTENSIONS`", + Usage: "disable using Darktable for specific file `EXTENSIONS`", Value: "raf,cr3,dng", EnvVar: "PHOTOPRISM_DARKTABLE_BLACKLIST", }, cli.StringFlag{ Name: "rawtherapee-bin", - Usage: "sets the RawTherapee CLI `COMMAND` for RAW file conversion", + Usage: "RawTherapee CLI `COMMAND` for RAW file conversion", Value: "rawtherapee-cli", EnvVar: "PHOTOPRISM_RAWTHERAPEE_BIN", }, cli.StringFlag{ Name: "rawtherapee-blacklist", - Usage: "disables using RawTherapee for specific file `EXTENSIONS`", + Usage: "disable using RawTherapee for specific file `EXTENSIONS`", Value: "", EnvVar: "PHOTOPRISM_RAWTHERAPEE_BLACKLIST", }, cli.StringFlag{ Name: "sips-bin", - Usage: "sets the Sips `COMMAND` for RAW file conversion on macOS", + Usage: "Sips `COMMAND` for RAW file conversion on macOS", Value: "sips", EnvVar: "PHOTOPRISM_SIPS_BIN", }, cli.StringFlag{ Name: "heifconvert-bin", - Usage: "sets the HEIC/HEIF image convert `COMMAND`", + Usage: "HEIC/HEIF image convert `COMMAND`", Value: "heif-convert", EnvVar: "PHOTOPRISM_HEIFCONVERT_BIN", }, cli.StringFlag{ Name: "ffmpeg-bin", - Usage: "sets the FFmpeg `COMMAND` for video transcoding and cover images", + Usage: "FFmpeg `COMMAND` for video transcoding and cover images", Value: "ffmpeg", EnvVar: "PHOTOPRISM_FFMPEG_BIN", }, cli.StringFlag{ Name: "ffmpeg-encoder", - Usage: "sets the FFmpeg AVC encoder `NAME`", + Usage: "FFmpeg AVC encoder `NAME`", Value: "libx264", EnvVar: "PHOTOPRISM_FFMPEG_ENCODER", }, cli.IntFlag{ Name: "ffmpeg-bitrate", - Usage: "limits the FFmpeg encoding `BITRATE` (Mbit/s)", + Usage: "max FFmpeg encoding `BITRATE` (Mbit/s)", Value: 50, EnvVar: "PHOTOPRISM_FFMPEG_BITRATE", }, cli.IntFlag{ Name: "ffmpeg-buffers", - Usage: "adjusts the number of FFmpeg capture buffers", + Usage: "`NUMBER` of FFmpeg capture buffers", Value: 32, EnvVar: "PHOTOPRISM_FFMPEG_BUFFERS", }, cli.StringFlag{ Name: "exiftool-bin", - Usage: "sets the ExifTool `COMMAND` for extracting metadata", + Usage: "ExifTool `COMMAND` for extracting metadata", Value: "exiftool", EnvVar: "PHOTOPRISM_EXIFTOOL_BIN", }, cli.StringFlag{ Name: "download-token", - Usage: "sets a custom download url `TOKEN`", + Usage: "custom download url `TOKEN`", EnvVar: "PHOTOPRISM_DOWNLOAD_TOKEN", }, cli.StringFlag{ Name: "preview-token", - Usage: "sets a custom thumbnail and video streaming url `TOKEN`", + Usage: "custom thumbnail and video streaming url `TOKEN`", EnvVar: "PHOTOPRISM_PREVIEW_TOKEN", }, cli.StringFlag{ Name: "thumb-filter", - Usage: "selects the thumbnail downscaling `FILTER` (best to worst: blackman, lanczos, cubic, linear)", + Usage: "thumbnail downscaling `FILTER` (best to worst: blackman, lanczos, cubic, linear)", Value: "lanczos", EnvVar: "PHOTOPRISM_THUMB_FILTER", }, cli.IntFlag{ Name: "thumb-size, s", - Usage: "limits the pre-cached thumbnail size in `PIXELS` (720-7680)", + Usage: "max pre-cached thumbnail size in `PIXELS` (720-7680)", Value: 2048, EnvVar: "PHOTOPRISM_THUMB_SIZE", }, cli.BoolFlag{ Name: "thumb-uncached, u", - Usage: "enables on-demand thumbnail generation (high memory and cpu usage)", + Usage: "enable on-demand thumbnail generation (high memory and cpu usage)", EnvVar: "PHOTOPRISM_THUMB_UNCACHED", }, cli.IntFlag{ Name: "thumb-size-uncached, x", - Usage: "limits the on-demand thumbnail size in `PIXELS` (720-7680)", + Usage: "max on-demand thumbnail size in `PIXELS` (720-7680)", Value: 7680, EnvVar: "PHOTOPRISM_THUMB_SIZE_UNCACHED", }, cli.IntFlag{ Name: "jpeg-size", - Usage: "limits the size of generated JPEG files in `PIXELS` (720-30000)", + Usage: "max size of generated JPEG files in `PIXELS` (720-30000)", Value: 7680, EnvVar: "PHOTOPRISM_JPEG_SIZE", }, cli.IntFlag{ Name: "jpeg-quality, q", - Usage: "adjusts the `QUALITY` of generated JPEG files, a higher value reduces compression (25-100)", + Usage: "`QUALITY` of generated JPEG files, a higher value reduces compression (25-100)", Value: 92, EnvVar: "PHOTOPRISM_JPEG_QUALITY", }, cli.IntFlag{ Name: "face-size", - Usage: "sets the min face size in `PIXELS`", + Usage: "min face size in `PIXELS`", Value: face.SizeThreshold, EnvVar: "PHOTOPRISM_FACE_SIZE", }, cli.Float64Flag{ Name: "face-score", - Usage: "adjusts the quality `THRESHOLD` for faces", + Usage: "quality `THRESHOLD` for faces", Value: face.ScoreThreshold, EnvVar: "PHOTOPRISM_FACE_SCORE", }, cli.IntFlag{ Name: "face-overlap", - Usage: "adjusts the face area overlap threshold in `PERCENT`", + Usage: "face area overlap threshold in `PERCENT`", Value: face.OverlapThreshold, EnvVar: "PHOTOPRISM_FACE_OVERLAP", }, cli.IntFlag{ Name: "face-cluster-size", - Usage: "sets the min size of faces forming a cluster in `PIXELS`", + Usage: "min size of faces forming a cluster in `PIXELS`", Value: face.ClusterSizeThreshold, EnvVar: "PHOTOPRISM_FACE_CLUSTER_SIZE", }, cli.IntFlag{ Name: "face-cluster-score", - Usage: "adjusts the quality `THRESHOLD` for faces forming a cluster", + Usage: "quality `THRESHOLD` for faces forming a cluster", Value: face.ClusterScoreThreshold, EnvVar: "PHOTOPRISM_FACE_CLUSTER_SCORE", }, cli.IntFlag{ Name: "face-cluster-core", - Usage: "determines the `NUMBER` of faces forming a cluster core", + Usage: "`NUMBER` of faces forming a cluster core", Value: face.ClusterCore, EnvVar: "PHOTOPRISM_FACE_CLUSTER_CORE", }, cli.Float64Flag{ Name: "face-cluster-dist", - Usage: "determines how close faces forming a cluster core must be to each other", + Usage: "similarity distance of faces forming a cluster core", Value: face.ClusterDist, EnvVar: "PHOTOPRISM_FACE_CLUSTER_DIST", }, cli.Float64Flag{ Name: "face-match-dist", - Usage: "adjusts the similarity offset for matching faces with existing clusters", + Usage: "similarity offset for matching faces with existing clusters", Value: face.MatchDist, EnvVar: "PHOTOPRISM_FACE_MATCH_DIST", }, + cli.StringFlag{ + Name: "pid-filename", + Usage: "daemon process id `FILENAME`", + EnvVar: "PHOTOPRISM_PID_FILENAME", + }, } diff --git a/internal/config/options.go b/internal/config/options.go index 404e4d1a1..74e8afad8 100644 --- a/internal/config/options.go +++ b/internal/config/options.go @@ -34,15 +34,17 @@ type Options struct { Version string `json:"-"` Copyright string `json:"-"` Debug bool `yaml:"Debug" json:"Debug" flag:"debug"` + LogLevel string `yaml:"LogLevel" json:"-" flag:"log-level"` + LogFilename string `yaml:"LogFilename" json:"-" flag:"log-filename"` Test bool `yaml:"-" json:"Test,omitempty" flag:"test"` Demo bool `yaml:"Demo" json:"-" flag:"demo"` Sponsor bool `yaml:"-" json:"-" flag:"sponsor"` Public bool `yaml:"Public" json:"-" flag:"public"` + AdminPassword string `yaml:"AdminPassword" json:"-" flag:"admin-password"` 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"` ConfigFile string `json:"-"` - AdminPassword string `yaml:"AdminPassword" json:"-" flag:"admin-password"` OriginalsPath string `yaml:"OriginalsPath" json:"-" flag:"originals-path"` OriginalsLimit int64 `yaml:"OriginalsLimit" json:"OriginalsLimit" flag:"originals-limit"` ImportPath string `yaml:"ImportPath" json:"-" flag:"import-path"` @@ -56,8 +58,8 @@ type Options struct { WakeupInterval int `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"` - DisableBackups bool `yaml:"DisableBackups" json:"DisableBackups" flag:"disable-backups"` 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"` DisablePlaces bool `yaml:"DisablePlaces" json:"DisablePlaces" flag:"disable-places"` DisableExifTool bool `yaml:"DisableExifTool" json:"DisableExifTool" flag:"disable-exiftool"` @@ -71,14 +73,11 @@ type Options struct { DisableClassification bool `yaml:"DisableClassification" json:"DisableClassification" flag:"disable-classification"` DetectNSFW bool `yaml:"DetectNSFW" json:"DetectNSFW" flag:"detect-nsfw"` UploadNSFW bool `yaml:"UploadNSFW" json:"-" flag:"upload-nsfw"` - LogLevel string `yaml:"LogLevel" json:"-" flag:"log-level"` - LogFilename string `yaml:"LogFilename" json:"-" flag:"log-filename"` - PIDFilename string `yaml:"PIDFilename" json:"-" flag:"pid-filename"` CdnUrl string `yaml:"CdnUrl" json:"CdnUrl" flag:"cdn-url"` SiteUrl string `yaml:"SiteUrl" json:"SiteUrl" flag:"site-url"` SitePreview string `yaml:"SitePreview" json:"SitePreview" flag:"site-preview"` - SiteTitle string `yaml:"SiteTitle" json:"SiteTitle" flag:"site-title"` SiteAuthor string `yaml:"SiteAuthor" json:"SiteAuthor" flag:"site-author"` + SiteTitle string `yaml:"SiteTitle" json:"SiteTitle" flag:"site-title"` SiteCaption string `yaml:"SiteCaption" json:"SiteCaption" flag:"site-caption"` SiteDescription string `yaml:"SiteDescription" json:"SiteDescription" flag:"site-description"` DatabaseDriver string `yaml:"DatabaseDriver" json:"-" flag:"database-driver"` @@ -122,6 +121,7 @@ type Options struct { FaceClusterCore int `yaml:"-" json:"-" flag:"face-cluster-core"` FaceClusterDist float64 `yaml:"-" json:"-" flag:"face-cluster-dist"` FaceMatchDist float64 `yaml:"-" json:"-" flag:"face-match-dist"` + PIDFilename string `yaml:"PIDFilename" json:"-" flag:"pid-filename"` } // NewOptions creates a new configuration entity by using two methods: diff --git a/internal/entity/file.go b/internal/entity/file.go index 4b30605b5..a83fa8fbb 100644 --- a/internal/entity/file.go +++ b/internal/entity/file.go @@ -202,7 +202,7 @@ func (m File) Missing() bool { return m.FileMissing || m.DeletedAt != nil } -// DeletePermanently permanently deletes a file from the index. +// DeletePermanently permanently removes a file from the index. func (m *File) DeletePermanently() error { if m.ID < 1 || m.FileUID == "" { return fmt.Errorf("invalid file id %d / uid %s", m.ID, txt.Quote(m.FileUID)) diff --git a/internal/entity/photo.go b/internal/entity/photo.go index de60d8b54..9fd397ab7 100644 --- a/internal/entity/photo.go +++ b/internal/entity/photo.go @@ -951,7 +951,7 @@ func (m *Photo) Delete(permanently bool) (files Files, err error) { return files, m.Updates(map[string]interface{}{"DeletedAt": TimeStamp(), "PhotoQuality": -1}) } -// DeletePermanently permanently deletes a photo from the index. +// DeletePermanently permanently removes a photo from the index. func (m *Photo) DeletePermanently() (files Files, err error) { if m.ID < 1 || m.PhotoUID == "" { return files, fmt.Errorf("invalid photo id %d / uid %s", m.ID, txt.Quote(m.PhotoUID)) diff --git a/internal/photoprism/delete.go b/internal/photoprism/delete.go index 7e92beb3a..0eb6607f2 100644 --- a/internal/photoprism/delete.go +++ b/internal/photoprism/delete.go @@ -13,7 +13,7 @@ import ( func Delete(p entity.Photo) error { yamlFileName := p.YamlFileName(Config().OriginalsPath(), Config().SidecarPath()) - // Permanently delete photo from index. + // Permanently remove photo from index. files, err := p.DeletePermanently() if err != nil { diff --git a/internal/photoprism/mediafile.go b/internal/photoprism/mediafile.go index 8644c31f6..461301b31 100644 --- a/internal/photoprism/mediafile.go +++ b/internal/photoprism/mediafile.go @@ -543,7 +543,7 @@ func (m *MediaFile) Exists() bool { return fs.FileExists(m.FileName()) } -// Remove permanently deletes a media file. +// Remove permanently removes a media file. func (m *MediaFile) Remove() error { return os.Remove(m.FileName()) } @@ -1036,7 +1036,7 @@ func (m *MediaFile) RenameSidecars(oldFileName string) (renamed map[string]strin return renamed, nil } -// RemoveSidecars permanently deletes related sidecar files. +// RemoveSidecars permanently removes related sidecar files. func (m *MediaFile) RemoveSidecars() (err error) { fileName := m.FileName() sidecarPath := Config().SidecarPath() diff --git a/internal/photoprism/purge.go b/internal/photoprism/purge.go index 7e0e0ebc7..c205e26e4 100644 --- a/internal/photoprism/purge.go +++ b/internal/photoprism/purge.go @@ -220,7 +220,7 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot purgedPhotos[photo.PhotoUID] = true if opt.Hard { - log.Infof("purge: permanently deleted %s", txt.Quote(photo.PhotoName)) + log.Infof("purge: permanently removed %s", txt.Quote(photo.PhotoName)) } else { log.Infof("purge: flagged photo %s as deleted", txt.Quote(photo.PhotoName)) } diff --git a/internal/query/faces.go b/internal/query/faces.go index 9669afc36..98c8cff25 100644 --- a/internal/query/faces.go +++ b/internal/query/faces.go @@ -210,7 +210,7 @@ func ResolveFaceCollisions() (conflicts, resolved int, err error) { return conflicts, resolved, nil } -// RemovePeopleAndFaces permanently deletes all people, faces, and face markers. +// RemovePeopleAndFaces permanently removes all people, faces, and face markers. func RemovePeopleAndFaces() (err error) { // Delete people. if err = UnscopedDb().Delete(entity.Subject{}, "subj_type = ?", entity.SubjPerson).Error; err != nil { diff --git a/internal/query/subjects.go b/internal/query/subjects.go index d9fee36cf..9c764f4ef 100644 --- a/internal/query/subjects.go +++ b/internal/query/subjects.go @@ -61,7 +61,7 @@ func SubjectMap() (result map[string]entity.Subject, err error) { return result, err } -// RemoveOrphanSubjects permanently deletes dangling marker subjects from the index. +// RemoveOrphanSubjects permanently removes dangling marker subjects from the index. func RemoveOrphanSubjects() (removed int64, err error) { res := UnscopedDb(). Where("subj_src = ?", entity.SrcMarker).