Merge remote-tracking branch 'upstream/develop' into feature/custom-tf-model-127

This commit is contained in:
raystlin 2025-05-12 18:46:57 +00:00
commit 38956e0f4a
409 changed files with 34588 additions and 23182 deletions

View file

@ -1,18 +1,18 @@
---
name: Question
about: You have a general question or need assistance
title: 'STOP! DO NOT PROCEED, USE GITHUB DISCUSSIONS INSTEAD - THANK YOU'
labels: technical-support
title: 'PLEASE DO NOT OPEN AN ISSUE FOR YOUR QUESTION, AND USE GITHUB DISCUSSIONS OR OUR COMMUNITY CHAT INSTEAD'
labels: question
assignees: ''
---
FOR GENERAL QUESTIONS, TECHNICAL SUPPORT, AND TO GET TO KNOW OTHER COMMUNITY MEMBERS:
<https://github.com/photoprism/photoprism/discussions>
<https://github.com/photoprism/photoprism/discussions>
OUR TROUBLESHOOTING CHECKLISTS HELP YOU QUICKLY DIAGNOSE AND FIX COMMON PROBLEMS:
<https://docs.photoprism.app/getting-started/troubleshooting/>
<https://docs.photoprism.app/getting-started/troubleshooting/>
DO NOT PROCEED, THANK YOU!
PLEASE DO NOT OPEN AN ISSUE FOR YOUR QUESTION, AND USE GITHUB DISCUSSIONS OR OUR COMMUNITY CHAT INSTEAD. THANK YOU VERY MUCH!

View file

@ -1,33 +1,32 @@
<!--
Thank you for your interest in contributing!
Because we want to create the best possible product for our users, we have a set of criteria to ensure that all submissions are acceptable, see https://docs.photoprism.app/developer-guide/pull-requests/ for details.
(1) Please provide a concise description of your pull request.
- What does it implement / fix / improve? Why?
- Are the changes related to an existing issue?
(2) After you submit your first pull request, you will be asked to accept our CLA, see https://www.photoprism.app/cla.
(3) Finally, please confirm that the following criteria are met by replacing "[ ]" with "[x]" (also possible at a later time).
-->
Acceptance Criteria:
- [ ] Features and enhancements must be fully implemented so that they can be released at any time without additional work
- [ ] Automated unit and/or acceptance tests are mandatory to ensure the changes work as expected and to reduce repetitive manual work
- [ ] Frontend components must be responsive to work and look properly on phones, tablets, and desktop computers; you must have tested them on all major browsers and different devices
- [ ] Documentation and translation updates should be provided if needed
- [ ] In case you submit database-related changes, they must be tested and compatible with SQLite 3 and MariaDB 10.5.12+
### Description
<!--
We appreciate your interest in contributing! Please provide a brief description of your changes so that we know what is included in this pull request, and confirm that it meets the acceptance criteria:
Since reviewing, testing and finally merging pull requests requires significant resources on our side, this can take several months if it's not just a small fix, especially if extensive testing is required to prevent bugs from getting into our stable version.
We thank you for your patience! :)
What does it aim to implement, fix or improve? Why?
-->
These changes implement/fix/improve...
#### Related Issues
- Links to issues that this PR fixes, implements, or is otherwise related to...
### Acceptance Criteria
<!-- You may add additional criteria and/or remove criteria that do not apply, e.g. because your PR does not include frontend changes: -->
- [ ] New features or enhancements are fully implemented and do not break existing functionality, so that they can be released at any time without requiring additional work
- [ ] Automated unit and/or acceptance tests are included to ensure that changes work as expected and to reduce repetitive manual work
- [ ] Documentation has been / will be updated, especially as it relates to new configuration options or potentially disruptive changes
- [ ] The user interface has been tested on Chrome, Safari, and Firefox and is fully responsive for use on phones, tablets, and desktop computers
- [ ] Database-related changes have been successfully tested with SQLite 3 and MariaDB 10.5.12+
<!--
Contribution Agreement:
PhotoPrism UG ("PhotoPrism", "we" or "us") hereby confirms that, to the fullest extent permitted by applicable law, this Contribution is provided "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OR CONDITIONS OF NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. You have no obligation to provide support, maintenance, or other services for your Contribution.
If you contribute code or other intellectual property, we kindly ask you to confirm the agreement after submitting your first PR, so that we can safely use it in our projects without risking unexpected legal disputes.
Thank you very much! :)
-->

5
.gitignore vendored
View file

@ -27,6 +27,8 @@ venv
.tmp
.nv
.eslintcache
/pro
/plus
/tmp/
/test/
*-lock.json
@ -49,10 +51,9 @@ frontend/coverage/
/assets/nasnet
/assets/nsfw
/assets/static/build/
/assets/static/maps/
/assets/*net
/assets/vision
/pro
/plus
# Files created automatically by editors and/or operating systems:
.DS_Store

View file

@ -1,8 +1,9 @@
# Ubuntu 24.10 (Oracular Oriole)
FROM photoprism/develop:250412-oracular
# Ubuntu 25.04 (Plucky Puffin)
FROM photoprism/develop:250507-plucky
## Alternative Environments:
# FROM photoprism/develop:armv7 # ARMv7 (32bit)
# FROM photoprism/develop:plucky # Ubuntu 25.04 (Plucky Puffin)
# FROM photoprism/develop:oracular # Ubuntu 24.10 (Oracular Oriole)
# FROM photoprism/develop:noble # Ubuntu 24.04 LTS (Noble Numbat)
# FROM photoprism/develop:mantic # Ubuntu 23.10 (Mantic Minotaur)

124
Makefile
View file

@ -7,17 +7,19 @@ export GO111MODULE=on
-include .semver
-include .env
export
# Binary file names.
BINARY_NAME=photoprism
GOIMPORTS=goimports
# Build version.
SEMVER_MAJOR ?= 0
# Build version string.
SEMVER_MAJOR ?= 1
export SEMVER_MAJOR
SEMVER_MINOR ?= $(shell date -u +%y%m)
export SEMVER_MINOR
SEMVER_PATCH ?= $(shell date -u +%d)
SEMVER_VERSION ?= $(SEMVER_MAJOR).$(SEMVER_MINOR).$(SEMVER_PATCH)
export SEMVER_VERSION
# Build parameters.
BUILD_PATH ?= $(shell realpath "./build")
@ -25,8 +27,10 @@ BUILD_DATE ?= $(shell date -u +%y%m%d)
REPORT_DATE ?= $(shell date -u +%Y-%m-%d)
BUILD_VERSION ?= $(shell git describe --always)
BUILD_TAG ?= $(BUILD_DATE)-$(BUILD_VERSION)
export BUILD_TAG
BUILD_OS ?= $(shell uname -s)
BUILD_ARCH ?= $(shell scripts/dist/arch.sh)
BUILD_ARCH ?= $(shell ./scripts/dist/arch.sh)
export BUILD_ARCH
JS_BUILD_PATH ?= $(shell realpath "./assets/static/build")
TF_VERSION ?= 2.18.0
@ -191,15 +195,15 @@ acceptance-sqlite-restart:
rm -rf storage/acceptance/originals/2011
rm -rf storage/acceptance/originals/2013
rm -rf storage/acceptance/originals/2017
./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" --test start -d
./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" start -d
acceptance-sqlite-stop:
./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" --test stop
./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" stop
acceptance-auth-sqlite-restart:
cp -f storage/acceptance/backup.db storage/acceptance/index.db
cp -f storage/acceptance/config-sqlite/settingsBackup.yml storage/acceptance/config-sqlite/settings.yml
./photoprism --auth-mode="password" -c "./storage/acceptance/config-sqlite" --test start -d
./photoprism --auth-mode="password" -c "./storage/acceptance/config-sqlite" start -d
acceptance-auth-sqlite-stop:
./photoprism --auth-mode="password" -c "./storage/acceptance/config-sqlite" --test stop
./photoprism --auth-mode="password" -c "./storage/acceptance/config-sqlite" stop
start:
./photoprism start -d
stop:
@ -274,24 +278,28 @@ build-static:
scripts/build.sh static $(BINARY_NAME)
build-libheif: build-libheif-amd64 build-libheif-arm64 build-libheif-armv7
build-libheif-amd64:
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:oracular ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:oracular ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.19.7
build-libheif-arm64:
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:oracular ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:oracular ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.19.7
build-libheif-armv7:
docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.19.5
docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh v1.19.7
docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.19.7
build-libheif-latest: build-libheif-amd64-latest build-libheif-arm64-latest build-libheif-armv7-latest
build-libheif-amd64-latest:
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:oracular ./scripts/dist/build-libheif.sh
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh
docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh
build-libheif-arm64-latest:
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:oracular ./scripts/dist/build-libheif.sh
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh
docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh
@ -396,29 +404,32 @@ docker-pull:
$(DOCKER_COMPOSE) -f compose.latest.yaml pull --ignore-pull-failures
docker-build:
$(DOCKER_COMPOSE) --profile=all pull --ignore-pull-failures
$(DOCKER_COMPOSE) down --remove-orphans
$(DOCKER_COMPOSE) build --pull
docker-nvidia: docker-nvidia-up
docker-nvidia-up:
docker compose --profile=qdrant -f compose.nvidia.yaml up
docker-nvidia-down:
docker compose --profile=qdrant -f compose.nvidia.yaml down --remove-orphans
docker-nvidia-build:
docker compose --profile=qdrant -f compose.nvidia.yaml build
docker-intel: docker-intel-up
docker-intel-up:
docker compose -f compose.intel.yaml up
docker-intel-build:
docker compose -f compose.intel.yaml build
docker-local-up:
$(DOCKER_COMPOSE) -f compose.local.yaml up --force-recreate
docker-local-down:
$(DOCKER_COMPOSE) -f compose.local.yaml down -V
nvidia: nvidia-up
nvidia-build:
$(DOCKER_COMPOSE) --profile=qdrant -f compose.nvidia.yaml pull --ignore-pull-failures
$(DOCKER_COMPOSE) --profile=qdrant -f compose.nvidia.yaml build
nvidia-up:
$(DOCKER_COMPOSE) --profile=qdrant -f compose.nvidia.yaml pull --ignore-pull-failures
$(DOCKER_COMPOSE) --profile=qdrant -f compose.nvidia.yaml up --remove-orphans
nvidia-down:
$(DOCKER_COMPOSE) --profile=qdrant -f compose.nvidia.yaml down --remove-orphans
intel: intel-up
intel-build:
$(DOCKER_COMPOSE) -f compose.intel.yaml pull --ignore-pull-failures
$(DOCKER_COMPOSE) -f compose.intel.yaml build
intel-up:
$(DOCKER_COMPOSE) -f compose.intel.yaml pull --ignore-pull-failures
$(DOCKER_COMPOSE) -f compose.intel.yaml up --remove-orphans
intel-down:
$(DOCKER_COMPOSE) -f compose.intel.yaml down --remove-orphans
develop: docker-develop
docker-develop: docker-develop-latest
docker-develop-all: docker-develop-latest docker-develop-other
docker-develop-latest: docker-develop-ubuntu
docker-develop-debian: docker-develop-bookworm docker-develop-bookworm-slim
docker-develop-ubuntu: docker-develop-oracular docker-develop-oracular-slim
docker-develop-ubuntu: docker-develop-plucky docker-develop-plucky-slim
docker-develop-other: docker-develop-debian docker-develop-bullseye docker-develop-bullseye-slim docker-develop-buster
docker-develop-bookworm:
docker pull --platform=amd64 debian:bookworm-slim
@ -485,11 +496,19 @@ docker-develop-noble-slim:
docker-develop-oracular:
docker pull --platform=amd64 ubuntu:oracular
docker pull --platform=arm64 ubuntu:oracular
scripts/docker/buildx-multi.sh develop linux/amd64,linux/arm64 oracular /oracular "-t photoprism/develop:latest -t photoprism/develop:ubuntu"
scripts/docker/buildx-multi.sh develop linux/amd64,linux/arm64 oracular /oracular
docker-develop-oracular-slim:
docker pull --platform=amd64 ubuntu:oracular
docker pull --platform=arm64 ubuntu:oracular
scripts/docker/buildx-multi.sh develop linux/amd64,linux/arm64 oracular-slim /oracular-slim
docker-develop-plucky:
docker pull --platform=amd64 ubuntu:plucky
docker pull --platform=arm64 ubuntu:plucky
scripts/docker/buildx-multi.sh develop linux/amd64,linux/arm64 plucky /plucky "-t photoprism/develop:latest -t photoprism/develop:ubuntu"
docker-develop-plucky-slim:
docker pull --platform=amd64 ubuntu:plucky
docker pull --platform=arm64 ubuntu:plucky
scripts/docker/buildx-multi.sh develop linux/amd64,linux/arm64 plucky-slim /plucky-slim
unstable: docker-unstable
docker-unstable: docker-unstable-mantic
docker-unstable-jammy:
@ -507,10 +526,10 @@ docker-unstable-mantic:
preview: docker-preview-ce
docker-preview: docker-preview-ce
docker-preview-all: docker-preview-latest docker-preview-other
docker-preview-ce: docker-preview-oracular
docker-preview-ce: docker-preview-plucky
docker-preview-latest: docker-preview-ubuntu
docker-preview-debian: docker-preview-bookworm
docker-preview-ubuntu: docker-preview-oracular
docker-preview-ubuntu: docker-preview-plucky
docker-preview-other: docker-preview-debian docker-preview-bullseye
docker-preview-arm: docker-preview-arm64 docker-preview-armv7
docker-preview-bookworm:
@ -575,12 +594,18 @@ docker-preview-oracular:
docker pull --platform=arm64 photoprism/develop:oracular
docker pull --platform=arm64 photoprism/develop:oracular-slim
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 preview-ce /oracular
docker-preview-plucky:
docker pull --platform=amd64 photoprism/develop:plucky
docker pull --platform=amd64 photoprism/develop:plucky-slim
docker pull --platform=arm64 photoprism/develop:plucky
docker pull --platform=arm64 photoprism/develop:plucky-slim
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 preview-ce /plucky
release: docker-release
docker-release: docker-release-latest
docker-release-all: docker-release-latest docker-release-other
docker-release-latest: docker-release-ubuntu
docker-release-debian: docker-release-bookworm
docker-release-ubuntu: docker-release-oracular
docker-release-ubuntu: docker-release-plucky
docker-release-other: docker-release-debian docker-release-bullseye
docker-release-arm: docker-release-arm64 docker-release-armv7
docker-release-bookworm:
@ -645,6 +670,12 @@ docker-release-oracular:
docker pull --platform=arm64 photoprism/develop:oracular
docker pull --platform=arm64 photoprism/develop:oracular-slim
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 ce /oracular
docker-release-plucky:
docker pull --platform=amd64 photoprism/develop:plucky
docker pull --platform=amd64 photoprism/develop:plucky-slim
docker pull --platform=arm64 photoprism/develop:plucky
docker pull --platform=arm64 photoprism/develop:plucky-slim
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 ce /plucky
start-local:
$(DOCKER_COMPOSE) -f compose.local.yaml up -d --wait
stop-local:
@ -687,8 +718,12 @@ terminal-preview:
$(DOCKER_COMPOSE) -f compose.preview.yaml exec photoprism-preview bash
logs-preview:
$(DOCKER_COMPOSE) -f compose.preview.yaml logs -f photoprism-preview
docker-local: docker-local-oracular
docker-local-all: docker-local-oracular docker-local-noble docker-local-mantic docker-local-lunar docker-local-jammy docker-local-bookworm docker-local-bullseye docker-local-buster
docker-local: docker-local-plucky
docker-local-up:
$(DOCKER_COMPOSE) -f compose.local.yaml up --force-recreate
docker-local-down:
$(DOCKER_COMPOSE) -f compose.local.yaml down --remove-orphans
docker-local-all: docker-local-plucky docker-local-oracular docker-local-noble docker-local-mantic docker-local-lunar docker-local-jammy docker-local-bookworm docker-local-bullseye docker-local-buster
docker-local-bookworm:
docker pull photoprism/develop:bookworm
docker pull photoprism/develop:bookworm-slim
@ -725,6 +760,10 @@ docker-local-oracular:
docker pull photoprism/develop:oracular
docker pull ubuntu:oracular
scripts/docker/build.sh photoprism ce-oracular /oracular "-t photoprism/photoprism:local"
docker-local-plucky:
docker pull photoprism/develop:plucky
docker pull ubuntu:plucky
scripts/docker/build.sh photoprism ce-plucky /plucky "-t photoprism/photoprism:local"
local-develop: docker-local-develop
docker-local-develop: docker-local-develop-oracular
docker-local-develop-all: docker-local-develop-oracular docker-local-develop-noble docker-local-develop-mantic docker-local-develop-lunar docker-local-develop-jammy docker-local-develop-bookworm docker-local-develop-bullseye docker-local-develop-buster docker-local-develop-impish
@ -755,6 +794,9 @@ docker-local-develop-noble:
docker-local-develop-oracular:
docker pull ubuntu:oracular
scripts/docker/build.sh develop oracular /oracular
docker-local-develop-plucky:
docker pull ubuntu:plucky
scripts/docker/build.sh develop plucky /plucky
docker-ddns:
docker pull golang:alpine
scripts/docker/buildx-multi.sh ddns linux/amd64,linux/arm64 $(BUILD_DATE)

481
NOTICE
View file

@ -9,7 +9,7 @@ The following 3rd-party software packages may be used by or distributed with
PhotoPrism. Any information relevant to third-party vendors listed below are
collected using common, reasonable means.
Date generated: 2025-03-27
Date generated: 2025-05-06
================================================================================
@ -541,7 +541,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
Package: github.com/dsoprea/go-heic-exif-extractor/v2
Version: v2.0.0-20210512044107-62067e44c235
License: MIT (https://github.com/dsoprea/go-heic-exif-extractor/blob/62067e44c235/v2/LICENSE)
License: MIT (https://github.com/dsoprea/go-heic-exif-extractor/blob/62067e44c235/LICENSE)
MIT LICENSE
@ -585,7 +585,7 @@ SOFTWARE.
Package: github.com/dsoprea/go-jpeg-image-structure/v2
Version: v2.0.0-20221012074422-4f3f7e934102
License: MIT (https://github.com/dsoprea/go-jpeg-image-structure/blob/4f3f7e934102/v2/LICENSE)
License: MIT (https://github.com/dsoprea/go-jpeg-image-structure/blob/4f3f7e934102/LICENSE)
MIT LICENSE
@ -661,7 +661,7 @@ SOFTWARE.
Package: github.com/dsoprea/go-png-image-structure/v2
Version: v2.0.0-20210512210324-29b889a6093d
License: MIT (https://github.com/dsoprea/go-png-image-structure/blob/29b889a6093d/v2/LICENSE)
License: MIT (https://github.com/dsoprea/go-png-image-structure/blob/29b889a6093d/LICENSE)
MIT LICENSE
@ -677,7 +677,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
Package: github.com/dsoprea/go-tiff-image-structure/v2
Version: v2.0.0-20221003165014-8ecc4f52edca
License: MIT (https://github.com/dsoprea/go-tiff-image-structure/blob/8ecc4f52edca/v2/LICENSE)
License: MIT (https://github.com/dsoprea/go-tiff-image-structure/blob/8ecc4f52edca/LICENSE)
MIT License
@ -705,7 +705,7 @@ SOFTWARE.
Package: github.com/dsoprea/go-utility/v2
Version: v2.0.0-20221003172846-a3e1774ef349
License: MIT (https://github.com/dsoprea/go-utility/blob/a3e1774ef349/v2/LICENSE)
License: MIT (https://github.com/dsoprea/go-utility/blob/a3e1774ef349/LICENSE)
Copyright 2019 Random Ingenuity InformationWorks
@ -1011,8 +1011,8 @@ SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/gabriel-vasile/mimetype
Version: v1.4.8
License: MIT (https://github.com/gabriel-vasile/mimetype/blob/v1.4.8/LICENSE)
Version: v1.4.9
License: MIT (https://github.com/gabriel-vasile/mimetype/blob/v1.4.9/LICENSE)
MIT License
@ -1039,8 +1039,8 @@ SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/gin-contrib/gzip
Version: v1.2.2
License: MIT (https://github.com/gin-contrib/gzip/blob/v1.2.2/LICENSE)
Version: v1.2.3
License: MIT (https://github.com/gin-contrib/gzip/blob/v1.2.3/LICENSE)
MIT License
@ -1067,8 +1067,8 @@ SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/gin-contrib/sse
Version: v1.0.0
License: MIT (https://github.com/gin-contrib/sse/blob/v1.0.0/LICENSE)
Version: v1.1.0
License: MIT (https://github.com/gin-contrib/sse/blob/v1.1.0/LICENSE)
The MIT License (MIT)
@ -1879,8 +1879,8 @@ SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/go-playground/validator/v10
Version: v10.25.0
License: MIT (https://github.com/go-playground/validator/blob/v10.25.0/LICENSE)
Version: v10.26.0
License: MIT (https://github.com/go-playground/validator/blob/v10.26.0/LICENSE)
The MIT License (MIT)
@ -2316,8 +2316,8 @@ SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/golang/geo
Version: v0.0.0-20250324010448-bc23e40121c4
License: Apache-2.0 (https://github.com/golang/geo/blob/bc23e40121c4/LICENSE)
Version: v0.0.0-20250505201543-5b58c72585db
License: Apache-2.0 (https://github.com/golang/geo/blob/5b58c72585db/LICENSE)
Apache License
@ -2525,8 +2525,8 @@ License: Apache-2.0 (https://github.com/golang/geo/blob/bc23e40121c4/LICENSE)
--------------------------------------------------------------------------------
Package: github.com/google/open-location-code/go
Version: v0.0.0-20250307090349-1695db3c3b15
License: Apache-2.0 (https://github.com/google/open-location-code/blob/1695db3c3b15/go/LICENSE)
Version: v0.0.0-20250415120251-fa6d7f9d4765
License: Apache-2.0 (https://github.com/google/open-location-code/blob/fa6d7f9d4765/go/LICENSE)
Apache License
@ -4432,8 +4432,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: github.com/pelletier/go-toml/v2
Version: v2.2.3
License: MIT (https://github.com/pelletier/go-toml/blob/v2.2.3/LICENSE)
Version: v2.2.4
License: MIT (https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)
The MIT License (MIT)
@ -4670,8 +4670,8 @@ License: Apache-2.0 (https://github.com/pquerna/otp/blob/v1.4.0/LICENSE)
--------------------------------------------------------------------------------
Package: github.com/prometheus/client_golang/prometheus
Version: v1.21.1
License: Apache-2.0 (https://github.com/prometheus/client_golang/blob/v1.21.1/LICENSE)
Version: v1.22.0
License: Apache-2.0 (https://github.com/prometheus/client_golang/blob/v1.22.0/LICENSE)
Apache License
Version 2.0, January 2004
@ -5663,11 +5663,204 @@ SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/tensorflow/tensorflow/tensorflow/go
Version: v1.15.2
License: Apache-2.0 (https://github.com/tensorflow/tensorflow/blob/v1.15.2/LICENSE)
Package: github.com/tidwall/gjson
Version: v1.18.0
License: MIT (https://github.com/tidwall/gjson/blob/v1.18.0/LICENSE)
Copyright 2019 The TensorFlow Authors. All rights reserved.
The MIT License (MIT)
Copyright (c) 2016 Josh Baker
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/tidwall/match
Version: v1.1.1
License: MIT (https://github.com/tidwall/match/blob/v1.1.1/LICENSE)
The MIT License (MIT)
Copyright (c) 2016 Josh Baker
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/tidwall/pretty
Version: v1.2.1
License: MIT (https://github.com/tidwall/pretty/blob/v1.2.1/LICENSE)
The MIT License (MIT)
Copyright (c) 2017 Josh Baker
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/ugjka/go-tz/v2
Version: v2.2.6
License: MIT (https://github.com/ugjka/go-tz/blob/v2.2.6/LICENSE)
MIT License
Copyright (c) 2017 ugjka <esesmu@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/ugorji/go/codec
Version: v1.2.12
License: MIT (https://github.com/ugorji/go/blob/codec/v1.2.12/codec/LICENSE)
The MIT License (MIT)
Copyright (c) 2012-2020 Ugorji Nwoke.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/ulule/deepcopier
Version: v0.0.0-20200430083143-45decc6639b6
License: MIT (https://github.com/ulule/deepcopier/blob/45decc6639b6/LICENSE)
The MIT License (MIT)
Copyright (c) 2015 Ulule
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/urfave/cli/v2
Version: v2.27.6
License: MIT (https://github.com/urfave/cli/blob/v2.27.6/LICENSE)
MIT License
Copyright (c) 2022 urfave/cli maintainers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/wamuir/graft/tensorflow
Version: v0.10.0
License: Apache-2.0 (https://github.com/wamuir/graft/blob/v0.10.0/LICENSE)
Apache License
Version 2.0, January 2004
@ -5873,201 +6066,6 @@ Copyright 2019 The TensorFlow Authors. All rights reserved.
--------------------------------------------------------------------------------
Package: github.com/tidwall/gjson
Version: v1.18.0
License: MIT (https://github.com/tidwall/gjson/blob/v1.18.0/LICENSE)
The MIT License (MIT)
Copyright (c) 2016 Josh Baker
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/tidwall/match
Version: v1.1.1
License: MIT (https://github.com/tidwall/match/blob/v1.1.1/LICENSE)
The MIT License (MIT)
Copyright (c) 2016 Josh Baker
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/tidwall/pretty
Version: v1.2.1
License: MIT (https://github.com/tidwall/pretty/blob/v1.2.1/LICENSE)
The MIT License (MIT)
Copyright (c) 2017 Josh Baker
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/ugjka/go-tz/v2
Version: v2.2.6
License: MIT (https://github.com/ugjka/go-tz/blob/v2.2.6/LICENSE)
MIT License
Copyright (c) 2017 ugjka <esesmu@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/ugorji/go/codec
Version: v1.2.12
License: MIT (https://github.com/ugorji/go/blob/codec/v1.2.12/codec/LICENSE)
The MIT License (MIT)
Copyright (c) 2012-2020 Ugorji Nwoke.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/ulule/deepcopier
Version: v0.0.0-20200430083143-45decc6639b6
License: MIT (https://github.com/ulule/deepcopier/blob/45decc6639b6/LICENSE)
The MIT License (MIT)
Copyright (c) 2015 Ulule
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/urfave/cli/v2
Version: v2.27.6
License: MIT (https://github.com/urfave/cli/blob/v2.27.6/LICENSE)
MIT License
Copyright (c) 2022 urfave/cli maintainers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
Package: github.com/xrash/smetrics
Version: v0.0.0-20240521201337-686a1a2994c1
License: MIT (https://github.com/xrash/smetrics/blob/686a1a2994c1/LICENSE)
@ -6305,8 +6303,8 @@ License: Apache-2.0 (https://github.com/zitadel/logging/blob/v0.6.2/LICENSE)
--------------------------------------------------------------------------------
Package: github.com/zitadel/oidc/v3/pkg
Version: v3.37.0
License: Apache-2.0 (https://github.com/zitadel/oidc/blob/v3.37.0/LICENSE)
Version: v3.38.1
License: Apache-2.0 (https://github.com/zitadel/oidc/blob/v3.38.1/LICENSE)
Apache License
Version 2.0, January 2004
@ -7588,8 +7586,8 @@ License: Apache-2.0 (https://github.com/go4org/go4/blob/214862532bf5/LICENSE)
--------------------------------------------------------------------------------
Package: golang.org/x/crypto
Version: v0.36.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.36.0:LICENSE)
Version: v0.38.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.38.0:LICENSE)
Copyright 2009 The Go Authors.
@ -7622,8 +7620,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: golang.org/x/image
Version: v0.25.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.25.0:LICENSE)
Version: v0.27.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.27.0:LICENSE)
Copyright 2009 The Go Authors.
@ -7690,8 +7688,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: golang.org/x/net
Version: v0.37.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.37.0:LICENSE)
Version: v0.40.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.40.0:LICENSE)
Copyright 2009 The Go Authors.
@ -7724,8 +7722,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: golang.org/x/oauth2
Version: v0.28.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/oauth2/+/v0.28.0:LICENSE)
Version: v0.29.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/oauth2/+/v0.29.0:LICENSE)
Copyright 2009 The Go Authors.
@ -7758,8 +7756,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: golang.org/x/sync/errgroup
Version: v0.12.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.12.0:LICENSE)
Version: v0.14.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.14.0:LICENSE)
Copyright 2009 The Go Authors.
@ -7792,8 +7790,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: golang.org/x/sys
Version: v0.31.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.31.0:LICENSE)
Version: v0.33.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.33.0:LICENSE)
Copyright 2009 The Go Authors.
@ -7826,8 +7824,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
Package: golang.org/x/text
Version: v0.23.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.23.0:LICENSE)
Version: v0.25.0
License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.25.0:LICENSE)
Copyright 2009 The Go Authors.
@ -8240,7 +8238,13 @@ Package License Copyright
@eslint/js MIT n/a
@lcdp/offline-plugin MIT Le Comptoir Des Pharmacies <webmaster@lecomptoirdespharmacies.fr>
@mdi/font Apache-2.0 Austin Andrews
@testing-library/jest-dom MIT Ernesto Garcia <gnapse@gmail.com> (http://gnapse.github.io)
@testing-library/react MIT Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
@vitejs/plugin-react MIT Evan You
@vitest/coverage-v8 MIT Anthony Fu <anthonyfu117@hotmail.com>
@vitest/ui MIT n/a
@vue/compiler-sfc MIT Evan You
@vue/language-server MIT n/a
@vvo/tzdb MIT Vincent Voyer <vincent@codeagain.com>
axios MIT Matt Zabriskie
axios-mock-adapter MIT Colin Timmermans <colintimmermans@gmail.com>
@ -8274,6 +8278,7 @@ floating-vue MIT Guillaume Chau <guillaume.b.chau
globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com
hls.js Apache-2.0 n/a
i MIT Pavan Kumar Sunkara <pavan.sss1991@gmail.com> (pksunkara.github.com)
jsdom MIT n/a
karma MIT Vojta Jína <vojta.jina@gmail.com>
karma-chrome-launcher MIT Vojta Jina <vojta.jina@gmail.com>
karma-coverage-istanbul-reporter MIT Matt Lewis
@ -8310,6 +8315,8 @@ svg-url-loader MIT Hovhannes Babayan
tar ISC Isaac Z. Schlueter
url-loader MIT Tobias Koppers @sokra
util MIT Joyent http://www.joyent.com
vite-tsconfig-paths MIT aleclarson
vitest MIT Anthony Fu <anthonyfu117@hotmail.com>
vue MIT Evan You
vue-3-sanitize MIT Vannsl, Vanessa Otto <mail@vannsl.io>
vue-loader MIT Evan You

BIN
assets/examples/example.zip Normal file

Binary file not shown.

View file

@ -7,7 +7,7 @@ msgstr ""
"Last-Translator: DeepL <noreply-mt-deepl@weblate.org>\n"
"Language-Team: Japanese <https://translate.photoprism.app/projects/"
"photoprism/backend/ja/>\n"
"Language: ja_JP\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View file

@ -28,8 +28,8 @@
<div class="splash-logo">
{{template "logo.gohtml" .}}
</div>
<progress id="progress" class="html-progress" max="100"></progress>
<progress id="progress" class="html-progress" role="progressbar" max="100"></progress>
</div>
</div>
</div>
<div id="busy-overlay"><div class="splash-center"><progress id="busy-progress" class="html-progress" max="100"></progress></div></div>
<div id="busy-overlay"><div class="splash-center"><progress id="busy-progress" class="html-progress" role="progressbar" max="100"></progress></div></div>

View file

@ -62,12 +62,12 @@ services:
# 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)
TF_CPP_MIN_LOG_LEVEL: 0 # Show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # Show TensorFlow log messages for development
## Enable TensorFlow AVX2 support for modern Intel CPUs (requires starting the container as root):
# PHOTOPRISM_INIT: "tensorflow-amd64-avx2"
## Hardware video transcoding config (optional):
# PHOTOPRISM_FFMPEG_BUFFERS: "64" # FFmpeg capture buffers (default: 32)
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbps (default: 60)
# PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m" # Use Video4Linux for AVC transcoding (default: libx264)
# PHOTOPRISM_FFMPEG_ENCODER: "h264_qsv" # Use Intel Quick Sync Video for AVC transcoding (default: libx264)
# PHOTOPRISM_INIT: "intel-graphics tensorflow-amd64-avx2" # Enable TensorFlow AVX2 & Intel Graphics support

View file

@ -8,6 +8,7 @@ services:
- dummy-webdav
- dummy-oidc
stop_grace_period: 10s
privileged: true
security_opt:
- seccomp:unconfined
- apparmor:unconfined
@ -109,12 +110,12 @@ services:
PHOTOPRISM_THUMB_LIBRARY: "auto" # image processing library to be used for generating thumbnails (auto, imaging, vips)
PHOTOPRISM_THUMB_FILTER: "auto" # downscaling filter (imaging best to worst: blackman, lanczos, cubic, linear, nearest)
PHOTOPRISM_THUMB_UNCACHED: "true" # enables on-demand thumbnail rendering (high memory and cpu usage)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
## Intel Quick Sync Video (QSV) (https://docs.photoprism.app/getting-started/advanced/transcoding/#intel-quick-sync):
PHOTOPRISM_FFMPEG_ENCODER: "intel" # H.264/AVC encoder (software, intel, nvidia, apple, raspberry, or vaapi)
PHOTOPRISM_FFMPEG_SIZE: "1920" # video size limit in pixels (720-7680) (default: 3840)
PHOTOPRISM_FFMPEG_BITRATE: "50" # video bitrate limit in Mbit/s (default: 50)
## Run/install on first startup (options: update https gpu ffmpeg tensorflow davfs clitools clean):
# PHOTOPRISM_FFMPEG_BITRATE: "60" # video bitrate limit in Mbps (default: 60)
## Run/install on first startup (options: update tensorflow https intel gpu davfs):
PHOTOPRISM_INIT: "https intel tensorflow"
## Share hardware devices with FFmpeg for hardware video transcoding:
devices:
@ -133,6 +134,10 @@ services:
extends:
file: ./compose.yaml
service: qdrant
photoprism-vision:
extends:
file: ./compose.yaml
service: photoprism-vision
traefik:
extends:
file: ./compose.yaml
@ -164,9 +169,3 @@ volumes:
driver: local
mariadb:
driver: local
## Create shared "photoprism-develop" network for connecting with services in other compose.yaml files
networks:
default:
name: photoprism
driver: bridge

View file

@ -57,7 +57,7 @@ services:
# 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)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
working_dir: "/photoprism"
volumes:
- "./storage:/photoprism/storage"

View file

@ -58,7 +58,7 @@ services:
# 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)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
# PHOTOPRISM_INIT: "http gpu tensorflow" # Options: "update https gpu tensorflow davfs clitools clean"
PHOTOPRISM_FFMPEG_ENCODER: "nvidia" # Options: "software", "intel", "nvidia", "apple", "raspberry"
PHOTOPRISM_STORAGE_PATH: "/photoprism/storage"

View file

@ -3,11 +3,13 @@ services:
photoprism:
build: .
image: photoprism/photoprism:develop
runtime: nvidia
depends_on:
- mariadb
- dummy-webdav
- dummy-oidc
stop_grace_period: 10s
privileged: true
security_opt:
- seccomp:unconfined
- apparmor:unconfined
@ -111,15 +113,15 @@ services:
PHOTOPRISM_THUMB_LIBRARY: "auto" # image processing library to be used for generating thumbnails (auto, imaging, vips)
PHOTOPRISM_THUMB_FILTER: "auto" # downscaling filter (imaging best to worst: blackman, lanczos, cubic, linear, nearest)
PHOTOPRISM_THUMB_UNCACHED: "true" # enables on-demand thumbnail rendering (high memory and cpu usage)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
## Run/install on first startup, see https://github.com/photoprism/photoprism/blob/develop/scripts/dist/Makefile:
PHOTOPRISM_INIT: "https tensorflow-gpu" # common options: update https tensorflow tensorflow-gpu intel gpu davfs
## Nvidia Video Transcoding (https://docs.photoprism.app/getting-started/advanced/transcoding/#nvidia-container-toolkit):
NVIDIA_VISIBLE_DEVICES: "all"
NVIDIA_DRIVER_CAPABILITIES: "all"
PHOTOPRISM_FFMPEG_ENCODER: "nvidia" # H.264/AVC encoder (software, intel, nvidia, apple, raspberry, or vaapi)
PHOTOPRISM_FFMPEG_SIZE: "1920" # video size limit in pixels (720-7680) (default: 3840)
PHOTOPRISM_FFMPEG_BITRATE: "50" # video bitrate limit in Mbit/s (default: 50)
## Run/install on first startup (options: update https gpu ffmpeg tensorflow davfs clitools clean):
PHOTOPRISM_INIT: "https tensorflow"
# PHOTOPRISM_FFMPEG_BITRATE: "60" # video bitrate limit in Mbps (default: 60)
## Share hardware devices with FFmpeg and TensorFlow (optional):
# devices:
# - "/dev/dri:/dev/dri" # Intel QSV (Broadwell and later) or VAAPI (Haswell and earlier)
@ -140,8 +142,9 @@ services:
reservations:
devices:
- driver: "nvidia"
count: 1
capabilities: [ gpu ]
capabilities: [gpu]
count: "all"
mariadb:
extends:
file: ./compose.yaml

View file

@ -65,7 +65,7 @@ services:
# 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)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
## PostgreSQL Database Server
## Docs: https://www.postgresql.org/docs/

View file

@ -57,7 +57,7 @@ services:
# 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)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
working_dir: "/photoprism"
volumes:
- "./storage:/photoprism/storage"

View file

@ -118,13 +118,13 @@ services:
PHOTOPRISM_THUMB_LIBRARY: "auto" # image processing library to be used for generating thumbnails (auto, imaging, vips)
PHOTOPRISM_THUMB_FILTER: "auto" # downscaling filter (imaging best to worst: blackman, lanczos, cubic, linear, nearest)
PHOTOPRISM_THUMB_UNCACHED: "true" # enables on-demand thumbnail rendering (high memory and cpu usage)
TF_CPP_MIN_LOG_LEVEL: 0 # show TensorFlow log messages for development
TF_CPP_MIN_LOG_LEVEL: 1 # show TensorFlow log messages for development
## Video Transcoding (https://docs.photoprism.app/getting-started/advanced/transcoding/):
# PHOTOPRISM_FFMPEG_ENCODER: "software" # H.264/AVC encoder (software, intel, nvidia, apple, raspberry, or vaapi)
# PHOTOPRISM_FFMPEG_SIZE: "1920" # video size limit in pixels (720-7680) (default: 3840)
# PHOTOPRISM_FFMPEG_BITRATE: "32" # video bitrate limit in Mbit/s (default: 50)
# LIBVA_DRIVER_NAME: "i965" # For Intel architectures Haswell and older which do not support QSV yet but use VAAPI instead
## Run/install on first startup (options: update https gpu ffmpeg tensorflow davfs clitools clean):
PHOTOPRISM_FFMPEG_SIZE: "1920" # video size limit in pixels (720-7680) (default: 3840)
# PHOTOPRISM_FFMPEG_BITRATE: "60" # video bitrate limit in Mbps (default: 60)
## Run/install on first startup (options: update tensorflow https intel gpu davfs):
PHOTOPRISM_INIT: "https"
## Share hardware devices with FFmpeg and TensorFlow (optional):
# devices:

View file

@ -1,9 +1,9 @@
FROM photoprism/photoprism:preview-ce AS build
# Set environment variables
ENV TF_CPP_MIN_LOG_LEVEL=2 \
ENV TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \
PHOTOPRISM_DEBUG="false" \
PHOTOPRISM_READONLY="false" \

View file

@ -1,7 +1,6 @@
services:
demo:
restart: always
command: photoprism --public start
image: photoprism/demo:latest
container_name: demo
depends_on:
@ -14,6 +13,8 @@ services:
volumes:
- "./config:/photoprism/storage/config"
environment:
PHOTOPRISM_DEMO: "true"
PHOTOPRISM_PUBLIC: "true"
PHOTOPRISM_SITE_URL: "https://demo.yourdomain.com/"
# PHOTOPRISM_CDN_URL: "https://demo-cdn.yourdomain.com/"
PHOTOPRISM_SITE_TITLE: "PhotoPrism"

View file

@ -1,9 +1,9 @@
FROM photoprism/photoprism:preview-ce-debian AS build
# Set environment variables
ENV TF_CPP_MIN_LOG_LEVEL=2 \
ENV TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \
PHOTOPRISM_DEBUG="false" \
PHOTOPRISM_READONLY="false" \

View file

@ -1,9 +1,9 @@
FROM photoprism/photoprism:preview-ce-ubuntu AS build
# Set environment variables
ENV TF_CPP_MIN_LOG_LEVEL=2 \
ENV TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \
PHOTOPRISM_DEBUG="false" \
PHOTOPRISM_READONLY="false" \

View file

@ -1,9 +1,9 @@
FROM photoprism/photoprism:unstable-ce AS build
# Set environment variables
ENV TF_CPP_MIN_LOG_LEVEL=2 \
ENV TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \
PHOTOPRISM_DEBUG="false" \
PHOTOPRISM_READONLY="false" \

View file

@ -31,8 +31,8 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_VERSION=1.15.2 \
TF_CPP_MIN_LOG_LEVEL=0 \
MALLOC_ARENA_MAX=4 \
TF_CPP_MIN_LOG_LEVEL=1 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \
@ -64,6 +64,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
iputils-ping dnsutils \
&& \
/scripts/install-nodejs.sh && \
/scripts/install-yt-dlp.sh && \
/scripts/install-libheif.sh && \
/scripts/install-tensorflow.sh && \
echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism"
# Copy scripts and package sources config.

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism"
# copy scripts and debian backports sources list

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
NODE_ENV="production" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
NODE_ENV="production" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
S6_KEEP_ENV=0 \
S6_VERBOSITY=0 \
@ -53,10 +53,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
xz-utils exiftool sqlite3 postgresql-client tzdata gpg make zip unzip wget curl rsync \
imagemagick libvips-dev rawtherapee ffmpeg libavcodec-extra x264 x265 libde265-dev \
libaom-dev libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libebml5 libgav1-bin libatomic1 \
iputils-ping dnsutils \
va-driver-all libva2 iputils-ping dnsutils \
&& \
/scripts/install-mariadb.sh mariadb-client && \
/scripts/install-darktable.sh && \
/scripts/install-yt-dlp.sh && \
/scripts/install-libheif.sh && \
echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \
echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \
@ -59,7 +59,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
xz-utils exiftool sqlite3 postgresql-client tzdata gpg make zip unzip wget curl rsync \
imagemagick libvips-dev rawtherapee ffmpeg libavcodec-extra x264 x265 libde265-dev \
libaom-dev libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libebml5 libgav1-bin libatomic1 \
iputils-ping dnsutils \
va-driver-all libva2 iputils-ping dnsutils \
&& \
apt-get -qq install \
apt-utils pkg-config software-properties-common \
@ -74,6 +74,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
/scripts/install-mariadb.sh mariadb-client && \
/scripts/install-tensorflow.sh && \
/scripts/install-darktable.sh && \
/scripts/install-yt-dlp.sh && \
/scripts/install-libheif.sh && \
/scripts/install-chrome.sh && \
echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism"
# Copy scripts and package sources config.

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism"
# Copy scripts and package sources config.

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism"
# Copy scripts and package sources config.

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -29,9 +29,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
S6_KEEP_ENV=0 \
S6_VERBOSITY=0 \

View file

@ -30,9 +30,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=0 \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \

View file

@ -0,0 +1,91 @@
#### Base Image: Ubuntu 25.04 (Plucky Puffin)
FROM ubuntu:plucky
# Copyright © 2018 - 2025 PhotoPrism UG. All rights reserved.
#
# Questions? Email us at hello@photoprism.app or visit our website to learn
# more about our team, products and services: https://www.photoprism.app/
# Add Open Container Initiative (OCI) annotations.
# See: https://github.com/opencontainers/image-spec/blob/main/annotations.md
LABEL org.opencontainers.image.title="PhotoPrism® Base Image (Ubuntu 25.04)"
LABEL org.opencontainers.image.description="Ubuntu 25.04 (Plucky Puffin)"
LABEL org.opencontainers.image.url="https://hub.docker.com/repository/docker/photoprism/develop"
LABEL org.opencontainers.image.source="https://github.com/photoprism/photoprism"
LABEL org.opencontainers.image.documentation="https://docs.photoprism.app/developer-guide/setup/"
LABEL org.opencontainers.image.authors="PhotoPrism UG <hello@photoprism.app>"
LABEL org.opencontainers.image.vendor="PhotoPrism UG"
# Declare build parameters.
ARG TARGETARCH
ARG BUILD_TAG
# Set environment variables, see https://docs.photoprism.app/getting-started/config-options/.
ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_TAG=$BUILD_TAG \
DOCKER_ENV="prod" \
PS1="\u@$BUILD_TAG:\w\$ " \
PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/scripts:/opt/photoprism/bin" \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
S6_KEEP_ENV=0 \
S6_VERBOSITY=0 \
S6_LOGGING=0
# Copy scripts and package sources config.
COPY --chown=root:root --chmod=755 /scripts/dist/ /scripts/
# Update base image and add dependencies.
RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \
echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \
echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \
echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \
echo 'force-confold' > /etc/dpkg/dpkg.cfg.d/force-confold && \
apt-get update && apt-get -qq dist-upgrade && \
apt-get -qq install \
libc6 ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \
xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \
ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \
libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \
libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \
va-driver-all libva2 iputils-ping dnsutils \
&& \
/scripts/install-mariadb.sh mariadb-client && \
/scripts/install-darktable.sh && \
/scripts/install-yt-dlp.sh && \
/scripts/install-libheif.sh && \
echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \
echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \
echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \
/scripts/install-dircolors.sh && \
cp /etc/skel/.bashrc /root/.bashrc && \
/scripts/create-users.sh && \
install -d -m 0777 -o 1000 -g 1000 \
/photoprism/originals \
/photoprism/import \
/photoprism/storage \
/photoprism/storage/sidecar \
/photoprism/storage/albums \
/photoprism/storage/backups \
/photoprism/storage/config \
/photoprism/storage/cache && \
/scripts/install-s6.sh && \
ln -sf /scripts/services/photoprism /etc/s6-overlay/s6-rc.d/photoprism && \
touch /etc/s6-overlay/s6-rc.d/user/contents.d/photoprism && \
apt modernize-sources && \
/scripts/cleanup.sh
# Set default working directory.
WORKDIR /photoprism
# Expose default HTTP and HTTPS ports.
EXPOSE 2342 2442 2443
# Set default entrypoint and command.
ENTRYPOINT ["/init"]

View file

@ -0,0 +1,127 @@
#### Base Image: Ubuntu 25.04 (Plucky Puffin)
FROM ubuntu:plucky
# Copyright © 2018 - 2025 PhotoPrism UG. All rights reserved.
#
# Questions? Email us at hello@photoprism.app or visit our website to learn
# more about our team, products and services: https://www.photoprism.app/
# Add Open Container Initiative (OCI) annotations.
# See: https://github.com/opencontainers/image-spec/blob/main/annotations.md
LABEL org.opencontainers.image.title="PhotoPrism® Build Image (Ubuntu 25.04)"
LABEL org.opencontainers.image.description="Ubuntu 25.04 (Plucky Puffin)"
LABEL org.opencontainers.image.url="https://hub.docker.com/repository/docker/photoprism/develop"
LABEL org.opencontainers.image.source="https://github.com/photoprism/photoprism"
LABEL org.opencontainers.image.documentation="https://docs.photoprism.app/developer-guide/setup/"
LABEL org.opencontainers.image.authors="PhotoPrism UG <hello@photoprism.app>"
LABEL org.opencontainers.image.vendor="PhotoPrism UG"
# Declare build parameters.
ARG TARGETARCH
ARG BUILD_TAG
# Set environment variables, see https://docs.photoprism.app/getting-started/config-options/.
ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_TAG=$BUILD_TAG \
DOCKER_ENV="develop" \
NODE_ENV="production" \
PS1="\u@$BUILD_TAG:\w\$ " \
PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/scripts:/usr/local/go/bin:/go/bin:/opt/photoprism/bin" \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
DEBIAN_FRONTEND="noninteractive" \
TMPDIR="/tmp" \
TF_CPP_MIN_LOG_LEVEL=1 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=2 \
GOPATH="/go" \
GOBIN="/usr/local/bin" \
GO111MODULE="on" \
CGO_CFLAGS="-g -O2 -Wno-return-local-addr" \
PROG="photoprism" \
S6_KEEP_ENV=1 \
S6_VERBOSITY=0 \
S6_LOGGING=0
# Copy scripts and package sources config.
COPY --chown=root:root --chmod=755 /scripts/dist/ /scripts/
COPY --chown=root:root --chmod=644 /.my.cnf /etc/my.cnf
# Update base image and add dependencies.
RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/80recommends && \
echo 'APT::Install-Suggests "false";' > /etc/apt/apt.conf.d/80suggests && \
echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \
echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \
echo 'force-confold' > /etc/dpkg/dpkg.cfg.d/force-confold && \
apt-get update && apt-get -qq dist-upgrade && \
apt-get -qq install \
libc6 libbsd-dev ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \
xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \
ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \
libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \
libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \
va-driver-all libva2 iputils-ping dnsutils \
&& \
apt-get -qq install \
software-properties-common pkg-config apt-utils \
build-essential gcc g++ git gettext davfs2 chrpath apache2-utils \
autoconf automake cmake libtool libjpeg-dev libpng-dev libwebp-dev libavcodec-dev \
libx264-dev libx265-dev libaom-dev libvpx-dev libwebm-dev libxft-dev \
libc6-dev libhdf5-serial-dev libzmq3-dev libssl-dev libnss3 \
libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev fonts-roboto \
librsvg2-bin ghostscript gsfonts pdf2svg ps2eps libsharpyuv-dev \
&& \
/scripts/install-nodejs.sh && \
/scripts/install-mariadb.sh mariadb-client && \
/scripts/install-tensorflow.sh && \
/scripts/install-darktable.sh && \
/scripts/install-yt-dlp.sh && \
/scripts/install-libheif.sh && \
/scripts/install-chrome.sh && \
echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \
mkdir -p /etc/skel/.config/go/telemetry && \
echo 'off 2025-01-03' > '/etc/skel/.config/go/telemetry/mode' && \
cp -r /etc/skel/.config /root/.config && \
/scripts/install-go.sh && \
/scripts/install-go-tools.sh && \
echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \
echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \
/scripts/install-dircolors.sh && \
cp /etc/skel/.bashrc /root/.bashrc && \
cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \
/scripts/create-users.sh && \
install -d -m 0777 -o 1000 -g 1000 \
/photoprism/originals \
/photoprism/import \
/photoprism/storage \
/photoprism/storage/sidecar \
/photoprism/storage/albums \
/photoprism/storage/backups \
/photoprism/storage/config \
/photoprism/storage/cache && \
/scripts/install-s6.sh && \
apt modernize-sources && \
/scripts/cleanup.sh
# Download machine learning models and test data.
RUN mkdir /tmp/photoprism && \
wget "https://dl.photoprism.app/tensorflow/nsfw.zip?${BUILD_TAG}" -O /tmp/photoprism/nsfw.zip && \
wget "https://dl.photoprism.app/tensorflow/nasnet.zip?${BUILD_TAG}" -O /tmp/photoprism/nasnet.zip && \
wget "https://dl.photoprism.app/tensorflow/facenet.zip?${BUILD_TAG}" -O /tmp/photoprism/facenet.zip && \
wget "https://dl.photoprism.app/qa/testdata.zip?${BUILD_TAG}" -O /tmp/photoprism/testdata.zip
# Set default working directory.
WORKDIR "/go/src/github.com/photoprism/photoprism"
# Expose the following container ports:
# - 2342 (HTTP)
# - 2343 (Acceptance Tests)
# - 2442 (HTTP)
# - 2443 (HTTPS)
# - 9515 (Chromedriver)
# - 40000 (Go Debugger)
EXPOSE 2342 2343 2442 2443 9515 40000
# Set default entrypoint and command.
ENTRYPOINT ["/init"]
CMD ["/scripts/cmd.sh", "tail", "-f", "/dev/null"]

View file

@ -47,8 +47,8 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_VERSION=1.15.2 \
TF_CPP_MIN_LOG_LEVEL=2 \
MALLOC_ARENA_MAX=4 \
TF_CPP_MIN_LOG_LEVEL=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \
@ -116,6 +116,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \
libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \
iputils-ping dnsutils \
&& \
/scripts/install-yt-dlp.sh && \
/scripts/install-libheif.sh && \
echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \
echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \

View file

@ -41,9 +41,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -41,9 +41,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -44,9 +44,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -44,9 +44,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
LD_LIBRARY_PATH="/usr/local/lib:/usr/lib" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -42,9 +42,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -42,9 +42,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -42,9 +42,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -42,9 +42,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -42,9 +42,9 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=2 \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=4 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \

View file

@ -0,0 +1,103 @@
##################################################### BUILD STAGE ######################################################
FROM photoprism/develop:plucky AS build
# Copyright © 2018 - 2025 PhotoPrism UG. All rights reserved.
#
# Questions? Email us at hello@photoprism.app or visit our website to learn
# more about our team, products and services: https://www.photoprism.app/
# Declare build parameters.
ARG TARGETARCH
ARG TARGETPLATFORM
ARG BUILD_TAG
# Copy source to image.
WORKDIR "/go/src/github.com/photoprism/photoprism"
COPY . .
# Build app.
RUN make all install DESTDIR=/opt/photoprism
################################################## PRODUCTION STAGE ####################################################
#### Base Image: Ubuntu 25.04 (Plucky Puffin)
FROM photoprism/develop:plucky-slim
# Add Open Container Initiative (OCI) annotations.
# See: https://github.com/opencontainers/image-spec/blob/main/annotations.md
LABEL org.opencontainers.image.title="PhotoPrism® (Ubuntu 25.04)"
LABEL org.opencontainers.image.description="Ubuntu 25.04 (Plucky Puffin)"
LABEL org.opencontainers.image.url="https://hub.docker.com/r/photoprism/photoprism"
LABEL org.opencontainers.image.source="https://github.com/photoprism/photoprism"
LABEL org.opencontainers.image.documentation="https://docs.photoprism.app/getting-started/"
LABEL org.opencontainers.image.authors="PhotoPrism UG <hello@photoprism.app>"
LABEL org.opencontainers.image.vendor="PhotoPrism UG"
# Declare build parameters.
ARG TARGETARCH
ARG BUILD_TAG
# Set environment variables, see https://docs.photoprism.app/getting-started/config-options/.
ENV PHOTOPRISM_ARCH=$TARGETARCH \
DOCKER_TAG=$BUILD_TAG \
DOCKER_ENV="prod" \
TMPDIR="/tmp" \
DEBIAN_FRONTEND="noninteractive" \
TF_CPP_MIN_LOG_LEVEL=4 \
TF_ENABLE_ONEDNN_OPTS=1 \
MALLOC_ARENA_MAX=2 \
PROG="photoprism" \
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \
PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \
PHOTOPRISM_STORAGE_PATH="/photoprism/storage" \
PHOTOPRISM_BACKUP_PATH="/photoprism/storage/backups" \
PHOTOPRISM_LOG_FILENAME="/photoprism/storage/photoprism.log" \
PHOTOPRISM_PID_FILENAME="/photoprism/storage/photoprism.pid" \
PHOTOPRISM_DEBUG="false" \
PHOTOPRISM_PUBLIC="false" \
PHOTOPRISM_READONLY="false" \
PHOTOPRISM_UPLOAD_NSFW="true" \
PHOTOPRISM_DETECT_NSFW="false" \
PHOTOPRISM_EXPERIMENTAL="false" \
PHOTOPRISM_SITE_URL="http://localhost:2342/" \
PHOTOPRISM_SITE_CAPTION="AI-Powered Photos App" \
PHOTOPRISM_SITE_DESCRIPTION="" \
PHOTOPRISM_SITE_AUTHOR="" \
PHOTOPRISM_HTTP_HOST="0.0.0.0" \
PHOTOPRISM_HTTP_PORT=2342 \
PHOTOPRISM_DATABASE_DRIVER="sqlite" \
PHOTOPRISM_DATABASE_SERVER="" \
PHOTOPRISM_DATABASE_NAME="photoprism" \
PHOTOPRISM_DATABASE_USER="photoprism" \
PHOTOPRISM_DATABASE_PASSWORD="" \
PHOTOPRISM_DISABLE_CHOWN="false" \
PHOTOPRISM_DISABLE_WEBDAV="false" \
PHOTOPRISM_DISABLE_SETTINGS="false" \
PHOTOPRISM_DISABLE_BACKUPS="false" \
PHOTOPRISM_DISABLE_EXIFTOOL="false" \
PHOTOPRISM_DISABLE_PLACES="false" \
PHOTOPRISM_DISABLE_TENSORFLOW="false" \
PHOTOPRISM_DISABLE_FACES="false" \
PHOTOPRISM_DISABLE_CLASSIFICATION="false" \
PHOTOPRISM_RAW_PRESETS="false" \
PHOTOPRISM_THUMB_UNCACHED="false" \
PHOTOPRISM_AUTO_INDEX="300" \
PHOTOPRISM_AUTO_IMPORT="-1" \
PHOTOPRISM_INIT="https"
# Copy scripts.
COPY --chown=root:root --chmod=755 /scripts/dist/ /scripts/
# Update pre-installed packages.
RUN apt-get update && \
apt-get -qq dist-upgrade && \
/scripts/cleanup.sh
# Set default working directory.
WORKDIR /photoprism
# Expose HTTP(S) ports.
EXPOSE 2342 2443
# Copy app files.
COPY --from=build --chown=root:root --chmod=755 /opt/photoprism/ /opt/photoprism

View file

@ -1,4 +1,4 @@
all: libtensorflow libtensorflow-avx libtensorflow-avx2 libtensorflow-vnni libtensorflow-avx512
all: libtensorflow libtensorflow-ssse3 libtensorflow-avx libtensorflow-avx2 libtensorflow-vnni libtensorflow-avx512
# Downloads the TensorFlow source code from GitHub and extracts it to a subdirectory:
download:
wget https://github.com/tensorflow/tensorflow/archive/v$(TF_VERSION).tar.gz
@ -7,8 +7,11 @@ download:
# Clang command line argument reference:
# https://clang.llvm.org/docs/ClangCommandLineReference.html#x86
libtensorflow:
bazel build -c opt //tensorflow:libtensorflow.so --copt=-O2 --copt=-mno-avx --copt=-mno-avx2 --copt=-mno-fma --copt=-march=core2
bazel build -c opt //tensorflow:libtensorflow.so --copt=-O2 --copt=-mno-avx --copt=-mno-avx2 --copt=-mno-fma --copt=-march=x86-64
./create_archive.sh amd64 $(TF_VERSION)
libtensorflow-ssse3:
bazel build -c opt //tensorflow:libtensorflow.so --copt=-O2 --copt=-mno-avx --copt=-mno-avx2 --copt=-mno-fma --copt=-march=core2
./create_archive.sh amd64-ssse3 $(TF_VERSION)
libtensorflow-avx:
bazel build -c opt //tensorflow:libtensorflow.so --copt=-O2 --copt=-mavx
./create_archive.sh amd64-avx $(TF_VERSION)

View file

@ -10,7 +10,13 @@ Package License Copyright
@eslint/js MIT n/a
@lcdp/offline-plugin MIT Le Comptoir Des Pharmacies <webmaster@lecomptoirdespharmacies.fr>
@mdi/font Apache-2.0 Austin Andrews
@testing-library/jest-dom MIT Ernesto Garcia <gnapse@gmail.com> (http://gnapse.github.io)
@testing-library/react MIT Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
@vitejs/plugin-react MIT Evan You
@vitest/coverage-v8 MIT Anthony Fu <anthonyfu117@hotmail.com>
@vitest/ui MIT n/a
@vue/compiler-sfc MIT Evan You
@vue/language-server MIT n/a
@vvo/tzdb MIT Vincent Voyer <vincent@codeagain.com>
axios MIT Matt Zabriskie
axios-mock-adapter MIT Colin Timmermans <colintimmermans@gmail.com>
@ -44,6 +50,7 @@ floating-vue MIT Guillaume Chau <guillaume.b.chau
globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com
hls.js Apache-2.0 n/a
i MIT Pavan Kumar Sunkara <pavan.sss1991@gmail.com> (pksunkara.github.com)
jsdom MIT n/a
karma MIT Vojta Jína <vojta.jina@gmail.com>
karma-chrome-launcher MIT Vojta Jina <vojta.jina@gmail.com>
karma-coverage-istanbul-reporter MIT Matt Lewis
@ -80,6 +87,8 @@ svg-url-loader MIT Hovhannes Babayan
tar ISC Isaac Z. Schlueter
url-loader MIT Tobias Koppers @sokra
util MIT Joyent http://www.joyent.com
vite-tsconfig-paths MIT aleclarson
vitest MIT Anthony Fu <anthonyfu117@hotmail.com>
vue MIT Evan You
vue-3-sanitize MIT Vannsl, Vanessa Otto <mail@vannsl.io>
vue-loader MIT Evan You

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,10 @@
"gettext-extract": "gettext-extract --output src/locales/translations.pot $(find ${SRC:-src} -type f \\( -iname \\*.vue -o -iname \\*.js \\) -not -path src/common/gettext.js)",
"lint": "eslint --cache src/ *.js",
"test": "karma start",
"test:vitest": "vitest run",
"test:vitest:watch": "vitest",
"test:vitest:coverage": "vitest run --coverage",
"test:vitest:ui": "vitest --ui",
"testcafe": "testcafe",
"trace": "webpack --stats-children",
"upgrade": "npm update && npm audit fix",
@ -27,50 +31,57 @@
">0.25% and last 2 years"
],
"dependencies": {
"@babel/cli": "^7.27.0",
"@babel/core": "^7.26.10",
"@babel/plugin-transform-runtime": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@babel/register": "^7.25.9",
"@babel/runtime": "^7.27.0",
"@babel/cli": "^7.27.1",
"@babel/core": "^7.27.1",
"@babel/plugin-transform-runtime": "^7.27.1",
"@babel/preset-env": "^7.27.1",
"@babel/register": "^7.27.1",
"@babel/runtime": "^7.27.1",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.24.0",
"@eslint/js": "^9.26.0",
"@lcdp/offline-plugin": "^5.1.1",
"@mdi/font": "^7.4.47",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@vitejs/plugin-react": "^4.4.1",
"@vitest/coverage-v8": "^3.1.3",
"@vitest/ui": "^3.1.3",
"@vue/compiler-sfc": "^3.5.13",
"@vue/language-server": "^2.2.10",
"@vvo/tzdb": "^6.161.0",
"axios": "^1.8.4",
"axios": "^1.9.0",
"axios-mock-adapter": "^2.1.0",
"babel-loader": "^10.0.0",
"babel-plugin-istanbul": "^7.0.0",
"babel-plugin-polyfill-corejs3": "^0.12.0",
"browserslist": "^4.24.4",
"browserslist": "^4.24.5",
"chai": "^5.2.0",
"cheerio": "1.0.0-rc.12",
"chrome-finder": "^1.0.7",
"core-js": "^3.41.0",
"core-js": "^3.42.0",
"cross-env": "^7.0.3",
"css-loader": "^7.1.2",
"cssnano": "^7.0.6",
"cssnano": "^7.0.7",
"easygettext": "^2.17.0",
"eslint": "^9.24.0",
"eslint-config-prettier": "^10.1.2",
"eslint": "^9.26.0",
"eslint-config-prettier": "^10.1.3",
"eslint-formatter-pretty": "^6.0.1",
"eslint-plugin-html": "^8.1.2",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.2.6",
"eslint-plugin-prettier": "^5.4.0",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-vue": "^10.0.0",
"eslint-plugin-vue": "^10.1.0",
"eslint-plugin-vuetify": "^2.5.2",
"eslint-webpack-plugin": "^5.0.0",
"eslint-webpack-plugin": "^5.0.1",
"eventsource-polyfill": "^0.9.6",
"file-loader": "^6.2.0",
"file-saver": "^2.0.5",
"floating-vue": "^5.2.2",
"globals": "^16.0.0",
"globals": "^16.0.1",
"hls.js": "^1.6.2",
"i": "^0.3.7",
"jsdom": "^26.1.0",
"karma": "^6.4.4",
"karma-chrome-launcher": "^3.2.0",
"karma-coverage-istanbul-reporter": "^3.0.3",
@ -79,26 +90,26 @@
"karma-verbose-reporter": "^0.0.8",
"karma-webpack": "^5.0.1",
"luxon": "^3.6.1",
"maplibre-gl": "^5.3.0",
"maplibre-gl": "^5.5.0",
"memoize-one": "^6.0.0",
"mini-css-extract-plugin": "^2.9.2",
"minimist": ">=1.2.8",
"mocha": "^11.1.0",
"mocha": "^11.2.2",
"node-storage-shim": "^2.0.1",
"passive-events-support": "^1.1.0",
"photoswipe": "^5.4.4",
"postcss": "^8.5.3",
"postcss-import": "^16.1.0",
"postcss-loader": "^8.1.1",
"postcss-preset-env": "^10.1.5",
"postcss-preset-env": "^10.1.6",
"postcss-reporter": "^7.1.0",
"postcss-url": "^10.1.3",
"prettier": "^3.5.3",
"pubsub-js": "^1.9.5",
"regenerator-runtime": "^0.14.1",
"resolve-url-loader": "^5.0.0",
"sanitize-html": "^2.15.0",
"sass": "^1.86.3",
"sanitize-html": "^2.16.0",
"sass": "^1.87.0",
"sass-loader": "^16.0.5",
"server": "^1.0.41",
"sockette": "^2.0.6",
@ -107,17 +118,19 @@
"tar": "^7.4.3",
"url-loader": "^4.1.1",
"util": "^0.12.5",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.1.3",
"vue": "^3.5.13",
"vue-3-sanitize": "^0.1.4",
"vue-loader": "^17.4.2",
"vue-loader-plugin": "^1.3.0",
"vue-luxon": "^0.10.0",
"vue-router": "^4.5.0",
"vue-router": "^4.5.1",
"vue-sanitize-directive": "^0.2.1",
"vue-style-loader": "^4.1.3",
"vue3-gettext": "^2.4.0",
"vuetify": "^3.8.1",
"webpack": "^5.99.5",
"vuetify": "^3.8.4",
"webpack": "^5.99.8",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^6.0.1",
"webpack-hot-middleware": "^2.26.1",
@ -126,9 +139,6 @@
"webpack-merge": "^6.0.1",
"webpack-plugin-vuetify": "^3.1.1"
},
"devDependencies": {
"@vue/language-server": "^2.2.8"
},
"engines": {
"node": ">= 18.0.0",
"npm": ">= 9.0.0",

View file

@ -1,3 +1,3 @@
module.exports = {
plugins: ["postcss-import", "postcss-preset-env", "cssnano"],
plugins: [require("postcss-import"), require("postcss-preset-env"), require("cssnano")],
};

View file

@ -26,7 +26,7 @@ Additional information can be found in our Developer Guide:
import $api from "common/api";
import $event from "common/event";
import * as themes from "options/themes";
import { Languages } from "options/options";
import * as options from "options/options";
import { Photo } from "model/photo";
import { onInit, onSetTheme } from "common/hooks";
import { ref, reactive } from "vue";
@ -174,6 +174,10 @@ export default class Config {
$event.publish("dialog.update", { values });
}
if (values.DefaultLocale && options.DefaultLocale !== values.DefaultLocale) {
options.SetDefaultLocale(values.DefaultLocale);
}
for (let key in values) {
if (values.hasOwnProperty(key) && values[key] != null) {
this.set(key, values[key]);
@ -184,7 +188,7 @@ export default class Config {
if (values.settings) {
this.setBatchSize(values.settings);
await this.setLanguage(values.settings.ui.language, true);
await this.setLanguage(this.getLanguageLocale(), true);
this.setTheme(values.settings.ui.theme);
}
@ -505,18 +509,39 @@ export default class Config {
// getLanguageLocale returns the ISO/IEC 15897 locale,
// e.g. "en" or "zh_TW" (minimum 2 letters).
getLanguageLocale() {
let locale = "en";
// Get default locale from web browser.
let locale = navigator?.language;
// Override language locale with query parameter?
if (window.location?.search) {
const query = new URLSearchParams(window.location.search);
const queryLocale = query.get("locale");
if (queryLocale && queryLocale.length > 1 && queryLocale.length < 6) {
// Change the locale settings.
locale = options.FindLocale(queryLocale);
this.storage.setItem(this.storageKey + ".locale", locale);
if (this.values?.settings?.ui) {
this.values.settings.ui.language = locale;
}
}
}
// Get user locale from localStorage if settings have not yet been loaded from backend.
if (this.loading()) {
const stored = this.storage.getItem(this.storageKey + ".locale");
if (stored) {
locale = stored;
if (this.values?.settings?.ui) {
this.values.settings.ui.language = locale;
}
}
} else if (this.values.settings && this.values.settings.ui && this.values.settings.ui.language) {
} else if (this.values?.settings?.ui?.language) {
locale = this.values.settings.ui.language;
}
return locale;
// Find and return the best matching language locale that exists.
return options.FindLocale(locale);
}
// getLanguageCode returns the ISO 639-1 language code (2 letters),
@ -525,13 +550,22 @@ export default class Config {
return this.getLanguageLocale().substring(0, 2);
}
// getTimeZone returns user time zone.
getTimeZone() {
if (this.values?.settings?.ui?.timeZone) {
return this.values?.settings?.ui?.timeZone;
}
return "Local";
}
// isRtl returns true if a right-to-left language is currently used.
isRtl(locale) {
if (!locale) {
locale = this.getLanguageLocale();
}
return Languages().some((l) => l.value === locale && l.rtl);
return options.Languages().some((l) => l.value === locale && l.rtl);
}
// dir returns the user interface direction (for the current locale if no argument is given).
@ -742,33 +776,24 @@ export default class Config {
return;
}
if (tokens.previewToken) {
if (this.previewToken !== tokens.previewToken) {
this.previewToken = tokens.previewToken;
}
if (this.values.previewToken !== tokens.previewToken) {
this.values.previewToken = tokens.previewToken;
}
if (tokens.previewToken && this.values?.previewToken !== tokens.previewToken) {
this.values.previewToken = tokens.previewToken;
}
if (tokens.downloadToken) {
if (this.downloadToken !== tokens.downloadToken) {
this.downloadToken = tokens.downloadToken;
}
if ((this.values.downloadToken = tokens.downloadToken)) {
this.values.downloadToken = tokens.downloadToken;
}
if (tokens.downloadToken && this.values?.downloadToken !== tokens.downloadToken) {
this.values.downloadToken = tokens.downloadToken;
}
this.updateTokens();
}
// updateTokens updates the security tokens required to load thumbnails and download files from the server.
updateTokens() {
if (this.values["previewToken"]) {
if (this.values?.previewToken && this.previewToken !== this.values.previewToken) {
this.previewToken = this.values.previewToken;
}
if (this.values["downloadToken"]) {
if (this.values?.downloadToken && this.downloadToken !== this.values.downloadToken) {
this.downloadToken = this.values.downloadToken;
}
}
@ -868,6 +893,10 @@ export default class Config {
}
getIcon() {
if (this.theme?.variables?.icon) {
return this.theme.variables.icon;
}
switch (this.get("appIcon")) {
case "crisp":
case "mint":
@ -878,6 +907,15 @@ export default class Config {
}
}
getLoginIcon() {
const loginTheme = themes.Get("login");
if (loginTheme?.variables?.icon) {
return loginTheme?.variables?.icon;
}
return this.getIcon();
}
getVersion() {
return this.version;
}

View file

@ -0,0 +1,23 @@
let loading = false;
let maplibregl = null;
// Loads the maplibregl library.
export async function load() {
if (maplibregl !== null || loading) {
return Promise.resolve(maplibregl);
}
loading = true;
try {
const module = await import("./maplibregl.js");
maplibregl = module.default;
loading = false;
} catch (e) {
loading = false;
console.error("maps: failed to load maplibregl", e);
return Promise.reject(e);
}
return Promise.resolve(maplibregl);
}

View file

@ -40,6 +40,11 @@ const Minute = 60 * Second;
const Hour = 60 * Minute;
let start = new Date();
// List of characters used in the values returned by generateToken.
const tokenAlphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
export const tokenRegexp = /^[a-z0-9]{7}$/;
export const tokenLength = 7;
// True if debug logs should be created.
const debug = window.__CONFIG__?.debug || window.__CONFIG__?.trace;
@ -90,18 +95,6 @@ export default class $util {
let options;
switch (format) {
case "date_full":
case "DATE_FULL":
options = formats.DATE_FULL;
break;
case "date_full_tz":
case "DATE_FULL_TZ":
options = formats.DATE_FULL_TZ;
break;
case "date_med_tz":
case "DATE_MED_TZ":
options = formats.DATE_MED_TZ;
break;
case "date_med":
case "DATE_MED":
options = formats.DATE_MED;
@ -110,8 +103,26 @@ export default class $util {
case "DATETIME_MED":
options = formats.DATETIME_MED;
break;
case "date_med_tz":
case "DATE_MED_TZ":
case "datetime_med_tz":
case "DATETIME_MED_TZ":
options = formats.DATETIME_MED_TZ;
break;
case "date_full":
case "DATE_FULL":
case "datetime_full":
case "DATETIME_FULL":
options = formats.DATETIME_LONG;
break;
case "date_full_tz":
case "datetime_full_tz":
case "DATE_FULL_TZ":
case "DATETIME_FULL_TZ":
options = formats.DATETIME_LONG_TZ;
break;
default:
options = formats.DATE_FULL;
options = formats.DATETIME_LONG;
break;
}
@ -323,8 +334,16 @@ export default class $util {
return s.charAt(0).toUpperCase() + s.slice(1);
}
// Generates a random token that makes some effort to be relatively
// unique each time. This isn't suitable for use in
// security-critical locations where predictability or collisions
// would cause a serious problem.
static generateToken() {
return (Math.random() + 1).toString(36).substring(6);
let result = "";
for (let i = 0; i < tokenLength; i++) {
result += tokenAlphabet.charAt(Math.floor(Math.random() * tokenAlphabet.length));
}
return result;
}
static hasTouch() {
@ -434,7 +453,7 @@ export default class $util {
case "ps":
return "Adobe PostScript";
case "eps":
return "Encapsulated PostScript";
return "EPS";
default:
return value.toUpperCase();
}

View file

@ -5,7 +5,11 @@
<v-col xs="12" class="pa-0 text-subtitle-2 text-selectable text-start hidden-xs">
{{ about }}
</v-col>
<v-col v-if="legalInfo" xs="12" class="pa-0 text-subtitle-2 text-center text-sm-end">
<v-col v-if="loginInfo" xs="12" class="pa-0 text-subtitle-2 text-center text-sm-end">
<a v-if="legalUrl" :href="legalUrl" target="_blank" class="text-link">{{ loginInfo }}</a>
<span v-else>{{ loginInfo }}</span>
</v-col>
<v-col v-else-if="legalInfo" xs="12" class="pa-0 text-subtitle-2 text-center text-sm-end">
<a v-if="legalUrl" :href="legalUrl" target="_blank" class="text-link">{{ legalInfo }}</a>
<span v-else>{{ legalInfo }}</span>
</v-col>
@ -32,6 +36,7 @@ export default {
caption: config.values.siteCaption ? config.values.siteCaption : config.values.siteTitle,
legalUrl: config.values.legalUrl,
legalInfo: config.values.legalInfo,
loginInfo: config.values.loginInfo,
config: config.values,
rtl: this.$isRtl,
};

View file

@ -7,6 +7,7 @@ import PLoading from "component/loading.vue";
import PLoadingBar from "component/loading-bar.vue";
import PLightboxMenu from "component/lightbox/menu.vue";
import PSidebarInfo from "component/sidebar/info.vue";
import PMap from "component/map.vue";
import PLightbox from "component/lightbox.vue";
// Icons.
@ -82,6 +83,7 @@ export function install(app) {
app.component("PLoadingBar", PLoadingBar);
app.component("PLightboxMenu", PLightboxMenu);
app.component("PSidebarInfo", PSidebarInfo);
app.component("PMap", PMap);
app.component("PLightbox", PLightbox);
app.component("PUpdate", PUpdate);

View file

@ -677,13 +677,13 @@ export default {
nativeSource.type = model.Mime;
nativeSource.src = this.$util.videoFormatUrl(model.Hash, format);
video.appendChild(nativeSource);
} else {
const avcSource = document.createElement("source");
avcSource.type = media.ContentTypeMp4AvcMain;
avcSource.src = this.$util.videoFormatUrl(model.Hash, media.FormatAvc);
video.appendChild(avcSource);
}
const avcSource = document.createElement("source");
avcSource.type = media.ContentTypeMp4AvcMain;
avcSource.src = this.$util.videoFormatUrl(model.Hash, media.FormatAvc);
video.appendChild(avcSource);
if (video.remote && video.remote instanceof RemotePlayback) {
if (!this.video.castable) {
video.remote.watchAvailability((castable) => {
@ -1138,7 +1138,7 @@ export default {
});
// Add information toggle button.
if (this.featExperimental && window.innerWidth > this.mobileBreakpoint) {
if (window.innerWidth > this.mobileBreakpoint) {
lightbox.pswp.ui.registerElement({
name: "sidebar-button",
className: "pswp__button--info-button pswp__button--mdi", // Sets the icon style/size in lightbox.css.
@ -2183,7 +2183,7 @@ export default {
},
// Shows the lightbox sidebar, if hidden.
showInfo() {
if (!this.visible || this.info || !this.featExperimental) {
if (!this.visible || this.info) {
return;
}
@ -2199,7 +2199,7 @@ export default {
},
// Hides the lightbox sidebar, if visible.
hideInfo() {
if (!this.visible || !this.info || !this.featExperimental) {
if (!this.visible || !this.info) {
return;
}

View file

@ -0,0 +1,128 @@
<template>
<div ref="map" class="p-map"></div>
</template>
<script>
import * as map from "common/map";
let maplibregl = null;
export default {
name: "PMap",
props: {
lat: {
type: Number,
default: 0.0,
},
lng: {
type: Number,
default: 0.0,
},
zoom: {
type: Number,
default: 9,
},
style: {
type: String,
default: "embedded",
},
},
data() {
return {
map: null,
marker: null,
position: [0.0, 0.0],
options: {
container: null,
// Styles can be edited/created with https://maplibre.org/maputnik/.
// To test new styles, put the style file in /assets/static/maps
// and include it from there e.g. "/static/maps/embedded.json":
// style: "/static/maps/embedded.json",
style: `https://cdn.photoprism.app/maps/${this.style}.json`,
glyphs: `https://cdn.photoprism.app/maps/font/{fontstack}/{range}.pbf`,
zoom: this.zoom,
interactive: true,
attributionControl: false,
},
loaded: false,
};
},
watch: {
lat() {
this.updatePosition();
},
lng() {
this.updatePosition();
},
},
mounted() {
map.load().then((m) => {
maplibregl = m;
this.initMap();
});
},
beforeUnmount() {
if (this.map) {
this.map.remove();
}
},
methods: {
initMap() {
if (this.map || !this.$refs.map || !maplibregl) {
return;
}
try {
this.options.container = this.$refs.map;
this.map = new maplibregl.Map(this.options);
// Add controls.
/* this.map.addControl(
new maplibregl.NavigationControl({
showCompass: false,
showZoom: true,
visualizePitch: false,
}),
"top-right"
);
this.map.addControl(new maplibregl.ScaleControl({ maxWidth: 80, unit: "metric" }), "bottom-left");
*/
this.map.on("error", (e) => {
console.error("map:", e);
});
this.map.on("load", () => {
this.loaded = true;
this.updatePosition();
});
} catch (error) {
console.error("map: initialization failed", error);
this.loaded = false;
}
},
updatePosition() {
if (this.map && this.loaded) {
if (this.position[0] === this.lng && this.position[1] === this.lat) {
return;
}
this.position = [this.lng, this.lat];
this.map.setCenter(this.position);
if (this.marker) {
this.marker.setLngLat(this.position);
} else {
this.marker = new maplibregl.Marker({
color: "#3fb4df",
draggable: false,
})
.setLngLat(this.position)
.addTo(this.map);
}
}
},
},
};
</script>

View file

@ -1,32 +1,35 @@
<template>
<teleport to="body">
<div v-if="visible" id="p-notify" tabindex="-1">
<div
:class="'p-notify--' + message.color"
class="v-snackbar v-snackbar--bottom v-snackbar--center p-notify"
role="alert"
@click.stop.prevent="showNext"
>
<div class="v-snackbar__wrapper rounded-pill v-snackbar--variant-flat">
<span class="v-snackbar__underlay"></span>
<div class="v-snackbar__content">
<i
v-if="message.icon"
:class="['text-' + message.color, 'mdi-' + message.icon]"
class="mdi v-icon notranslate p-notify__icon"
aria-hidden="true"
></i>
<div class="p-notify__text">
{{ message.text }}
<div id="notify">
<transition name="fade-transition">
<div
v-if="visible"
:class="'p-notify--' + message.color"
class="p-notify v-snackbar"
role="alert"
@click.stop.prevent="showNext"
>
<div class="v-snackbar__wrapper">
<span class="v-snackbar__underlay"></span>
<div class="v-snackbar__content">
<i
v-if="message.icon"
:class="['text-' + message.color, 'mdi-' + message.icon]"
class="mdi v-icon notranslate p-notify__icon"
aria-hidden="true"
></i>
<div class="p-notify__text">
{{ message.text }}
</div>
<i
:class="'text-on-' + message.color"
class="mdi-close mdi v-icon notranslate p-notify__close"
aria-hidden="true"
></i>
</div>
<i
:class="'text-on-' + message.color"
class="mdi-close mdi v-icon notranslate p-notify__close"
aria-hidden="true"
></i>
</div>
</div>
</div>
</transition>
</div>
</teleport>
</template>
@ -50,7 +53,7 @@ export default {
defaultColor: "info",
defaultDelay: 2000,
warningDelay: 3000,
errorDelay: 8000,
errorDelay: 6000,
};
},
created() {
@ -139,14 +142,6 @@ export default {
this.showNext();
}
},
onSnackbar(show) {
if (show) {
this.snackbar = true;
} else {
this.snackbar = false;
this.showNext();
}
},
showNext() {
const message = this.messages.shift();

View file

@ -604,14 +604,8 @@ export default {
this.view.model.TakenAt = isoTime;
}
},
left() {
this.$emit("next");
},
right() {
this.$emit("prev");
},
openPhoto() {
this.$lightbox.openModels(Thumb.fromFiles([this.view.model]), 0);
this.$lightbox.openModels(Thumb.fromPhotos([this.view.model]), 0);
},
save(close) {
if (this.invalidDate) {

View file

@ -390,6 +390,7 @@ import Thumb from "model/thumb";
import { DateTime } from "luxon";
import $notify from "common/notify";
import * as options from "options/options";
import * as formats from "options/formats";
export default {
name: "PTabPhotoFiles",
@ -409,6 +410,7 @@ export default {
},
features: this.$config.getSettings().features,
config: this.$config.values,
timeZone: this.$config.getTimeZone(),
readonly: this.$config.get("readonly"),
experimental: this.$config.get("experimental"),
canAccessPrivate:
@ -553,7 +555,7 @@ export default {
});
},
formatTime(s) {
return DateTime.fromISO(s).toLocaleString(DateTime.DATETIME_MED);
return DateTime.fromISO(s, { zone: this.timeZone }).toLocaleString(formats.TIMESTAMP);
},
refresh() {},
},

View file

@ -326,6 +326,7 @@
import { DateTime } from "luxon";
import * as options from "options/options";
import { $gettext, T } from "common/gettext";
import * as formats from "options/formats";
export default {
name: "PTabPhotoAdvanced",
@ -340,6 +341,7 @@ export default {
view: this.$view.getData(),
options: options,
config: this.$config.values,
timeZone: this.$config.getTimeZone(),
readonly: this.$config.get("readonly"),
};
},
@ -391,14 +393,11 @@ export default {
}
},
formatTime(s) {
return DateTime.fromISO(s).toLocaleString(DateTime.DATETIME_MED);
return DateTime.fromISO(s, { zone: this.timeZone }).toLocaleString(formats.TIMESTAMP);
},
save() {
this.view.model.update();
},
close() {
this.$emit("close");
},
albumUrl(m) {
if (!m) {
return "#";

View file

@ -280,7 +280,7 @@ export default {
return;
}
this.$lightbox.openModels(Thumb.fromFiles([this.view.model]), 0);
this.$lightbox.openModels(Thumb.fromPhotos([this.view.model]), 0);
},
},
};

View file

@ -1,12 +1,10 @@
<template>
<transition name="fade-transition">
<button v-if="showButton" type="button" :style="`top: ${offsetTop}px`" class="p-scroll" @click.stop="scrollToTop">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"></path>
</svg>
{{ $gettext(`Back to top`) }}
</button>
</transition>
<button v-if="showButton" type="button" :style="`top: ${offsetTop}px`" class="p-scroll" @click.stop="scrollToTop">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"></path>
</svg>
{{ $gettext(`Back to top`) }}
</button>
</template>
<script>

View file

@ -284,6 +284,7 @@ export default {
showPassword: false,
minLength: this.$config.get("passwordLength"),
maxLength: 72,
timeZone: this.$config.getTimeZone(),
rtl: this.$isRtl,
action: "",
confirmAction: "",
@ -365,12 +366,12 @@ export default {
}
if (!Number.isInteger(d)) {
return DateTime.fromISO(d).toLocaleString(DateTime.DATE_SHORT);
return DateTime.fromISO(d, { zone: this.timeZone }).toLocaleString(DateTime.DATE_SHORT);
} else if (d <= 0) {
return "";
}
return DateTime.fromSeconds(d).toLocaleString(DateTime.DATE_SHORT);
return DateTime.fromSeconds(d, { zone: this.timeZone }).toLocaleString(DateTime.DATE_SHORT);
},
formatDateTime(d) {
if (!d) {
@ -378,12 +379,12 @@ export default {
}
if (!Number.isInteger(d)) {
return DateTime.fromISO(d).toLocaleString(DateTime.DATETIME_SHORT);
return DateTime.fromISO(d, { zone: this.timeZone }).toLocaleString(DateTime.DATETIME_SHORT);
} else if (d <= 0) {
return "";
}
return DateTime.fromSeconds(d).toLocaleString(DateTime.DATETIME_SHORT);
return DateTime.fromSeconds(d, { zone: this.timeZone }).toLocaleString(DateTime.DATETIME_SHORT);
},
scopeInfo(s) {
let info = memoizeOne(auth.Scopes)()[s];

View file

@ -38,7 +38,7 @@
<v-divider v-if="model.Title || model.Caption" class="my-4"></v-divider>
<v-list-item
v-tooltip="$gettext('Taken')"
:title="$util.formatDate(model.TakenAtLocal, 'date_med_tz', model.TimeZone)"
:title="formatTime(model)"
prepend-icon="mdi-calendar"
class="metadata__item"
>
@ -59,20 +59,32 @@
<v-divider class="my-4"></v-divider>
<v-list-item
v-tooltip="$gettext('Location')"
:title="model.getLatLng()"
prepend-icon="mdi-map-marker"
:title="model.getLatLng()"
class="clickable metadata__item"
@click.stop="model.copyLatLng()"
>
</v-list-item>
<v-list-item v-if="featPlaces" class="mx-0 px-0">
<p-map :lat="model.Lat" :lng="model.Lng"></p-map>
</v-list-item>
</template>
</v-list>
</div>
</div>
</template>
<script>
import { DateTime } from "luxon";
import * as formats from "options/formats";
import PMap from "component/map.vue";
export default {
name: "PSidebarInfo",
components: {
PMap,
},
props: {
modelValue: {
type: Object,
@ -91,6 +103,7 @@ export default {
data() {
return {
actions: [],
featPlaces: this.$config.feature("places"),
};
},
computed: {
@ -102,6 +115,17 @@ export default {
close() {
this.$emit("close");
},
formatTime(model) {
if (!model || !model.TakenAtLocal) {
return this.$gettext("Unknown");
}
if (model.TimeZone && model.TimeZone !== "Local") {
return DateTime.fromISO(model.TakenAtLocal, { zone: model.TimeZone }).toLocaleString(formats.DATETIME_MED_TZ);
} else {
return DateTime.fromISO(model.TakenAtLocal, { zone: "UTC" }).toLocaleString(formats.DATETIME_MED);
}
},
},
};
</script>

View file

@ -96,10 +96,10 @@ main {
margin: auto;
opacity: 1;
color: rgb(var(--v-theme-on-button, #000000));
background-color: rgba(var(--v-theme-button, #ffffff), 0.5);
backdrop-filter: blur(12px);
background-color: rgba(var(--v-theme-button, #ffffff), 0.8);
/* backdrop-filter: blur(12px);
box-shadow: 0 0.2rem 0.5rem #0000001a, 0 0 0.05rem #00000040;
transition: color 125ms, background-color 125ms, transform 125ms cubic-bezier(.4, 0, .2, 1), opacity 125ms;
transition: color 125ms, background-color 125ms, transform 125ms cubic-bezier(.4, 0, .2, 1), opacity 125ms; */
-webkit-tap-highlight-color: transparent;
border: 0;
border-radius: 1.6rem;

View file

@ -77,6 +77,16 @@ main .auth-login .clickable {
left: unset;
}
.auth-login .auth-language {
position: fixed;
top: 20px;
right: 20px;
width: auto;
height: auto;
margin: auto;
z-index: 2;
}
.auth-layout {
justify-content: center;
align-items: center;

View file

@ -62,6 +62,8 @@
z-index: 1;
}
/* Sidebar Info */
.p-lightbox__container > .p-lightbox__sidebar {
position: relative;
display: block;
@ -124,6 +126,16 @@
hyphens: auto;
}
.p-lightbox__container > .p-lightbox__sidebar .p-map {
display: block;
min-height: 259px;
aspect-ratio: 1;
width: auto;
margin: 0;
padding: 0;
overflow: hidden;
}
/* Media Content */
.pswp__content {
@ -471,9 +483,9 @@
border-radius: 0;
z-index: 10;
margin: 0;
padding: 16px 12px 12px 12px;
padding: 20px 12px 12px 12px;
gap: 6px;
background: linear-gradient(0deg, #000000AA, #00000000);
background: linear-gradient(0deg, #000000BF, #00000000);
}
.p-lightbox__controls .video-label,

View file

@ -25,11 +25,17 @@
font-weight: bold;
}
.p-log-message span {
.p-log-message span,
.p-log-message .p-log-message__text {
color: rgba(var(--v-theme-on-surface), .95);
font-weight: normal;
}
.p-log-message .p-log-message__time {
font-weight: 600;
color: rgba(var(--v-theme-on-surface), .95);
}
.p-log-fatal,
.p-log-critical,
.p-log-error {

View file

@ -1,40 +1,50 @@
/* Notifications */
#p-notify {
#notify {
position: fixed;
bottom: 16px;
left: 16px;
right: 16px;
font-size: 0.875rem;
font-weight: 400;
z-index: 2500;
top: auto;
left: 0;
right: 0;
bottom: 0;
margin-top: auto;
user-select: none;
margin-left: auto;
margin-right: auto;
display: flex;
gap: 4px;
align-items: center;
flex-direction: column;
justify-items: center;
z-index: 2500;
font-size: 0.875rem;
font-weight: 400;
user-select: none;
width: auto;
height: auto;
max-width: 440px;
pointer-events: none;
}
#p-notify .v-snackbar {
.v-snackbar.p-notify {
margin-left: auto;
margin-right: auto;
width: auto;
min-width: 200px;
max-width: 440px;
margin-bottom: 24px;
}
#p-notify .v-snackbar .v-snackbar__wrapper {
position: relative;
.v-snackbar.p-notify .v-snackbar__wrapper {
cursor: pointer;
min-width: 280px;
max-width: 440px;
color: rgba(var(--v-theme-on-surface), 1);
background-color: rgba(var(--v-theme-surface), 0.32);
backdrop-filter: blur(6px);
box-shadow: 0 2px 1px -1px var(--v-shadow-key-umbra-opacity, #0003), 0 1px 1px 0 var(--v-shadow-key-penumbra-opacity, #00000024), 0 1px 3px 0 var(--v-shadow-key-ambient-opacity, #0000001f) !important;
padding: 8px 14px;
padding: 10px 16px;
pointer-events: auto;
border-radius: 9999px;
}
#p-notify .v-snackbar__wrapper .v-snackbar__content {
.v-snackbar.p-notify .v-snackbar__wrapper .v-snackbar__content {
z-index: 2;
display: flex;
gap: 4px;
@ -48,7 +58,7 @@
margin: 0;
}
#p-notify .v-snackbar__wrapper .v-snackbar__content .p-notify__icon {
.v-snackbar.p-notify .v-snackbar__wrapper .v-snackbar__content .p-notify__icon {
margin: 0;
align-self: center;
font-size: 22px;
@ -56,7 +66,7 @@
width: 22px;
}
#p-notify .v-snackbar__wrapper .v-snackbar__content .p-notify__text {
.v-snackbar.p-notify .v-snackbar__wrapper .v-snackbar__content .p-notify__text {
flex-grow: 1;
margin: 2px 8px;
padding: 0;
@ -64,15 +74,15 @@
align-self: center;
}
#p-notify .v-snackbar__wrapper .v-snackbar__content .p-notify__close {
opacity: 0.8;
.v-snackbar.p-notify .v-snackbar__wrapper .v-snackbar__content .p-notify__close {
opacity: 0.78;
font-size: 24px;
height: 24px;
width: 24px;
cursor: pointer;
}
.v-snackbar__wrapper .v-snackbar__underlay {
.v-snackbar.p-notify .v-snackbar__wrapper .v-snackbar__underlay {
background-color: rgba(var(--v-theme-surface), 0.32);
position: absolute;
z-index: -1;
@ -103,3 +113,10 @@
background-color: rgba(var(--v-theme-error), 0.42) !important;
color: rgba(var(--v-theme-on-error), 1) !important;
}
@media only screen and (min-width: 600px) {
.v-snackbar.p-notify {
min-width: 280px;
margin-bottom: 16px;
}
}

View file

@ -120,7 +120,7 @@ body.dark-theme {
.v-overlay.v-dialog.v-dialog--sidepanel:not(.v-dialog--fullscreen) .v-overlay__content {
height: 100vh;
min-width: 940px;
width: 48vw;
width: 75vw;
max-width: 1080px;
margin: 0;
padding: 0;
@ -129,6 +129,11 @@ body.dark-theme {
border-radius: 0;
}
.v-overlay.v-dialog.v-dialog--sidepanel.v-dialog--sidepanel-wide:not(.v-dialog--fullscreen) .v-overlay__content {
min-width: 950px;
width: 56vw;
}
.v-overlay.v-dialog > .v-overlay__content > .v-card,
.v-overlay.v-dialog > .v-overlay__content > form > .v-card {
border-radius: 8px;

View file

@ -18,7 +18,6 @@ export const Locale = () => {
export let Options = [
{
text: "English", // English
translated: "English",
value: "en",
},
{
@ -174,7 +173,7 @@ export let Options = [
},
{
text: "日本語", // Japanese
value: "ja_JP",
value: "ja",
},
{
text: "한국어", // Korean

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more