Commit graph

13574 commits

Author SHA1 Message Date
Michael Mayer
0cecb5287f Search: Match folder album_path case-insensitively #5724
Folder search lowercases the query term, but album_path is VARBINARY and
compared byte-exact (case-sensitive) on MySQL/MariaDB, so a lowercased
term no longer matched uppercase folder paths. A parent folder still
appeared via its case-insensitive title, while child folders - matchable
only by path - dropped out of the results.

Add a dialect-aware PathLike helper: MySQL converts album_path to a
case-insensitive collation for the LIKE, SQLite and other dialects fall
back to a plain LIKE (SQLite is already ASCII case-insensitive). Only the
folder search filter is affected; byte-exact album_path identity lookups
are unchanged, so emoji and case-distinct folders stay distinct.
2026-07-16 16:53:28 +00:00
Michael Mayer
3f039866ff Sharing: Fix single-item access for shared smart albums #5727
Pictures shared only through a folder, moment, calendar, or region link
have no photos_albums row, so the by-UID and by-hash visibility checks
reported them out of scope and returned "Entity not found" - for example
when downloading a single image from a shared folder. The photo and file
visibility helpers now fall back to the shared album's filter, matching
what browsing and full-album downloads already allow. The fallback runs
only after the cheaper personal-scope check misses and skips regular
albums, so full-access and regular-share sessions add no queries.
2026-07-16 12:10:44 +00:00
Michael Mayer
4946bd2050 Vision: Add OpenAI service_tier via Service.Tier config #5725
Add a string-valued Service.Tier field (OpenAI-scoped) that is sent
verbatim as a top-level service_tier field in the Responses API request
body, reusing the existing Org/Project plumbing. Defaults empty
(backward compatible, OpenAI "auto") and supports ${ENV} expansion.

Bounded exponential-backoff retry on HTTP 429 is a separate follow-up
on the shared client (#5729).
2026-07-16 10:37:15 +00:00
Michael Mayer
5682b3df2e Docker: Allow Ollama and Vision env overrides via .env #5726
Make PHOTOPRISM_VISION_URI/KEY and OLLAMA_BASE_URL/OLLAMA_API_KEY
configurable through .env so Ollama Cloud can be tested without
editing compose.yaml directly.
2026-07-16 10:21:54 +00:00
Michael Mayer
311929ab27 Vision: Disable Ollama reasoning by default, refresh defaults #5728 #5726
- Default Service.Think to "false" for the Ollama engine via a new
  EngineInfo.DefaultThink applied in ApplyEngineDefaults; re-enable
  reasoning explicitly with Service.Think: "true".
- Replace the retired cloud default qwen3-vl:235b-instruct-cloud with
  minimax-m3:cloud, and refresh the self-hosted default from
  gemma3:latest to gemma4:latest.
- Warn on HTTP 404/410 (retired/renamed model) and other 4xx statuses
  in ollamaParser.Parse so failures are diagnosable instead of silent.
- Defensively strip a leading, tag-delimited <think>...</think> block
  from the response body.
- Update tests, regenerate testdata/vision.yml, and refresh package docs.
2026-07-16 10:21:49 +00:00
Michael Mayer
017e24927e Tests: Refine isolated test-folder cleanup and logging #5263 2026-07-12 06:31:52 +00:00
Keith Martin
b6687b6c29
Tests: Improve isolation and add fixes #5263
* Tests: fix random selection of deleted record causing test failure
* Tests: fix test folders being left after test
* Tests: ensure that required records are available
* Tests: make each package execute against it's own testdata folder to ensure no interpackage test failures
* Tests: add unit tests of CleanupTestFolder
* Tests:  Allow defer in TestMain
* Tests: rename testMain to runTestMain
2026-07-12 05:47:21 +02:00
Michael Mayer
79a3d36334 AI: Drop ROCm support from the llama.cpp install script
Only Vulkan and CPU (plus Intel SYCL) builds are installed now. Benchmarks
show Vulkan generally matches or beats the ROCm build for llama.cpp (except
some prompt-processing cases), while ROCm is far more complex to provision:
the prebuilt HIP backend needs a matching ROCm runtime, and consumer/iGPU
architectures such as gfx1150 additionally require HSA_OVERRIDE_GFX_VERSION
because rocBLAS ships no kernels for them. Vulkan drives NVIDIA, AMD, and
Intel GPUs on Linux with none of that setup, so auto-detection now selects
the Vulkan build for any supported GPU and the CPU build otherwise.
2026-07-10 10:40:58 +02:00
Cathie Integra
fb6e17ee69 Index: Resolve S2 cell in XMP branch, downgrade geocoding warn
When an XMP sidecar provides GPS coordinates, call UpdateLocation()
immediately so the S2 cell is resolved and cached in the local DB.
Without this, subsequent re-indexes always triggered a live geocoding
request (even though the coordinates were already known), producing a
spurious error on every re-index pass.

Downgrade the geocoding failure log in photo_location.go and
places/cell.go from Errorf to Warnf: a transient network failure to
the places service is non-fatal (the photo is indexed successfully,
just without a resolved place name) and must not surface as an
indexing error in the test suite.
2026-07-10 10:14:02 +02:00
Michael Mayer
98aa4d24ea AI: Add install-llamacpp.sh for llama.cpp Linux binaries
Installs prebuilt llama.cpp binaries from GitHub releases on AMD64/ARM64,
defaulting to the latest release or an explicit tag. Auto-detects the GPU
(sysfs PCI vendor IDs, lspci/nvidia-smi fallback) and picks ROCm, Vulkan,
or a plain CPU build, with a graceful fallback chain; NVIDIA GPUs get the
Vulkan build since upstream ships no CUDA build for Linux. Extracts into
<destdir>/lib/llama.cpp and symlinks the executables into <destdir>/bin
(the binaries carry RUNPATH "$ORIGIN"). Accelerator overridable via flags
or PHOTOPRISM_LLAMA_ACCEL; optional LLAMA_SHA256 verification.
2026-07-10 10:02:56 +02:00
Michael Mayer
c9362a6720 Docker: Refine smaller-skeleton bashrc setup for all images #5154 #5155
Follow-up to the contributor change that moves shell customization out of
per-user home directories:

- Migrate the resolute, trixie, and questing (+ slim) dev images to the
  shared install-bashrc.sh; the shared create-users.sh now hands users a
  minimal skeleton, so images still writing to /etc/skel/.bashrc would
  otherwise lose their aliases and prompt.
- Restore export PATH="$PATH:$HOME/.local/bin" (needed for claude/gh) in
  the full dev images by writing it to /etc/bash.bashrc; kept out of the
  slim and production images, which never had it.
- Guard the /etc/skel/.config copy in create-users.sh so production images
  without it don't emit a spurious error, and use rm -f /root/.bashrc.
- Fix the install-bashrc.sh header reference and silence an intentional
  SC2016 on the runtime-expanded PS1.
2026-07-10 00:56:15 +02:00
Alexis Lefebvre
44e7ed3f7e feat: use a smaller skeleton when calling useradd
# Conflicts:
#	docker/develop/armv7/Dockerfile
#	docker/develop/bookworm/Dockerfile
#	docker/develop/bullseye/Dockerfile
#	docker/develop/buster/Dockerfile
#	docker/develop/jammy/Dockerfile
#	docker/develop/lunar/Dockerfile
#	docker/develop/mantic/Dockerfile
#	docker/develop/noble/Dockerfile
#	docker/develop/oracular/Dockerfile
#	docker/develop/plucky/Dockerfile
2026-07-10 00:48:46 +02:00
Michael Mayer
1f9909d148 Develop: Make "docker-build" only pull the most important images
Signed-off-by: Michael Mayer <michael@photoprism.app>
2026-07-10 00:36:06 +02:00
Cathie Integra
cff0dcf92f Docker: Bump dev base image to develop:260709-resolute 2026-07-10 00:24:01 +02:00
Michael Mayer
c7a292e5a0 Backend: Update Go deps in go.mod and go.sum
Signed-off-by: Michael Mayer <michael@photoprism.app>
2026-07-09 17:13:11 +02:00
Michael Mayer
12d043f809 Places: Reuse pooled transport and log geocoding host only 2026-07-09 15:08:40 +00:00
Michael Mayer
d06ea1e19f Rules: Note gettext-lint gate and msgid-trim workflow 2026-07-09 13:57:51 +00:00
Michael Mayer
d33d3f11ab Translations: Trim trailing space in a German catalog string 2026-07-09 12:58:07 +00:00
Michael Mayer
9f6b95d049 Translations: Trim redundant trailing spaces on services help text 2026-07-09 12:03:17 +00:00
Michael Mayer
f864348474 Translations: Restore dropped placeholders in ga, ja, ku, nl, fa 2026-07-09 11:43:01 +00:00
Michael Mayer
6b4dcb09bd Translations: Fix French grammar and recompile stale fr.json
A recent Weblate update changed six French strings in fr.po without
recompiling fr.json, leaving the JSON out of sync. Recompile fr.json to
match, and fix "plutôt qu'au cliquant" -> "plutôt qu'au clic" (invalid
French) in the Open on Hover hint.
2026-07-09 11:26:14 +00:00
Cathie Integra
0eecc6e99b Frontend: Recompile translation JSON 2026-07-09 13:17:46 +02:00
Cathie Integra
6a1dc7d194 Translations: Restore broken placeholder tokens in catalogs 2026-07-09 13:17:46 +02:00
Cathie Integra
d5fb43f3d8 Translations: Add gettext placeholder and whitespace lint script 2026-07-09 13:17:46 +02:00
Weblate
54e258d4eb Weblate: Update frontend translations 2026-07-09 13:05:41 +02:00
Theresa Gresch
543a7c4258 Tests: Adapt tests to changes 2026-07-08 16:13:02 +02:00
Michael Mayer
4acbfd3d1b Frontend: Recompile translation JSON
Recompile the frontend translation JSON files from the current .po
catalogs (the pulled Weblate updates plus the German/French/Hebrew
refinements) via `make gettext-compile`.
2026-07-08 12:34:13 +00:00
Michael Mayer
d08d136ce8 Frontend: Refine German, French, and Hebrew settings translations #5429
- German: use „Bereich" for the Folders hint to match the sibling
  sections, and phrase the Open on Hover hint as an imperative.
- French: switch the new Accessibility and feature hints from informal
  tutoiement to the infinitive/vouvoiement used elsewhere in the UI.
- Hebrew: use the singular imperative for Reduce Motion, „קטע" (section)
  for the Albums hint, and align the Open on Hover hint with the label's
  hover wording.
2026-07-08 12:34:13 +00:00
Weblate
af7e06e5d1 Weblate: Update frontend translations 2026-07-08 14:17:58 +02:00
Ömer Duran
6dc0acac13
Settings: Reorganize UI and add an Accessibility section #848 #799 #5429
* Frontend: Add settings for albums, favorites, folders, and media features

* Frontend: Enhance download settings for files and albums #848

* Frontend: Enhance download settings for files and albums #848

* Frontend: Update album download settings to restrict access to super admins

* Frontend: Add album sorting options to settings for super admins

* Frontend: Update download settings visibility

* Frontend: Refine download settings access control for user roles

* Tests: Add album, folder, moment, state, and month order selection options to page-model

* Frontend: Update access control for super admins in settings to include scope check

* Tests: Add new tests for download name and album order settings persistence

* Tests: Implement new tests for default album sort order persistence in settings

* Frontend: Move default album order settings

* Frontend: Add zoom accessibility option in settings #799

* Frontend: Update download name from "Share Identifier" to "Share Friendly" and refine hints for download options in settings

* Tests: Add new acceptance test for disabling album downloads while allowing file downloads in settings

* Frontend: Improve download options layout and hints

* Frontend: Refactor download options condition in settings page

* Frontend: Implement native zoom control in lightbox component

* Settings: Add Collections tab and move Services to its own page #848 #5429

- Add a super-admin Collections tab after Content holding the album
  Download and Sort Order settings; remove those cards from Content.
- Move Services from a settings tab to a dedicated page
  (page/services.vue) with a search toolbar and a Reload / Learn More
  action menu; link it from the navigation settings menu.
- Implement server-side services search (acc_name filter) with tests.
- De-duplicate the picture sort-order options into a shared
  SortOrderOptions builder in options.js.
- Update acceptance/unit tests and page models to match.

* Frontend: Regenerate translation catalogs #848 #5429

Ran `make gettext-extract` to pick up the new settings strings
(Collections, Features, Disable Downloads, and related messages) so
Weblate can translate them. Existing translations are preserved.

* Frontend: Move lightbox viewport-zoom handling into the view helper

- Move the viewport pinch-zoom lock/restore (disableNativeZoom /
  restoreNativeZoom + savedViewportContent) from lightbox.vue onto the
  View singleton in common/view.js.
- Drive it passively from View.apply() via a disableViewportZoom flag in
  the PLightbox case, alongside hideScrollbar / disableScrolling /
  disableNavigationGestures; lightbox.vue no longer references zoom.
- Make save/restore idempotent and extract the viewport constants.
- Cover the helpers and the apply() wiring in view.test.js.

* Settings: Add Accessibility section to General with Reduce Motion #848 #5429

- Move the page-zoom checkbox out of the feature-flags grid into a
  dedicated Accessibility card (super-admin only) with four toggles:
  Open on Hover, Reduce Motion, Hide Scrollbar, and Allow Page Zoom.
- Add a UI.ReduceMotion flag (defaults false) that toggles an
  html.reduce-motion class via config.setReduceMotion and suppresses map
  fly-to animations non-destructively (util.mapAnimateDuration).
- Make Open on Hover apply live by reading shouldOpenOnHover() through a
  reactive computed in the action/auth/lightbox menus; Zoom and Hide
  Scrollbar reload since they are baked into the server-rendered HTML.
- Reword two feature-grid hints to the "pictures" convention and cover
  the new helpers with Go and Vitest tests.

* Frontend: Regenerate translation catalogs #848 #5429

Ran `make gettext-extract` to pick up the new Accessibility settings
strings (Accessibility, Allow Page Zoom, Open on Hover, Hide Scrollbar,
Reduce Motion, and their hints) and the reworded feature-grid hints.
Existing translations are preserved.

---------

Co-authored-by: Michael Mayer <michael@photoprism.app>
2026-07-08 14:11:36 +02:00
Michael Mayer
a22c99dd12 Frontend: Upgrade Vitest, Vite, browserslist & Vue language server
- @vitest/coverage-v8 ^4.1.9 => ^4.1.10
- @vue/language-server ^3.3.5 => ^3.3.6
- browserslist ^4.28.4 => ^4.28.5
- vite ^8.1.0 => ^8.1.3
- vitest ^4.1.9 => ^4.1.10

Dev dependencies only; NOTICE (prod-only) unchanged.
2026-07-08 00:04:29 +00:00
Michael Mayer
138075fc0a Dependencies: Upgrade klauspost, geo, x/text & x/tools Go modules
- github.com/klauspost/compress v1.18.6 => v1.19.0
- github.com/klauspost/cpuid/v2 v2.3.0 => v2.4.0
- github.com/golang/geo => 20260706204034
- golang.org/x/text v0.38.0 => v0.39.0
- golang.org/x/tools v0.45.0 => v0.47.0 (indirect)

Run go mod tidy and regenerate NOTICE.
2026-07-07 23:57:52 +00:00
Michael Mayer
c9f21cd965 Server: Derive WebDAV proxy test paths from proxy.PathPrefix
TestIsWebDAVPath hardcoded the "/i/" proxy prefix, so it failed when
proxy.DefaultPathPrefix changed. Build the proxy cases from proxy.PathPrefix,
the same value IsWebDAVPath uses, so they track the configured prefix.
2026-07-07 23:47:57 +00:00
Michael Mayer
a693df1eaa WebDAV: Route favorite-flag sidecar errors to the system log #5715
WebDAVSetFavoriteFlag logged sidecar mkdir/write failures at error level on
the UI log stream with the raw error, leaking the absolute sidecar path.
Route them through event.SystemError with clean.Error, matching the request
error handling in the WebDAV logger.
2026-07-07 23:47:57 +00:00
Michael Mayer
7bea2dccfe WebDAV: Route request errors to the system log, not the UI #5715
All WebDAV write-method errors (PUT/DELETE/MOVE/COPY/MKCOL/...) now go to
the console-only system log instead of the in-app errors table and browser
log viewer, because golang.org/x/net/webdav embeds absolute server paths in
its messages. Operators still see full detail in the container/service logs.

A MKCOL against an already-existing collection is a benign probe used by
sync clients such as PhotoSync to test for a directory before creating it;
it returns 405 and is logged at debug rather than as an error.
2026-07-07 23:27:52 +00:00
Michael Mayer
d33bca4f48 Metadata: Fix XMP body serial and add tiff: field fallbacks #2260
Read the standard exifEX:BodySerialNumber property, which ExifTool and
Adobe emit; the previous exifEX:SerialNumber matched no compliant XMP
sidecar and silently fell through to aux:SerialNumber.

Add deprecated TIFF-schema fallbacks still emitted by some writers:
tiff:Software (Software), tiff:ImageDescription (Description), and
tiff:Copyright (Copyright).
2026-07-07 11:44:33 +00:00
Michael Mayer
b7e758c607 PWA: Only emit maskable icons when the variant exists #5696 2026-07-06 10:58:16 +00:00
Ömer Duran
4b33d3bd1a
PWA: Add maskable icons, lang/dir, and install screenshots #5696 2026-06-30 19:53:52 +02:00
Michael Mayer
25b99b3ec4 Convert: Gate RAW render rejection by file format #5673
Apply the RawTherapee stderr rejection (raw.DecoderErrors) only for a
gated set of formats (default .cr3) instead of every RAW format.
RawTherapee prints "Cannot use camera white balance" for any sensor it
cannot read, including bodies whose default-WB render is fine, so for
formats it alone can decode (e.g. .raw, .kdc) the warning-based discard
left nothing to index. CR3 is unchanged: a magenta render warns and
falls back to the embedded preview.
2026-06-30 14:04:59 +00:00
Michael Mayer
6dc3ecbf25 Metadata: Map XMP dc:subject to Subject field, not Keywords #2075 #2260
dc:subject is Adobe's "Keywords" panel, but PhotoPrism's Keywords,
Labels, and Subject fields serve distinct purposes. Route dc:subject to
the descriptive Details.Subject field only (matching the embedded/
ExifTool path, where data.Subject comes from the dc:subject-backed
Subject tag and data.Keywords from IPTC Keywords), never the Keywords
field. Multi-word entries keep their spaces; the value stays searchable
via IndexKeywords and still drives label matching.
2026-06-30 10:12:45 +00:00
Michael Mayer
38b50724f5 Convert: Prefer embedded preview over untrustworthy RAW render #5673 2026-06-30 07:49:32 +00:00
Michael Mayer
9f3d958b02 Frontend: Update deps in package.json and package-lock.json
Signed-off-by: Michael Mayer <michael@photoprism.app>
2026-06-30 01:55:38 +02:00
Michael Mayer
1b572c0da7 Auth: Store session login_at as NULL when no client IP is set #5707 2026-06-29 23:28:12 +00:00
Cathie Integra
b2116154d3 Docker: Bump dev base image to develop:260629-resolute 2026-06-30 01:13:20 +02:00
Michael Mayer
b1a7a5d147 HEIC: Allow install-libheif.sh to upgrade held package #5708 2026-06-29 22:30:23 +00:00
Michael Mayer
50d4256b71 Frontend: Regenerate src/locales/json/fr.json
Signed-off-by: Michael Mayer <michael@photoprism.app>
2026-06-30 00:25:18 +02:00
Michael Mayer
5eeb0d6291 Convert: Verify RAW previews and prefer djxl for JPEG XL #5673 #5693 2026-06-29 21:59:48 +00:00
Michael Mayer
d330f0e05c Users: Apply 2FA changes for the cluster service principal 2026-06-29 21:59:48 +00:00
Michael Mayer
3e5ea71fb6 Users: Strengthen Add Account and built-in super-admin form gating 2026-06-29 21:59:48 +00:00
Cathie Integra
fd02897278 HEIC: Default install-libheif.sh to v1.23.1 #5708 2026-06-29 23:29:22 +02:00