Websites/app/jobs/e621_thumbnail_job.rb
Donovan Daniels b1c702e3cd
Add image management ui
poorly tested but it worked well enough, I'm sure I'll be patching bugs over the next few weeks
Also remove turbo because it sucks
Also changed the way we handle hosts in dev
2024-05-06 03:25:17 -05:00

74 lines
3.0 KiB
Ruby

# frozen_string_literal: true
class E621ThumbnailJob < ApplicationJob
queue_as :default
def perform(entry)
infile = Tempfile.new(%W[e621-thumbnail-#{entry.stripped_md5} .webm])
outfile = Tempfile.new(%W[e621-thumbnail-#{entry.stripped_md5} .#{entry.filetype}])
cutfile = Tempfile.new(%W[e621-thumbnail-#{entry.stripped_md5} .cut.webm])
palettefile = Tempfile.new(%W[e621-thumbnail-#{entry.stripped_md5} .palette.png])
Timeout.timeout(120) do
infile.binmode
io = FileDownload.new("https://static1.e621.net/data/#{entry.stripped_md5[0..1]}/#{entry.stripped_md5[2..3]}/#{entry.stripped_md5}.webm").download!
IO.copy_stream(io, infile)
duration = `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 #{infile.path}`.to_f
offset = duration > 10 ? rand(0..(duration - 10)) : duration / 2
if entry.filetype == "gif"
`ffmpeg -y -i #{infile.path} -ss #{offset} -t 3 -c:v copy -an #{cutfile.path} 1>&2`
`ffmpeg -y -i #{cutfile.path} -filter_complex "[0:v] palettegen" #{palettefile.path} 1>&2`
`ffmpeg -y -i #{cutfile.path} -i #{palettefile.path} -filter_complex "[0:v][1:v] paletteuse" #{outfile.path} 1>&2`
else
`ffmpeg -y -i #{infile.path} -ss #{offset} -vframes 1 #{outfile.path} 1>&2`
end
ImageOptim.new.optimize_image!(outfile.path)
Websites.config.e621_thumbnails_storage.upload("/#{entry.stripped_md5}.#{entry.filetype}", outfile)
entry.update!(status: "complete")
execute_webhook(entry, title: "Thumbnail Generated (#{entry.filetype})")
end
rescue Timeout::Error
entry.update!(status: "timeout")
execute_webhook(entry, title: "Thumbnail Generation Timed Out (#{entry.filetype})", error: true)
rescue StandardError => e
code = Requests::Pastebin.default.create(title: "E621 Thumbnail Generation Error (#{entry.stripped_md5})", content: "#{e}\n#{e.backtrace&.join("\n") || ''}")
entry.update!(status: "error", error_code: code)
execute_webhook(entry, title: "Thumbnail Generation Errored (#{entry.filetype})", body: "Backtrace: https://passtebin.com/#{code}", error: true)
raise(e)
ensure
[infile, outfile, palettefile, cutfile].each do |file|
file&.close
file&.unlink
end
end
def execute_webhook(entry, title:, body: "", error: false)
if error
entry.update(expires_at: 5.minutes.from_now)
E621ThumbnailErrorCleanupJob.set(wait: 5.minutes).perform_later(entry)
end
thumb = {}
if entry.complete?
thumb = {
thumbnail: {
url: entry.url,
},
}
end
Websites.config.e621_thumbnails_webhook.execute({
embeds: [
{
title: title,
description: <<~DESC,
Key: ##{entry.api_key_id} (`#{entry.api_key.application_name}`)
Post: [##{entry.post_id}](https://e621.net/posts/#{entry.post_id})
#{body}
DESC
color: error ? 0xDC143C : 0x008000,
timestamp: Time.now.iso8601,
**thumb,
},
],
})
end
end