PhoenixKit.Modules.Storage.Workers.CaptureDateBackfillJob (phoenix_kit v2.37.5)

Copy Markdown View Source

Dates the images and videos stored before capture dates existed (V200).

New uploads get their date from ProcessFileJob. Files already stored have none, so this job walks them in @batch_size batches, in uuid order, reads each one's bytes and records a date through the same CaptureDate.replace?/2 guard. Every visited file ends up with a date: when its bytes cannot be read, the file name or the upload time is used.

Chaining. Each run handles one batch and enqueues the next with a cursor ("after", the last uuid it visited), so a file is visited once per pass even when it cannot be dated — a stuck row cannot loop the chain. Only one pending run exists at a time (unique over [:worker, :queue], ignoring the cursor); a run that is executing does not count, so it can enqueue its own successor.

An edited image is dated from its unedited backup (original_file_uuid) when it has one: an edit keeps only the ICC profile, so the edited bytes carry no EXIF.

Start a pass in the background with enqueue/0, or run one to completion in the calling process with run_pass/1 — which is what mix phoenix_kit.storage.backfill_capture_dates does.

Summary

Functions

Starts a backfill pass from the beginning, unless one is already queued.

How many images and videos still have no capture date.

Reads and records the capture date of one file. Returns :ok when a date was written, :kept when a stronger one was already there, :changed when the file's bytes changed while they were being read, and :gone when the file no longer exists.

Runs a whole pass in the calling process, batch after batch, and returns how many files ended in each outcome of record/1 (plus :error). progress is called with the running totals after every batch.

Functions

enqueue()

@spec enqueue() :: {:ok, Oban.Job.t()} | {:error, term()}

Starts a backfill pass from the beginning, unless one is already queued.

pending_count()

@spec pending_count() :: non_neg_integer()

How many images and videos still have no capture date.

record(file_uuid)

@spec record(String.t()) :: :ok | :kept | :changed | :gone | {:error, term()}

Reads and records the capture date of one file. Returns :ok when a date was written, :kept when a stronger one was already there, :changed when the file's bytes changed while they were being read, and :gone when the file no longer exists.

run_pass(progress \\ fn _totals -> :ok end)

@spec run_pass((map() -> any())) :: %{required(atom()) => pos_integer()}

Runs a whole pass in the calling process, batch after batch, and returns how many files ended in each outcome of record/1 (plus :error). progress is called with the running totals after every batch.