image8 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -2
- data/image8.gemspec +5 -3
- data/lib/image8.rb +81 -60
- metadata +33 -7
data/Gemfile
CHANGED
data/image8.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "image8"
|
3
|
-
s.version = "0.3.
|
4
|
-
s.date = "2010-06-
|
3
|
+
s.version = "0.3.2"
|
4
|
+
s.date = "2010-06-24"
|
5
5
|
s.summary = "dynamic image resizing."
|
6
6
|
s.email = "harry@vangberg.name"
|
7
7
|
s.homepage = "http://github.com/ichverstehe/image8"
|
@@ -14,8 +14,10 @@ Gem::Specification.new do |s|
|
|
14
14
|
"lib/image8.rb",
|
15
15
|
]
|
16
16
|
s.add_dependency "sinatra", ">= 1.0"
|
17
|
-
s.add_dependency "async_sinatra", ">= 0.1
|
17
|
+
s.add_dependency "async_sinatra", ">= 0.2.1"
|
18
18
|
s.add_dependency "em-http-request", ">= 0.2.7"
|
19
|
+
s.add_dependency "em-synchrony", ">= 0.1.5"
|
20
|
+
s.add_dependency "json"
|
19
21
|
s.add_dependency "rmagick", ">= 2.13.1"
|
20
22
|
end
|
21
23
|
|
data/lib/image8.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require "uri"
|
2
2
|
require "sinatra/async"
|
3
|
-
require "em-
|
3
|
+
require "em-synchrony"
|
4
|
+
require "em-synchrony/em-http"
|
5
|
+
require "fiber"
|
6
|
+
require "json"
|
4
7
|
require "RMagick"
|
5
8
|
|
6
9
|
class Image8 < Sinatra::Base
|
@@ -9,79 +12,97 @@ class Image8 < Sinatra::Base
|
|
9
12
|
|
10
13
|
register Sinatra::Async
|
11
14
|
|
12
|
-
aget %r
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
aget %r[/(resize|crop)/([0-9x]+)/(.*)] do |action, format, uri|
|
16
|
+
EM.synchrony do
|
17
|
+
puts "uri: #{uri.inspect} - #{uri.class}"
|
18
|
+
|
19
|
+
if uri.strip.empty?
|
20
|
+
status 404
|
21
|
+
body "No such image."
|
22
|
+
else
|
23
|
+
# This is retarded.
|
24
|
+
uri = append_query_string(uri)
|
25
|
+
doc = doc_uri(uri, format, action)
|
17
26
|
|
18
|
-
|
27
|
+
expires 31_536_000 # 1 year
|
28
|
+
request = EM::HttpRequest.new(doc).get(:timeout => 5)
|
29
|
+
if request.response_header.status == 200
|
30
|
+
puts "Serving straight from cache.."
|
31
|
+
content_type request.response_header["CONTENT_TYPE"]
|
32
|
+
body request.response
|
33
|
+
else
|
34
|
+
original, rev = download_original(uri)
|
35
|
+
image = transform_image(original, action, format)
|
19
36
|
|
20
|
-
|
37
|
+
http = EM::HttpRequest.new "#{doc}?rev=#{rev}"
|
38
|
+
http.aput(
|
39
|
+
:head => {'Content-Type' => image.mime_type},
|
40
|
+
:body => image.to_blob,
|
41
|
+
:params => {:rev => rev}
|
42
|
+
)
|
43
|
+
content_type image.mime_type
|
44
|
+
body image.to_blob
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def append_query_string uri
|
21
51
|
if !request.query_string.empty?
|
22
52
|
uri += "?#{request.query_string}"
|
23
53
|
end
|
24
|
-
uri
|
25
|
-
|
26
|
-
doc_id = encode_uri_for_couchdb(uri)
|
27
|
-
doc_uri = settings.couchdb + "/#{doc_id}"
|
28
|
-
doc_http = EventMachine::HttpRequest.new(doc_uri + "/" + format)
|
29
|
-
|
30
|
-
request = doc_http.get(:timeout => 5)
|
31
|
-
request.callback {
|
32
|
-
expires 31_536_000 # 1 year
|
33
|
-
if request.response_header.status == 200
|
34
|
-
puts "Serving straight from cache.."
|
35
|
-
content_type request.response_header["CONTENT_TYPE"]
|
36
|
-
body request.response
|
37
|
-
else
|
38
|
-
download_original(uri, doc_uri) {|blob|
|
39
|
-
resize_image(blob, format) {|img|
|
40
|
-
doc_http.put(
|
41
|
-
:head => {'Content-Type' => img.mime_type},
|
42
|
-
:body => img.to_blob
|
43
|
-
)
|
44
|
-
content_type img.mime_type
|
45
|
-
body img.to_blob
|
46
|
-
}
|
47
|
-
}
|
48
|
-
end
|
49
|
-
}
|
54
|
+
uri
|
50
55
|
end
|
51
56
|
|
52
|
-
def
|
57
|
+
def doc_id uri
|
53
58
|
uri = URI.encode(uri)
|
54
59
|
uri.gsub! "/", "%2F"
|
55
60
|
uri
|
56
61
|
end
|
57
62
|
|
58
|
-
def
|
59
|
-
|
63
|
+
def doc_uri uri, format=nil, action=nil
|
64
|
+
format = "#{action}/#{format}" if action
|
65
|
+
[settings.couchdb, doc_id(uri), format].compact.join("/")
|
66
|
+
end
|
67
|
+
|
68
|
+
def download_original uri
|
69
|
+
cache = EM::HttpRequest.new doc_uri(uri, "full")
|
60
70
|
request = cache.get
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
|
72
|
+
if request.response_header.status == 200
|
73
|
+
puts "Serving original from cache.."
|
74
|
+
blob = request.response
|
75
|
+
rev = request.response_header["ETAG"][1..-2]
|
76
|
+
else
|
77
|
+
puts "Downloading original.."
|
78
|
+
original = EM::HttpRequest.new(uri).get
|
79
|
+
request = cache.put(
|
80
|
+
:head => {'Content-Type' => original.response_header["CONTENT_TYPE"]},
|
81
|
+
:body => original.response
|
82
|
+
)
|
83
|
+
blob = original.response
|
84
|
+
rev = JSON.parse(request.response)["rev"]
|
85
|
+
end
|
86
|
+
|
87
|
+
[blob, rev]
|
77
88
|
end
|
78
89
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
90
|
+
def format_response request
|
91
|
+
rev = etag[1..-2]
|
92
|
+
[blob, rev]
|
93
|
+
end
|
94
|
+
|
95
|
+
def transform_image blob, action, format
|
96
|
+
puts "#{action} image.."
|
97
|
+
image = Magick::Image.from_blob(blob).first
|
98
|
+
case action
|
99
|
+
when "resize" then
|
100
|
+
image.change_geometry!(format) {|width, height|
|
101
|
+
image.resize! width, height
|
102
|
+
}
|
103
|
+
when "crop" then
|
104
|
+
image.resize_to_fill! format.to_i
|
105
|
+
end
|
106
|
+
image
|
86
107
|
end
|
87
108
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 2
|
9
|
+
version: 0.3.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Harry Vangberg
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-06-
|
17
|
+
date: 2010-06-24 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -39,9 +39,9 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
segments:
|
41
41
|
- 0
|
42
|
+
- 2
|
42
43
|
- 1
|
43
|
-
|
44
|
-
version: 0.1.5
|
44
|
+
version: 0.2.1
|
45
45
|
type: :runtime
|
46
46
|
version_requirements: *id002
|
47
47
|
- !ruby/object:Gem::Dependency
|
@@ -59,9 +59,35 @@ dependencies:
|
|
59
59
|
type: :runtime
|
60
60
|
version_requirements: *id003
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
62
|
+
name: em-synchrony
|
63
63
|
prerelease: false
|
64
64
|
requirement: &id004 !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
- 1
|
71
|
+
- 5
|
72
|
+
version: 0.1.5
|
73
|
+
type: :runtime
|
74
|
+
version_requirements: *id004
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: json
|
77
|
+
prerelease: false
|
78
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
type: :runtime
|
86
|
+
version_requirements: *id005
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rmagick
|
89
|
+
prerelease: false
|
90
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
65
91
|
requirements:
|
66
92
|
- - ">="
|
67
93
|
- !ruby/object:Gem::Version
|
@@ -71,7 +97,7 @@ dependencies:
|
|
71
97
|
- 1
|
72
98
|
version: 2.13.1
|
73
99
|
type: :runtime
|
74
|
-
version_requirements: *
|
100
|
+
version_requirements: *id006
|
75
101
|
description: dynamic image resizing.
|
76
102
|
email: harry@vangberg.name
|
77
103
|
executables: []
|