class Rasterday

Rasterday is a piece of Rack Middleware that automatically converts SVG images to raster images.

Constants

DefaultOpts

Specifies default values for Rasterday#initialize’s opts.

FormatToContent

Attributes

app[R]
content_type[R]
outf[R]
trigger[R]

Public Class Methods

new(app, opts = {}) click to toggle source
# File lib/rasterday.rb, line 25
def initialize app, opts = {}
        @app = app
        opts = DefaultOpts.merge opts

        @stamp_responses = opts[:stamp_responses]
        @outf = opts[:format]
        @content_type = opts[:content_type] || FormatToContent[@outf]

        m = opts[:trigger]
        case m
        when Method, Proc
                @trigger = m
        when Symbol, String
                @trigger = method(m)
        end

        if trigger.nil?
                raise ArgumentError, "Apparently invalid trigger:  #{opts[:trigger].inspect}"
        end
end

Public Instance Methods

always(*) click to toggle source
# File lib/rasterday.rb, line 90
def always(*)
        true
end
bad_browsers(env, *) click to toggle source
# File lib/rasterday.rb, line 94
def bad_browsers(env, *)
        ua = env['HTTP_USER_AGENT']
        # IE hates SVGs:
        return true if ua.include?('MSIE') || ua.include?('Trident/')
        # Older versions of Firefox:
        ff = /Firefox\/(\d+(\.\d+))/.match(ua)
        if ff != nil
                return ff[1].to_i <= 3
        end
        # The rest of this chunk is TODO.  See ../doc/TODO .
        false
end
call(env) click to toggle source
# File lib/rasterday.rb, line 46
def call env
        r = @app.call env

        begin
                r = r.to_a
                # We only touch 2xx-class messages:
                return r unless (200...300).include?(r[0])
                # We don't touch HEAD requests:
                return r if env['REQUEST_METHOD'] == 'HEAD'
                # The reason for this is that we can't generate the appropriate headers
                # unless we get a body back.

                # We only care about SVGs:
                ctk, ct = r[1].find { |k,v| k.downcase == 'content-type' }
                return r if ct != "image/svg+xml"
                # Run the trigger last (most likely to be expensive):
                return r if !trigger[env, r]
                svg = ''
                r[2].each { |chunk| svg << chunk }
                of = @outf
                i, * = Magick::Image.from_blob(svg) { |info|
                        info.background_color = 'none'
                }
                i.format = @outf
                r[1][ctk] = content_type
                blob = i.to_blob
                clk, cl = r[1].find { |k,v| k.downcase == 'content-length' }
                r[1][clk] = blob.bytesize.to_s
                r[2] = [i.to_blob]
                r[1]['Rasterday'] = '1'
        rescue StandardError => e
                logger.error { "Failed to convert:  #{e} #{e.backtrace.join("\n")}" }
        end
        r
end
logger() click to toggle source
# File lib/rasterday.rb, line 82
def logger
        @logger ||= Logger.new($stderr)
end
stamp_responses?() click to toggle source
# File lib/rasterday.rb, line 86
def stamp_responses?
        @stamp_responses
end