feat(dates): container video dates, filesystem branch, manual edit (#115)
The exiftool branch of the date waterfall now pulls raw strings with group prefixes (one `exiftool -j -q -G1` subprocess per batch, no `-d %s`) and classifies each candidate: - zoned strings (own offset / Z) are true instants; - naive strings from container groups (QuickTime/Track*/Apple) are UTC-rendered creation_time fields -> true instants (utc_direct). Running them through the camera wall-clock cascade was the "videos off by 4-5 hours" bug: it reinterpreted a UTC instant in the server zone; - naive strings from photo-EXIF groups are camera wall clocks and run the offset cascade (OffsetTime* pairing + GPS evidence pulled in the same exiftool pass). The legacy date_taken column stays byte-identical to the old server-local interpretation (reproduced in Rust, DST-aware); the new-contract date_utc / camera_offset_minutes / date_taken_tz_source columns carry the true instant. Manual date edit (POST /image/exif/date) reinterprets the naive-as-UTC epoch the client sent as a wall clock in the user's display zone (camera_tz::manual_date_resolution, tz_source = 'manual'), snapshots the pre-override new-contract triple next to the existing legacy snapshot pair (3 new columns, migration 2026-09-25-000000), and revert restores both pairs. ADR-0001 records the container-date finding; CLAUDE.md date-pipeline section updated.
This commit is contained in:
1 parent
6f020f4201
commit
d2263be6ac
13 files changed
+866
-178
No files matched your search
@@ -307,6 +307,14 @@ pub struct ExifMetadata {
|
||||
pub original_date_taken: Option<i64>,
|
||||
/// When `date_taken_source = "manual"`, the prior source.
|
||||
pub original_date_taken_source: Option<String>,
|
||||
/// When `date_taken_source = "manual"`, the prior `date_utc` snapshot
|
||||
/// (the new-contract triple the revert restores alongside the legacy
|
||||
/// pair above).
|
||||
pub original_date_utc: Option<i64>,
|
||||
/// When `date_taken_source = "manual"`, the prior camera offset.
|
||||
pub original_camera_offset_minutes: Option<i32>,
|
||||
/// When `date_taken_source = "manual"`, the prior tz source.
|
||||
pub original_date_taken_tz_source: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@@ -397,6 +405,9 @@ impl From<ImageExif> for ExifMetadata {
|
||||
date_taken_tz_source: exif.date_taken_tz_source,
|
||||
original_date_taken: exif.original_date_taken,
|
||||
original_date_taken_source: exif.original_date_taken_source,
|
||||
original_date_utc: exif.original_date_utc,
|
||||
original_camera_offset_minutes: exif.original_camera_offset_minutes,
|
||||
original_date_taken_tz_source: exif.original_date_taken_tz_source,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -624,6 +635,9 @@ mod date_contract_tests {
|
||||
date_utc: Some(1_720_108_800),
|
||||
camera_offset_minutes: Some(-240),
|
||||
date_taken_tz_source: Some("offset_tag".to_string()),
|
||||
original_date_utc: None,
|
||||
original_camera_offset_minutes: None,
|
||||
original_date_taken_tz_source: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user