class RackPipeline::Base

Constants

CONTENT_TYPES
STATIC_TYPES

Attributes

assets[RW]
settings[RW]

Public Class Methods

new(app, *args) click to toggle source
# File lib/rack-pipeline/base.rb, line 24
def initialize(app, *args)
  @generations = 0
  @assets = {}
  @settings = {
    :temp => nil,
    :compress => false,
    :combine => false,
    :bust_cache => false,
    :css => {
      :app => 'assets/**/*.css',
    },
    :js => {
      :app => 'assets/**/*.js',
    },
  }
  @settings.merge!(args.pop)  if args.last.kind_of?(Hash)
  ensure_temp_directory
  populate_pipelines
  @app = app
end

Public Instance Methods

assets_for(pipes, type, opts = {}) click to toggle source
# File lib/rack-pipeline/base.rb, line 18
def assets_for(pipes, type, opts = {})
  Array(pipes).inject([]) do |all,pipe|
    all += Array(settings[:combine] ? "#{pipe}.#{type}" : assets[type][pipe].keys)
  end.compact.uniq
end
call(env) click to toggle source
# File lib/rack-pipeline/base.rb, line 49
def call(env)
  @env = env
  env['rack-pipeline'] = self
  if file_path = prepare_pipe(env['PATH_INFO'])
    serve_file(file_path, env['HTTP_IF_MODIFIED_SINCE'])
  else
    @app.call(env)
  end
rescue MustRepopulate
  populate_pipelines
  retry
end
inspect() click to toggle source
# File lib/rack-pipeline/base.rb, line 45
def inspect
  { :settings => settings, :assets => assets }
end

Private Instance Methods

busted?() click to toggle source
# File lib/rack-pipeline/base.rb, line 64
def busted?
  result = settings[:bust_cache] && @busted
  @busted = false
  result
end
content_type(file) click to toggle source
# File lib/rack-pipeline/base.rb, line 97
def content_type(file)
  CONTENT_TYPES[File.extname(file)] || 'text'
end
file_kind(file) click to toggle source
# File lib/rack-pipeline/base.rb, line 127
def file_kind(file)
  static_type(file) ? :raw : :source
end
glob_files(globs) click to toggle source
# File lib/rack-pipeline/base.rb, line 131
def glob_files(globs)
  Array(globs).each_with_object({}) do |glob,all|
    Dir.glob(glob).sort.each do |file|
      all[file] = file_kind(file)
    end
  end
end
populate_pipelines() click to toggle source
# File lib/rack-pipeline/base.rb, line 139
def populate_pipelines
  fail SystemStackError, 'too many RackPipeline generations'  if @generations > 5
  @generations += 1
  STATIC_TYPES.each do |extname,type|
    pipes = settings[type]
    assets[type] = {}
    pipes.each do |pipe, dirs|
      assets[type][pipe] = glob_files(dirs)
    end
  end
end
prepare_file(source, type) click to toggle source
# File lib/rack-pipeline/base.rb, line 115
def prepare_file(source, type)
  assets[type].each do |pipe,files|
    case files[source]
    when :raw
      return source
    when :source
      return compile(source, File.basename(source, '.*') + ".#{type}")
    end
  end
  nil
end
prepare_pipe(path_info) click to toggle source
# File lib/rack-pipeline/base.rb, line 101
def prepare_pipe(path_info)
  file = path_info.start_with?('/') ? path_info[1..-1] : path_info
  type = static_type(file)  or return nil
  unless ready_file = prepare_file(file, type)
    pipename = File.basename(file, '.*').to_sym
    if assets[type] && assets[type][pipename]
      ready_file = combine(assets[type][pipename], File.basename(file))
    end
  end
  compress(ready_file, File.basename(ready_file))  if ready_file
rescue Errno::ENOENT
  raise MustRepopulate
end
serve_file(file, mtime) click to toggle source
# File lib/rack-pipeline/base.rb, line 70
def serve_file(file, mtime)
  headers = { 'Last-Modified' => File.mtime(file).httpdate }
  if mtime == headers['Last-Modified']
    [304, headers, []]
  else
    if busted?
      headers['Location'] = "#{@env['PATH_INFO']}?#{File.mtime(file).to_i}"
      [302, headers, []]
    else
      body = File.read file
      headers['Content-Type'] = "#{content_type(file)}; charset=#{body.encoding.to_s}"
      headers['Content-Length'] = File.size(file).to_s
      [200, headers, [body]]
    end
  end
rescue Errno::ENOENT
  raise MustRepopulate
end
static_type(file) click to toggle source
# File lib/rack-pipeline/base.rb, line 89
def static_type(file)
  if file.kind_of? String
    STATIC_TYPES[file] || STATIC_TYPES[File.extname(file)]
  else
    STATIC_TYPES.values.include?(file) && file
  end
end