summaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
5 daysSwitch face detection to CNN model with parallel batch processingKen D'Ambrosio2-49/+93
- faces.py: use model="cnn" (more accurate, better at angles/small faces/poor lighting) instead of HOG; model comment explains the trade-off clearly - faces.py: accept multiple image paths; process with ThreadPoolExecutor (dlib releases GIL during C++ inference → genuine thread parallelism); output JSON dict {path: [faces]} for batch calls - update.rb: batch_detect_faces() collects all unprocessed images per directory and calls faces.py once per directory rather than once per image, avoiding repeated model load overhead - update.rb: FACES_WORKERS read from config.yml faces.workers (default 4; set to 20 in this install's config.yml on a 64-core Xeon) - update.rb: process_dir() now takes idx/total and prints [N/total] prefix on every Scanning/Skipping line for progress monitoring To monitor a long run: nohup ruby /opt/albumen/scripts/update.rb > /tmp/faces_update.log 2>&1 & tail -f /tmp/faces_update.log Resume/restart is fully safe: sentinel files are only written after atomic_write_json, so an aborted directory reruns cleanly from scratch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 daysAdd opt-in facial recognition: detection and embedding storageKen D'Ambrosio4-3/+202
- scripts/faces.py: Python helper using face_recognition (dlib/HOG) to detect faces and return 128-D encodings as JSON; called by update.rb - scripts/update.rb: enrich_faces() stores face boxes and encodings in album.json per image (null = not yet processed, [] = processed/none found); skips files already processed; gated on faces.enabled in config.yml - Reads CONFIG_PATH (same env var as app.rb) to check faces.enabled flag - Feature is off by default; enabled in this install via config.yml - README.md, DESIGN.md: document installation, opt-in config, data model, and planned clustering/people-management pipeline People management UI and clustering script are the next milestone. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22Add hover zoom preview for admin thumbnailsv1.1Ken D'Ambrosio2-0/+51
Hovering over a thumbnail in the admin file table pops up the full 300×300 cached version near the cursor, making it easy to confirm identity before deleting or editing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22Speed up update.rb and fix UI always forcing full rescanKen D'Ambrosio6-13/+266
- 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>
2026-05-14Fill viewport with media in lightbox and slideshowKen D'Ambrosio2-11/+7
Lightbox: .lb-media now fills the full stage (flex, 100%x100%) and #lb-img/#lb-video use width/height:100% + object-fit:contain so at least one axis always reaches the edge. Click-to-close updated to check event.target===stage instead of stopPropagation. Slideshow: #ss-img/#ss-video likewise changed from max-width/max-height to width/height:100% so small or portrait media fills the stage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14Hide transcoded originals from non-admins; mark them visually for adminsKen D'Ambrosio5-20/+39
update.rb records transcoded_to in album.json (even on re-runs where the MP4 already exists) so the marker survives across scans. app.rb filters files with transcoded_to from non-admin views. album.erb renders them greyed-out with an amber "⚠ original" badge in admin mode. admin/album.erb marks the edit-table row and shows the target filename under the original. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14Auto-transcode non-browser-playable videos to MP4 in update.rbKen D'Ambrosio1-4/+39
On each run, any .avi, .mkv, or .mov file without a same-named .mp4 sibling is transcoded with ffmpeg (H.264/AAC, CRF 23, faststart). The original is kept on disk and hidden in album.json so only the playable MP4 appears in the UI; admins can un-hide the original if needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14Add per-photo delete checkbox to admin edit formKen D'Ambrosio3-5/+39
Checking Delete and saving permanently removes the file and its thumbnail; a JS confirm dialog gates the submit. Deleted files are stripped from params before save_edits so they don't linger in album.json. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13Add folder rename and background update trigger to admin UIKen D'Ambrosio3-0/+145
- Admin edit form: "Folder name" field renames the directory on save; also moves the thumbnail cache subtree to match the new path - Admin edit page: "Run Update" button spawns update.rb in a background thread, streams output into a terminal-style log panel via 1.5s polling; shows Done/Error status when complete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Use albumen.png as OG image for root URLKen D'Ambrosio1-3/+3
Root album leaves @og_image_rel nil so layout.erb falls back to /img/albumen.png; photo-based OG image only applies to sub-albums. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Add albumen.png as app icon, favicon, and OG fallback imageKen D'Ambrosio4-1/+3
- public/img/albumen.png: app logo - public/favicon.ico: 32x32 + 16x16 multi-size - public/apple-touch-icon.png: 180x180 for iOS home screen - layout.erb: favicon link tags; og:image falls back to albumen.png when no specific photo is selected Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Show slideshow button for folders with media anywhere in hierarchyKen D'Ambrosio2-4/+2
- slideshow_view now uses all_media_entries for non-root dirs so the slideshow traverses sub-albums instead of only direct files - album.erb condition simplified: show launcher when albums OR media entries exist (previously hidden for folders with only sub-albums) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Add organize_by_day.rb script for GPS-based day/location splittingKen D'Ambrosio1-0/+135
Groups media files in an album directory by EXIF date, reverse-geocodes the first GPS fix of each day via Nominatim, and moves files into "Day N - Location" subdirectories. Dry-run by default; pass --go to execute. Supports a LOCATION_OVERRIDES map for cleaning up Nominatim names that are overly granular. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Add photo counts, EXIF details, video duration badges, slideshow launcher UIKen D'Ambrosio5-13/+67
- Album cards show recursive photo count (bubbles up through sub-albums). - Lightbox info panel shows camera, aperture, shutter speed, and ISO; update.rb now extracts and stores these EXIF fields. - Video thumbnail cards show a duration badge (e.g. "1:23"). - Slideshow launcher redesigned: button on its own line, with Shuffle / Full screen / Interval options on a second line, all inside a rounded border to make the grouping clear. - Fixed album-actions alignment so Interval sits level with the checkboxes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Reverse default slideshow order to show newest photos firstKen D'Ambrosio1-0/+2
When not shuffled, reverse SS_ENTRIES so the most recently added photos play first instead of last. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Move slideshow interval control to album page; fix mobile viewport clippingKen D'Ambrosio5-9/+13
- Interval input (default 5 s) now lives beside Shuffle/Full screen on the album page; passed as ?interval= param to the slideshow and seeded into the hidden ss-interval input on load. - Added "Interval" label text next to the input. - Fixed slideshow controls being pushed off-screen on mobile by using 100dvh (dynamic viewport height) with 100vh as a fallback, so the layout accounts for mobile browser chrome. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Prune orphaned thumbnails when update.rb removes deleted filesKen D'Ambrosio1-4/+10
When a media file is deleted from disk, also delete its cached thumbnail from cache/thumbs/ so stale .th.jpg files don't accumulate. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Fix slideshow photos showing too briefly due to preload timingKen D'Ambrosio1-5/+8
The next timer was starting as soon as ssShow() was called, so preload time + 500ms crossfade ate into the visible interval. Now the timer starts only after applyEntry() fires (photo is actually on screen), guaranteeing each photo gets a full interval of visibility. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12Keep screen awake during slideshow via Wake Lock APIKen D'Ambrosio1-1/+16
Acquire a screen wake lock when the slideshow is playing; release on pause or page hide; re-acquire when the tab returns to the foreground. Failures are silently ignored so older browsers degrade gracefully. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Fix slideshow timer burst when returning from background tabKen D'Ambrosio1-1/+10
Use Page Visibility API to cancel the timer when the tab hides and reschedule fresh on return, so no queued ticks fire in a burst. Also fix stale #photo= → ?photo= in stage click-through. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11v1.01: replace bcrypt with PBKDF2-SHA256; update README and DESIGN docsv1.01Ken D'Ambrosio7-36/+149
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Fix OG image previews: use ?photo= param so server can set correct og:imagev1.0Ken D'Ambrosio3-19/+30
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Add Open Graph meta tags for social media link previewsKen D'Ambrosio2-0/+19
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Add HTTP vs HTTPS setup guide with Certbot instructions to INSTALL.mdKen D'Ambrosio1-0/+67
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Replace cover dropdown with Random checkbox and per-file cover radioKen D'Ambrosio2-13/+25
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Always show filename in lightbox info panelKen D'Ambrosio2-2/+2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Limit slideshow to filtered albums when search filter is activeKen D'Ambrosio3-26/+43
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Fix set_password.rb to chown config.yml to albumen user when run as rootKen D'Ambrosio1-0/+9
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Add INSTALL.md with Debian/Ubuntu setup instructionsKen D'Ambrosio1-0/+103
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Reverse sub-album listing order on admin edit pageKen D'Ambrosio1-1/+1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Add Save button above Files table; redirect admin login to current albumKen D'Ambrosio1-0/+4
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11Return to current album's edit page after admin loginKen D'Ambrosio1-1/+1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10Add slideshow: root-level, shuffle, fullscreen, click-to-albumKen D'Ambrosio7-27/+159
- Root slideshow: all_media_entries walks the full media tree so /slideshow/ shows every photo across all albums; Slideshow button always appears on the root album page - Shuffle and Full screen checkboxes sit next to the Slideshow button on the album page; options pass as ?shuffle=1&fullscreen=1 URL params - Fullscreen uses a tap-to-activate overlay (browsers block auto-entry on page load); webkit-prefixed for Safari; ⛶ button and F key for mid-session toggle - Fullscreen mode hides controls, counter, caption bar, and site header - Exiting fullscreen auto-pauses so the current photo stays visible - Click/tap anywhere in the stage navigates to the photo's album lightbox; reads the live src attribute instead of ssIdx to avoid a race where ssIdx advances during the cross-fade while the old photo is still on screen - layout.erb excluded from slideshow (layout: false) so the site header never appears there - CSS cache-busted with ?v=2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Fix taken_at timezone: store and display as camera local timeKen D'Ambrosio2-2/+2
EXIF DateTimeOriginal has no timezone — it's the camera's wall clock. Storing it via .iso8601 attached +00:00 (server TZ), causing browsers to shift the time to their local zone when parsing. Switch to strftime('%Y-%m-%dT%H:%M:%S') so no offset is written. JS strips any existing +00:00 suffix from already-stored values so old data is also displayed correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Add info overlay to lightbox showing photo metadataKen D'Ambrosio4-0/+36
Tap "ℹ Info" in the caption bar to toggle a semi-transparent panel at the bottom of the image showing filename (if different from title), date taken, and pixel dimensions. Panel resets to hidden on each photo change. Button is hidden automatically when no metadata is available. Width/height are now included in the ENTRIES payload. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Add show/hide password toggle to admin loginKen D'Ambrosio2-1/+22
SVG eye icon sits inside the right edge of the password field. Tap/click to reveal; tap again to conceal. Helps mobile users confirm what they're typing without a separate "show password" step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Bump album.js cache-buster to force fresh load of search codeKen D'Ambrosio1-1/+1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Add live album filter search boxKen D'Ambrosio3-1/+18
Typing in the search box instantly hides non-matching album cards. Shown only when an album has more than 4 sub-albums (no point otherwise). Pure client-side — no server round-trips. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Add DESIGN.md — architecture and workflow referenceKen D'Ambrosio1-0/+398
Covers system architecture, directory layout, dependencies, data model, all HTTP routes, request flows (browse, thumbnail, lightbox, slideshow, admin), the update.rb script, security model, and deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Search subdirs recursively for album cover candidatesKen D'Ambrosio1-6/+11
Albums with no top-level photos (only sub-albums) now find a cover by walking the full directory tree. Extracted cover_candidates() does a recursive glob and returns paths relative to the album dir so the existing thumb URL construction works unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Replace dynamic cover checkbox with random image dropdown optionKen D'Ambrosio2-12/+10
Adds "— random image —" as a selectable cover option (stored as __random__ sentinel). album_cover() now picks a random eligible file when that value is set, giving a fresh cover on each page load. Removes the cover_dynamic field that was saved but never actually used in display logic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Fix video/audio players showing on image lightboxKen D'Ambrosio1-0/+1
#lb-video and #lb-audio had explicit display:block via ID selectors, which outweighed the .hidden class selector and kept the players visible for photos. Added !important to .hidden so the utility class always wins. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09Initial commit — Albumen photo albumKen19-0/+1788
Ruby/Sinatra self-hosted photo album with directory hierarchy, per-photo captions and visibility, lightbox, slideshow, admin UI, and Let's Encrypt HTTPS via Apache reverse proxy on prouter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>