class Postmortem::Layout

Wraps provided body in an enclosing layout for presentation purposes.

Public Class Methods

new(mail) click to toggle source
# File lib/postmortem/layout.rb, line 6
def initialize(mail)
  @mail = mail
end

Public Instance Methods

content() click to toggle source
# File lib/postmortem/layout.rb, line 14
def content
  mail = @mail
  mail.html_body = with_inlined_images(mail.html_body) if defined?(Nokogiri)
  ERB.new(Postmortem.config.layout.read).result(binding)
end
css_dependencies() click to toggle source
# File lib/postmortem/layout.rb, line 28
def css_dependencies
  default_layout_directory.join('dependencies.css').read
end
favicon_b64() click to toggle source
# File lib/postmortem/layout.rb, line 40
def favicon_b64
  default_layout_directory.join('favicon.b64').read
end
format_email_array(array) click to toggle source
# File lib/postmortem/layout.rb, line 10
def format_email_array(array)
  array&.map { |email| %(<a href="mailto:#{email}">#{email}</a>) }&.join(', ')
end
headers_template() click to toggle source
# File lib/postmortem/layout.rb, line 36
def headers_template
  default_layout_directory.join('headers_template.html').read
end
javascript() click to toggle source
# File lib/postmortem/layout.rb, line 24
def javascript
  default_layout_directory.join('layout.js').read
end
javascript_dependencies() click to toggle source
# File lib/postmortem/layout.rb, line 32
def javascript_dependencies
  default_layout_directory.join('dependencies.js').read
end
styles() click to toggle source
# File lib/postmortem/layout.rb, line 20
def styles
  default_layout_directory.join('layout.css').read
end
upload_url() click to toggle source
# File lib/postmortem/layout.rb, line 44
def upload_url
  ENV.fetch('POSTMORTEM_DELIVERY_URL', 'https://postmortem.delivery/emails')
end

Private Instance Methods

common_locations() click to toggle source
# File lib/postmortem/layout.rb, line 97
def common_locations
  ['public/assets', 'app/assets/images'].map { |path| Pathname.new(path) }
end
default_layout_directory() click to toggle source
# File lib/postmortem/layout.rb, line 50
def default_layout_directory
  Postmortem.root.join('layout')
end
encoded_image(path) click to toggle source
# File lib/postmortem/layout.rb, line 93
def encoded_image(path)
  "data:#{mime_type(path)};base64,#{Base64.encode64(path.read)}"
end
local_file?(uri) click to toggle source
# File lib/postmortem/layout.rb, line 66
def local_file?(uri)
  return false if uri.nil?
  return true if uri.host.nil?
  return true if /^www\.example\.[a-z]+$/.match(uri.host)
  return true if %w[127.0.0.1 localhost].include?(uri.host)

  false
end
located_image(uri) click to toggle source
# File lib/postmortem/layout.rb, line 81
def located_image(uri)
  path = uri.path.partition('/').last
  common_locations.each do |location|
    full_path = location.join(path)
    next unless full_path.file?

    return full_path
  end

  nil
end
mime_type(path) click to toggle source
# File lib/postmortem/layout.rb, line 101
def mime_type(path)
  extension = path.extname.partition('.').last
  extension == 'jpg' ? 'jpeg' : extension
end
try_uri(uri) click to toggle source
# File lib/postmortem/layout.rb, line 75
def try_uri(uri)
  URI(uri)
rescue URI::InvalidURIError
  nil
end
with_inlined_images(body) click to toggle source
# File lib/postmortem/layout.rb, line 54
def with_inlined_images(body)
  parsed = Nokogiri::HTML.parse(body)
  parsed.css('img').each do |img|
    uri = try_uri(img['src'])
    next unless local_file?(uri)

    path = located_image(uri)
    img['src'] = encoded_image(path) unless path.nil?
  end
  parsed.to_s
end