Photo: one async accessor per EXIF field, each calling exif() #148

Open
opened 2026-10-01 21:05:33 +02:00 by clawbot · 3 comments
Collaborator

Owner's ruling (chat, 2026-10-01 ~19:05 UTC), answering question 2 of #141 (comment):

exif: both! .exif() should return everything, but .CaptureTime() (or whatever the exif field is called) should call .exif() and return the requested value.

PRIORITY: an owner's direct request. Sequence it with #145 (HEIF/HEIC EXIF), which touches the same code: land after 145, or together with it.

Definition of done:

  • await photo.exif() stays, returning every EXIF field quak reads.
  • For each field exif() returns, Photo has its own async method, named after the field in quak's naming style, for example await photo.dateTimeOriginal() or await photo.captureTime(). The plan comment on this issue lists the names. Each one calls exif() and returns that one value, or undefined when the file lacks it.
  • One shared source of truth for the field list, so exif() and the accessors cannot drift apart.
  • Works for JPEG and, once 145 lands, HEIF/HEIC.
  • Tests cover every accessor against a JPEG fixture and a HEIC fixture. README/API docs list them. Lands on next with an independent review, and milestone PR 134's description is updated.

model: opus-5-5

Owner's ruling (chat, 2026-10-01 ~19:05 UTC), answering question 2 of https://git.eeqj.de/sneak/quak/issues/141#issuecomment-107489: > exif: both! .exif() should return everything, but .CaptureTime() (or whatever the exif field is called) should call .exif() and return the requested value. PRIORITY: an owner's direct request. Sequence it with https://git.eeqj.de/sneak/quak/issues/145 (HEIF/HEIC EXIF), which touches the same code: land after 145, or together with it. Definition of done: - `await photo.exif()` stays, returning every EXIF field quak reads. - For each field `exif()` returns, `Photo` has its own async method, named after the field in quak's naming style, for example `await photo.dateTimeOriginal()` or `await photo.captureTime()`. The plan comment on this issue lists the names. Each one calls `exif()` and returns that one value, or `undefined` when the file lacks it. - One shared source of truth for the field list, so `exif()` and the accessors cannot drift apart. - Works for JPEG and, once 145 lands, HEIF/HEIC. - Tests cover every accessor against a JPEG fixture and a HEIC fixture. README/API docs list them. Lands on `next` with an independent review, and milestone PR 134's description is updated. model: opus-5-5
clawbot self-assigned this 2026-10-01 21:05:33 +02:00
Author
Collaborator

Plan. The work is dispatched once #145 is on next, because it touches the same code.

  • await photo.exif() is unchanged. It returns every field quak reads, typed as PhotoExif. For JPEG and HEIC/HEIF that is the full list below.

  • One async method per field, named after the field, the same name PhotoExif uses:

    • make(), model() and lensModel();
    • dateTimeOriginal() and offsetTimeOriginal();
    • exposureTime(), fNumber(), iso() and focalLength();
    • orientation();
    • gpsLatitude(), gpsLongitude() and gpsAltitude().

    The capture time is dateTimeOriginal(), the EXIF field's own name. Each method takes the same optional opts as exif(), calls it, and returns that one value, or undefined when the file lacks the field.

  • One source of truth. The methods are thirteen plain one-line methods, each typed by its own PhotoExif field, so a field's type cannot drift. A test reads exif() on a fixture and checks that every field it returns has a method giving the same value, so a field added to PhotoExif without a method fails the gate.

  • Cost. Each call reads the original again, from the save path or the cache. Nothing is downloaded twice, and there is no extra memo.

  • Tests cover every method on the JPEG fixture and on the HEIC fixture from 145. README lists the methods.

Standing rule: quak is pre-1.0, with no installed base and no data anywhere. There is no compatibility shim, no migration, and no deprecated alias.

Question for sneak: ".exif() should return everything." This plan reads that as every field quak reads, the thirteen above. Should exif() instead return every EXIF tag found in the file, untyped, with the thirteen typed methods on top? Recommendation: keep the typed thirteen. The full tag dump already exists as quak backup-metadata --exif.

Model: opus-5-5

Plan. The work is dispatched once https://git.eeqj.de/sneak/quak/issues/145 is on `next`, because it touches the same code. - **`await photo.exif()` is unchanged.** It returns every field quak reads, typed as `PhotoExif`. For JPEG and HEIC/HEIF that is the full list below. - **One async method per field**, named after the field, the same name `PhotoExif` uses: - `make()`, `model()` and `lensModel()`; - `dateTimeOriginal()` and `offsetTimeOriginal()`; - `exposureTime()`, `fNumber()`, `iso()` and `focalLength()`; - `orientation()`; - `gpsLatitude()`, `gpsLongitude()` and `gpsAltitude()`. The capture time is `dateTimeOriginal()`, the EXIF field's own name. Each method takes the same optional `opts` as `exif()`, calls it, and returns that one value, or `undefined` when the file lacks the field. - **One source of truth.** The methods are thirteen plain one-line methods, each typed by its own `PhotoExif` field, so a field's type cannot drift. A test reads `exif()` on a fixture and checks that every field it returns has a method giving the same value, so a field added to `PhotoExif` without a method fails the gate. - **Cost.** Each call reads the original again, from the save path or the cache. Nothing is downloaded twice, and there is no extra memo. - **Tests** cover every method on the JPEG fixture and on the HEIC fixture from 145. README lists the methods. Standing rule: quak is pre-1.0, with no installed base and no data anywhere. There is no compatibility shim, no migration, and no deprecated alias. Question for sneak: "`.exif()` should return everything." This plan reads that as every field quak reads, the thirteen above. Should `exif()` instead return every EXIF tag found in the file, untyped, with the thirteen typed methods on top? Recommendation: keep the typed thirteen. The full tag dump already exists as `quak backup-metadata --exif`. Model: opus-5-5
sneak reopened this issue 2026-10-02 03:01:05 +02:00
Owner

let exif() return everything. CLI options are not the same as API methods.

let exif() return everything. CLI options are not the same as API methods.
Author
Collaborator

sneak, chat, 2026-10-02 ~01:00 UTC, on the question above: "return every EXIF tag in the file" and "return all tags obvs". The built thirteen-field shape is changed under #156; the thirteen typed accessors stay.

model: opus-5-5

sneak, chat, 2026-10-02 ~01:00 UTC, on the question above: "return every EXIF tag in the file" and "return all tags obvs". The built thirteen-field shape is changed under https://git.eeqj.de/sneak/quak/issues/156; the thirteen typed accessors stay. model: opus-5-5
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/quak#148