module HtmlTo
require_relative 'html_to/image_generate'
require_relative 'html_to/meta_image_generate_job'
require_relative 'html_to/configuration'
require_relative 'html_to/chromium'
require_relative 'html_to/serializer'
class HtmlToImageSettings
OPTIONS = %i[
template width height image_name
].freeze
DEFAULT_OPTIONS = {
template: :white,
width: 1200,
height: 630,
image_name: :meta_image
}.freeze
attr_reader(*OPTIONS, :serializer)
def initialize(klass, serializer, options, &block)
@klass = klass
@options = options
validate_options
@serializer = serializer.to_s
setup_options
instance_exec(&block) if block_given?
end
def validate_options
@options.each_key { |opt| raise ArgumentError, "html_to error #{opt} is unknown option" unless OPTIONS.include? opt }
end
def setup_options
OPTIONS.each do |k|
instance_variable_set("@#{k}", @options[k] || DEFAULT_OPTIONS[k])
end
find_template_path!
end
def additional_images
@additional_images || {}
end
def add_image(image_name, serializer, options = {})
@additional_images ||= {}
options[:image_name] = image_name
@klass.class_eval do
has_one_attached image_name
end
@additional_images[image_name] = HtmlToImageSettings.new(@klass, serializer, options)
end
def find_template_path!
user_template = Rails.root.join('app/views/html_to').join("#{template}.html.erb")
return user_template.to_s if File.file? user_template
gem_template = File.expand_path("views/html_to/#{template}.html.erb", __dir__)
return gem_template.to_s if File.file? gem_template
raise ArgumentError, "html_to error Template file not found #{user_template} #{gem_template} "
end
end
class << self
attr_reader :included_in
def included(klass)
@included_in ||= []
@included_in << klass
@included_in.uniq!
klass.class_eval do
extend ClassMethods
include InstanceMethods
end
end
end
module ClassMethods
def self.extended(base)
class << base
alias_method :create_meta_images!, :html_to_create_meta_images! unless method_defined? :create_meta_images!
end
base.cattr_accessor :html_to_image_settings
end
def html_to_create_meta_images!
all.each(&:html_to_create_meta_image!)
end
def html_to(serializer, options = {}, &block)
after_validation :html_to_mark_synchronous if options.delete(:synchronous) == true && respond_to?(:after_validation)
after_validation :html_to_mark_skip_meta_image_generate if options.delete(:skip_auto_update) == true && respond_to?(:after_validation)
self.html_to_image_settings = HtmlToImageSettings.new(self, serializer, options, &block)
class_eval do
has_one_attached options[:image_name] || html_to_image_settings.image_name
end
end
end
module InstanceMethods
def self.included(base)
base.attr_accessor :html_to_skip_meta_image_generate
base.instance_eval do
alias_method :create_meta_image!, :html_to_create_meta_image! unless method_defined? :create_meta_images!
end
base.after_commit :html_to_create_meta_image!, unless: :html_to_skip_meta_image_generate
end
def html_to_create_meta_image!
share_images_settings = [self.class.html_to_image_settings, *self.class.html_to_image_settings.additional_images.values].flatten
share_images_settings.each do |image_settings|
generator_args = [
id, self.class.name, image_settings.serializer, {
image_name: image_settings.image_name,
width: image_settings.width,
height: image_settings.height,
template: image_settings.find_template_path!
}
]
if html_to_synchronous?
MetaImageGenerateJob.perform_now(*generator_args)
else
MetaImageGenerateJob.perform_later(*generator_args)
end
end
end
private
def html_to_mark_synchronous
@html_to_synchronous = true
end
def html_to_mark_skip_meta_image_generate
@html_to_skip_meta_image_generate = true
end
def html_to_synchronous?
@html_to_synchronous
end
end
end