Class: Rasterday
- Inherits:
-
Object
- Object
- Rasterday
- Defined in:
- lib/rasterday.rb
Overview
Rasterday is a piece of Rack Middleware that automatically converts SVG images to raster images.
Constant Summary collapse
- DefaultOpts =
Specifies default values for Rasterday#initialize’s
opts
. { trigger: :bad_browsers, format: 'GIF', content_type: nil, # See FormatToContent logger: nil, stamp_responses: true, # Helps with debugging, performance. # TODO: Caching. }
- FormatToContent =
{ 'GIF' => 'image/gif', 'PNG' => 'image/png', 'JPEG' => 'image/jpeg', }
Instance Attribute Summary collapse
-
#app ⇒ Object
readonly
Returns the value of attribute app.
-
#content_type ⇒ Object
readonly
Returns the value of attribute content_type.
-
#outf ⇒ Object
readonly
Returns the value of attribute outf.
-
#trigger ⇒ Object
readonly
Returns the value of attribute trigger.
Instance Method Summary collapse
- #always ⇒ Object
- #bad_browsers(env) ⇒ Object
- #call(env) ⇒ Object
-
#initialize(app, opts = {}) ⇒ Rasterday
constructor
A new instance of Rasterday.
- #logger ⇒ Object
- #stamp_responses? ⇒ Boolean
Constructor Details
#initialize(app, opts = {}) ⇒ Rasterday
Returns a new instance of Rasterday.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# 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 |
Instance Attribute Details
#app ⇒ Object (readonly)
Returns the value of attribute app.
23 24 25 |
# File 'lib/rasterday.rb', line 23 def app @app end |
#content_type ⇒ Object (readonly)
Returns the value of attribute content_type.
23 24 25 |
# File 'lib/rasterday.rb', line 23 def content_type @content_type end |
#outf ⇒ Object (readonly)
Returns the value of attribute outf.
23 24 25 |
# File 'lib/rasterday.rb', line 23 def outf @outf end |
#trigger ⇒ Object (readonly)
Returns the value of attribute trigger.
23 24 25 |
# File 'lib/rasterday.rb', line 23 def trigger @trigger end |
Instance Method Details
#always ⇒ Object
90 91 92 |
# File 'lib/rasterday.rb', line 90 def always(*) true end |
#bad_browsers(env) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 |
# 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) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# 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 ⇒ Object
82 83 84 |
# File 'lib/rasterday.rb', line 82 def logger @logger ||= Logger.new($stderr) end |
#stamp_responses? ⇒ Boolean
86 87 88 |
# File 'lib/rasterday.rb', line 86 def stamp_responses? @stamp_responses end |