This commit is contained in:
24c02 2026-02-07 19:14:38 -05:00
parent 2e8cb65768
commit da78c0c1f7

View file

@ -1,9 +1,11 @@
require "open3"
require "rmagick"
require "parallel"
module SnailMail
module Preview
OUTPUT_DIR = Rails.root.join("app", "frontend", "images", "template_previews")
PREVIEW_DPI = 150
class FakeAddress < OpenStruct
def us_format
@ -34,6 +36,17 @@ module SnailMail
def self.generate_previews
OUTPUT_DIR.mkpath
templates = SnailMail::Components::Registry.available_templates
Rails.logger.info("Generating #{templates.size} template previews in parallel...")
Parallel.each(templates, in_threads: Parallel.processor_count, progress: "Generating previews") do |name|
generate_single_preview(name)
end
Rails.logger.info("Finished generating #{templates.size} template previews")
end
def self.generate_single_preview(name)
return_address = OpenStruct.new(
name: "Hack Club",
line_1: "15 Falls Rd",
@ -53,50 +66,76 @@ module SnailMail
usps_mailer_id = OpenStruct.new(mid: "111111")
SnailMail::Components::Registry.available_templates.each do |name|
template = SnailMail::Components::Registry.get_component_class(name)
sender, recipient = names.sample(2)
template = SnailMail::Components::Registry.get_component_class(name)
sender, recipient = names.sample(2)
mock_letter = OpenStruct.new(
address: FakeAddress.new(
line_1: "8605 Santa Monica Blvd",
line_2: "Apt. 86294",
city: "West Hollywood",
state: "CA",
postal_code: "90069",
country: "US",
name_line: sender,
),
return_address:,
return_address_name_line: recipient,
postage_type: "stamps",
postage: 0.73,
usps_mailer_id:,
imb_serial_number: "1337",
metadata: {},
rubber_stamps: "here's where rubber stamps go!",
public_id: "ltr!PR3V13W",
)
mock_letter = OpenStruct.new(
address: FakeAddress.new(
line_1: "8605 Santa Monica Blvd",
line_2: "Apt. 86294",
city: "West Hollywood",
state: "CA",
postal_code: "90069",
country: "US",
name_line: sender,
),
return_address:,
return_address_name_line: recipient,
postage_type: "stamps",
postage: 0.73,
usps_mailer_id:,
imb_serial_number: "1337",
metadata: {},
rubber_stamps: "here's where rubber stamps go!",
public_id: "ltr!PR3V13W",
)
Rails.logger.info("generating preview for #{name}...")
pdf = SnailMail::PhlexService.generate_label(mock_letter, template: name)
Rails.logger.info("generating preview for #{name}...")
pdf = SnailMail::PhlexService.generate_label(mock_letter, template: name)
pdf_data = pdf.render
png_path = OUTPUT_DIR.join("#{template.name.split("::").last.underscore}.png")
png_path = OUTPUT_DIR.join("#{template.name.split("::").last.underscore}.png")
begin
image = Magick::Image.from_blob(pdf.render) do |i|
i.density = 300
end.first
convert_pdf_to_png(pdf_data, png_path)
end
image.alpha(Magick::RemoveAlphaChannel)
image.background_color = "white"
image.pixel_interpolation_method = Magick::IntegerInterpolatePixel
image.write(png_path)
rescue => e
Rails.logger.error("Failed to convert PDF to PNG: #{e.message}")
raise e
def self.convert_pdf_to_png(pdf_data, png_path)
if pdftoppm_available?
convert_with_pdftoppm(pdf_data, png_path)
else
convert_with_rmagick(pdf_data, png_path)
end
end
def self.pdftoppm_available?
@pdftoppm_available ||= system("which pdftoppm > /dev/null 2>&1")
end
def self.convert_with_pdftoppm(pdf_data, png_path)
base_path = png_path.to_s.sub(/\.png$/, "")
Open3.popen3("pdftoppm", "-png", "-r", PREVIEW_DPI.to_s, "-singlefile", "-", base_path) do |stdin, stdout, stderr, wait_thr|
stdin.binmode
stdin.write(pdf_data)
stdin.close
unless wait_thr.value.success?
raise "pdftoppm failed: #{stderr.read}"
end
end
end
def self.convert_with_rmagick(pdf_data, png_path)
image = Magick::Image.from_blob(pdf_data) do |i|
i.density = PREVIEW_DPI
end.first
image.alpha(Magick::RemoveAlphaChannel)
image.background_color = "white"
image.write(png_path)
rescue => e
Rails.logger.error("Failed to convert PDF to PNG: #{e.message}")
raise e
end
end
end