Merge branch 'develop' into feature/oidc-v2
This commit is contained in:
commit
1b2e60a7eb
21 changed files with 976 additions and 206 deletions
55
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
55
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve
|
||||
title: 'Bug: Short Issue Description'
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
PLEASE USE GITHUB ISSUES ONLY TO REPORT CLEARLY IDENTIFIED BUGS - THANK YOU!
|
||||
|
||||
Use GitHub Discussions or our Community Chat if you need assistance and for general questions:
|
||||
|
||||
- https://github.com/photoprism/photoprism/discussions
|
||||
- https://gitter.im/browseyourlife/community
|
||||
|
||||
Sponsors receive direct technical support via email:
|
||||
|
||||
- https://photoprism.app/contact
|
||||
|
||||
**What does not work as expected?**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**How can we reproduce it?**
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**What behavior do you expect?**
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Can you provide us with example files for testing or screenshots?**
|
||||
|
||||
Please add example files or screenshots that help to reproduce your problem.
|
||||
You may also send files via email or share a download link:
|
||||
https://photoprism.app/contact
|
||||
|
||||
**What version you are using?**
|
||||
|
||||
Your app version / build number can be found in *Settings* when you scroll to the bottom.
|
||||
|
||||
**Any other helpful information?**
|
||||
|
||||
If you are reporting a UI or performance issue, please always provide details about your...
|
||||
|
||||
- Web browsers
|
||||
- operating systems
|
||||
- installed memory
|
||||
- and processors
|
29
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
name: Feature Request
|
||||
about: Suggest a new feature or improvement
|
||||
title: " "
|
||||
labels: idea
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
PLEASE ONLY SUBMIT A NEW IDEA AFTER YOU HAVE VERIFIED THAT NO SIMILAR ISSUE ALREADY EXISTS - THANK YOU!
|
||||
|
||||
- Roadmap: https://github.com/photoprism/photoprism/projects/5
|
||||
- Open Issues: https://github.com/photoprism/photoprism/issues
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context or screenshots about the feature request here.
|
19
.github/ISSUE_TEMPLATE/support-request.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/support-request.md
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
name: Support Request
|
||||
about: You have general questions or need assistance
|
||||
title: " "
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
PLEASE USE GITHUB ISSUES ONLY TO REPORT CLEARLY IDENTIFIED BUGS - THANK YOU!
|
||||
|
||||
Use GitHub Discussions or our Community Chat if you need assistance and for general questions:
|
||||
|
||||
- https://github.com/photoprism/photoprism/discussions
|
||||
- https://gitter.im/browseyourlife/community
|
||||
|
||||
Sponsors receive direct technical support via email:
|
||||
|
||||
- https://photoprism.app/contact
|
25
SECURITY.md
25
SECURITY.md
|
@ -1,20 +1,21 @@
|
|||
# Security Policy
|
||||
**Please contact us at [security@photoprism.app](mailto:security@photoprism.app) when you've discovered a potential security issue.**
|
||||
|
||||
When you think you've discovered a security issue, please contact us at hello@photoprism.app.
|
||||
At a minimum, your report should include the following:
|
||||
|
||||
Your report should at least include the following:
|
||||
* Version and architecture
|
||||
* Vulnerability description
|
||||
* Reproduction steps
|
||||
|
||||
- Version and architecture
|
||||
- Vulnerability description
|
||||
- Reproduction steps
|
||||
We will then try to reproduce the problem, determine the impact and get back to you as soon as possible.
|
||||
|
||||
We will then try to reproduce it, determine the impact, and get back to you as soon as possible.
|
||||
Avoid activities that disrupt, degrade, or interrupt our services or compromise other users' data, such as spam, brute force attacks, denial of service attacks, and malicious file distribution.
|
||||
|
||||
Please also report vulnerabilities in third-party applications.
|
||||
You are welcome to also report vulnerabilities in third-party applications that we may not be able to fix directly.
|
||||
|
||||
### Responsible Disclosure ###
|
||||
|
||||
- Only test for vulnerabilities on your own PhotoPrism instance
|
||||
- Confirm the vulnerability applies to a supported version
|
||||
- Share vulnerability details with us first
|
||||
- Wait for a fix before publicly sharing details
|
||||
1. Confirm that the vulnerability applies to a current version
|
||||
2. First share the vulnerability details with us
|
||||
3. Wait for resolution before sharing details
|
||||
|
||||
**Thank you!** 👍
|
||||
|
|
|
@ -14,9 +14,9 @@ to a folder of your choice, change it as needed, and run "docker-compose up":
|
|||
wget https://dl.photoprism.org/docker/arm64/docker-compose.yml
|
||||
sudo docker-compose up -d
|
||||
|
||||
Please always change PHOTOPRISM_ADMIN_PASSWORD so that PhotoPrism starts with a secure initial password.
|
||||
Never use "photoprism", or other easy-to-guess passwords, on a public server.
|
||||
A minimum length of 4 characters is required.
|
||||
Always change PHOTOPRISM_ADMIN_PASSWORD so that the app starts with a secure initial password.
|
||||
Never use easy-to-guess passwords or default values like insecure on publicly accessible servers.
|
||||
There is no default in case no password was provided. A minimum length of 4 characters is required.
|
||||
|
||||
For more details, see:
|
||||
- https://docs.photoprism.org/getting-started/docker-compose/
|
||||
|
@ -50,8 +50,10 @@ Use the --help flag to see a detailed command info like
|
|||
| Re-index | docker-compose exec photoprism photoprism index -f
|
||||
| Import | docker-compose exec photoprism photoprism import
|
||||
|
||||
Note: "photoprism index -f" will re-index all originals, including already indexed and unchanged files.
|
||||
This may be necessary after upgrading, especially to new major versions.
|
||||
For more examples, see https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface
|
||||
|
||||
NOTE: "photoprism index -f" will re-index all originals, including already indexed and unchanged files.
|
||||
This may be necessary after upgrading, especially to new major versions.
|
||||
|
||||
## System Requirements ##
|
||||
|
||||
|
|
|
@ -2,18 +2,18 @@ version: '3.5'
|
|||
|
||||
# Example Docker Compose config file for PhotoPrism (Raspberry Pi and other ARM-based devices)
|
||||
#
|
||||
# ATTENTION: It's important that you boot your Raspberry Pi 3 / 4 with the parameter "arm_64bit=1"
|
||||
# in config.txt to use our ARM64 image.
|
||||
#
|
||||
# Documentation : https://docs.photoprism.org/getting-started/raspberry-pi/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# ATTENTION: You have to boot your Raspberry Pi 3 / 4 with the parameter "arm_64bit=1"
|
||||
# in config.txt to use our ARM64 image.
|
||||
#
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# -------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# -------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -28,19 +28,23 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
# Note: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will change the home directory "~" to "/root" in your configuration.
|
||||
#
|
||||
# NOTE: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will point the home directory placeholder ~ to /root in volume mounts.
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Our stable version and development preview now come as a single multi-arch image for AMD64, ARM64, and ARMv7.
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# NOTE: photoprism/photoprism-arm64 has been replaced by a single multi-arch image for AMD64,
|
||||
# ARM64, and ARMv7. Use photoprism/photoprism:preview for testing preview builds or
|
||||
# photoprism/photoprism:latest for the stable release.
|
||||
image: photoprism/photoprism:latest
|
||||
# Owners of ARMv7-based devices may have to explicitly specify the image architecture:
|
||||
# platform: "linux/arm/v7"
|
||||
# platform: "linux/arm"
|
||||
depends_on:
|
||||
- mariadb
|
||||
# Only enable automatic restarts once your installation is properly
|
||||
|
@ -56,6 +60,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "none" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_WORKERS: 2 # Limits the number of indexing workers to reduce system load
|
||||
|
@ -75,12 +80,11 @@ services:
|
|||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true" # Allow uploads that MAY be offensive
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
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_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -105,9 +109,7 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# ATTENTION: Owners of ARMv7-based devices have to revert to an alternative image if they want to use MariaDB.
|
||||
# The official image is available for AMD64 and ARM64 only. Pay close attention to changed directory and
|
||||
# environment variable names.
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
|
||||
mariadb:
|
||||
restart: unless-stopped
|
||||
image: arm64v8/mariadb:10.6
|
||||
|
@ -123,14 +125,33 @@ services:
|
|||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: insecure
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Owners of ARMv7-based devices have to revert to an alternative image if they want to use MariaDB.
|
||||
# The official image is available for AMD64 and ARM64 only. Pay close attention to changed directory
|
||||
# and environment variable names.
|
||||
#
|
||||
# mariadb:
|
||||
# restart: unless-stopped
|
||||
# image: lscr.io/linuxserver/mariadb:latest
|
||||
# security_opt:
|
||||
# - seccomp:unconfined
|
||||
# - apparmor:unconfined
|
||||
# command: mysqld --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=120
|
||||
# volumes:
|
||||
# - "./mariadb:/config" # Never remove
|
||||
# environment:
|
||||
# MYSQL_ROOT_PASSWORD: insecure
|
||||
# MYSQL_DATABASE: photoprism
|
||||
# MYSQL_USER: photoprism
|
||||
# MYSQL_PASSWORD: insecure
|
||||
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
|
@ -5,12 +5,12 @@ version: '3.5'
|
|||
# Documentation : https://docs.photoprism.org/getting-started/raspberry-pi/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# -------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# -------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -25,16 +25,20 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
# Note: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will change the home directory "~" to "/root" in your configuration.
|
||||
#
|
||||
# NOTE: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will point the home directory placeholder ~ to /root in volume mounts.
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Our stable version and development preview now come as a single multi-arch image for AMD64, ARM64, and ARMv7.
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# NOTE: photoprism/photoprism-arm64 has been replaced by a single multi-arch image for AMD64,
|
||||
# ARM64, and ARMv7. Use photoprism/photoprism:preview for testing preview builds or
|
||||
# photoprism/photoprism:latest for the stable release.
|
||||
image: photoprism/photoprism:latest
|
||||
platform: "linux/arm"
|
||||
depends_on:
|
||||
|
@ -52,6 +56,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "none" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_WORKERS: 1 # Limits the number of indexing workers to reduce system load
|
||||
|
@ -70,12 +75,11 @@ services:
|
|||
PHOTOPRISM_DETECT_NSFW: "false" # Flag photos as private that MAY be offensive
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true" # Allow uploads that MAY be offensive
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
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_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -100,6 +104,7 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
|
||||
mariadb:
|
||||
restart: unless-stopped
|
||||
image: lscr.io/linuxserver/mariadb:latest
|
||||
|
@ -115,14 +120,14 @@ services:
|
|||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: insecure
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
|
@ -46,7 +46,7 @@ version: '3.5'
|
|||
# See jobs.ini for details.
|
||||
#
|
||||
# SYSTEM REQUIREMENTS
|
||||
# -------------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
#
|
||||
# We recommend hosting PhotoPrism on a server with at least 2 cores and
|
||||
# 4 GB of memory. Beyond these minimum requirements, the amount of RAM
|
||||
|
@ -57,7 +57,7 @@ version: '3.5'
|
|||
# will be disabled on servers with less than 2 GB of physical memory.
|
||||
#
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# -------------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -72,11 +72,13 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
#
|
||||
# USING LET'S ENCRYPT HTTPS
|
||||
# -------------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
#
|
||||
# If your server has a public domain name, please disable the self-signed
|
||||
# certificate and enable domain based routing in docker-compose.yml and
|
||||
|
@ -90,12 +92,12 @@ version: '3.5'
|
|||
# docker-compose up -d
|
||||
#
|
||||
# You should now be able to access your instance without security warnings.
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
restart: always
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# Use photoprism/photoprism:preview for testing preview builds:
|
||||
image: photoprism/photoprism:latest
|
||||
container_name: photoprism
|
||||
depends_on:
|
||||
|
@ -145,11 +147,11 @@ services:
|
|||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Enables Darktable presets and disables concurrent RAW conversion
|
||||
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_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: "_admin_password_" # MariaDB database user password
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "_admin_password_" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_INIT: "tensorflow-amd64-avx2"
|
||||
HOME: "/photoprism"
|
||||
working_dir: "/photoprism"
|
||||
|
@ -162,6 +164,7 @@ services:
|
|||
- "./storage:/photoprism/storage"
|
||||
- "./backup:/var/lib/photoprism"
|
||||
|
||||
# REQUIRED: Traefik Reverse Proxy, see https://docs.photoprism.org/getting-started/proxies/traefik/
|
||||
traefik:
|
||||
restart: always
|
||||
image: traefik:v2.4
|
||||
|
@ -178,6 +181,7 @@ services:
|
|||
- "./traefik.yaml:/etc/traefik/traefik.yaml"
|
||||
- "./certs/:/certs/"
|
||||
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
|
||||
mariadb:
|
||||
restart: always
|
||||
image: mariadb:10.6
|
||||
|
@ -194,6 +198,7 @@ services:
|
|||
MYSQL_USER: "photoprism"
|
||||
MYSQL_PASSWORD: "_admin_password_"
|
||||
|
||||
# RECOMMENDED: Ofelia Job Runner, see https://github.com/mcuadros/ofelia
|
||||
ofelia:
|
||||
restart: always
|
||||
image: mcuadros/ofelia:latest
|
||||
|
@ -202,6 +207,7 @@ services:
|
|||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
- "./jobs.ini:/etc/ofelia/config.ini"
|
||||
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
watchtower:
|
||||
restart: always
|
||||
image: containrrr/watchtower
|
||||
|
|
|
@ -5,12 +5,12 @@ version: '3.5'
|
|||
# Documentation : https://docs.photoprism.org/getting-started/docker-compose/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# ------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -25,15 +25,18 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
# Note: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will change the home directory "~" to "/root" in your configuration.
|
||||
#
|
||||
# NOTE: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will point the home directory placeholder ~ to /root in volume mounts.
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# Use photoprism/photoprism:preview for testing preview builds:
|
||||
image: photoprism/photoprism:latest
|
||||
depends_on:
|
||||
- mariadb
|
||||
|
@ -50,6 +53,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode (shows additional log messages)
|
||||
|
@ -66,12 +70,11 @@ services:
|
|||
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_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
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_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -106,6 +109,7 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
|
||||
mariadb:
|
||||
restart: unless-stopped
|
||||
image: mariadb:10.6
|
||||
|
@ -121,14 +125,14 @@ services:
|
|||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: insecure
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
|
|
|
@ -5,12 +5,12 @@ version: '3.5'
|
|||
# Documentation : https://docs.photoprism.org/getting-started/docker-compose/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# ------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -25,13 +25,15 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# Use photoprism/photoprism:preview for testing preview builds:
|
||||
image: photoprism/photoprism:latest
|
||||
depends_on:
|
||||
- mariadb
|
||||
|
@ -46,6 +48,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode (shows additional log messages)
|
||||
|
@ -61,12 +64,11 @@ services:
|
|||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Enables Darktable presets and disables concurrent RAW conversion
|
||||
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_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_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -85,6 +87,7 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysqll
|
||||
mariadb:
|
||||
restart: unless-stopped
|
||||
image: mariadb:10.6
|
||||
|
@ -100,17 +103,17 @@ services:
|
|||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: insecure
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
|
||||
volumes:
|
||||
mariadb_data:
|
||||
|
|
|
@ -7,12 +7,12 @@ version: '3.5'
|
|||
# Documentation : https://docs.photoprism.org/getting-started/docker-compose/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# ------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -27,15 +27,18 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
# Note: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will change the home directory "~" to "/root" in your configuration.
|
||||
#
|
||||
# NOTE: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will point the home directory placeholder ~ to /root in volume mounts.
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# Use photoprism/photoprism:preview for testing preview builds:
|
||||
image: photoprism/photoprism:latest
|
||||
container_name: photoprism
|
||||
depends_on:
|
||||
|
@ -53,6 +56,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode (shows additional log messages)
|
||||
|
@ -69,12 +73,11 @@ services:
|
|||
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_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
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_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -98,6 +101,7 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
|
||||
mariadb:
|
||||
restart: unless-stopped
|
||||
image: mariadb:10.6
|
||||
|
@ -114,6 +118,7 @@ services:
|
|||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: insecure
|
||||
|
||||
# REQUIRED: Ofelia Job Runner, see https://github.com/mcuadros/ofelia
|
||||
ofelia:
|
||||
restart: unless-stopped
|
||||
image: mcuadros/ofelia:latest
|
||||
|
@ -122,15 +127,14 @@ services:
|
|||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
- "./jobs.ini:/etc/ofelia/config.ini"
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# container_name: watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
|
@ -5,12 +5,12 @@ version: '3.5'
|
|||
# Documentation : https://docs.photoprism.org/getting-started/docker-compose/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# ------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -25,15 +25,18 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
# Note: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will change the home directory "~" to "/root" in your configuration.
|
||||
#
|
||||
# NOTE: All commands may have to be prefixed with "sudo" when not running as root.
|
||||
# This will point the home directory placeholder ~ to /root in volume mounts.
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# Use photoprism/photoprism:preview for testing preview builds:
|
||||
image: photoprism/photoprism:latest
|
||||
# Only enable automatic restarts once your installation is properly
|
||||
# configured as it otherwise may get stuck in a restart loop:
|
||||
|
@ -48,6 +51,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode (shows additional log messages)
|
||||
|
@ -64,7 +68,6 @@ services:
|
|||
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_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -88,14 +91,14 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
|
@ -8,12 +8,12 @@ version: '3.5'
|
|||
# Documentation : https://docs.photoprism.org/getting-started/docker-compose/
|
||||
# Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
|
||||
#
|
||||
# Please run behind a reverse proxy like Caddy, Traefik or Nginx if you need HTTPS / SSL support
|
||||
# e.g. when running PhotoPrism on a public server outside your home network.
|
||||
# IMPORTANT: When installing PhotoPrism on a public server outside your home network, please
|
||||
# always run it behind a secure HTTPS reverse proxy like Traefik, Caddy, or NGINX.
|
||||
# Your files and passwords will be transmitted in clear text otherwise.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
# DOCKER COMPOSE COMMAND REFERENCE
|
||||
# ------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------
|
||||
# Start | docker-compose up -d
|
||||
# Stop | docker-compose stop
|
||||
# Update | docker-compose pull
|
||||
|
@ -28,13 +28,15 @@ version: '3.5'
|
|||
# Reindex | docker-compose exec photoprism photoprism index -f
|
||||
# Import | docker-compose exec photoprism photoprism import
|
||||
#
|
||||
# See https://docs.photoprism.org/getting-started/docker-compose/#command-line-interface for more examples.
|
||||
#
|
||||
# To search originals for faces without a complete rescan:
|
||||
# docker-compose exec photoprism photoprism faces index
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
services:
|
||||
# REQUIRED: PhotoPrism Application Server
|
||||
photoprism:
|
||||
# Use photoprism/photoprism:preview instead for testing preview builds:
|
||||
# Use photoprism/photoprism:preview for testing preview builds:
|
||||
image: photoprism/photoprism:latest
|
||||
depends_on:
|
||||
- mariadb
|
||||
|
@ -49,6 +51,7 @@ services:
|
|||
- "2342:2342" # [server]:[container]
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # PLEASE CHANGE: Your initial admin password (min 4 characters)
|
||||
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # Public URL incl http:// or https:// and /path, :port is optional
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # File size limit for originals in MB (increase for high-res video)
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # Improves transfer speed and bandwidth utilization (none or gzip)
|
||||
PHOTOPRISM_DEBUG: "false" # Run in debug mode, shows additional log messages
|
||||
|
@ -64,12 +67,11 @@ services:
|
|||
PHOTOPRISM_DARKTABLE_PRESETS: "false" # Enables Darktable presets and disables concurrent RAW conversion
|
||||
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_DATABASE_DRIVER: "mysql" # Use MariaDB (or MySQL) instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB database server hostname (:port is optional)
|
||||
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_SITE_URL: "http://localhost:2342/" # Public PhotoPrism URL
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql" # Use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
|
||||
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server hostname (:port is optional)
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
|
@ -87,6 +89,7 @@ services:
|
|||
# Cache, session, thumbnail, and sidecar files will be created in the *storage* folder (never remove):
|
||||
- "./storage:/photoprism/storage"
|
||||
|
||||
# RECOMMENDED: MariaDB Server, see https://docs.photoprism.org/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
|
||||
mariadb:
|
||||
restart: unless-stopped
|
||||
image: mariadb:10.6
|
||||
|
@ -102,17 +105,17 @@ services:
|
|||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: insecure
|
||||
|
||||
# Uncomment the following lines to upgrade automatically, whenever there is a new Docker image available:
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
# OPTIONAL: Upgrades services automatically, see https://docs.photoprism.org/getting-started/updates/#watchtower
|
||||
#
|
||||
# watchtower:
|
||||
# restart: unless-stopped
|
||||
# image: containrrr/watchtower
|
||||
# environment:
|
||||
# WATCHTOWER_CLEANUP: "true"
|
||||
# WATCHTOWER_POLL_INTERVAL: 7200 # Checks for updates every two hours
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - "~/.docker/config.json:/config.json" # Optional, for authentication if you have a Docker Hub account
|
||||
|
||||
volumes:
|
||||
mariadb_data:
|
||||
|
|
|
@ -197,6 +197,30 @@ var AlbumFixtures = AlbumMap{
|
|||
UpdatedAt: time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
DeletedAt: nil,
|
||||
},
|
||||
"september-2021": {
|
||||
ID: 1000007,
|
||||
AlbumUID: "at1lxuqipogaabj9",
|
||||
AlbumSlug: "september-2021",
|
||||
AlbumPath: "",
|
||||
AlbumType: AlbumMonth,
|
||||
AlbumTitle: "September 2021",
|
||||
AlbumLocation: "",
|
||||
AlbumCategory: "",
|
||||
AlbumCaption: "",
|
||||
AlbumDescription: "",
|
||||
AlbumNotes: "",
|
||||
AlbumFilter: "public:true year:2021 month:9",
|
||||
AlbumOrder: "newest",
|
||||
AlbumTemplate: "",
|
||||
AlbumCountry: UnknownID,
|
||||
AlbumYear: 0,
|
||||
AlbumMonth: 0,
|
||||
AlbumDay: 0,
|
||||
AlbumFavorite: false,
|
||||
CreatedAt: time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC),
|
||||
UpdatedAt: time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||
DeletedAt: nil,
|
||||
},
|
||||
}
|
||||
|
||||
// CreateAlbumFixtures inserts known entities into the database for testing.
|
||||
|
|
83
internal/form/face_search_test.go
Normal file
83
internal/form/face_search_test.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package form
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewFaceSearch(t *testing.T) {
|
||||
r := NewFaceSearch("yes")
|
||||
assert.IsType(t, FaceSearch{}, r)
|
||||
}
|
||||
|
||||
func TestFaceSearch_GetQuery(t *testing.T) {
|
||||
form := &FaceSearch{Query: "test"}
|
||||
|
||||
assert.Equal(t, "test", form.GetQuery())
|
||||
}
|
||||
|
||||
func TestFaceSearch_SetQuery(t *testing.T) {
|
||||
form := &FaceSearch{Query: "test"}
|
||||
form.SetQuery("new query")
|
||||
|
||||
assert.Equal(t, "new query", form.GetQuery())
|
||||
}
|
||||
|
||||
func TestFaceSearch_ParseQueryString(t *testing.T) {
|
||||
|
||||
t.Run("valid query", func(t *testing.T) {
|
||||
form := &FaceSearch{Query: "subject:test count:10 offset:1"}
|
||||
|
||||
err := form.ParseQueryString()
|
||||
|
||||
// log.Debugf("%+v\n", form)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("err should be nil")
|
||||
}
|
||||
|
||||
assert.Equal(t, "test", form.Subject)
|
||||
assert.Equal(t, 10, form.Count)
|
||||
assert.Equal(t, 1, form.Offset)
|
||||
|
||||
})
|
||||
t.Run("valid query with umlauts", func(t *testing.T) {
|
||||
form := &FaceSearch{Query: "query:\"tübingen\""}
|
||||
|
||||
err := form.ParseQueryString()
|
||||
|
||||
// log.Debugf("%+v\n", form)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("err should be nil")
|
||||
}
|
||||
|
||||
assert.Equal(t, "tübingen", form.Query)
|
||||
})
|
||||
t.Run("query for invalid filter", func(t *testing.T) {
|
||||
form := &FaceSearch{Query: "xxx:false"}
|
||||
|
||||
err := form.ParseQueryString()
|
||||
|
||||
if err == nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// log.Debugf("%+v\n", form)
|
||||
|
||||
assert.Equal(t, "unknown filter: Xxx", err.Error())
|
||||
})
|
||||
t.Run("query for count with invalid type", func(t *testing.T) {
|
||||
form := &FaceSearch{Query: "count:cat"}
|
||||
|
||||
err := form.ParseQueryString()
|
||||
|
||||
if err == nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// log.Debugf("%+v\n", form)
|
||||
|
||||
assert.Equal(t, "strconv.Atoi: parsing \"cat\": invalid syntax", err.Error())
|
||||
})
|
||||
}
|
|
@ -57,6 +57,13 @@ func TestAlbumCoverByUID(t *testing.T) {
|
|||
assert.Error(t, err, "record not found")
|
||||
t.Log(file)
|
||||
})
|
||||
|
||||
t.Run("existing uid empty month album", func(t *testing.T) {
|
||||
file, err := AlbumCoverByUID("at1lxuqipogaabj9")
|
||||
|
||||
assert.EqualError(t, err, "no cover found", err)
|
||||
assert.Equal(t, "", file.FileName)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateAlbumDates(t *testing.T) {
|
||||
|
|
|
@ -223,3 +223,13 @@ func TestResolveFaceCollisions(t *testing.T) {
|
|||
assert.LessOrEqual(t, 3, c)
|
||||
assert.LessOrEqual(t, 3, r)
|
||||
}
|
||||
|
||||
func TestRemoveAutoFaceClusters(t *testing.T) {
|
||||
removed, err := RemoveAutoFaceClusters()
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, int64(3), removed)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestFaces(t *testing.T) {
|
|||
assert.LessOrEqual(t, 1, len(results))
|
||||
})
|
||||
t.Run("Exclude Unknown & Hidden", func(t *testing.T) {
|
||||
results, err := Faces(form.FaceSearch{Unknown: "no", Hidden: "yes", Order: "added", Markers: true})
|
||||
results, err := Faces(form.FaceSearch{Unknown: "no", Hidden: "yes", Order: "samples", Markers: true})
|
||||
assert.NoError(t, err)
|
||||
t.Logf("Faces: %#v", results)
|
||||
assert.LessOrEqual(t, 0, len(results))
|
||||
|
|
|
@ -265,6 +265,31 @@ func TestGeo(t *testing.T) {
|
|||
|
||||
assert.GreaterOrEqual(t, len(photos), 4)
|
||||
})
|
||||
t.Run("face:yes", func(t *testing.T) {
|
||||
var f form.PhotoSearchGeo
|
||||
f.Face = "Yes"
|
||||
|
||||
photos, err := PhotosGeo(f)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.GreaterOrEqual(t, len(photos), 4)
|
||||
})
|
||||
t.Run("f.Faces:new", func(t *testing.T) {
|
||||
var f form.PhotoSearchGeo
|
||||
f.Faces = "New"
|
||||
f.Face = ""
|
||||
|
||||
photos, err := PhotosGeo(f)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.GreaterOrEqual(t, len(photos), 3)
|
||||
})
|
||||
t.Run("faces:no", func(t *testing.T) {
|
||||
var f form.PhotoSearchGeo
|
||||
f.Faces = "No"
|
||||
|
@ -289,6 +314,18 @@ func TestGeo(t *testing.T) {
|
|||
|
||||
assert.GreaterOrEqual(t, len(photos), 1)
|
||||
})
|
||||
t.Run("face: TOSCDXCS4VI3PGIUTCNIQCNI6HSFXQVZ", func(t *testing.T) {
|
||||
var f form.PhotoSearchGeo
|
||||
f.Face = "TOSCDXCS4VI3PGIUTCNIQCNI6HSFXQVZ"
|
||||
|
||||
photos, err := PhotosGeo(f)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.GreaterOrEqual(t, len(photos), 2)
|
||||
})
|
||||
t.Run("day", func(t *testing.T) {
|
||||
var f form.PhotoSearchGeo
|
||||
f.Day = "18"
|
||||
|
@ -369,6 +406,97 @@ func TestGeo(t *testing.T) {
|
|||
assert.Equal(t, "video", r.PhotoType)
|
||||
}
|
||||
})
|
||||
t.Run("query: video", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Query = "video"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "video", r.PhotoType)
|
||||
}
|
||||
})
|
||||
t.Run("query: live", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Query = "live"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "live", r.PhotoType)
|
||||
}
|
||||
})
|
||||
t.Run("query: raws", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Query = "raws"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "raw", r.PhotoType)
|
||||
}
|
||||
})
|
||||
t.Run("query: panoramas", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Query = "panoramas"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("query: scans", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Query = "scans"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("query: faces", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
|
@ -462,6 +590,24 @@ func TestGeo(t *testing.T) {
|
|||
}
|
||||
assert.Greater(t, len(photos), len(photos2))
|
||||
})
|
||||
t.Run("f.Album = uid", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Album = "at9lxuqxpogaaba9"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("people and and or search", func(t *testing.T) {
|
||||
var f form.PhotoSearchGeo
|
||||
f.People = "Actor A|Actress A"
|
||||
|
@ -524,5 +670,125 @@ func TestGeo(t *testing.T) {
|
|||
|
||||
assert.Equal(t, len(photos3), len(photos4))
|
||||
assert.Equal(t, len(photos), len(photos4))
|
||||
|
||||
var f5 form.PhotoSearchGeo
|
||||
f5.Subject = "jqy1y111h1njaaad"
|
||||
|
||||
photos5, err5 := PhotosGeo(f5)
|
||||
|
||||
if err5 != nil {
|
||||
t.Fatal(err5)
|
||||
}
|
||||
|
||||
assert.Equal(t, len(photos5), len(photos4))
|
||||
})
|
||||
|
||||
t.Run("f.Scan = true", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Scan = true
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("f.Panorama = true", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Panorama = true
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("f.Raw = true", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Raw = true
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("f.Live = true", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Live = true
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("f.Title = phototobebatchapproved2", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
|
||||
frm.Title = "phototobebatchapproved2"
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
t.Run("f.Query = p", func(t *testing.T) {
|
||||
var frm form.PhotoSearchGeo
|
||||
frm.Query = "p"
|
||||
frm.Title = ""
|
||||
|
||||
photos, err := PhotosGeo(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, GeoResult{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -632,6 +632,18 @@ func TestPhotos(t *testing.T) {
|
|||
}
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
})
|
||||
t.Run("f.album", func(t *testing.T) {
|
||||
var f form.PhotoSearch
|
||||
f.Query = ""
|
||||
f.Album = "Berlin"
|
||||
|
||||
photos, _, err := Photos(f)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
})
|
||||
t.Run("search for state", func(t *testing.T) {
|
||||
var f form.PhotoSearch
|
||||
f.State = "KwaZulu-Natal"
|
||||
|
@ -864,6 +876,18 @@ func TestPhotos(t *testing.T) {
|
|||
|
||||
assert.GreaterOrEqual(t, len(photos), 9)
|
||||
})
|
||||
t.Run("f.face yes", func(t *testing.T) {
|
||||
var f form.PhotoSearch
|
||||
f.Face = "yes"
|
||||
|
||||
photos, _, err := Photos(f)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.GreaterOrEqual(t, len(photos), 9)
|
||||
})
|
||||
t.Run("faces:2", func(t *testing.T) {
|
||||
var f form.PhotoSearch
|
||||
f.Faces = "2"
|
||||
|
@ -943,6 +967,138 @@ func TestPhotos(t *testing.T) {
|
|||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: video", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Query = "video"
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "video", r.PhotoType)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: live", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Query = "live"
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "live", r.PhotoType)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("f.live", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Live = true
|
||||
frm.Query = ""
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "live", r.PhotoType)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: raws", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Query = "raws"
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "raw", r.PhotoType)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("f.Raw", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Raw = true
|
||||
frm.Query = ""
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.Equal(t, "raw", r.PhotoType)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: faces", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
|
@ -968,6 +1124,32 @@ func TestPhotos(t *testing.T) {
|
|||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: faces", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Query = "faces:new"
|
||||
frm.Face = ""
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.LessOrEqual(t, 1, r.PhotoFaces)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: people", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
|
@ -1122,6 +1304,31 @@ func TestPhotos(t *testing.T) {
|
|||
}
|
||||
}
|
||||
})
|
||||
t.Run("query: mono", func(t *testing.T) {
|
||||
var frm form.PhotoSearch
|
||||
|
||||
frm.Query = "mono"
|
||||
frm.Count = 10
|
||||
frm.Offset = 0
|
||||
|
||||
photos, _, err := Photos(frm)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.LessOrEqual(t, 1, len(photos))
|
||||
|
||||
for _, r := range photos {
|
||||
assert.IsType(t, Photo{}, r)
|
||||
assert.NotEmpty(t, r.ID)
|
||||
assert.NotEmpty(t, r.LensID)
|
||||
|
||||
if fix, ok := entity.PhotoFixtures[r.PhotoName]; ok {
|
||||
assert.Equal(t, fix.PhotoName, r.PhotoName)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.Run("filename", func(t *testing.T) {
|
||||
var f form.PhotoSearch
|
||||
f.Filename = "1990/04/Quality1FavoriteTrue.jpg"
|
||||
|
@ -1260,4 +1467,22 @@ func TestPhotos(t *testing.T) {
|
|||
assert.Equal(t, len(photos3), len(photos4))
|
||||
assert.Equal(t, len(photos), len(photos4))
|
||||
})
|
||||
|
||||
t.Run("Search in Title", func(t *testing.T) {
|
||||
var f form.PhotoSearch
|
||||
f.Query = "N"
|
||||
f.Title = ""
|
||||
f.Count = 10
|
||||
f.Offset = 0
|
||||
|
||||
photos, _, err := Photos(f)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("results: %+v", photos)
|
||||
assert.Equal(t, 1, len(photos))
|
||||
assert.Equal(t, photos[0].PhotoTitle, "Neckarbrücke")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -64,13 +64,13 @@ func TestSubjects(t *testing.T) {
|
|||
assert.Equal(t, 0, len(results))
|
||||
})
|
||||
t.Run("search file count >2", func(t *testing.T) {
|
||||
results, err := Subjects(form.SubjectSearch{Type: entity.SubjPerson, Files: 2})
|
||||
results, err := Subjects(form.SubjectSearch{Type: entity.SubjPerson, Files: 2, Excluded: "no"})
|
||||
assert.NoError(t, err)
|
||||
//t.Logf("Subjects: %#v", results)
|
||||
assert.LessOrEqual(t, 1, len(results))
|
||||
})
|
||||
t.Run("search for alias", func(t *testing.T) {
|
||||
results, err := Subjects(form.SubjectSearch{Type: entity.SubjPerson, Query: "Powell"})
|
||||
results, err := Subjects(form.SubjectSearch{Type: entity.SubjPerson, Query: "Powell", Favorite: "no", Private: "no"})
|
||||
assert.NoError(t, err)
|
||||
//t.Logf("Subjects: %#v", results)
|
||||
assert.Equal(t, "Dangling Subject", results[0].SubjName)
|
||||
|
|
Loading…
Add table
Reference in a new issue