class Inert::Builder

Attributes

app[RW]
build_path[RW]
history[R]
queue[R]

Public Class Methods

new(app) click to toggle source
# File lib/inert/builder.rb, line 12
def initialize(app)
  @app = app
  @queue = []
  @history = Set.new
  @build_path = "./build"
end

Public Instance Methods

already_visited?(url) click to toggle source
# File lib/inert/builder.rb, line 70
def already_visited?(url)
  history.include?(url)
end
call(starting_url) click to toggle source
# File lib/inert/builder.rb, line 19
def call(starting_url)
  copy_static

  save(starting_url)
  history.add(starting_url)

  while (url = queue.pop)
    next if already_visited?(url) || is_anchor?(url) || is_remote?(url)

    save(url)
    history.add(url)
  end
end
copy_static() click to toggle source
# File lib/inert/builder.rb, line 66
def copy_static
  FileUtils.cp_r(app.opts[:public_root]+"/.", build_path)
end
is_anchor?(url) click to toggle source
# File lib/inert/builder.rb, line 74
def is_anchor?(url)
  url.start_with?("#")
end
is_remote?(url) click to toggle source
# File lib/inert/builder.rb, line 78
def is_remote?(url)
  url =~ /\A(\w+):/ || url.start_with?("//")
end
save(url) click to toggle source
# File lib/inert/builder.rb, line 33
def save(url)
  warn "Saving #{url}"
  request = Rack::MockRequest.new(app)

  dest = URI(url.dup).path
  dest << "index.html"  if dest.end_with?("/")
  dest << ".html"       unless dest =~ /\.\w+$/
  dest = File.expand_path(dest[1..-1], build_path)

  FileUtils.mkdir_p(File.dirname(dest))

  response = request.get(url)
  return unless response.ok?

  File.write(dest, response.body)
  return unless response.content_type == "text/html"

  html = Oga.parse_html(response.body)
  html.css("[href], [src]").each do |el|
    url = (el.get("href") || el.get("src"))

    next if url =~ /\Ahttps?/

    queue.push(url)
  end

  html.css("[style*='url']").each do |el|
    el.get("style").match(/url\(['"]?([^'"]+)['"]?\)/) do |m|
      queue.push(m[1])
    end
  end
end