diff options
| author | Ken D'Ambrosio <ken@jots.org> | 2026-05-22 22:50:35 +0000 |
|---|---|---|
| committer | Ken D'Ambrosio <ken@jots.org> | 2026-05-22 22:50:35 +0000 |
| commit | d32b5e99afc6f0cffefa594510cda0e4f414db75 (patch) | |
| tree | b4c24a1a7264bcbde72c0fff906e7bf380c18a02 /DESIGN.md | |
| parent | de80b9871ebe1497c672f3c7c7bb5467dabcb83a (diff) | |
Speed up update.rb and fix UI always forcing full rescan
- update.rb: skip exiftool on images marked exif_absent (set after first
failed attempt); prevents repeated slow scans of old photos with no EXIF
- update.rb: explicit directory argument now implies force — passing a path
always rescans that subtree regardless of sentinel mtime
- app.rb: /admin/update no longer hardcodes --force; sentinel-based skipping
is used by default, making UI updates finish in seconds instead of minutes
- admin/album.erb: add "Force rescan all" checkbox to Run Update button;
checked state passes force=1 to the server and restores --force behavior
- README.md, DESIGN.md: document sentinel skipping, exif_absent flag, and
explicit-directory force behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'DESIGN.md')
| -rw-r--r-- | DESIGN.md | 25 |
1 files changed, 21 insertions, 4 deletions
@@ -163,6 +163,7 @@ used. The file is written atomically (write to a `.tmp` file, then | `visible` | `true` | If `false`, hidden from non-admin visitors | | `taken_at` | `null` | ISO 8601 timestamp from EXIF; used for chronological sorting | | `width` / `height` | `null` | Pixel dimensions recorded by `update.rb` | +| `exif_absent` | `null` | Set to `true` by `update.rb` when exiftool found no metadata; skips re-extraction on future rescans | When `taken_at` is present on *any* file in an album, the entire album is sorted chronologically. Albums with no `taken_at` data stay in filename @@ -342,17 +343,31 @@ Run this after copying new media files onto the server. It is safe to re-run at any time — all operations are idempotent. ```bash -ruby /opt/albumen/scripts/update.rb [optional/subdir] +ruby /opt/albumen/scripts/update.rb # full tree, skip unchanged dirs +ruby /opt/albumen/scripts/update.rb 2024-Italy # explicit subtree, always runs +ruby /opt/albumen/scripts/update.rb --force # full tree, ignore all sentinels ``` -**What it does, per directory:** +**Change detection** — each directory gets a `.albumen_scanned` sentinel file +whose mtime is set at the end of a successful scan. On subsequent runs the +script compares `sentinel.mtime >= dir.mtime`: if true the directory is skipped +entirely (no file I/O). A global run with nothing new completes in well under a +second regardless of library size. + +Providing an explicit subdirectory argument bypasses the sentinel for that +subtree, so `update.rb some-album` always rescans that album even if the +directory mtime appears unchanged. `--force` bypasses sentinels for the whole +tree. + +**What it does, per directory (when not skipped):** 1. Reads the existing `album.json` (or starts from defaults). -2. Removes stale `files` entries for deleted files. +2. Removes stale `files` entries for deleted files (and their thumbnails). 3. For each media file: - **Images:** reads EXIF `DateTimeOriginal` (or `CreateDate`) and stores it as `taken_at`; reads pixel dimensions. Both are skipped if already - recorded. + recorded. If exiftool finds no metadata at all, sets `exif_absent: true` + so the tool is not re-invoked on future rescans of that file. - **Videos:** runs `ffprobe` to record duration. Skipped if already recorded. - **All non-audio:** generates a thumbnail if one doesn't already exist. @@ -361,6 +376,8 @@ ruby /opt/albumen/scripts/update.rb [optional/subdir] fields (`title`, `description`, `cover`, `sort_reverse`, `visible`, per-file `title`/`caption`/`visible`). 5. Writes the updated JSON atomically. +6. Touches the `.albumen_scanned` sentinel so the next global run skips + this directory. **Ownership:** When run as root (the typical case after an rsync), the script calls `FileUtils.chown_R` to transfer ownership of the media tree |
