EXIF GPS write: POST /image/exif/gps via exiftool

New endpoint accepts {path, library, latitude, longitude} and shells
out to exiftool to write GPSLatitude/GPSLongitude (with N/S, E/W refs)
into the file's EXIF in place. After the write, the handler
re-extracts EXIF and updates the image_exif row so the DB stays in
sync — the response carries the updated metadata block in one
round-trip. Falls through to store_exif if the row is missing.

`exif::write_gps` is the small helper. `-overwrite_original` so no
.orig sidecar is left behind. Validates lat/lon range + supports_exif
before spawning exiftool. Format support matches the existing read
path (JPEG / TIFF / RAW / HEIF / PNG / WebP) — videos still need a
different writer and aren't covered.

Apollo's "+ PIN" carousel button (separate commit on the Apollo side)
calls this through /api/photos/exif/gps. Drive-by: cargo fmt one-line
collapse on apollo_client.rs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cameron Cordes
2026-04-28 22:25:40 +00:00
parent 4ae7be35e9
commit 57fb0bcd3c
5 changed files with 217 additions and 6 deletions

View File

@@ -84,9 +84,7 @@ impl ApolloClient {
match self.fetch_places_containing(base, lat, lon).await {
Ok(places) => places,
Err(err) => {
log::warn!(
"apollo_client: places_containing({lat:.4}, {lon:.4}) failed: {err}"
);
log::warn!("apollo_client: places_containing({lat:.4}, {lon:.4}) failed: {err}");
Vec::new()
}
}