Commit Graph
8 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 2475cf5e32 Merge PR #1773
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 00:31:26 -04:00
Michael Anderson 9ef40b9886 Commands: Refuse malformed photo ids instead of using the selection (#1506)
A wrongly typed id or ids fell back to the selection, or kept only the valid part of the list. Session::targets now returns an error for those, and callers pass it on.
2026-10-14 13:56:33 -05:00
Michael Anderson 30ec48d9b3 LR-META-XMP: Retry automatic XMP sidecar writes that failed
A sidecar write that failed because the folder was offline or read-only was only logged. Keep those photos waiting, write them again once their files are reachable, and tell the user.
2026-10-14 13:56:23 -05:00
Nathaniel LedfordandClaude Opus 5.5 2783e5de9b PERF-IMPORT: a scan, an import and a sidecar write no longer make a table of the whole library first
Setting up Synchronize Folder, an import review or an import made a table
of every photo in the library on the session's thread before the first
file was looked at, and naming one photo's sidecar worked out who owns
every shared sidecar name in the library. In a library of 3.5 million
photos (`scan_setup_bench`, release, a folder of 500): 5.8 s before a
Synchronize scan, 2.6 s before an import review, 1.7 s before an import,
2.4 s for each sidecar written.

- A scan keeps the library as it is (photos are shared, not copied) and
  looks up the files it finds (`library_files`) and the contents it probes
  (`library_hashes`) on its own thread.
- An import looks the library up with its first files
  (`ImportJob::look_up_library`), from the library and the options as they
  were when it was set up.
- The owners of shared sidecar names are worked out for the photos asked
  about (`StemOwners::among`): all five callers name only those photos.
- Synchronize Folder names its photos' sidecars in the scan, after it has
  seen that the folder is there.

Now 0.9 s, 0.05 s, 0.05 s and under 1 s. What is found, and how sidecars
are named, is unchanged: the tests hold the owners against the table of
the whole library as it was made before, and the key made without
allocating against the key, for every string of up to six of the
characters that decide it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:52:56 -04:00
Alex ChambersandClaude Opus 5.5 f1c023ed3d LR-META-XMP: Read Metadata from File doesn't auto-write the sidecar it just read (#934)
With XMP auto-write on, photo.readMetadataFromFile committed what it read
and the command handler then wrote the sidecar back, adding lc:settings to
a sidecar that had only another app's crs: settings. Later reads prefer
lc:settings, so LRTimelapse's next crs: edits were ignored. The read now
sets the existing one-command skip_auto_write switch (as photo.removeRegion
does); edits made afterwards are still auto-written.

Tests: a read leaves the sidecar byte for byte and a later develop edit is
still written; the issue's crs:Exposure2012 0.5 -> 1.2 round trip is read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:24:29 +02:00
Adrian D'souza 7d3cd8afe5 XMP: preserve Upright warning modes across import paths 2026-10-09 08:54:49 +05:30
Brandon ThomasandClaude Opus 5.5 882a059fac Issue #92: XMP: merge into an existing sidecar instead of replacing it
Saving (Cmd+S or auto-write) now merges LightCraft's properties into an
existing sidecar (lightcraft_meta::merge_xmp): owned properties (rating,
label, dc/IPTC/rights fields, lc:*) are replaced or removed, capture time
and GPS only when LightCraft has a value; everything else (crs:,
xmpMM:History, unknown namespaces, packet wrapper) is kept byte for byte.
The result is re-parsed and checked before it is written (temp + fsync +
rename). A sidecar that isn't valid XMP is copied to .xmp.bak-<time>
(never overwriting) before it is replaced; one that can't be read at all
is left alone and the save fails.

Shared stems: when several catalogued files map to one stem sidecar
(IMG.CR3 + IMG.JPG), it belongs to the raw (else the first by name) and
the others write and read <file>.xmp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:08:18 -04:00
Brandon ThomasandClaude Opus 5.5 8af27c11b1 M10.8: XMP sidecars — save/read metadata + develop settings, auto-write, crs: interchange
- crates/engine/src/sidecar.rs: <stem>.xmp (default) or <file>.xmp next to originals with rating,
  label, title, caption, copyright, creator, keywords, capture time/GPS, pick flag + full develop
  settings in lc:settings; atomic writes; read on import (sidecar wins for metadata, edits restored)
  and via photo.readMetadataFromFile (one undo step); raw/DNG embedded XMP used without a sidecar.
- Commands: photo.saveMetadataToFile (Cmd+S), photo.readMetadataFromFile, library.xmpPreferences
  {autoWrite, naming}, library.toggleAutoWriteXmp; prefs persisted in the library's prefs.json.
  Auto-write rewrites sidecars after each committed change (not mid-drag; undo/redo too).
- crates/engine/src/crs.rs: crs: develop fields (PV2012 light, WB abs/incremental, presence, HSL,
  B&W mix, parametric + point curves, colour grading, sharpening, NR, vignette, grain, optics,
  geometry, crop) → partial settings; documented in docs/xmp-interop.md.
- meta: write_xmp_lc for extra lc: properties; crs namespace canonicalised on read (never written).
- Tests: packet round trip, crs mapping with hand-written snippets, save → delete library →
  re-import restores edits, auto-write + prefs persistence, foreign sidecar, DNG-embedded XMP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:36:19 -04:00