image8 0.3.1 → 0.3.2

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.
Files changed (4) hide show
  1. data/Gemfile +4 -2
  2. data/image8.gemspec +5 -3
  3. data/lib/image8.rb +81 -60
  4. metadata +33 -7
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "async_sinatra", "0.1.5"
3
+ gem "async_sinatra", "0.2.1"
4
4
  gem "em-http-request", "0.2.7"
5
- gem "image_science", "1.2.1"
5
+ gem "em-synchrony", "0.1.5"
6
+ gem "json", ">= 1.2.4"
7
+ gem "rmagick", "2.13.1"
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "image8"
3
- s.version = "0.3.1"
4
- s.date = "2010-06-18"
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.5"
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
 
@@ -1,6 +1,9 @@
1
1
  require "uri"
2
2
  require "sinatra/async"
3
- require "em-http"
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|/([0-9x]+)/(.*)| do |format, uri|
13
- if uri.strip.empty?
14
- status 404
15
- body "No such image."
16
- end
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
- puts "uri: #{uri.inspect} - #{uri.class}"
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
- # This is retarded.
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 = URI.encode(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 encode_uri_for_couchdb uri
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 download_original uri, doc_uri
59
- cache = EventMachine::HttpRequest.new(doc_uri + "/full")
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
- request.callback {
62
- if request.response_header.status == 200
63
- puts "Serving original from cache.."
64
- yield request.response if block_given?
65
- else
66
- puts "Downloading original.."
67
- original = EventMachine::HttpRequest.new(uri).get
68
- original.callback {
69
- req = cache.put(
70
- :head => {'Content-Type' => original.response_header["CONTENT_TYPE"]},
71
- :body => original.response
72
- )
73
- req.callback { yield original.response if block_given? }
74
- }
75
- end
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 resize_image blob, format, &block
80
- puts "Resizing image.."
81
- img = Magick::Image.from_blob(blob).first
82
- img.change_geometry!(format) {|width, height|
83
- img.resize! width, height
84
- }
85
- block.call(img) if block
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
- - 1
9
- version: 0.3.1
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-18 00:00:00 +02:00
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
- - 5
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: rmagick
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: *id004
100
+ version_requirements: *id006
75
101
  description: dynamic image resizing.
76
102
  email: harry@vangberg.name
77
103
  executables: []