1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class Sequencer::Unit::Import::Common::Ticket::Article::InlineImages < Sequencer::Unit::Base
- include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
- uses :mapped, :instance
- def process
- check_for_existing_instance
- return if !contains_inline_image?(mapped[:body])
- replaced_body = replaced_inline_images
- (replaced_body, inline_attachments) = HtmlSanitizer.replace_inline_images(replaced_body, mapped[:ticket_id])
- provide_mapped do
- {
- body: replaced_body.strip,
- attachments: inline_attachments,
- }
- end
- end
- def self.inline_data(image_url)
- clean_image_url = image_url.gsub(%r{^cid:}, '')
- return if !%r{^(http|https)://.+?$}.match?(clean_image_url)
- @cache ||= {}
- return @cache[clean_image_url] if @cache[clean_image_url]
- image_data = download(clean_image_url)
- return if image_data.blank?
- @cache[clean_image_url] = "data:image/png;base64,#{Base64.strict_encode64(image_data)}"
- @cache[clean_image_url]
- end
- def self.download(image_url)
- logger.debug { "Downloading inline image from #{image_url}" }
- response = UserAgent.get(
- image_url,
- {},
- {
- open_timeout: 20,
- read_timeout: 240,
- verify_ssl: true,
- },
- )
- return response.body if response.success?
- logger.error response.error
- nil
- end
- private
- def contains_inline_image?(string)
- return false if string.blank?
- string.include?(inline_image_url_prefix)
- end
- def replaced_inline_images
- body_html = Nokogiri::HTML(mapped[:body])
- body_html.css('img').each do |node|
- next if !contains_inline_image?(node['src'])
- node.attributes['src'].value = self.class.inline_data(node['src'])
- end
- body_html.to_html
- end
- def check_for_existing_instance
- return if instance.blank? || local_inline_attachments.blank?
- local_inline_attachments.each(&:delete)
- end
- def local_inline_attachments
- @local_inline_attachments ||= instance.attachments&.filter { |attachment| attachment.preferences&.dig('Content-Disposition') == 'inline' }
- end
- def inline_image_url_prefix
- raise NotImplementedError
- end
- end
|