Class: Enhance::Enhancer

Inherits:
Object
  • Object
show all
Defined in:
lib/enhance/enhancer.rb

Constant Summary collapse

Geometry =
/^(?<geometry>(?<width>\d+)?x?(?<height>\d+)?([\>\<\@\%^!])?)(?<filter>sample)?$/

Instance Method Summary collapse

Constructor Details

#initialize(app = nil) {|@config| ... } ⇒ Enhancer

Returns a new instance of Enhancer.

Yields:

  • (@config)


5
6
7
8
9
# File 'lib/enhance/enhancer.rb', line 5

def initialize app = nil
  @app = app
  @config = Enhance::Config.new
  yield @config if block_given?
end

Instance Method Details

#_call(env, matches) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/enhance/enhancer.rb', line 20

def _call env, matches
  folder = @config.routes[matches[:folder]] || Dir.pwd
  
  request   = File.join(folder, matches['filename'])
  destname  = File.join(*[matches['folder'], matches['filename']].reject{|s| s.nil? || s.empty?}.compact)
  
  if request && File.exists?(request) && (filename = convert(request, destname, CGI.unescape(matches['geometry'])))
    filename.gsub!(@config.cache, '')
    env["PATH_INFO"] = filename
    @config.server.call env
  else
    _next env
  end
end

#_next(env) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/enhance/enhancer.rb', line 35

def _next(env)
  if @app
    @app.call env
  else
    content = "Not Found"
    [404, {'Content-Type' => 'text/html', 'Content-Length' => content.length.to_s}, [content]]
  end
end

#call(env) ⇒ Object



11
12
13
14
15
16
17
18
# File 'lib/enhance/enhancer.rb', line 11

def call env
  matches = path_info(env).match regex
  if matches && !matches['filename'].include?("..")
    dup._call env, matches
  else
    _next env
  end
end

#convert(path, filename, geometry) ⇒ Object

Finds the image and resizes it if needs be



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/enhance/enhancer.rb', line 59

def convert path, filename, geometry
  # Extract the width and height
  if sizes = geometry.match(Geometry)
    w, h = sizes['width'], sizes['height']
    ow, oh = original_size path
    
    # Resize if needed
    if (w.nil? || w.to_i <= @config.max_side) && (h.nil? || h.to_i <= @config.max_side) && (ow != w || oh != h)
      new_name = File.join(@config.cache, filename, geometry) + File.extname(filename)
      resize path, new_name, geometry
    end
  end
end

#original_size(filename) ⇒ Object

Finds the size of the original image



89
90
91
# File 'lib/enhance/enhancer.rb', line 89

def original_size filename
  `#{@config.command_path}identify -format '%w %h' #{filename}`.split(/\s/)
end

#path_info(env) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/enhance/enhancer.rb', line 44

def path_info(env)
  # Matches for Rails using no config
  if @config.routes.empty? && (info = env["action_dispatch.request.path_parameters"])
    [info[:path], info[:format]].compact.join(".")
  else
    env['PATH_INFO']
  end
end

#regexObject



53
54
55
56
# File 'lib/enhance/enhancer.rb', line 53

def regex
  folders = @config.routes.keys
  /^\/?(?<folder>#{folders.join('|')})\/?(?<filename>.*\.(#{@config.extensions.join('|')}))\/(?<geometry>.*)/i
end

#resize(source, destination, geometry) ⇒ Object

Creates the path and resizes the images



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/enhance/enhancer.rb', line 74

def resize source, destination, geometry
  FileUtils.mkdir_p File.dirname(destination)
  
  match = geometry.match Geometry

  method = match['filter'] || 'resize'
  unless File.exists?(destination) && File.mtime(destination) > File.mtime(source)
    command = "#{@config.command_path}convert \"#{source}\" -#{method} \"#{match['geometry']}\" -quality #{@config.quality} \"#{destination}\""
    puts command
    `#{command}`
  end
  destination
end