UX: Refactor config options to be more intuitive
Make sure to update your local config files when upgrading as the name of some config values has changed. The default config path has changed from "settings" to "config".
This commit is contained in:
parent
cd59b1b8ca
commit
7940786ce9
49 changed files with 597 additions and 539 deletions
8
Makefile
8
Makefile
|
@ -32,7 +32,7 @@ upgrade: dep-upgrade-js dep-upgrade
|
|||
clean-local: clean-local-config clean-local-share clean-local-cache
|
||||
clean-install: clean-local dep build-js install-bin install-assets
|
||||
acceptance-start:
|
||||
go run cmd/photoprism/photoprism.go --public --database-driver sqlite --database-dsn ./storage/acceptance/index.db --import-path ./storage/acceptance/import --http-port=2343 --config-path ./storage/acceptance/config --originals-path ./storage/acceptance/originals --sidecar-json=false --sidecar-yaml=false start -d
|
||||
go run cmd/photoprism/photoprism.go --public --database-driver sqlite --database-dsn ./storage/acceptance/index.db --import-path ./storage/acceptance/import --http-port=2343 --config-path ./storage/acceptance/config --originals-path ./storage/acceptance/originals --disable-exiftool --disable-backups start -d
|
||||
acceptance-restart:
|
||||
go run cmd/photoprism/photoprism.go stop
|
||||
cp -f storage/acceptance/backup.db storage/acceptance/index.db
|
||||
|
@ -40,7 +40,7 @@ acceptance-restart:
|
|||
rm -rf storage/acceptance/originals/2010
|
||||
rm -rf storage/acceptance/originals/2013
|
||||
rm -rf storage/acceptance/originals/2017
|
||||
go run cmd/photoprism/photoprism.go --public --database-driver sqlite --database-dsn ./storage/acceptance/index.db --import-path ./storage/acceptance/import --http-port=2343 --config-path ./storage/acceptance/config --originals-path ./storage/acceptance/originals --sidecar-json=false --sidecar-yaml=false start -d
|
||||
go run cmd/photoprism/photoprism.go --public --database-driver sqlite --database-dsn ./storage/acceptance/index.db --import-path ./storage/acceptance/import --http-port=2343 --config-path ./storage/acceptance/config --originals-path ./storage/acceptance/originals --disable-exiftool --disable-backups start -d
|
||||
acceptance-restore-db:
|
||||
cp -f storage/acceptance/config/settingsBackup.yml storage/acceptance/config/settings.yml
|
||||
cp -f storage/acceptance/backup.db storage/acceptance/index.db
|
||||
|
@ -63,7 +63,7 @@ install-bin:
|
|||
scripts/build.sh prod ~/.local/bin/$(BINARY_NAME)
|
||||
install-assets:
|
||||
$(info Installing assets)
|
||||
mkdir -p ~/.photoprism/storage/settings
|
||||
mkdir -p ~/.photoprism/storage/config
|
||||
mkdir -p ~/.photoprism/storage/cache
|
||||
mkdir -p ~/.photoprism/storage
|
||||
mkdir -p ~/.photoprism/assets
|
||||
|
@ -76,7 +76,7 @@ clean-local-assets:
|
|||
clean-local-cache:
|
||||
rm -rf ~/.photoprism/storage/cache/*
|
||||
clean-local-config:
|
||||
rm -f ~/.photoprism/storage/settings/*
|
||||
rm -f ~/.photoprism/storage/config/*
|
||||
dep-list:
|
||||
go list -u -m -json all | go-mod-outdated -direct
|
||||
dep-js:
|
||||
|
|
|
@ -21,8 +21,6 @@ services:
|
|||
PHOTOPRISM_DEBUG: "false"
|
||||
PHOTOPRISM_READONLY: "false"
|
||||
PHOTOPRISM_PUBLIC: "true"
|
||||
PHOTOPRISM_UPLOAD_NSFW: "false"
|
||||
PHOTOPRISM_DETECT_NSFW: "false"
|
||||
PHOTOPRISM_PID_FILENAME: "photoprism.pid"
|
||||
PHOTOPRISM_LOG_FILENAME: "photoprism.log"
|
||||
PHOTOPRISM_DETACH_SERVER: "true"
|
||||
|
@ -40,16 +38,21 @@ services:
|
|||
PHOTOPRISM_STORAGE_PATH: "/go/src/github.com/photoprism/photoprism/storage"
|
||||
PHOTOPRISM_ORIGINALS_PATH: "/go/src/github.com/photoprism/photoprism/storage/originals"
|
||||
PHOTOPRISM_IMPORT_PATH: "/go/src/github.com/photoprism/photoprism/storage/import"
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "true" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
# PHOTOPRISM_THUMB_SIZE: 4096 # Retina 4K, DCI 4K (requires more storage); 7680 for 8K Ultra HD
|
||||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use darktable presets (disables concurrent raw to jpeg conversion)
|
||||
PHOTOPRISM_SIDECAR_JSON: "true" # Read metadata from JSON sidecar files created by exiftool
|
||||
PHOTOPRISM_SIDECAR_YAML: "true" # Backup photo metadata to YAML sidecar files
|
||||
PHOTOPRISM_DISABLE_BACKUPS: "false" # Don't backup photo and album metadata to YAML files
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_PLACES: "false" # Disables reverse geocoding and maps
|
||||
PHOTOPRISM_DISABLE_EXIFTOOL: "false" # Don't create ExifTool JSON files for improved metadata extraction
|
||||
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # Don't use TensorFlow for image classification
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive (requires TensorFlow)
|
||||
PHOTOPRISM_UPLOAD_NSFW: "false" # Allow uploads that may be offensive
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use Darktable presets (disables concurrent raw image conversion)
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "true" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
# PHOTOPRISM_THUMB_SIZE: 4096 # Retina 4K, DCI 4K (requires more storage); 7680 for 8K Ultra HD
|
||||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
CODECOV_TOKEN:
|
||||
CODECOV_ENV:
|
||||
CODECOV_URL:
|
||||
|
|
|
@ -27,8 +27,6 @@ services:
|
|||
PHOTOPRISM_READONLY: "false"
|
||||
PHOTOPRISM_PUBLIC: "true"
|
||||
PHOTOPRISM_EXPERIMENTAL: "true"
|
||||
PHOTOPRISM_UPLOAD_NSFW: "false"
|
||||
PHOTOPRISM_DETECT_NSFW: "false"
|
||||
PHOTOPRISM_SERVER_MODE: "debug"
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
|
@ -44,16 +42,21 @@ services:
|
|||
PHOTOPRISM_STORAGE_PATH: "/go/src/github.com/photoprism/photoprism/storage"
|
||||
PHOTOPRISM_ORIGINALS_PATH: "/go/src/github.com/photoprism/photoprism/storage/originals"
|
||||
PHOTOPRISM_IMPORT_PATH: "/go/src/github.com/photoprism/photoprism/storage/import"
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "true" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
# PHOTOPRISM_THUMB_SIZE: 4096 # Retina 4K, DCI 4K (requires more storage); 7680 for 8K Ultra HD
|
||||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use darktable presets (disables concurrent raw to jpeg conversion)
|
||||
PHOTOPRISM_SIDECAR_JSON: "true" # Read metadata from JSON sidecar files created by exiftool
|
||||
PHOTOPRISM_SIDECAR_YAML: "true" # Backup photo metadata to YAML sidecar files
|
||||
PHOTOPRISM_DISABLE_BACKUPS: "false" # Don't backup photo and album metadata to YAML files
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_PLACES: "false" # Disables reverse geocoding and maps
|
||||
PHOTOPRISM_DISABLE_EXIFTOOL: "false" # Don't create ExifTool JSON files for improved metadata extraction
|
||||
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # Don't use TensorFlow for image classification
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive (requires TensorFlow)
|
||||
PHOTOPRISM_UPLOAD_NSFW: "false" # Allow uploads that may be offensive
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use Darktable presets (disables concurrent raw image conversion)
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "true" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
# PHOTOPRISM_THUMB_SIZE: 4096 # Retina 4K, DCI 4K (requires more storage); 7680 for 8K Ultra HD
|
||||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
|
||||
postgres:
|
||||
image: postgres:12-alpine
|
||||
|
|
|
@ -42,8 +42,6 @@ services:
|
|||
PHOTOPRISM_READONLY: "false"
|
||||
PHOTOPRISM_PUBLIC: "true"
|
||||
PHOTOPRISM_EXPERIMENTAL: "true"
|
||||
PHOTOPRISM_UPLOAD_NSFW: "false"
|
||||
PHOTOPRISM_DETECT_NSFW: "false"
|
||||
PHOTOPRISM_SERVER_MODE: "debug"
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
|
@ -59,17 +57,21 @@ services:
|
|||
PHOTOPRISM_STORAGE_PATH: "/go/src/github.com/photoprism/photoprism/storage"
|
||||
PHOTOPRISM_ORIGINALS_PATH: "/go/src/github.com/photoprism/photoprism/storage/originals"
|
||||
PHOTOPRISM_IMPORT_PATH: "/go/src/github.com/photoprism/photoprism/storage/import"
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "true" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
# PHOTOPRISM_THUMB_SIZE: 4096 # Retina 4K, DCI 4K (requires more storage); 7680 for 8K Ultra HD
|
||||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use darktable presets (disables concurrent raw to jpeg conversion)
|
||||
PHOTOPRISM_SIDECAR_JSON: "true" # Read metadata from JSON sidecar files created by exiftool
|
||||
PHOTOPRISM_SIDECAR_YAML: "true" # Backup photo metadata to YAML sidecar files
|
||||
|
||||
PHOTOPRISM_DISABLE_BACKUPS: "false" # Don't backup photo and album metadata to YAML files
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_PLACES: "false" # Disables reverse geocoding and maps
|
||||
PHOTOPRISM_DISABLE_EXIFTOOL: "false" # Don't create ExifTool JSON files for improved metadata extraction
|
||||
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # Don't use TensorFlow for image classification
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive (requires TensorFlow)
|
||||
PHOTOPRISM_UPLOAD_NSFW: "false" # Allow uploads that may be offensive
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use Darktable presets (disables concurrent raw image conversion)
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "true" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
# PHOTOPRISM_THUMB_SIZE: 4096 # Retina 4K, DCI 4K (requires more storage); 7680 for 8K Ultra HD
|
||||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
photoprism-db:
|
||||
image: mariadb:10.5
|
||||
command: mysqld --port=4001 --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=50
|
||||
|
|
|
@ -17,9 +17,6 @@ ENV PHOTOPRISM_PUBLIC true
|
|||
ENV PHOTOPRISM_EXPERIMENTAL true
|
||||
ENV PHOTOPRISM_UPLOAD_NSFW false
|
||||
ENV PHOTOPRISM_DETECT_NSFW false
|
||||
ENV PHOTOPRISM_SIDECAR_JSON true
|
||||
ENV PHOTOPRISM_SIDECAR_YAML false
|
||||
ENV PHOTOPRISM_GEOCODING_API places
|
||||
ENV PHOTOPRISM_THUMB_FILTER lanczos
|
||||
ENV PHOTOPRISM_THUMB_UNCACHED true
|
||||
ENV PHOTOPRISM_THUMB_SIZE 4096
|
||||
|
|
|
@ -85,17 +85,23 @@ ENV PHOTOPRISM_SITE_DESCRIPTION ""
|
|||
ENV PHOTOPRISM_SITE_AUTHOR ""
|
||||
ENV PHOTOPRISM_HTTP_HOST "0.0.0.0"
|
||||
ENV PHOTOPRISM_HTTP_PORT 2342
|
||||
ENV PHOTOPRISM_SETTINGS_HIDDEN "false"
|
||||
ENV PHOTOPRISM_DATABASE_DRIVER "sqlite"
|
||||
ENV PHOTOPRISM_SIDECAR_JSON "true"
|
||||
ENV PHOTOPRISM_SIDECAR_YAML "true"
|
||||
ENV PHOTOPRISM_DATABASE_SERVER ""
|
||||
ENV PHOTOPRISM_DATABASE_NAME "photoprism"
|
||||
ENV PHOTOPRISM_DATABASE_USER "photoprism"
|
||||
ENV PHOTOPRISM_DATABASE_PASSWORD ""
|
||||
ENV PHOTOPRISM_DISABLE_TENSORFLOW "false"
|
||||
ENV PHOTOPRISM_DISABLE_EXIFTOOL "false"
|
||||
ENV PHOTOPRISM_DISABLE_BACKUPS "false"
|
||||
ENV PHOTOPRISM_DISABLE_SETTINGS "false"
|
||||
ENV PHOTOPRISM_DISABLE_PLACES "false"
|
||||
ENV PHOTOPRISM_DARKTABLE_PRESETS "false"
|
||||
ENV PHOTOPRISM_THUMB_FILTER "lanczos"
|
||||
ENV PHOTOPRISM_THUMB_UNCACHED "false"
|
||||
ENV PHOTOPRISM_THUMB_SIZE 2048
|
||||
ENV PHOTOPRISM_THUMB_SIZE_UNCACHED 7680
|
||||
ENV PHOTOPRISM_JPEG_SIZE 7680
|
||||
ENV PHOTOPRISM_JPEG_QUALITY 92
|
||||
ENV PHOTOPRISM_DARKTABLE_PRESETS "false"
|
||||
|
||||
# Copy files to /photoprism
|
||||
COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism
|
||||
|
@ -106,7 +112,7 @@ RUN mkdir -p \
|
|||
/var/lib/photoprism \
|
||||
/photoprism/originals \
|
||||
/photoprism/import \
|
||||
/photoprism/storage/settings \
|
||||
/photoprism/storage/config \
|
||||
/photoprism/storage/cache && \
|
||||
chown -R photoprism:photoprism /photoprism /var/lib/photoprism && \
|
||||
chmod -R a+rw /photoprism /var/lib/photoprism
|
||||
|
|
|
@ -171,17 +171,23 @@ ENV PHOTOPRISM_SITE_DESCRIPTION ""
|
|||
ENV PHOTOPRISM_SITE_AUTHOR ""
|
||||
ENV PHOTOPRISM_HTTP_HOST "0.0.0.0"
|
||||
ENV PHOTOPRISM_HTTP_PORT 2342
|
||||
ENV PHOTOPRISM_SETTINGS_HIDDEN "false"
|
||||
ENV PHOTOPRISM_DATABASE_DRIVER "sqlite"
|
||||
ENV PHOTOPRISM_SIDECAR_JSON "true"
|
||||
ENV PHOTOPRISM_SIDECAR_YAML "true"
|
||||
ENV PHOTOPRISM_DATABASE_SERVER ""
|
||||
ENV PHOTOPRISM_DATABASE_NAME "photoprism"
|
||||
ENV PHOTOPRISM_DATABASE_USER "photoprism"
|
||||
ENV PHOTOPRISM_DATABASE_PASSWORD ""
|
||||
ENV PHOTOPRISM_DISABLE_TENSORFLOW "false"
|
||||
ENV PHOTOPRISM_DISABLE_EXIFTOOL "false"
|
||||
ENV PHOTOPRISM_DISABLE_BACKUPS "false"
|
||||
ENV PHOTOPRISM_DISABLE_SETTINGS "false"
|
||||
ENV PHOTOPRISM_DISABLE_PLACES "false"
|
||||
ENV PHOTOPRISM_DARKTABLE_PRESETS "false"
|
||||
ENV PHOTOPRISM_THUMB_FILTER "lanczos"
|
||||
ENV PHOTOPRISM_THUMB_UNCACHED "false"
|
||||
ENV PHOTOPRISM_THUMB_SIZE 2048
|
||||
ENV PHOTOPRISM_THUMB_SIZE_UNCACHED 7680
|
||||
ENV PHOTOPRISM_JPEG_SIZE 7680
|
||||
ENV PHOTOPRISM_JPEG_QUALITY 92
|
||||
ENV PHOTOPRISM_DARKTABLE_PRESETS "false"
|
||||
|
||||
# Copy files to /photoprism
|
||||
COPY --from=build /root/.local/bin/photoprism /photoprism/bin/photoprism
|
||||
|
@ -192,7 +198,7 @@ RUN mkdir -p \
|
|||
/var/lib/photoprism \
|
||||
/photoprism/originals \
|
||||
/photoprism/import \
|
||||
/photoprism/storage/settings \
|
||||
/photoprism/storage/config \
|
||||
/photoprism/storage/cache && \
|
||||
chown -R photoprism:photoprism /photoprism /var/lib/photoprism && \
|
||||
chmod -R a+rw /photoprism /var/lib/photoprism
|
||||
|
|
|
@ -30,12 +30,10 @@ services:
|
|||
#
|
||||
# Run "photoprism help" and "photoprism config" too see all config options and current values:
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "please-change" # Initial admin password: PLEASE CHANGE!
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: This is your initial admin password
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode (shows additional log messages)
|
||||
PHOTOPRISM_PUBLIC: "false" # No authentication required (disables password protection)
|
||||
PHOTOPRISM_READONLY: "false" # Don't modify originals directory (reduced functionality)
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true" # Allow uploads that MAY be offensive
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive
|
||||
PHOTOPRISM_EXPERIMENTAL: "false" # Enable experimental features
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Canonical / public site URL
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
|
@ -44,15 +42,20 @@ services:
|
|||
PHOTOPRISM_SITE_AUTHOR: ""
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
PHOTOPRISM_SETTINGS_HIDDEN: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_BACKUPS: "false" # Don't backup photo and album metadata to YAML files
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_PLACES: "false" # Disables reverse geocoding and maps
|
||||
PHOTOPRISM_DISABLE_EXIFTOOL: "false" # Don't create ExifTool JSON files for improved metadata extraction
|
||||
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # Don't use TensorFlow for image classification
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true" # Allow uploads that MAY be offensive
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use Darktable presets (disables concurrent raw image conversion)
|
||||
PHOTOPRISM_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB instead of SQLite for improved performance
|
||||
# PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
|
||||
# PHOTOPRISM_DATABASE_NAME: "photoprism"
|
||||
# PHOTOPRISM_DATABASE_USER: "photoprism"
|
||||
# PHOTOPRISM_DATABASE_PASSWORD: "insecure"
|
||||
PHOTOPRISM_SIDECAR_JSON: "true" # Automatically create JSON sidecar files using Exiftool
|
||||
PHOTOPRISM_SIDECAR_YAML: "true" # Automatically backup metadata to YAML sidecar files
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB (or MySQL) instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB database user password
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "false" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
|
@ -60,7 +63,6 @@ services:
|
|||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use darktable presets (disables concurrent raw to jpeg conversion)
|
||||
# You may optionally set user, group and/or file permissions using environment variables:
|
||||
# UID: 1000
|
||||
# GID: 1000
|
||||
|
@ -85,10 +87,10 @@ services:
|
|||
# volumes:
|
||||
# - "/var/lib/mysql"
|
||||
# environment:
|
||||
# MYSQL_ROOT_PASSWORD: please-change
|
||||
# MYSQL_ROOT_PASSWORD: insecure
|
||||
# MYSQL_DATABASE: photoprism
|
||||
# MYSQL_USER: photoprism
|
||||
# MYSQL_PASSWORD: insecure
|
||||
# MYSQL_DATABASE: photoprism
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
|
|
|
@ -30,12 +30,10 @@ services:
|
|||
#
|
||||
# Run "photoprism help" and "photoprism config" too see all config options and current values:
|
||||
environment: # Run "photoprism help" and "photoprism config" too see all config options and current values
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "please-change" # Initial admin password: PLEASE CHANGE!
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: This is your initial admin password
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode (shows additional log messages)
|
||||
PHOTOPRISM_PUBLIC: "false" # No authentication required (disables password protection)
|
||||
PHOTOPRISM_READONLY: "false" # Don't modify originals directory (reduced functionality)
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true" # Allow uploads that MAY be offensive
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive
|
||||
PHOTOPRISM_EXPERIMENTAL: "false" # Enable experimental features
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Canonical / public site URL
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
|
@ -44,15 +42,20 @@ services:
|
|||
PHOTOPRISM_SITE_AUTHOR: ""
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
PHOTOPRISM_SETTINGS_HIDDEN: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_BACKUPS: "false" # Don't backup photo and album metadata to YAML files
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false" # Users can not view or change settings
|
||||
PHOTOPRISM_DISABLE_PLACES: "false" # Disables reverse geocoding and maps
|
||||
PHOTOPRISM_DISABLE_EXIFTOOL: "false" # Don't create ExifTool JSON files for improved metadata extraction
|
||||
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # Don't use TensorFlow for image classification
|
||||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive (requires TensorFlow)
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true" # Allow uploads that MAY be offensive
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use Darktable presets (disables concurrent raw image conversion)
|
||||
PHOTOPRISM_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB instead of SQLite for improved performance
|
||||
# PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
|
||||
# PHOTOPRISM_DATABASE_NAME: "photoprism"
|
||||
# PHOTOPRISM_DATABASE_USER: "photoprism"
|
||||
# PHOTOPRISM_DATABASE_PASSWORD: "insecure"
|
||||
PHOTOPRISM_SIDECAR_JSON: "true" # Automatically create JSON sidecar files using Exiftool
|
||||
PHOTOPRISM_SIDECAR_YAML: "true" # Automatically backup metadata to YAML sidecar files
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB (or MySQL) instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB database user password
|
||||
PHOTOPRISM_THUMB_FILTER: "lanczos" # Resample filter, best to worst: blackman, lanczos, cubic, linear
|
||||
PHOTOPRISM_THUMB_UNCACHED: "false" # Enable on-demand thumbnail rendering (high memory and cpu usage)
|
||||
PHOTOPRISM_THUMB_SIZE: 2048 # Pre-rendered thumbnail size limit (default 2048, min 720, max 7680)
|
||||
|
@ -60,7 +63,6 @@ services:
|
|||
PHOTOPRISM_THUMB_SIZE_UNCACHED: 7680 # On-demand rendering size limit (default 7680, min 720, max 7680)
|
||||
PHOTOPRISM_JPEG_SIZE: 7680 # Size limit for converted image files in pixels (720-30000)
|
||||
PHOTOPRISM_JPEG_QUALITY: 92 # Set to 95 for high-quality thumbnails (25-100)
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Use darktable presets (disables concurrent raw to jpeg conversion)
|
||||
# You may optionally set user, group and/or file permissions using environment variables:
|
||||
# UID: 1000
|
||||
# GID: 1000
|
||||
|
@ -85,10 +87,10 @@ services:
|
|||
# volumes:
|
||||
# - "/var/lib/mysql"
|
||||
# environment:
|
||||
# MYSQL_ROOT_PASSWORD: please-change
|
||||
# MYSQL_ROOT_PASSWORD: insecure
|
||||
# MYSQL_DATABASE: photoprism
|
||||
# MYSQL_USER: photoprism
|
||||
# MYSQL_PASSWORD: insecure
|
||||
# MYSQL_DATABASE: photoprism
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
|
|
|
@ -339,7 +339,7 @@
|
|||
</v-list-tile>
|
||||
</v-list-group>
|
||||
|
||||
<template v-if="!config.disableSettings">
|
||||
<template v-if="!config.disable.settings">
|
||||
<v-list-tile v-if="mini" to="/settings" @click="" class="nav-settings">
|
||||
<v-list-tile-action :title="$gettext('Settings')">
|
||||
<v-icon>settings</v-icon>
|
||||
|
|
|
@ -327,7 +327,7 @@
|
|||
</v-checkbox>
|
||||
</v-flex>
|
||||
|
||||
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
|
||||
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2" v-if="!config.disable.places">
|
||||
<v-checkbox
|
||||
@change="onChange"
|
||||
:disabled="busy"
|
||||
|
@ -345,7 +345,7 @@
|
|||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
<v-card flat tile class="mt-0 px-1 application" v-if="settings.features.places">
|
||||
<v-card flat tile class="mt-0 px-1 application" v-if="settings.features.places && !config.disable.places">
|
||||
<v-card-title primary-title class="pb-2">
|
||||
<h3 class="body-2 mb-0">
|
||||
<translate key="Places">Places</translate>
|
||||
|
@ -400,6 +400,7 @@ export default {
|
|||
return {
|
||||
readonly: this.$config.get("readonly"),
|
||||
experimental: this.$config.get("experimental"),
|
||||
config: this.$config.values,
|
||||
settings: new Settings(this.$config.settings()),
|
||||
options: options,
|
||||
busy: false,
|
||||
|
|
|
@ -276,7 +276,7 @@ export default [
|
|||
meta: {title: $gettext("Settings"), auth: true, background: "application-light"},
|
||||
props: {tab: 0},
|
||||
beforeEnter: (to, from, next) => {
|
||||
if (c.disableSettings) {
|
||||
if (c.disable.settings) {
|
||||
next({name: "home"});
|
||||
} else {
|
||||
next();
|
||||
|
@ -290,7 +290,7 @@ export default [
|
|||
meta: {title: $gettext("Settings"), auth: true, background: "application-light"},
|
||||
props: {tab: 1},
|
||||
beforeEnter: (to, from, next) => {
|
||||
if (c.disableSettings) {
|
||||
if (c.disable.settings) {
|
||||
next({name: "home"});
|
||||
} else {
|
||||
next();
|
||||
|
@ -304,7 +304,7 @@ export default [
|
|||
meta: {title: $gettext("Settings"), auth: true, background: "application-light"},
|
||||
props: {tab: 2},
|
||||
beforeEnter: (to, from, next) => {
|
||||
if (c.disableSettings) {
|
||||
if (c.disable.settings) {
|
||||
next({name: "home"});
|
||||
} else {
|
||||
next();
|
||||
|
|
|
@ -31,7 +31,7 @@ func SaveAlbumAsYaml(a entity.Album) {
|
|||
c := service.Config()
|
||||
|
||||
// Write YAML sidecar file (optional).
|
||||
if !c.SidecarYaml() {
|
||||
if !c.BackupYaml() {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func SavePhotoAsYaml(p entity.Photo) {
|
|||
c := service.Config()
|
||||
|
||||
// Write YAML sidecar file (optional).
|
||||
if !c.SidecarYaml() {
|
||||
if !c.BackupYaml() {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ func SaveSettings(router *gin.RouterGroup) {
|
|||
|
||||
conf := service.Config()
|
||||
|
||||
if conf.SettingsHidden() {
|
||||
if conf.DisableSettings() {
|
||||
AbortUnauthorized(c)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package commands
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -35,8 +37,40 @@ func configAction(ctx *cli.Context) error {
|
|||
fmt.Printf("%-25s %s\n", "config-file", conf.ConfigFile())
|
||||
fmt.Printf("%-25s %s\n", "settings-file", conf.SettingsFile())
|
||||
|
||||
// Passwords.
|
||||
fmt.Printf("%-25s %s\n", "admin-password", conf.AdminPassword())
|
||||
// Main directories.
|
||||
fmt.Printf("%-25s %s\n", "originals-path", conf.OriginalsPath())
|
||||
fmt.Printf("%-25s %d\n", "originals-limit", conf.OriginalsLimit())
|
||||
fmt.Printf("%-25s %s\n", "import-path", conf.ImportPath())
|
||||
fmt.Printf("%-25s %s\n", "storage-path", conf.StoragePath())
|
||||
fmt.Printf("%-25s %s\n", "sidecar-path", conf.SidecarPath())
|
||||
fmt.Printf("%-25s %s\n", "albums-path", conf.AlbumsPath())
|
||||
fmt.Printf("%-25s %s\n", "cache-path", conf.CachePath())
|
||||
fmt.Printf("%-25s %s\n", "temp-path", conf.TempPath())
|
||||
fmt.Printf("%-25s %s\n", "backup-path", conf.BackupPath())
|
||||
fmt.Printf("%-25s %s\n", "assets-path", conf.AssetsPath())
|
||||
|
||||
// Asset path and file names.
|
||||
fmt.Printf("%-25s %s\n", "static-path", conf.StaticPath())
|
||||
fmt.Printf("%-25s %s\n", "build-path", conf.BuildPath())
|
||||
fmt.Printf("%-25s %s\n", "img-path", conf.ImgPath())
|
||||
fmt.Printf("%-25s %s\n", "templates-path", conf.TemplatesPath())
|
||||
|
||||
// Workers.
|
||||
fmt.Printf("%-25s %d\n", "workers", conf.Workers())
|
||||
fmt.Printf("%-25s %d\n", "wakeup-interval", conf.WakeupInterval()/time.Second)
|
||||
|
||||
// Disable features.
|
||||
fmt.Printf("%-25s %t\n", "disable-backups", conf.DisableBackups())
|
||||
fmt.Printf("%-25s %t\n", "disable-settings", conf.DisableSettings())
|
||||
fmt.Printf("%-25s %t\n", "disable-places", conf.DisablePlaces())
|
||||
fmt.Printf("%-25s %t\n", "disable-exiftool", conf.DisableExifTool())
|
||||
|
||||
// Everything related to TensorFlow.
|
||||
fmt.Printf("%-25s %t\n", "disable-tensorflow", conf.DisableTensorFlow())
|
||||
fmt.Printf("%-25s %s\n", "tensorflow-version", conf.TensorFlowVersion())
|
||||
fmt.Printf("%-25s %s\n", "tensorflow-model-path", conf.TensorFlowModelPath())
|
||||
fmt.Printf("%-25s %t\n", "detect-nsfw", conf.DetectNSFW())
|
||||
fmt.Printf("%-25s %t\n", "upload-nsfw", conf.UploadNSFW())
|
||||
|
||||
// Site information.
|
||||
fmt.Printf("%-25s %s\n", "site-url", conf.SiteUrl())
|
||||
|
@ -46,24 +80,18 @@ func configAction(ctx *cli.Context) error {
|
|||
fmt.Printf("%-25s %s\n", "site-description", conf.SiteDescription())
|
||||
fmt.Printf("%-25s %s\n", "site-author", conf.SiteAuthor())
|
||||
|
||||
// Everything related to TensorFlow.
|
||||
fmt.Printf("%-25s %t\n", "tensorflow-off", conf.TensorFlowOff())
|
||||
fmt.Printf("%-25s %s\n", "tensorflow-version", conf.TensorFlowVersion())
|
||||
fmt.Printf("%-25s %s\n", "tensorflow-model-path", conf.TensorFlowModelPath())
|
||||
fmt.Printf("%-25s %t\n", "detect-nsfw", conf.DetectNSFW())
|
||||
fmt.Printf("%-25s %t\n", "upload-nsfw", conf.UploadNSFW())
|
||||
|
||||
// Background workers and logging.
|
||||
fmt.Printf("%-25s %d\n", "workers", conf.Workers())
|
||||
fmt.Printf("%-25s %d\n", "wakeup-interval", conf.WakeupInterval()/time.Second)
|
||||
// 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.HttpServerHost())
|
||||
fmt.Printf("%-25s %d\n", "http-port", conf.HttpServerPort())
|
||||
fmt.Printf("%-25s %s\n", "http-mode", conf.HttpServerMode())
|
||||
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)
|
||||
|
@ -73,28 +101,10 @@ func configAction(ctx *cli.Context) error {
|
|||
fmt.Printf("%-25s %s\n", "database-port", conf.DatabasePortString())
|
||||
fmt.Printf("%-25s %s\n", "database-name", conf.DatabaseName())
|
||||
fmt.Printf("%-25s %s\n", "database-user", conf.DatabaseUser())
|
||||
fmt.Printf("%-25s %s\n", "database-password", conf.DatabasePassword())
|
||||
fmt.Printf("%-25s %s\n", "database-password", strings.Repeat("*", utf8.RuneCountInString(conf.DatabasePassword())))
|
||||
fmt.Printf("%-25s %d\n", "database-conns", conf.DatabaseConns())
|
||||
fmt.Printf("%-25s %d\n", "database-conns-idle", conf.DatabaseConnsIdle())
|
||||
|
||||
// Main directories.
|
||||
fmt.Printf("%-25s %s\n", "assets-path", conf.AssetsPath())
|
||||
fmt.Printf("%-25s %s\n", "storage-path", conf.StoragePath())
|
||||
fmt.Printf("%-25s %s\n", "backup-path", conf.BackupPath())
|
||||
fmt.Printf("%-25s %s\n", "albums-path", conf.AlbumsPath())
|
||||
fmt.Printf("%-25s %s\n", "import-path", conf.ImportPath())
|
||||
fmt.Printf("%-25s %s\n", "originals-path", conf.OriginalsPath())
|
||||
fmt.Printf("%-25s %d\n", "originals-limit", conf.OriginalsLimit())
|
||||
|
||||
// Additional path and file names.
|
||||
fmt.Printf("%-25s %s\n", "static-path", conf.StaticPath())
|
||||
fmt.Printf("%-25s %s\n", "build-path", conf.BuildPath())
|
||||
fmt.Printf("%-25s %s\n", "img-path", conf.ImgPath())
|
||||
fmt.Printf("%-25s %s\n", "templates-path", conf.TemplatesPath())
|
||||
fmt.Printf("%-25s %s\n", "cache-path", conf.CachePath())
|
||||
fmt.Printf("%-25s %s\n", "temp-path", conf.TempPath())
|
||||
fmt.Printf("%-25s %t\n", "settings-hidden", conf.SettingsHidden())
|
||||
|
||||
// External binaries and sidecar configuration.
|
||||
fmt.Printf("%-25s %s\n", "rawtherapee-bin", conf.RawtherapeeBin())
|
||||
fmt.Printf("%-25s %s\n", "darktable-bin", conf.DarktableBin())
|
||||
|
@ -103,12 +113,6 @@ func configAction(ctx *cli.Context) error {
|
|||
fmt.Printf("%-25s %s\n", "heifconvert-bin", conf.HeifConvertBin())
|
||||
fmt.Printf("%-25s %s\n", "ffmpeg-bin", conf.FFmpegBin())
|
||||
fmt.Printf("%-25s %s\n", "exiftool-bin", conf.ExifToolBin())
|
||||
fmt.Printf("%-25s %t\n", "sidecar-json", conf.SidecarJson())
|
||||
fmt.Printf("%-25s %t\n", "sidecar-yaml", conf.SidecarYaml())
|
||||
fmt.Printf("%-25s %s\n", "sidecar-path", conf.SidecarPath())
|
||||
|
||||
// Geo data API.
|
||||
fmt.Printf("%-25s %s\n", "geo-api", conf.GeoApi())
|
||||
|
||||
// Thumbs, resampling and download security token.
|
||||
fmt.Printf("%-25s %s\n", "download-token", conf.DownloadToken())
|
||||
|
|
|
@ -51,14 +51,14 @@ func startAction(ctx *cli.Context) error {
|
|||
fmt.Printf("NAME VALUE\n")
|
||||
fmt.Printf("detach-server %t\n", conf.DetachServer())
|
||||
|
||||
fmt.Printf("http-host %s\n", conf.HttpServerHost())
|
||||
fmt.Printf("http-port %d\n", conf.HttpServerPort())
|
||||
fmt.Printf("http-mode %s\n", conf.HttpServerMode())
|
||||
fmt.Printf("http-host %s\n", conf.HttpHost())
|
||||
fmt.Printf("http-port %d\n", conf.HttpPort())
|
||||
fmt.Printf("http-mode %s\n", conf.HttpMode())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if conf.HttpServerPort() < 1 || conf.HttpServerPort() > 65535 {
|
||||
if conf.HttpPort() < 1 || conf.HttpPort() > 65535 {
|
||||
log.Fatal("server port must be a number between 1 and 65535")
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func statusAction(ctx *cli.Context) error {
|
|||
conf := config.NewConfig(ctx)
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
|
||||
url := fmt.Sprintf("http://%s:%d/api/v1/status", conf.HttpServerHost(), conf.HttpServerPort())
|
||||
url := fmt.Sprintf("http://%s:%d/api/v1/status", conf.HttpHost(), conf.HttpPort())
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
|
||||
|
@ -34,9 +34,9 @@ func statusAction(ctx *cli.Context) error {
|
|||
var status string
|
||||
|
||||
if resp, err := client.Do(req); err != nil {
|
||||
return fmt.Errorf("can't connect to %s:%d", conf.HttpServerHost(), conf.HttpServerPort())
|
||||
return fmt.Errorf("can't connect to %s:%d", conf.HttpHost(), conf.HttpPort())
|
||||
} else if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("server running at %s:%d, bad status %d\n", conf.HttpServerHost(), conf.HttpServerPort(), resp.StatusCode)
|
||||
return fmt.Errorf("server running at %s:%d, bad status %d\n", conf.HttpHost(), conf.HttpPort(), resp.StatusCode)
|
||||
} else if body, err := ioutil.ReadAll(resp.Body); err != nil {
|
||||
return err
|
||||
} else {
|
||||
|
|
|
@ -27,7 +27,6 @@ type ClientConfig struct {
|
|||
UploadNSFW bool `json:"uploadNSFW"`
|
||||
Public bool `json:"public"`
|
||||
Experimental bool `json:"experimental"`
|
||||
DisableSettings bool `json:"disableSettings"`
|
||||
AlbumCategories []string `json:"albumCategories"`
|
||||
Albums []entity.Album `json:"albums"`
|
||||
Cameras []entity.Camera `json:"cameras"`
|
||||
|
@ -41,6 +40,7 @@ type ClientConfig struct {
|
|||
JSHash string `json:"jsHash"`
|
||||
CSSHash string `json:"cssHash"`
|
||||
Settings Settings `json:"settings"`
|
||||
Disable ClientDisable `json:"disable"`
|
||||
Count ClientCounts `json:"count"`
|
||||
Pos ClientPosition `json:"pos"`
|
||||
Years []int `json:"years"`
|
||||
|
@ -50,6 +50,14 @@ type ClientConfig struct {
|
|||
Server RuntimeInfo `json:"server"`
|
||||
}
|
||||
|
||||
// ClientDisable represents disabled client features a user can't turn back on.
|
||||
type ClientDisable struct {
|
||||
Backups bool `json:"backups"`
|
||||
Settings bool `json:"settings"`
|
||||
Places bool `json:"places"`
|
||||
}
|
||||
|
||||
// ClientCounts represents photo, video and album counts for the client UI.
|
||||
type ClientCounts struct {
|
||||
Cameras int `json:"cameras"`
|
||||
Lenses int `json:"lenses"`
|
||||
|
@ -104,7 +112,7 @@ func (c *Config) Flags() (flags []string) {
|
|||
flags = append(flags, "readonly")
|
||||
}
|
||||
|
||||
if !c.SettingsHidden() {
|
||||
if !c.DisableSettings() {
|
||||
flags = append(flags, "settings")
|
||||
}
|
||||
|
||||
|
@ -130,6 +138,11 @@ func (c *Config) PublicConfig() ClientConfig {
|
|||
Features: settings.Features,
|
||||
Share: settings.Share,
|
||||
},
|
||||
Disable: ClientDisable{
|
||||
Backups: true,
|
||||
Settings: true,
|
||||
Places: c.DisablePlaces(),
|
||||
},
|
||||
Flags: strings.Join(c.Flags(), " "),
|
||||
Name: c.Name(),
|
||||
SiteUrl: c.SiteUrl(),
|
||||
|
@ -142,7 +155,6 @@ func (c *Config) PublicConfig() ClientConfig {
|
|||
Copyright: c.Copyright(),
|
||||
Debug: c.Debug(),
|
||||
ReadOnly: c.ReadOnly(),
|
||||
DisableSettings: c.SettingsHidden(),
|
||||
Public: c.Public(),
|
||||
Experimental: c.Experimental(),
|
||||
Status: "",
|
||||
|
@ -170,6 +182,11 @@ func (c *Config) GuestConfig() ClientConfig {
|
|||
Features: settings.Features,
|
||||
Share: settings.Share,
|
||||
},
|
||||
Disable: ClientDisable{
|
||||
Backups: true,
|
||||
Settings: true,
|
||||
Places: c.DisablePlaces(),
|
||||
},
|
||||
Flags: "readonly public shared",
|
||||
Name: c.Name(),
|
||||
SiteUrl: c.SiteUrl(),
|
||||
|
@ -183,7 +200,6 @@ func (c *Config) GuestConfig() ClientConfig {
|
|||
Debug: c.Debug(),
|
||||
ReadOnly: true,
|
||||
UploadNSFW: c.UploadNSFW(),
|
||||
DisableSettings: true,
|
||||
Public: true,
|
||||
Experimental: false,
|
||||
Colors: colors.All.List(),
|
||||
|
@ -203,7 +219,12 @@ func (c *Config) GuestConfig() ClientConfig {
|
|||
// UserConfig returns client configuration values for registered users.
|
||||
func (c *Config) UserConfig() ClientConfig {
|
||||
result := ClientConfig{
|
||||
Settings: *c.Settings(),
|
||||
Settings: *c.Settings(),
|
||||
Disable: ClientDisable{
|
||||
Backups: c.DisableBackups(),
|
||||
Settings: c.DisableSettings(),
|
||||
Places: c.DisablePlaces(),
|
||||
},
|
||||
Flags: strings.Join(c.Flags(), " "),
|
||||
Name: c.Name(),
|
||||
SiteUrl: c.SiteUrl(),
|
||||
|
@ -217,7 +238,6 @@ func (c *Config) UserConfig() ClientConfig {
|
|||
Debug: c.Debug(),
|
||||
ReadOnly: c.ReadOnly(),
|
||||
UploadNSFW: c.UploadNSFW(),
|
||||
DisableSettings: c.SettingsHidden(),
|
||||
Public: c.Public(),
|
||||
Experimental: c.Experimental(),
|
||||
Colors: colors.All.List(),
|
||||
|
|
|
@ -290,15 +290,13 @@ func (c *Config) WakeupInterval() time.Duration {
|
|||
return time.Duration(c.params.WakeupInterval) * time.Second
|
||||
}
|
||||
|
||||
// GeoApi returns the preferred geo coding api (none, osm or places).
|
||||
// GeoApi returns the preferred geo coding api (none or places).
|
||||
func (c *Config) GeoApi() string {
|
||||
switch c.params.GeoApi {
|
||||
case "places":
|
||||
return "places"
|
||||
case "osm":
|
||||
return "osm"
|
||||
if c.params.DisablePlaces {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
|
||||
return "places"
|
||||
}
|
||||
|
||||
// OriginalsLimit returns the file size limit for originals.
|
||||
|
|
|
@ -63,7 +63,7 @@ func TestConfig_TensorFlowVersion(t *testing.T) {
|
|||
func TestConfig_TensorFlowDisabled(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
version := c.TensorFlowOff()
|
||||
version := c.DisableTensorFlow()
|
||||
assert.Equal(t, false, version)
|
||||
}
|
||||
|
||||
|
@ -114,31 +114,24 @@ func TestConfig_DetachServer(t *testing.T) {
|
|||
func TestConfig_HttpServerHost(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
host := c.HttpServerHost()
|
||||
host := c.HttpHost()
|
||||
assert.Equal(t, "0.0.0.0", host)
|
||||
}
|
||||
|
||||
func TestConfig_HttpServerPort(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
port := c.HttpServerPort()
|
||||
port := c.HttpPort()
|
||||
assert.Equal(t, 2342, port)
|
||||
}
|
||||
|
||||
func TestConfig_HttpServerMode(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
mode := c.HttpServerMode()
|
||||
mode := c.HttpMode()
|
||||
assert.Equal(t, "release", mode)
|
||||
}
|
||||
|
||||
func TestConfig_HttpServerPassword(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
password := c.HttpServerPassword()
|
||||
assert.Equal(t, "", password)
|
||||
}
|
||||
|
||||
func TestConfig_OriginalsPath(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
|
@ -273,11 +266,9 @@ func TestConfig_WakeupInterval(t *testing.T) {
|
|||
func TestConfig_GeoApi(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.Equal(t, "", c.GeoApi())
|
||||
c.params.GeoApi = "places"
|
||||
assert.Equal(t, "places", c.GeoApi())
|
||||
c.params.GeoApi = "osm"
|
||||
assert.Equal(t, "osm", c.GeoApi())
|
||||
c.params.DisablePlaces = true
|
||||
assert.Equal(t, "", c.GeoApi())
|
||||
}
|
||||
|
||||
func TestConfig_OriginalsLimit(t *testing.T) {
|
||||
|
|
34
internal/config/disable.go
Normal file
34
internal/config/disable.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
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.params.DisableBackups
|
||||
}
|
||||
|
||||
// DisableSettings tests if users should not be allowed to change settings.
|
||||
func (c *Config) DisableSettings() bool {
|
||||
return c.params.DisableSettings
|
||||
}
|
||||
|
||||
// DisablePlaces tests if geocoding and maps should be disabled.
|
||||
func (c *Config) DisablePlaces() bool {
|
||||
return c.params.DisablePlaces
|
||||
}
|
||||
|
||||
// DisableExifTool tests if ExifTool JSON files should not be created for improved metadata extraction.
|
||||
func (c *Config) DisableExifTool() bool {
|
||||
if !c.SidecarWritable() || c.ExifToolBin() == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return c.params.DisableExifTool
|
||||
}
|
||||
|
||||
// DisableTensorFlow tests if TensorFlow should not be used for image classification (or anything else).
|
||||
func (c *Config) DisableTensorFlow() bool {
|
||||
return c.params.DisableTensorFlow
|
||||
}
|
|
@ -37,25 +37,113 @@ var GlobalFlags = []cli.Flag{
|
|||
EnvVar: "PHOTOPRISM_CONFIG_FILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "admin-password",
|
||||
Usage: "initial admin password",
|
||||
EnvVar: "PHOTOPRISM_ADMIN_PASSWORD",
|
||||
Name: "originals-path",
|
||||
Usage: "originals `PATH` for your photo and video collection",
|
||||
EnvVar: "PHOTOPRISM_ORIGINALS_PATH",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "tensorflow-off",
|
||||
Usage: "don't use TensorFlow for image classification (or anything else)",
|
||||
EnvVar: "PHOTOPRISM_TENSORFLOW_OFF",
|
||||
cli.IntFlag{
|
||||
Name: "originals-limit",
|
||||
Value: 1000,
|
||||
Usage: "file size limit for originals in `MEGABYTE`",
|
||||
EnvVar: "PHOTOPRISM_ORIGINALS_LIMIT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "import-path",
|
||||
Usage: "optional `PATH` for importing files to originals",
|
||||
EnvVar: "PHOTOPRISM_IMPORT_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "storage-path",
|
||||
Usage: "storage `PATH` for cache, database and sidecar files",
|
||||
EnvVar: "PHOTOPRISM_STORAGE_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "sidecar-path",
|
||||
Usage: "relative or absolute storage `PATH` for sidecar files",
|
||||
EnvVar: "PHOTOPRISM_SIDECAR_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cache-path",
|
||||
Usage: "cache storage `PATH` for sessions and thumbnails",
|
||||
EnvVar: "PHOTOPRISM_CACHE_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "temp-path",
|
||||
Usage: "temporary `PATH` for uploads and downloads",
|
||||
EnvVar: "PHOTOPRISM_TEMP_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "backup-path",
|
||||
Usage: "backup storage `PATH`",
|
||||
EnvVar: "PHOTOPRISM_BACKUP_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "assets-path",
|
||||
Usage: "assets `PATH` for static resources like models and templates",
|
||||
EnvVar: "PHOTOPRISM_ASSETS_PATH",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "workers, w",
|
||||
Usage: "number of workers for indexing",
|
||||
Usage: "`LIMIT` the number of indexing workers to reduce system load",
|
||||
EnvVar: "PHOTOPRISM_WORKERS",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "wakeup-interval",
|
||||
Usage: "background worker wakeup interval in seconds",
|
||||
Usage: "background worker wakeup interval in `SECONDS`",
|
||||
EnvVar: "PHOTOPRISM_WAKEUP_INTERVAL",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-backups",
|
||||
Usage: "don't backup photo and album metadata to YAML files",
|
||||
EnvVar: "PHOTOPRISM_DISABLE_BACKUPS",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-settings",
|
||||
Usage: "users can not view or change settings",
|
||||
EnvVar: "PHOTOPRISM_DISABLE_SETTINGS",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-places",
|
||||
Usage: "disables reverse geocoding and maps",
|
||||
EnvVar: "PHOTOPRISM_DISABLE_PLACES",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-exiftool",
|
||||
Usage: "don't create ExifTool JSON files for improved metadata extraction",
|
||||
EnvVar: "PHOTOPRISM_DISABLE_EXIFTOOL",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-tensorflow",
|
||||
Usage: "don't use TensorFlow for image classification",
|
||||
EnvVar: "PHOTOPRISM_DISABLE_TENSORFLOW",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "detect-nsfw",
|
||||
Usage: "flag photos as private that may be offensive (requires TensorFlow)",
|
||||
EnvVar: "PHOTOPRISM_DETECT_NSFW",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "upload-nsfw",
|
||||
Usage: "allow uploads that may be offensive",
|
||||
EnvVar: "PHOTOPRISM_UPLOAD_NSFW",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "log-level, l",
|
||||
Usage: "trace, debug, info, warning, error, fatal or panic",
|
||||
Value: "info",
|
||||
EnvVar: "PHOTOPRISM_LOG_LEVEL",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "log-filename",
|
||||
Usage: "server log `FILENAME`",
|
||||
EnvVar: "PHOTOPRISM_LOG_FILENAME",
|
||||
Value: "",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pid-filename",
|
||||
Usage: "server process id `FILENAME`",
|
||||
EnvVar: "PHOTOPRISM_PID_FILENAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "site-url",
|
||||
Usage: "public site `URL`",
|
||||
|
@ -105,6 +193,11 @@ var GlobalFlags = []cli.Flag{
|
|||
Usage: "debug, release or test",
|
||||
EnvVar: "PHOTOPRISM_HTTP_MODE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "admin-password",
|
||||
Usage: "initial admin `PASSWORD`",
|
||||
EnvVar: "PHOTOPRISM_ADMIN_PASSWORD",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "database-driver",
|
||||
Usage: "database driver `NAME` (sqlite or mysql)",
|
||||
|
@ -140,149 +233,55 @@ var GlobalFlags = []cli.Flag{
|
|||
},
|
||||
cli.IntFlag{
|
||||
Name: "database-conns",
|
||||
Usage: "max `NUMBER` of open connections to the database",
|
||||
Usage: "`LIMIT` the number of open database connections",
|
||||
EnvVar: "PHOTOPRISM_DATABASE_CONNS",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "database-conns-idle",
|
||||
Usage: "max `NUMBER` of idle connections (equal or less than open)",
|
||||
Usage: "`LIMIT` the number of idle database connections",
|
||||
EnvVar: "PHOTOPRISM_DATABASE_CONNS_IDLE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "assets-path",
|
||||
Usage: "assets `PATH` for static files like templates and TensorFlow models",
|
||||
EnvVar: "PHOTOPRISM_ASSETS_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "storage-path",
|
||||
Usage: "storage `PATH` for cache, database and sidecar files",
|
||||
EnvVar: "PHOTOPRISM_STORAGE_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "backup-path",
|
||||
Usage: "backup storage `PATH`",
|
||||
EnvVar: "PHOTOPRISM_BACKUP_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "import-path",
|
||||
Usage: "optional import `PATH` for copying files to originals",
|
||||
EnvVar: "PHOTOPRISM_IMPORT_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "originals-path",
|
||||
Usage: "originals `PATH` for photo, video and sidecar files",
|
||||
EnvVar: "PHOTOPRISM_ORIGINALS_PATH",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "originals-limit",
|
||||
Value: 1000,
|
||||
Usage: "file size limit for originals in `MEGABYTE`",
|
||||
EnvVar: "PHOTOPRISM_ORIGINALS_LIMIT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "log-level, l",
|
||||
Usage: "trace, debug, info, warning, error, fatal or panic",
|
||||
Value: "info",
|
||||
EnvVar: "PHOTOPRISM_LOG_LEVEL",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "log-filename",
|
||||
Usage: "filename for storing server logs",
|
||||
EnvVar: "PHOTOPRISM_LOG_FILENAME",
|
||||
Value: "",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pid-filename",
|
||||
Usage: "filename for the server process id (pid)",
|
||||
EnvVar: "PHOTOPRISM_PID_FILENAME",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cache-path",
|
||||
Usage: "cache `PATH`",
|
||||
EnvVar: "PHOTOPRISM_CACHE_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "temp-path",
|
||||
Usage: "temporary `PATH` for uploads and downloads",
|
||||
EnvVar: "PHOTOPRISM_TEMP_PATH",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "settings-hidden",
|
||||
Usage: "users can not view or change settings",
|
||||
EnvVar: "PHOTOPRISM_SETTINGS_HIDDEN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "rawtherapee-bin",
|
||||
Usage: "rawtherapee-cli executable `FILENAME`",
|
||||
Usage: "RawTherapee CLI `COMMAND` for raw image conversion",
|
||||
Value: "rawtherapee-cli",
|
||||
EnvVar: "PHOTOPRISM_RAWTHERAPEE_BIN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "darktable-bin",
|
||||
Usage: "darktable-cli executable `FILENAME`",
|
||||
Usage: "Darktable CLI `COMMAND` for raw image conversion",
|
||||
Value: "darktable-cli",
|
||||
EnvVar: "PHOTOPRISM_DARKTABLE_BIN",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "darktable-presets",
|
||||
Usage: "use darktable presets (disables concurrent raw to jpeg conversion)",
|
||||
Usage: "use Darktable presets (disables concurrent raw image conversion)",
|
||||
EnvVar: "PHOTOPRISM_DARKTABLE_PRESETS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "sips-bin",
|
||||
Usage: "sips executable `FILENAME`",
|
||||
Usage: "Scriptable Image Processing System `COMMAND`",
|
||||
Value: "sips",
|
||||
EnvVar: "PHOTOPRISM_SIPS_BIN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "heifconvert-bin",
|
||||
Usage: "heif-convert executable `FILENAME`",
|
||||
Usage: "HEIC/HEIF image convert `COMMAND`",
|
||||
Value: "heif-convert",
|
||||
EnvVar: "PHOTOPRISM_HEIFCONVERT_BIN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ffmpeg-bin",
|
||||
Usage: "ffmpeg executable `FILENAME`",
|
||||
Usage: "FFmpeg `COMMAND` for video transcoding and cover images",
|
||||
Value: "ffmpeg",
|
||||
EnvVar: "PHOTOPRISM_FFMPEG_BIN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "exiftool-bin",
|
||||
Usage: "exiftool executable `FILENAME`",
|
||||
Usage: "ExifTool `COMMAND` for metadata extraction",
|
||||
Value: "exiftool",
|
||||
EnvVar: "PHOTOPRISM_EXIFTOOL_BIN",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "sidecar-json, j",
|
||||
Usage: "automatically create JSON sidecar files using Exiftool",
|
||||
EnvVar: "PHOTOPRISM_SIDECAR_JSON",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "sidecar-yaml, y",
|
||||
Usage: "automatically backup metadata to YAML sidecar files",
|
||||
EnvVar: "PHOTOPRISM_SIDECAR_YAML",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "sidecar-path",
|
||||
Usage: "storage `PATH` for generated sidecar files (relative or absolute)",
|
||||
EnvVar: "PHOTOPRISM_SIDECAR_PATH",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "detect-nsfw",
|
||||
Usage: "flag photos as private that may be offensive",
|
||||
EnvVar: "PHOTOPRISM_DETECT_NSFW",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "upload-nsfw",
|
||||
Usage: "allow uploads that may be offensive",
|
||||
EnvVar: "PHOTOPRISM_UPLOAD_NSFW",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "geo-api, g",
|
||||
Usage: "geo data api (none, osm or places)",
|
||||
Value: "places",
|
||||
EnvVar: "PHOTOPRISM_GEO_API",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "download-token",
|
||||
Usage: "`SECRET` url token for file downloads",
|
||||
|
|
|
@ -216,21 +216,13 @@ func (c *Config) ExifToolBin() string {
|
|||
}
|
||||
|
||||
// Automatically create JSON sidecar files using Exiftool.
|
||||
func (c *Config) SidecarJson() bool {
|
||||
if !c.SidecarWritable() || c.ExifToolBin() == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return c.params.SidecarJson
|
||||
func (c *Config) ExifToolJson() bool {
|
||||
return !c.DisableExifTool()
|
||||
}
|
||||
|
||||
// Automatically backup metadata to YAML sidecar files.
|
||||
func (c *Config) SidecarYaml() bool {
|
||||
if !c.SidecarWritable() {
|
||||
return false
|
||||
}
|
||||
|
||||
return c.params.SidecarYaml
|
||||
func (c *Config) BackupYaml() bool {
|
||||
return !c.DisableBackups()
|
||||
}
|
||||
|
||||
// SidecarPath returns the storage path for generated sidecar files (relative or absolute).
|
||||
|
@ -266,7 +258,7 @@ func (c *Config) TempPath() string {
|
|||
return fs.Abs(c.params.TempPath)
|
||||
}
|
||||
|
||||
// CachePath returns the path to the cache.
|
||||
// CachePath returns the path for cache files.
|
||||
func (c *Config) CachePath() string {
|
||||
if c.params.CachePath == "" {
|
||||
return filepath.Join(c.StoragePath(), "cache")
|
||||
|
@ -326,7 +318,7 @@ func (c *Config) BackupPath() string {
|
|||
return filepath.Join(c.StoragePath(), "backup")
|
||||
}
|
||||
|
||||
// AssetsPath returns the path to static assets.
|
||||
// AssetsPath returns the path to static assets for models and templates.
|
||||
func (c *Config) AssetsPath() string {
|
||||
if c.params.AssetsPath == "" {
|
||||
// Try to find the right directory by iterating through a list.
|
||||
|
|
|
@ -13,17 +13,26 @@ func TestConfig_FindExecutable(t *testing.T) {
|
|||
|
||||
func TestConfig_SidecarJson(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
assert.Equal(t, false, c.SidecarJson())
|
||||
c.params.ReadOnly = true
|
||||
assert.Equal(t, false, c.SidecarJson())
|
||||
|
||||
assert.Equal(t, true, c.ExifToolJson())
|
||||
assert.Equal(t, c.DisableExifTool(), !c.ExifToolJson())
|
||||
|
||||
c.params.DisableExifTool = true
|
||||
|
||||
assert.Equal(t, false, c.ExifToolJson())
|
||||
assert.Equal(t, c.DisableExifTool(), !c.ExifToolJson())
|
||||
}
|
||||
|
||||
func TestConfig_SidecarYaml(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.Equal(t, false, c.SidecarYaml())
|
||||
c.params.ReadOnly = true
|
||||
assert.Equal(t, false, c.SidecarJson())
|
||||
assert.Equal(t, true, c.BackupYaml())
|
||||
assert.Equal(t, c.DisableBackups(), !c.BackupYaml())
|
||||
|
||||
c.params.DisableBackups = true
|
||||
|
||||
assert.Equal(t, false, c.BackupYaml())
|
||||
assert.Equal(t, c.DisableBackups(), !c.BackupYaml())
|
||||
}
|
||||
|
||||
func TestConfig_SidecarPath(t *testing.T) {
|
||||
|
|
|
@ -30,71 +30,71 @@ const (
|
|||
//
|
||||
// See https://github.com/photoprism/photoprism/issues/50#issuecomment-433856358
|
||||
type Params struct {
|
||||
Name string
|
||||
Version string
|
||||
Copyright string
|
||||
Debug bool `yaml:"debug" flag:"debug"`
|
||||
Public bool `yaml:"public" flag:"public"`
|
||||
ReadOnly bool `yaml:"read-only" flag:"read-only"`
|
||||
Experimental bool `yaml:"experimental" flag:"experimental"`
|
||||
ConfigPath string `yaml:"config-path" flag:"config-path"`
|
||||
ConfigFile string
|
||||
AdminPassword string `yaml:"admin-password" flag:"admin-password"`
|
||||
SiteUrl string `yaml:"site-url" flag:"site-url"`
|
||||
SitePreview string `yaml:"site-preview" flag:"site-preview"`
|
||||
SiteTitle string `yaml:"site-title" flag:"site-title"`
|
||||
SiteCaption string `yaml:"site-caption" flag:"site-caption"`
|
||||
SiteDescription string `yaml:"site-description" flag:"site-description"`
|
||||
SiteAuthor string `yaml:"site-author" flag:"site-author"`
|
||||
TensorFlowOff bool `yaml:"tensorflow-off" flag:"tensorflow-off"`
|
||||
Workers int `yaml:"workers" flag:"workers"`
|
||||
WakeupInterval int `yaml:"wakeup-interval" flag:"wakeup-interval"`
|
||||
LogLevel string `yaml:"log-level" flag:"log-level"`
|
||||
AssetsPath string `yaml:"assets-path" flag:"assets-path"`
|
||||
StoragePath string `yaml:"storage-path" flag:"storage-path"`
|
||||
BackupPath string `yaml:"backup-path" flag:"backup-path"`
|
||||
ImportPath string `yaml:"import-path" flag:"import-path"`
|
||||
OriginalsPath string `yaml:"originals-path" flag:"originals-path"`
|
||||
OriginalsLimit int64 `yaml:"originals-limit" flag:"originals-limit"`
|
||||
SettingsHidden bool `yaml:"settings-hidden" flag:"settings-hidden"`
|
||||
TempPath string `yaml:"temp-path" flag:"temp-path"`
|
||||
CachePath string `yaml:"cache-path" flag:"cache-path"`
|
||||
DatabaseDriver string `yaml:"database-driver" flag:"database-driver"`
|
||||
DatabaseDsn string `yaml:"database-dsn" flag:"database-dsn"`
|
||||
DatabaseServer string `yaml:"database-server" flag:"database-server"`
|
||||
DatabaseName string `yaml:"database-name" flag:"database-name"`
|
||||
DatabaseUser string `yaml:"database-user" flag:"database-user"`
|
||||
DatabasePassword string `yaml:"database-password" flag:"database-password"`
|
||||
DatabaseConns int `yaml:"database-conns" flag:"database-conns"`
|
||||
DatabaseConnsIdle int `yaml:"database-conns-idle" flag:"database-conns-idle"`
|
||||
HttpServerHost string `yaml:"http-host" flag:"http-host"`
|
||||
HttpServerPort int `yaml:"http-port" flag:"http-port"`
|
||||
HttpServerMode string `yaml:"http-mode" flag:"http-mode"`
|
||||
HttpServerPassword string `yaml:"http-password" flag:"http-password"`
|
||||
SipsBin string `yaml:"sips-bin" flag:"sips-bin"`
|
||||
RawtherapeeBin string `yaml:"rawtherapee-bin" flag:"rawtherapee-bin"`
|
||||
DarktableBin string `yaml:"darktable-bin" flag:"darktable-bin"`
|
||||
DarktablePresets bool `yaml:"darktable-presets" flag:"darktable-presets"`
|
||||
HeifConvertBin string `yaml:"heifconvert-bin" flag:"heifconvert-bin"`
|
||||
FFmpegBin string `yaml:"ffmpeg-bin" flag:"ffmpeg-bin"`
|
||||
ExifToolBin string `yaml:"exiftool-bin" flag:"exiftool-bin"`
|
||||
SidecarJson bool `yaml:"sidecar-json" flag:"sidecar-json"`
|
||||
SidecarYaml bool `yaml:"sidecar-yaml" flag:"sidecar-yaml"`
|
||||
SidecarPath string `yaml:"sidecar-path" flag:"sidecar-path"`
|
||||
PIDFilename string `yaml:"pid-filename" flag:"pid-filename"`
|
||||
LogFilename string `yaml:"log-filename" flag:"log-filename"`
|
||||
DetachServer bool `yaml:"detach-server" flag:"detach-server"`
|
||||
DetectNSFW bool `yaml:"detect-nsfw" flag:"detect-nsfw"`
|
||||
UploadNSFW bool `yaml:"upload-nsfw" flag:"upload-nsfw"`
|
||||
GeoApi string `yaml:"geo-api" flag:"geo-api"`
|
||||
DownloadToken string `yaml:"download-token" flag:"download-token"`
|
||||
PreviewToken string `yaml:"preview-token" flag:"preview-token"`
|
||||
ThumbFilter string `yaml:"thumb-filter" flag:"thumb-filter"`
|
||||
ThumbUncached bool `yaml:"thumb-uncached" flag:"thumb-uncached"`
|
||||
ThumbSize int `yaml:"thumb-size" flag:"thumb-size"`
|
||||
ThumbSizeUncached int `yaml:"thumb-size-uncached" flag:"thumb-size-uncached"`
|
||||
JpegSize int `yaml:"jpeg-size" flag:"jpeg-size"`
|
||||
JpegQuality int `yaml:"jpeg-quality" flag:"jpeg-quality"`
|
||||
Name string
|
||||
Version string
|
||||
Copyright string
|
||||
Debug bool `yaml:"Debug" flag:"debug"`
|
||||
Public bool `yaml:"Public" flag:"public"`
|
||||
ReadOnly bool `yaml:"ReadOnly" flag:"read-only"`
|
||||
Experimental bool `yaml:"Experimental" flag:"experimental"`
|
||||
ConfigPath string `yaml:"ConfigPath" flag:"config-path"`
|
||||
ConfigFile string
|
||||
AdminPassword string `yaml:"AdminPassword" flag:"admin-password"`
|
||||
OriginalsPath string `yaml:"OriginalsPath" flag:"originals-path"`
|
||||
OriginalsLimit int64 `yaml:"OriginalsLimit" flag:"originals-limit"`
|
||||
ImportPath string `yaml:"ImportPath" flag:"import-path"`
|
||||
StoragePath string `yaml:"StoragePath" flag:"storage-path"`
|
||||
SidecarPath string `yaml:"SidecarPath" flag:"sidecar-path"`
|
||||
TempPath string `yaml:"TempPath" flag:"temp-path"`
|
||||
BackupPath string `yaml:"BackupPath" flag:"backup-path"`
|
||||
AssetsPath string `yaml:"AssetsPath" flag:"assets-path"`
|
||||
CachePath string `yaml:"CachePath" flag:"cache-path"`
|
||||
Workers int `yaml:"Workers" flag:"workers"`
|
||||
WakeupInterval int `yaml:"WakeupInterval" flag:"wakeup-interval"`
|
||||
DisableBackups bool `yaml:"DisableBackups" flag:"disable-backups"`
|
||||
DisableSettings bool `yaml:"DisableSettings" flag:"disable-settings"`
|
||||
DisablePlaces bool `yaml:"DisablePlaces" flag:"disable-places"`
|
||||
DisableExifTool bool `yaml:"DisableExifTool" flag:"disable-exiftool"`
|
||||
DisableTensorFlow bool `yaml:"DisableTensorFlow" flag:"disable-tensorflow"`
|
||||
DetectNSFW bool `yaml:"DetectNSFW" flag:"detect-nsfw"`
|
||||
UploadNSFW bool `yaml:"UploadNSFW" flag:"upload-nsfw"`
|
||||
LogLevel string `yaml:"LogLevel" flag:"log-level"`
|
||||
LogFilename string `yaml:"LogFilename" flag:"log-filename"`
|
||||
PIDFilename string `yaml:"PIDFilename" flag:"pid-filename"`
|
||||
SiteUrl string `yaml:"SiteUrl" flag:"site-url"`
|
||||
SitePreview string `yaml:"SitePreview" flag:"site-preview"`
|
||||
SiteTitle string `yaml:"SiteTitle" flag:"site-title"`
|
||||
SiteCaption string `yaml:"SiteCaption" flag:"site-caption"`
|
||||
SiteDescription string `yaml:"SiteDescription" flag:"site-description"`
|
||||
SiteAuthor string `yaml:"SiteAuthor" flag:"site-author"`
|
||||
DatabaseDriver string `yaml:"DatabaseDriver" flag:"database-driver"`
|
||||
DatabaseDsn string `yaml:"DatabaseDsn" flag:"database-dsn"`
|
||||
DatabaseServer string `yaml:"DatabaseServer" flag:"database-server"`
|
||||
DatabaseName string `yaml:"DatabaseName" flag:"database-name"`
|
||||
DatabaseUser string `yaml:"DatabaseUser" flag:"database-user"`
|
||||
DatabasePassword string `yaml:"DatabasePassword" flag:"database-password"`
|
||||
DatabaseConns int `yaml:"DatabaseConns" flag:"database-conns"`
|
||||
DatabaseConnsIdle int `yaml:"DatabaseConnsIdle" flag:"database-conns-idle"`
|
||||
HttpHost string `yaml:"HttpHost" flag:"http-host"`
|
||||
HttpPort int `yaml:"HttpPort" flag:"http-port"`
|
||||
HttpMode string `yaml:"HttpMode" flag:"http-mode"`
|
||||
SipsBin string `yaml:"SipsBin" flag:"sips-bin"`
|
||||
RawtherapeeBin string `yaml:"RawtherapeeBin" flag:"rawtherapee-bin"`
|
||||
DarktableBin string `yaml:"DarktableBin" flag:"darktable-bin"`
|
||||
DarktablePresets bool `yaml:"DarktablePresets" flag:"darktable-presets"`
|
||||
HeifConvertBin string `yaml:"HeifConvertBin" flag:"heifconvert-bin"`
|
||||
FFmpegBin string `yaml:"FFmpegBin" flag:"ffmpeg-bin"`
|
||||
ExifToolBin string `yaml:"ExifToolBin" flag:"exiftool-bin"`
|
||||
BackupYaml bool `yaml:"BackupYaml" flag:"backup-yaml"`
|
||||
DetachServer bool `yaml:"DetachServer" flag:"detach-server"`
|
||||
DownloadToken string `yaml:"DownloadToken" flag:"download-token"`
|
||||
PreviewToken string `yaml:"PreviewToken" flag:"preview-token"`
|
||||
ThumbFilter string `yaml:"ThumbFilter" flag:"thumb-filter"`
|
||||
ThumbUncached bool `yaml:"ThumbUncached" flag:"thumb-uncached"`
|
||||
ThumbSize int `yaml:"ThumbSize" flag:"thumb-size"`
|
||||
ThumbSizeUncached int `yaml:"ThumbSizeUncached" flag:"thumb-size-uncached"`
|
||||
JpegSize int `yaml:"JpegSize" flag:"jpeg-size"`
|
||||
JpegQuality int `yaml:"JpegQuality" flag:"jpeg-quality"`
|
||||
}
|
||||
|
||||
// NewParams creates a new configuration entity by using two methods:
|
||||
|
|
|
@ -38,7 +38,7 @@ func TestParams_SetValuesFromFile(t *testing.T) {
|
|||
assert.Equal(t, "/srv/photoprism/temp", c.TempPath)
|
||||
assert.NotEmpty(t, c.DatabaseDriver)
|
||||
assert.NotEmpty(t, c.DatabaseDsn)
|
||||
assert.Equal(t, 81, c.HttpServerPort)
|
||||
assert.Equal(t, 81, c.HttpPort)
|
||||
}
|
||||
|
||||
func TestParams_ExpandFilenames(t *testing.T) {
|
||||
|
|
|
@ -11,27 +11,27 @@ func (c *Config) DetachServer() bool {
|
|||
return c.params.DetachServer
|
||||
}
|
||||
|
||||
// HttpServerHost returns the built-in HTTP server host name or IP address (empty for all interfaces).
|
||||
func (c *Config) HttpServerHost() string {
|
||||
if c.params.HttpServerHost == "" {
|
||||
// HttpHost returns the built-in HTTP server host name or IP address (empty for all interfaces).
|
||||
func (c *Config) HttpHost() string {
|
||||
if c.params.HttpHost == "" {
|
||||
return "0.0.0.0"
|
||||
}
|
||||
|
||||
return c.params.HttpServerHost
|
||||
return c.params.HttpHost
|
||||
}
|
||||
|
||||
// HttpServerPort returns the built-in HTTP server port.
|
||||
func (c *Config) HttpServerPort() int {
|
||||
if c.params.HttpServerPort == 0 {
|
||||
// HttpPort returns the built-in HTTP server port.
|
||||
func (c *Config) HttpPort() int {
|
||||
if c.params.HttpPort == 0 {
|
||||
return 2342
|
||||
}
|
||||
|
||||
return c.params.HttpServerPort
|
||||
return c.params.HttpPort
|
||||
}
|
||||
|
||||
// HttpServerMode returns the server mode.
|
||||
func (c *Config) HttpServerMode() string {
|
||||
if c.params.HttpServerMode == "" {
|
||||
// HttpMode returns the server mode.
|
||||
func (c *Config) HttpMode() string {
|
||||
if c.params.HttpMode == "" {
|
||||
if c.Debug() {
|
||||
return "debug"
|
||||
}
|
||||
|
@ -39,12 +39,7 @@ func (c *Config) HttpServerMode() string {
|
|||
return "release"
|
||||
}
|
||||
|
||||
return c.params.HttpServerMode
|
||||
}
|
||||
|
||||
// HttpServerPassword returns the password for the user interface (optional).
|
||||
func (c *Config) HttpServerPassword() string {
|
||||
return c.params.HttpServerPassword
|
||||
return c.params.HttpMode
|
||||
}
|
||||
|
||||
// TemplatesPath returns the server templates path.
|
||||
|
|
|
@ -9,27 +9,27 @@ import (
|
|||
func TestConfig_HttpServerHost2(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.Equal(t, "0.0.0.0", c.HttpServerHost())
|
||||
c.params.HttpServerHost = "test"
|
||||
assert.Equal(t, "test", c.HttpServerHost())
|
||||
assert.Equal(t, "0.0.0.0", c.HttpHost())
|
||||
c.params.HttpHost = "test"
|
||||
assert.Equal(t, "test", c.HttpHost())
|
||||
}
|
||||
|
||||
func TestConfig_HttpServerPort2(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.Equal(t, int(2342), c.HttpServerPort())
|
||||
c.params.HttpServerPort = int(1234)
|
||||
assert.Equal(t, int(1234), c.HttpServerPort())
|
||||
assert.Equal(t, int(2342), c.HttpPort())
|
||||
c.params.HttpPort = int(1234)
|
||||
assert.Equal(t, int(1234), c.HttpPort())
|
||||
}
|
||||
|
||||
func TestConfig_HttpServerMode2(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
|
||||
assert.Equal(t, "release", c.HttpServerMode())
|
||||
assert.Equal(t, "release", c.HttpMode())
|
||||
c.params.Debug = true
|
||||
assert.Equal(t, "debug", c.HttpServerMode())
|
||||
c.params.HttpServerMode = "test"
|
||||
assert.Equal(t, "test", c.HttpServerMode())
|
||||
assert.Equal(t, "debug", c.HttpMode())
|
||||
c.params.HttpMode = "test"
|
||||
assert.Equal(t, "test", c.HttpMode())
|
||||
}
|
||||
|
||||
func TestConfig_TemplateName(t *testing.T) {
|
||||
|
|
|
@ -13,89 +13,84 @@ import (
|
|||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// SettingsHidden returns true if the user is not allowed to change settings.
|
||||
func (c *Config) SettingsHidden() bool {
|
||||
return c.params.SettingsHidden
|
||||
}
|
||||
|
||||
// UISettings represents user interface settings.
|
||||
type UISettings struct {
|
||||
Scrollbar bool `json:"scrollbar" yaml:"scrollbar"`
|
||||
Theme string `json:"theme" yaml:"theme"`
|
||||
Language string `json:"language" yaml:"language"`
|
||||
Scrollbar bool `json:"scrollbar" yaml:"Scrollbar"`
|
||||
Theme string `json:"theme" yaml:"Theme"`
|
||||
Language string `json:"language" yaml:"Language"`
|
||||
}
|
||||
|
||||
// TemplateSettings represents template settings for the UI and messaging.
|
||||
type TemplateSettings struct {
|
||||
Default string `json:"default" yaml:"default"`
|
||||
Default string `json:"default" yaml:"Default"`
|
||||
}
|
||||
|
||||
// MapsSettings represents maps settings (for places).
|
||||
type MapsSettings struct {
|
||||
Animate int `json:"animate" yaml:"animate"`
|
||||
Style string `json:"style" yaml:"style"`
|
||||
Animate int `json:"animate" yaml:"Animate"`
|
||||
Style string `json:"style" yaml:"Style"`
|
||||
}
|
||||
|
||||
// FeatureSettings represents feature flags, mainly for the Web UI.
|
||||
type FeatureSettings struct {
|
||||
Upload bool `json:"upload" yaml:"upload"`
|
||||
Download bool `json:"download" yaml:"download"`
|
||||
Private bool `json:"private" yaml:"private"`
|
||||
Review bool `json:"review" yaml:"review"`
|
||||
Files bool `json:"files" yaml:"files"`
|
||||
Moments bool `json:"moments" yaml:"moments"`
|
||||
Labels bool `json:"labels" yaml:"labels"`
|
||||
Places bool `json:"places" yaml:"places"`
|
||||
Edit bool `json:"edit" yaml:"edit"`
|
||||
Archive bool `json:"archive" yaml:"archive"`
|
||||
Delete bool `json:"delete" yaml:"delete"`
|
||||
Share bool `json:"share" yaml:"share"`
|
||||
Library bool `json:"library" yaml:"library"`
|
||||
Import bool `json:"import" yaml:"import"`
|
||||
Logs bool `json:"logs" yaml:"logs"`
|
||||
Upload bool `json:"upload" yaml:"Upload"`
|
||||
Download bool `json:"download" yaml:"Download"`
|
||||
Private bool `json:"private" yaml:"Private"`
|
||||
Review bool `json:"review" yaml:"Review"`
|
||||
Files bool `json:"files" yaml:"Files"`
|
||||
Moments bool `json:"moments" yaml:"Moments"`
|
||||
Labels bool `json:"labels" yaml:"Labels"`
|
||||
Places bool `json:"places" yaml:"Places"`
|
||||
Edit bool `json:"edit" yaml:"Edit"`
|
||||
Archive bool `json:"archive" yaml:"Archive"`
|
||||
Delete bool `json:"delete" yaml:"Delete"`
|
||||
Share bool `json:"share" yaml:"Share"`
|
||||
Library bool `json:"library" yaml:"Library"`
|
||||
Import bool `json:"import" yaml:"Import"`
|
||||
Logs bool `json:"logs" yaml:"Logs"`
|
||||
}
|
||||
|
||||
// ImportSettings represents import settings.
|
||||
type ImportSettings struct {
|
||||
Path string `json:"path" yaml:"path"`
|
||||
Move bool `json:"move" yaml:"move"`
|
||||
Path string `json:"path" yaml:"Path"`
|
||||
Move bool `json:"move" yaml:"Move"`
|
||||
}
|
||||
|
||||
// IndexSettings represents indexing settings.
|
||||
type IndexSettings struct {
|
||||
Path string `json:"path" yaml:"path"`
|
||||
Convert bool `json:"convert" yaml:"convert"`
|
||||
Rescan bool `json:"rescan" yaml:"rescan"`
|
||||
Path string `json:"path" yaml:"Path"`
|
||||
Convert bool `json:"convert" yaml:"Convert"`
|
||||
Rescan bool `json:"rescan" yaml:"Rescan"`
|
||||
}
|
||||
|
||||
// StackSettings represents settings for files that belong to the same photo.
|
||||
type StackSettings struct {
|
||||
UUID bool `json:"uuid" yaml:"uuid"`
|
||||
Meta bool `json:"meta" yaml:"meta"`
|
||||
Name bool `json:"name" yaml:"name"`
|
||||
UUID bool `json:"uuid" yaml:"UUID"`
|
||||
Meta bool `json:"meta" yaml:"Meta"`
|
||||
Name bool `json:"name" yaml:"Name"`
|
||||
}
|
||||
|
||||
// ShareSettings represents content sharing settings.
|
||||
type ShareSettings struct {
|
||||
Title string `json:"title" yaml:"title"`
|
||||
Title string `json:"title" yaml:"Title"`
|
||||
}
|
||||
|
||||
// DownloadSettings represents content download settings.
|
||||
type DownloadSettings struct {
|
||||
Name entity.DownloadName `json:"name" yaml:"name"`
|
||||
Name entity.DownloadName `json:"name" yaml:"Name"`
|
||||
}
|
||||
|
||||
// Settings represents user settings for Web UI, indexing, and import.
|
||||
type Settings struct {
|
||||
UI UISettings `json:"ui" yaml:"ui"`
|
||||
Templates TemplateSettings `json:"templates" yaml:"templates"`
|
||||
Maps MapsSettings `json:"maps" yaml:"maps"`
|
||||
Features FeatureSettings `json:"features" yaml:"features"`
|
||||
Import ImportSettings `json:"import" yaml:"import"`
|
||||
Index IndexSettings `json:"index" yaml:"index"`
|
||||
Stack StackSettings `json:"stack" yaml:"stack"`
|
||||
Share ShareSettings `json:"share" yaml:"share"`
|
||||
Download DownloadSettings `json:"download" yaml:"download"`
|
||||
UI UISettings `json:"ui" yaml:"UI"`
|
||||
Templates TemplateSettings `json:"templates" yaml:"Templates"`
|
||||
Maps MapsSettings `json:"maps" yaml:"Maps"`
|
||||
Features FeatureSettings `json:"features" yaml:"Features"`
|
||||
Import ImportSettings `json:"import" yaml:"Import"`
|
||||
Index IndexSettings `json:"index" yaml:"Index"`
|
||||
Stack StackSettings `json:"stack" yaml:"Stack"`
|
||||
Share ShareSettings `json:"share" yaml:"Share"`
|
||||
Download DownloadSettings `json:"download" yaml:"Download"`
|
||||
}
|
||||
|
||||
// NewSettings creates a new Settings instance.
|
||||
|
@ -234,5 +229,9 @@ func (c *Config) Settings() *Settings {
|
|||
c.initSettings()
|
||||
}
|
||||
|
||||
if c.DisablePlaces() {
|
||||
c.settings.Features.Places = false
|
||||
}
|
||||
|
||||
return c.settings
|
||||
}
|
||||
|
|
|
@ -11,11 +11,6 @@ func (c *Config) TensorFlowVersion() string {
|
|||
return tf.Version()
|
||||
}
|
||||
|
||||
// TensorFlowOff returns true if TensorFlow should NOT be used for image classification (or anything else).
|
||||
func (c *Config) TensorFlowOff() bool {
|
||||
return c.params.TensorFlowOff
|
||||
}
|
||||
|
||||
// TensorFlowModelPath returns the TensorFlow model path.
|
||||
func (c *Config) TensorFlowModelPath() string {
|
||||
return filepath.Join(c.AssetsPath(), "nasnet")
|
||||
|
|
30
internal/config/testdata/config.yml
vendored
30
internal/config/testdata/config.yml
vendored
|
@ -1,15 +1,15 @@
|
|||
debug: false
|
||||
darktable-cli: /usr/bin/darktable-cli
|
||||
assets-path: /srv/photoprism
|
||||
cache-path: /srv/photoprism/cache
|
||||
originals-path: /srv/photoprism/photos/originals
|
||||
import-path: /srv/photoprism/photos/import
|
||||
temp-path: /srv/photoprism/temp
|
||||
http-host:
|
||||
http-mode: release
|
||||
http-port: 81
|
||||
http-password:
|
||||
database-driver: sqlite
|
||||
database-dsn: .photoprism.db
|
||||
theme: lavendel
|
||||
language: english
|
||||
Debug: false
|
||||
DarktableBin: /usr/bin/darktable-cli
|
||||
AssetsPath: /srv/photoprism
|
||||
CachePath: /srv/photoprism/cache
|
||||
OriginalsPath: /srv/photoprism/photos/originals
|
||||
ImportPath: /srv/photoprism/photos/import
|
||||
TempPath: /srv/photoprism/temp
|
||||
HttpServerHost:
|
||||
HttpMode: release
|
||||
HttpPort: 81
|
||||
HttpPassword:
|
||||
DatabaseDriver: sqlite
|
||||
DatabaseDsn: .photoprism.db
|
||||
Theme: lavendel
|
||||
Language: english
|
||||
|
|
80
internal/config/testdata/settings.yml
vendored
80
internal/config/testdata/settings.yml
vendored
|
@ -1,40 +1,40 @@
|
|||
ui:
|
||||
scrollbar: true
|
||||
theme: onyx
|
||||
language: de
|
||||
templates:
|
||||
default: index.tmpl
|
||||
maps:
|
||||
animate: 0
|
||||
style: streets
|
||||
features:
|
||||
upload: true
|
||||
download: true
|
||||
private: true
|
||||
review: true
|
||||
files: true
|
||||
moments: true
|
||||
labels: true
|
||||
places: true
|
||||
edit: true
|
||||
archive: true
|
||||
delete: false
|
||||
share: true
|
||||
library: true
|
||||
import: true
|
||||
logs: true
|
||||
import:
|
||||
path: /
|
||||
move: false
|
||||
index:
|
||||
path: /
|
||||
convert: true
|
||||
rescan: false
|
||||
stack:
|
||||
uuid: true
|
||||
meta: true
|
||||
name: false
|
||||
share:
|
||||
title: ""
|
||||
download:
|
||||
name: file
|
||||
UI:
|
||||
Scrollbar: true
|
||||
Theme: onyx
|
||||
Language: de
|
||||
Templates:
|
||||
Default: index.tmpl
|
||||
Maps:
|
||||
Animate: 0
|
||||
Style: streets
|
||||
Features:
|
||||
Upload: true
|
||||
Download: true
|
||||
Private: true
|
||||
Review: true
|
||||
Files: true
|
||||
Moments: true
|
||||
Labels: true
|
||||
Places: true
|
||||
Edit: true
|
||||
Archive: true
|
||||
Delete: false
|
||||
Share: true
|
||||
Library: true
|
||||
Import: true
|
||||
Logs: true
|
||||
Import:
|
||||
Path: /
|
||||
Move: false
|
||||
Index:
|
||||
Path: /
|
||||
Convert: true
|
||||
Rescan: false
|
||||
Stack:
|
||||
UUID: true
|
||||
Meta: true
|
||||
Name: false
|
||||
Share:
|
||||
Title: ""
|
||||
Download:
|
||||
Name: file
|
||||
|
|
|
@ -13,7 +13,7 @@ type PhotoAlbum struct {
|
|||
Order int `json:"Order" yaml:"Order,omitempty"`
|
||||
Hidden bool `json:"Hidden" yaml:"Hidden,omitempty"`
|
||||
CreatedAt time.Time `json:"CreatedAt" yaml:"CreatedAt,omitempty"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt" yaml:"UpdatedAt,omitempty"`
|
||||
UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"`
|
||||
Photo *Photo `gorm:"PRELOAD:false" yaml:"-"`
|
||||
Album *Album `gorm:"PRELOAD:true" yaml:"-"`
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ import (
|
|||
|
||||
// Config represents backend api credentials for maps & geodata.
|
||||
type Config struct {
|
||||
Key string `json:"key" yaml:"key"`
|
||||
Secret string `json:"secret" yaml:"secret"`
|
||||
Session string `json:"session" yaml:"session"`
|
||||
Status string `json:"status" yaml:"status"`
|
||||
Version string `json:"version" yaml:"version"`
|
||||
Serial string `json:"serial" yaml:"serial"`
|
||||
Key string `json:"key" yaml:"Key"`
|
||||
Secret string `json:"secret" yaml:"Secret"`
|
||||
Session string `json:"session" yaml:"Session"`
|
||||
Status string `json:"status" yaml:"Status"`
|
||||
Version string `json:"version" yaml:"Version"`
|
||||
Serial string `json:"serial" yaml:"Serial"`
|
||||
FileName string `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
|
|
10
internal/hub/testdata/hub1.yml
vendored
10
internal/hub/testdata/hub1.yml
vendored
|
@ -1,5 +1,5 @@
|
|||
key: b32e9ccdc90eb7c0f6f1b9fbc82b8a2b0e993304
|
||||
secret: 5991ea36a9611e9e00a8360c10b91567
|
||||
session: 3ef5685c6391a568731c8fc94ccad82d92dea60476c8b672990047c822248f45366fc0e8e812ad15e0b5ae1eb20e866235c56b
|
||||
status: unregistered
|
||||
version: 0.0.0
|
||||
Key: b32e9ccdc90eb7c0f6f1b9fbc82b8a2b0e993304
|
||||
Secret: 5991ea36a9611e9e00a8360c10b91567
|
||||
Session: 3ef5685c6391a568731c8fc94ccad82d92dea60476c8b672990047c822248f45366fc0e8e812ad15e0b5ae1eb20e866235c56b
|
||||
Status: unregistered
|
||||
Version: 0.0.0
|
||||
|
|
10
internal/hub/testdata/hub2.yml
vendored
10
internal/hub/testdata/hub2.yml
vendored
|
@ -1,5 +1,5 @@
|
|||
key: ab66cb5cfb3658dbea0a1433df048d900934ac68
|
||||
secret: 6b0f8440fe307d3120b3a4366350094b
|
||||
session: c0ca88fc3094b70a1947b5b10f980a420cd6b1542a20f6f26ecc6a16f340473b9fb16b80be1078e86d886b3a8d46bf8184d147
|
||||
status: unregistered
|
||||
version: 200925-f8e2b580-Darwin-i386-DEBUG
|
||||
Key: ab66cb5cfb3658dbea0a1433df048d900934ac68
|
||||
Secret: 6b0f8440fe307d3120b3a4366350094b
|
||||
Session: c0ca88fc3094b70a1947b5b10f980a420cd6b1542a20f6f26ecc6a16f340473b9fb16b80be1078e86d886b3a8d46bf8184d147
|
||||
Status: unregistered
|
||||
Version: 200925-f8e2b580-Darwin-i386-DEBUG
|
||||
|
|
10
internal/hub/testdata/hub3.yml
vendored
10
internal/hub/testdata/hub3.yml
vendored
|
@ -1,5 +1,5 @@
|
|||
key: 8dd8b115d052f91ac74b1c2475e305009366c487
|
||||
secret: ddf4ce46afbf6c16a6bd8555ab1e4efb
|
||||
session: 7607796238c26b2d95007957b05c72d63f504346576bc2aa064a6dc54344de47d2ab38422bd1d061c067a16ef517e6054d8b7f5336c120431935518277fed45e49472aaf740cac1bc33ab2e362c767007a59e953e9973709
|
||||
status: unregistered
|
||||
version: 0.0.0
|
||||
Key: 8dd8b115d052f91ac74b1c2475e305009366c487
|
||||
Secret: ddf4ce46afbf6c16a6bd8555ab1e4efb
|
||||
Session: 7607796238c26b2d95007957b05c72d63f504346576bc2aa064a6dc54344de47d2ab38422bd1d061c067a16ef517e6054d8b7f5336c120431935518277fed45e49472aaf740cac1bc33ab2e362c767007a59e953e9973709
|
||||
Status: unregistered
|
||||
Version: 0.0.0
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
func BackupAlbums(force bool) (count int, result error) {
|
||||
c := Config()
|
||||
|
||||
if !c.SidecarYaml() && !force {
|
||||
if !c.BackupYaml() && !force {
|
||||
log.Debugf("backup: album yaml files disabled")
|
||||
return count, nil
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ func BackupAlbums(force bool) (count int, result error) {
|
|||
func RestoreAlbums(force bool) (count int, result error) {
|
||||
c := Config()
|
||||
|
||||
if !c.SidecarYaml() && !force {
|
||||
if !c.BackupYaml() && !force {
|
||||
log.Debugf("restore: album yaml files disabled")
|
||||
return count, nil
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
func TestNewImport(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
@ -27,7 +27,7 @@ func TestImport_DestinationFilename(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
@ -59,7 +59,7 @@ func TestImport_Start(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||
}
|
||||
}
|
||||
|
||||
if imp.conf.SidecarJson() && f.IsMedia() && !f.HasJson() {
|
||||
if imp.conf.ExifToolJson() && f.IsMedia() && !f.HasJson() {
|
||||
if jsonFile, err := imp.convert.ToJson(f); err != nil {
|
||||
log.Errorf("import: %s in %s (create json sidecar)", err.Error(), txt.Quote(f.BaseName()))
|
||||
} else {
|
||||
|
@ -167,7 +167,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||
continue
|
||||
}
|
||||
|
||||
if ind.conf.SidecarJson() && f.IsMedia() && !f.HasJson() {
|
||||
if ind.conf.ExifToolJson() && f.IsMedia() && !f.HasJson() {
|
||||
if jsonFile, err := ind.convert.ToJson(f); err != nil {
|
||||
log.Errorf("import: failed creating json sidecar for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
} else {
|
||||
|
|
|
@ -560,7 +560,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
|||
if file.FilePrimary {
|
||||
primaryFile = file
|
||||
|
||||
if !Config().TensorFlowOff() {
|
||||
if !Config().DisableTensorFlow() {
|
||||
// Image classification via TensorFlow.
|
||||
labels = ind.classifyImage(m)
|
||||
|
||||
|
@ -837,7 +837,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
|||
return result
|
||||
}
|
||||
|
||||
if file.FilePrimary && Config().SidecarYaml() {
|
||||
if file.FilePrimary && Config().BackupYaml() {
|
||||
// Write YAML sidecar file (optional).
|
||||
yamlFile := photo.YamlFileName(Config().OriginalsPath(), Config().SidecarPath())
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestIndex_MediaFile(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
@ -40,7 +40,7 @@ func TestIndex_MediaFile(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result Inde
|
|||
}
|
||||
}
|
||||
|
||||
if ind.conf.SidecarJson() && f.IsMedia() && !f.HasJson() {
|
||||
if ind.conf.ExifToolJson() && f.IsMedia() && !f.HasJson() {
|
||||
if jsonFile, err := ind.convert.ToJson(f); err != nil {
|
||||
log.Errorf("index: failed creating json sidecar for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
} else {
|
||||
|
@ -102,7 +102,7 @@ func IndexRelated(related RelatedFiles, ind *Index, opt IndexOptions) (result In
|
|||
continue
|
||||
}
|
||||
|
||||
if ind.conf.SidecarJson() && f.IsMedia() && !f.HasJson() {
|
||||
if ind.conf.ExifToolJson() && f.IsMedia() && !f.HasJson() {
|
||||
if jsonFile, err := ind.convert.ToJson(f); err != nil {
|
||||
log.Errorf("index: failed creating json sidecar for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
} else {
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestIndexRelated(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestIndex_Start(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
@ -44,7 +44,7 @@ func TestIndex_File(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestResample_Start(t *testing.T) {
|
|||
|
||||
conf.InitializeTestData(t)
|
||||
|
||||
tf := classify.New(conf.AssetsPath(), conf.TensorFlowOff())
|
||||
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
|
||||
nd := nsfw.New(conf.NSFWModelPath())
|
||||
convert := NewConvert(conf)
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ func Start(ctx context.Context, conf *config.Config) {
|
|||
}
|
||||
}()
|
||||
|
||||
if conf.HttpServerMode() != "" {
|
||||
gin.SetMode(conf.HttpServerMode())
|
||||
if conf.HttpMode() != "" {
|
||||
gin.SetMode(conf.HttpMode())
|
||||
} else if conf.Debug() == false {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func Start(ctx context.Context, conf *config.Config) {
|
|||
registerRoutes(router, conf)
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", conf.HttpServerHost(), conf.HttpServerPort()),
|
||||
Addr: fmt.Sprintf("%s:%d", conf.HttpHost(), conf.HttpPort()),
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
var onceClassify sync.Once
|
||||
|
||||
func initClassify() {
|
||||
services.Classify = classify.New(Config().AssetsPath(), Config().TensorFlowOff())
|
||||
services.Classify = classify.New(Config().AssetsPath(), Config().DisableTensorFlow())
|
||||
}
|
||||
|
||||
func Classify() *classify.TensorFlow {
|
||||
|
|
Loading…
Add table
Reference in a new issue