bingo: fix photo rebuild on UTF-8 tagged S3 bodies
All checks were successful
Build and Deploy to Production / test (push) Successful in 22s
Build and Deploy to Production / build (push) Successful in 1m3s
Build and Deploy to Production / deploy (push) Successful in 39s

aws-sdk returns object bodies from a plain StringIO, so S3.get handed
back a UTF-8 tagged string and Photo.sniff's binary prefix comparison
raised Encoding::CompatibilityError: "Rebuild resized photos" died on
the first photo with a 500. URL imports had the same flaw via a UTF-8
read buffer. Treat image data as binary at the source and in sniff, and
let one failing photo no longer abort the batch (errors are reported in
the admin flash and logged).

Assisted-by: Claude:opus-5
This commit is contained in:
Sergei Poljanski 2026-10-10 06:32:06 +04:00
commit 61bb1393fe
Signed by: asxpi
GPG key ID: 4F8851660FA4121B
4 changed files with 33 additions and 4 deletions

View file

@ -162,8 +162,14 @@ module BingoAdmin
# Regenerate resized variants from the originals already in the bucket.
app.post '/admin/bingo/photos/rebuild' do
dcs = Bingo::Datacenter.exclude(photo_key: nil).all
dcs.each { |dc| Bingo::Photo.rebuild(dc) }
failed = dcs.reject(&:photo_variants).map(&:slug)
errors = {}
dcs.each do |dc|
Bingo::Photo.rebuild(dc)
rescue StandardError => e # one bad object must not abort the batch
errors[dc.slug] = "#{e.class}: #{e.message.lines.first&.strip}"
$logger.error("bingo: rebuild #{dc.slug}: #{e.class}: #{e.message}")
end
failed = dcs.reject(&:photo_variants).map { |dc| errors[dc.slug] ? "#{dc.slug} (#{errors[dc.slug]})" : dc.slug }
session[:bingo_flash] = "Rebuilt #{dcs.size - failed.size}/#{dcs.size}.#{" Failed: #{failed.join(', ')}" if failed.any?}"
redirect '/admin/bingo'
end