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 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
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ pkg
3
+ *.cache
4
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'mini_magick'
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # Ruby Adaptive-Images
2
+ This is a ruby port of Adaptive-Images (http://adaptive-images.com/, originally by Matt Wilcox).
3
+
4
+ It runs as a sinatra application that can be mounted using Rack.
5
+
6
+ # Author
7
+ Kim Nørgaard <jasen@jasen.dk>
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require "rai/version"
3
+ require 'bundler/gem_tasks'
4
+
5
+ #task :build do
6
+ # system "gem build rai.gemspec"
7
+ #end
8
+
9
+ #task :release => :build do
10
+ # system "gem push rai-#{RAI::VERSION}.gem"
11
+ #end
data/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+ require 'rai'
3
+
4
+ map('/photos') { run Rai::App }
@@ -0,0 +1,3 @@
1
+ module Rai
2
+ VERSION = '0.0.1'
3
+ end
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: []