rstacruz/sinatra-assetpack

View on GitHub
lib/sinatra/assetpack/class_methods.rb

Summary

Maintainability
C
7 hrs
Test Coverage
module Sinatra
  module AssetPack
    # Class methods that will be given to the Sinatra application.
    module ClassMethods
      # Sets asset options, or gets them
      def assets(&blk)
        @options ||= Options.new(self, &blk)
        self.assets_initialize!  if block_given?

        @options
      end

      def assets_initialize!
        add_compressed_routes!
        add_individual_routes!

        # Cache the built files.
        if assets.prebuild && !reload_templates
          assets.cache! { |file| $stderr.write "** Building #{file}...\n" }
        end
      end

      # Add routes for the compressed versions
      def add_compressed_routes!
        assets.packages.each do |name, package|
          get package.route_regex do
            if defined?(settings.assets.app.clear_tilt_cache) && settings.assets.app.clear_tilt_cache
              AssetPack.clear_tilt_cache!(@template_cache, settings.assets.app)
            end

            mtime, contents = @template_cache.fetch(package.path) {
              [ package.mtime, package.minify ]
            }

            content_type package.type
            last_modified mtime
            assets_expires
            contents
          end
        end
      end

      # Add the routes for the individual files.
      def add_individual_routes!
        assets.served.each do |path, from|
          get %r{#{"^/#{path}/".squeeze('/')}(.*)$} do |file|
            fmt = File.extname(file)[1..-1]

            if file =~ /(.*)\.([a-f0-9]{32})\.(.*)/
              clean_file = "#{$1}.#{$3}"
              requested_hash = $2
            else
              clean_file = file
            end

            # Sanity checks
            pass unless AssetPack.supported_formats.include?(fmt)

            fn = asset_path_for(clean_file, from) or pass

            pass if settings.assets.ignored?("#{path}/#{clean_file}")

            # Send headers
            content_type fmt.to_sym
            last_modified File.mtime(fn)
            assets_expires

            format = File.extname(fn)[1..-1]

            if defined?(settings.assets.app.clear_tilt_cache) && settings.assets.app.clear_tilt_cache
              AssetPack.clear_tilt_cache!(@template_cache, settings.assets.app)
            end

            if AssetPack.supported_formats.include?(format)
              # Static file
              if fmt == 'css'
                # Matching static file format
                pass unless fmt == File.extname(fn)[1..-1]
                @template_cache.fetch(fn) { asset_filter_css File.read(fn) }
              else
                # It's a raw file, just send it
                send_file fn
              end
            else
              # Dynamic file
              not_found unless AssetPack.tilt_formats[format] == fmt

              @template_cache.fetch(fn) {
                settings.assets.fetch_dynamic_asset(fn) {
                  out = render format.to_sym, File.read(fn), :filename => fn
                  out = asset_filter_css(out)  if fmt == 'css'
                  out
                }
              }
            end
          end
        end
      end
    end
  end
end