rai 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +7 -0
- data/Rakefile +11 -0
- data/config.ru +4 -0
- data/lib/rai/version.rb +3 -0
- data/lib/rai.rb +146 -0
- data/rai.gemspec +21 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7535f625055b6e362e4d80005c52b8e7052a5249
|
4
|
+
data.tar.gz: ba478f0a4db98ab3bae31376c50f4ce75b7a6fea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4fe859a9caaeaeee7e74d30237a0683693e7ff96e98bbc26daad5747a3c93f40be9badd2ec11309a6e21128e348c4b7c27d894f6c8fe6034b6f2a6d76b958df1
|
7
|
+
data.tar.gz: 5886575aeec57e804270c67628b9daa0531a4bcabe5a3be74b34e68839f97fbd89a37cb3c74bee36cbeadc3d2ec7b8b0eb7ed6e1fea2bce02822f2fd5149beb2
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
data/config.ru
ADDED
data/lib/rai/version.rb
ADDED
data/lib/rai.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'mini_magick'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Rai
|
6
|
+
class App < Sinatra::Base
|
7
|
+
# keep an eye on the cache to see if it needs updating
|
8
|
+
set :watch_cache, true
|
9
|
+
# resolution break-points (screen widths)
|
10
|
+
set :resolutions, [1382, 992, 768, 480, 320]
|
11
|
+
# jpg compression ratio, 0-100
|
12
|
+
set :jpg_quality, 75
|
13
|
+
# wether image should be sharpened or not
|
14
|
+
set :sharpen, true
|
15
|
+
# 7 days
|
16
|
+
set :cache_max_age, 60*60*24*7
|
17
|
+
# where images are placed
|
18
|
+
set :img_path, File.join(File.dirname(__FILE__), 'images')
|
19
|
+
# where cached versions are placed
|
20
|
+
set :cache_path, File.join(File.dirname(__FILE__), 'images', 'cache')
|
21
|
+
|
22
|
+
get %r{.*?\.(jpg|jpeg|png|gif)$} do
|
23
|
+
@img_file = File.join(settings.img_path, @request_path)
|
24
|
+
not_found unless File.exists? @img_file
|
25
|
+
@cache_file = File.join(settings.cache_path, @resolution.to_s, @request_path)
|
26
|
+
@extension = params[:captures][0].downcase
|
27
|
+
|
28
|
+
expires settings.cache_max_age, :private, :must_revalidate
|
29
|
+
|
30
|
+
if File.exists? @cache_file
|
31
|
+
refresh_cache
|
32
|
+
else
|
33
|
+
update_cached_image
|
34
|
+
end
|
35
|
+
send_file @cache_file
|
36
|
+
end
|
37
|
+
|
38
|
+
before do
|
39
|
+
@request_path = URI.decode(request.path_info)
|
40
|
+
settings.resolutions.sort!{|x,y| y <=> x }
|
41
|
+
@resolution = get_resolution
|
42
|
+
end
|
43
|
+
|
44
|
+
helpers do
|
45
|
+
def get_resolution
|
46
|
+
get_resolution_from_cookie || get_resolution_from_user_agent
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_resolution_from_cookie
|
50
|
+
if res_cookie = request.cookies['resolution']
|
51
|
+
cookie_data = res_cookie.split(',')
|
52
|
+
total_width = client_width = cookie_data[0].to_i
|
53
|
+
# the device's pixel density factor (physical pixels per CSS pixel)
|
54
|
+
pixel_density = cookie_data[1] ? cookie_data[1].to_i : 1
|
55
|
+
# by default use the largest supported break-point
|
56
|
+
resolution = settings.resolutions.first
|
57
|
+
|
58
|
+
if pixel_density != 1
|
59
|
+
total_width = client_width * pixel_density
|
60
|
+
end
|
61
|
+
|
62
|
+
resolution =
|
63
|
+
settings.resolutions.select {|res| total_width <= res}.last
|
64
|
+
resolution ||= settings.resolutions.first
|
65
|
+
|
66
|
+
if total_width > settings.resolutions.first
|
67
|
+
resolution *= pixel_density
|
68
|
+
end
|
69
|
+
|
70
|
+
return resolution
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_resolution_from_user_agent
|
75
|
+
is_mobile ? settings.resolutions.min : settings.resolutions.max
|
76
|
+
end
|
77
|
+
|
78
|
+
def is_mobile
|
79
|
+
request.user_agent.downcase.match(/mobile/)
|
80
|
+
end
|
81
|
+
|
82
|
+
def refresh_cache
|
83
|
+
return unless settings.watch_cache
|
84
|
+
return if File.mtime(@cache_file) >= File.mtime(@img_file)
|
85
|
+
|
86
|
+
File.delete @cache_file
|
87
|
+
update_cached_image
|
88
|
+
end
|
89
|
+
|
90
|
+
def update_cached_image
|
91
|
+
cache_dir = File.dirname(@cache_file)
|
92
|
+
begin
|
93
|
+
#Dir.mkdir(settings.cache_path, 0755) unless File.directory?(settings.cache_path)
|
94
|
+
FileUtils.mkdir_p(cache_dir, :mode => 0755) unless File.directory?(cache_dir)
|
95
|
+
rescue SystemCallError => e
|
96
|
+
halt(500, "Unable to create caching directory. #{e}")
|
97
|
+
rescue => e
|
98
|
+
halt(500, "Unable to create caching directory. #{e}")
|
99
|
+
end
|
100
|
+
|
101
|
+
begin
|
102
|
+
image = MiniMagick::Image.open(@img_file)
|
103
|
+
rescue Exception => e
|
104
|
+
halt(500, "Error loading image: #{e}")
|
105
|
+
end
|
106
|
+
|
107
|
+
# Do we need to downscale the image?
|
108
|
+
if image[:width] <= @resolution
|
109
|
+
@cache_file = @img_file
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
ratio = image["%[fx:w/h]"].to_f
|
114
|
+
new_width = @resolution
|
115
|
+
new_height = (new_width*ratio).ceil
|
116
|
+
|
117
|
+
if @extension == 'jpg'
|
118
|
+
image.combine_options do |c|
|
119
|
+
c.interlace 'plane'
|
120
|
+
c.quality settings.jpg_quality
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
if settings.sharpen
|
125
|
+
radius = 0.5
|
126
|
+
sigma = 0.5
|
127
|
+
amount = 1.0
|
128
|
+
threshold = 0.02
|
129
|
+
image.unsharp "#{radius}x#{sigma}+#{amount}+#{threshold}"
|
130
|
+
end
|
131
|
+
|
132
|
+
image.resize "#{new_width}x#{new_height}"
|
133
|
+
|
134
|
+
begin
|
135
|
+
image.write @cache_file
|
136
|
+
rescue Exception => e
|
137
|
+
halt(500, "Error writing cache file: #{e}")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
not_found do
|
143
|
+
"Not found: #{@request_path} not found."
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/rai.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rai/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'rai'
|
7
|
+
s.version = Rai::VERSION
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
|
+
s.authors = ["Kim Nørgaard"]
|
10
|
+
s.description = 'Ruby-port of Adaptive Images (http://adaptive-images.com/)'
|
11
|
+
s.summary = 'Scales images according to screen width'
|
12
|
+
s.email = 'jasen@jasen.dk'
|
13
|
+
s.homepage = %q{https://github.com/KimNorgaard/rai}
|
14
|
+
s.licenses = 'Creative Commons Attribution 3.0 Unported License'
|
15
|
+
|
16
|
+
s.add_runtime_dependency 'sinatra'
|
17
|
+
s.add_runtime_dependency 'mini_magick'
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rai
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kim Nørgaard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sinatra
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mini_magick
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Ruby-port of Adaptive Images (http://adaptive-images.com/)
|
42
|
+
email: jasen@jasen.dk
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- Gemfile
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- config.ru
|
52
|
+
- lib/rai.rb
|
53
|
+
- lib/rai/version.rb
|
54
|
+
- rai.gemspec
|
55
|
+
homepage: https://github.com/KimNorgaard/rai
|
56
|
+
licenses:
|
57
|
+
- Creative Commons Attribution 3.0 Unported License
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.0.3
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: Scales images according to screen width
|
79
|
+
test_files: []
|