ruby-thumbor 0.0.2 → 0.3.0

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.
data/lib/ruby-thumbor.rb CHANGED
@@ -6,7 +6,7 @@ require 'base64'
6
6
  require 'digest/md5'
7
7
 
8
8
  module Thumbor
9
- VERSION = '0.0.2'
9
+ VERSION = '0.3.0'
10
10
 
11
11
  class CryptoURL
12
12
  attr_accessor :key
@@ -19,13 +19,93 @@ module Thumbor
19
19
  s + ("{" * (16 - s.length % 16))
20
20
  end
21
21
 
22
- def generate(options)
22
+ def calculate_width_and_height(url_parts, options)
23
+ width = options[:width]
24
+ height = options[:height]
25
+
26
+ if width and options[:flip]
27
+ width = width * -1
28
+ end
29
+ if height and options[:flop]
30
+ height = height * -1
31
+ end
32
+
33
+ if width or height
34
+ width = 0 if not width
35
+ height = 0 if not height
36
+ end
37
+
38
+ has_width = width
39
+ has_height = height
40
+ if options[:flip] and not has_width and not has_height
41
+ width = "-0"
42
+ height = '0' if not has_height and not options[:flop]
43
+ end
44
+ if options[:flop] and not has_width and not has_height
45
+ height = "-0"
46
+ width = '0' if not has_width and not options[:flip]
47
+ end
48
+
49
+ if width or height
50
+ width = width.to_s
51
+ height = height.to_s
52
+ url_parts.push(width << 'x' << height)
53
+ end
54
+ end
55
+
56
+ def url_for(options)
57
+ if not options[:image]
58
+ raise 'image is a required argument.'
59
+ end
60
+
61
+ url_parts = Array.new
62
+
63
+ if options[:meta]
64
+ url_parts.push('meta')
65
+ end
66
+
67
+ crop = options[:crop]
68
+ if crop:
69
+ crop_left = crop[0]
70
+ crop_top = crop[1]
71
+ crop_right = crop[2]
72
+ crop_bottom = crop[3]
73
+
74
+ if crop_left > 0 or crop_top > 0 or crop_bottom > 0 or crop_right > 0
75
+ url_parts.push(crop_left.to_s << 'x' << crop_top.to_s << ':' << crop_right.to_s << 'x' << crop_bottom.to_s)
76
+ end
77
+ end
78
+
79
+ calculate_width_and_height(url_parts, options)
80
+
81
+ if options[:halign] and options[:halign] != 'center'
82
+ url_parts.push(options[:halign])
83
+ end
84
+
85
+ if options[:valign] and options[:valign] != 'middle'
86
+ url_parts.push(options[:valign])
87
+ end
88
+
89
+ if options[:smart]
90
+ url_parts.push('smart')
91
+ end
92
+
23
93
  image_hash = Digest::MD5.hexdigest(options[:image])
24
- url = pad(options[:width].to_s << 'x' << options[:height].to_s << '/' << image_hash)
94
+ url_parts.push(image_hash)
95
+
96
+ return url_parts.join('/')
97
+ end
98
+
99
+ def url_safe_base64(str)
100
+ Base64.encode64(str).gsub('+', '-').gsub('/', '_').gsub!(/[\n]/, '')
101
+ end
102
+
103
+ def generate(options)
104
+ url = pad(url_for(options))
25
105
  cipher = OpenSSL::Cipher::Cipher.new('aes-128-ecb').encrypt
26
106
  cipher.key = @key
27
107
  encrypted = cipher.update(url)
28
- based = Base64.encode64(encrypted).gsub('+', '-').gsub('/', '_').gsub!(/[\n]/, '')
108
+ based = url_safe_base64(encrypted)
29
109
 
30
110
  '/' << based << '/' << options[:image]
31
111
  end
@@ -1,22 +1,359 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'json'
3
+
4
+ image_url = 'my.domain.com/some/image/url.jpg'
5
+ image_md5 = 'f33af67e41168e80fcc5b00f8bd8061a'
6
+ key = 'my-security-key'
7
+
8
+ def decrypt_in_thumbor(str)
9
+ command = "python -c 'from thumbor.crypto import Crypto; cr = Crypto(\"my-security-keymy\"); print cr.decrypt(\"" << str << "\")'"
10
+ result = Array.new
11
+ IO.popen(command) { |f| result.push(f.gets) }
12
+ result = result.join('').strip
13
+ JSON.parse(result.gsub('"', "@@@").gsub("'", '"').gsub("@@@", '\\"').gsub('True', 'true').gsub('False', 'false'))
14
+ end
2
15
 
3
16
  describe Thumbor::CryptoURL, "#new" do
4
-
5
- it "should create a new instance passing key and keep it" do
6
- crypto = Thumbor::CryptoURL.new 'my-security-key'
7
- crypto.key.should == 'my-security-keymy'
8
- end
9
-
17
+
18
+ it "should create a new instance passing key and keep it" do
19
+ crypto = Thumbor::CryptoURL.new key
20
+ crypto.key.should == 'my-security-keymy'
21
+ end
22
+
23
+ end
24
+
25
+ describe Thumbor::CryptoURL, "#url_for" do
26
+ it "should return just the image hash if no arguments passed" do
27
+ crypto = Thumbor::CryptoURL.new key
28
+
29
+ url = crypto.url_for :image => image_url
30
+
31
+ url.should == image_md5
32
+ end
33
+
34
+ it "should raise if no image passed" do
35
+ crypto = Thumbor::CryptoURL.new key
36
+
37
+ expect { crypto.url_for Hash.new }.to raise_error(RuntimeError)
38
+ end
39
+
40
+ it "should return proper url for width-only" do
41
+ crypto = Thumbor::CryptoURL.new key
42
+
43
+ url = crypto.url_for :image => image_url, :width => 300
44
+
45
+ url.should == '300x0/' << image_md5
46
+ end
47
+
48
+ it "should return proper url for height-only" do
49
+ crypto = Thumbor::CryptoURL.new key
50
+
51
+ url = crypto.url_for :image => image_url, :height => 300
52
+
53
+ url.should == '0x300/' << image_md5
54
+ end
55
+
56
+ it "should return proper url for width and height" do
57
+ crypto = Thumbor::CryptoURL.new key
58
+
59
+ url = crypto.url_for :image => image_url, :width => 200, :height => 300
60
+
61
+ url.should == '200x300/' << image_md5
62
+ end
63
+
64
+ it "should return proper smart url" do
65
+ crypto = Thumbor::CryptoURL.new key
66
+
67
+ url = crypto.url_for :image => image_url, :width => 200, :height => 300, :smart => true
68
+
69
+ url.should == '200x300/smart/' << image_md5
70
+ end
71
+
72
+ it "should return proper flip url if no width and height" do
73
+ crypto = Thumbor::CryptoURL.new key
74
+
75
+ url = crypto.url_for :image => image_url, :flip => true
76
+
77
+ url.should == '-0x0/' << image_md5
78
+ end
79
+
80
+ it "should return proper flop url if no width and height" do
81
+ crypto = Thumbor::CryptoURL.new key
82
+
83
+ url = crypto.url_for :image => image_url, :flop => true
84
+
85
+ url.should == '0x-0/' << image_md5
86
+ end
87
+
88
+ it "should return proper flip-flop url if no width and height" do
89
+ crypto = Thumbor::CryptoURL.new key
90
+
91
+ url = crypto.url_for :image => image_url, :flip => true, :flop => true
92
+
93
+ url.should == '-0x-0/' << image_md5
94
+ end
95
+
96
+ it "should return proper flip url if width" do
97
+ crypto = Thumbor::CryptoURL.new key
98
+
99
+ url = crypto.url_for :image => image_url, :width => 300, :flip => true
100
+
101
+ url.should == '-300x0/' << image_md5
102
+ end
103
+
104
+ it "should return proper flip url if width" do
105
+ crypto = Thumbor::CryptoURL.new key
106
+
107
+ url = crypto.url_for :image => image_url, :height => 300, :flop => true
108
+
109
+ url.should == '0x-300/' << image_md5
110
+ end
111
+
112
+ it "should return horizontal align" do
113
+ crypto = Thumbor::CryptoURL.new key
114
+
115
+ url = crypto.url_for :image => image_url, :halign => 'left'
116
+
117
+ url.should == 'left/' << image_md5
118
+ end
119
+
120
+ it "should not return horizontal align if it is center" do
121
+ crypto = Thumbor::CryptoURL.new key
122
+
123
+ url = crypto.url_for :image => image_url, :halign => 'center'
124
+
125
+ url.should == image_md5
126
+ end
127
+
128
+ it "should return vertical align" do
129
+ crypto = Thumbor::CryptoURL.new key
130
+
131
+ url = crypto.url_for :image => image_url, :valign => 'top'
132
+
133
+ url.should == 'top/' << image_md5
134
+ end
135
+
136
+ it "should not return vertical align if it is middle" do
137
+ crypto = Thumbor::CryptoURL.new key
138
+
139
+ url = crypto.url_for :image => image_url, :valign => 'middle'
140
+
141
+ url.should == image_md5
142
+ end
143
+
144
+ it "should return halign and valign properly" do
145
+ crypto = Thumbor::CryptoURL.new key
146
+
147
+ url = crypto.url_for :image => image_url, :halign => 'left', :valign => 'top'
148
+
149
+ url.should == 'left/top/' << image_md5
150
+ end
151
+
152
+ it "should return meta properly" do
153
+ crypto = Thumbor::CryptoURL.new key
154
+
155
+ url = crypto.url_for :image => image_url, :meta => true
156
+
157
+ url.should == 'meta/' << image_md5
158
+ end
159
+
160
+ it "should return proper crop url" do
161
+ crypto = Thumbor::CryptoURL.new key
162
+
163
+ url = crypto.url_for :image => image_url, :crop => [10, 20, 30, 40]
164
+
165
+ url.should == '10x20:30x40/' << image_md5
166
+ end
167
+
168
+ it "should ignore crop if all zeros" do
169
+ crypto = Thumbor::CryptoURL.new key
170
+
171
+ url = crypto.url_for :image => image_url, :crop => [0, 0, 0, 0]
172
+
173
+ url.should == image_md5
174
+ end
175
+
176
+ it "should have smart after halign and valign" do
177
+ crypto = Thumbor::CryptoURL.new key
178
+
179
+ url = crypto.url_for :image => image_url, :halign => 'left', :valign => 'top', :smart => true
180
+
181
+ url.should == 'left/top/smart/' << image_md5
182
+ end
183
+
10
184
  end
11
185
 
12
186
  describe Thumbor::CryptoURL, "#generate" do
13
-
14
- it "should create a new instance passing key and keep it" do
15
- crypto = Thumbor::CryptoURL.new 'my-security-key'
16
187
 
17
- url = crypto.generate :width => 300, :height => 200, :image => 'my.domain.com/some/image/url.jpg'
188
+ it "should create a new instance passing key and keep it" do
189
+ crypto = Thumbor::CryptoURL.new key
190
+
191
+ url = crypto.generate :width => 300, :height => 200, :image => image_url
192
+
193
+ url.should == '/qkLDiIbvtiks0Up9n5PACtmpOfX6dPXw4vP4kJU-jTfyF6y1GJBJyp7CHYh1H3R2/' << image_url
194
+ end
195
+
196
+ it "should allow thumbor to decrypt it properly" do
197
+ crypto = Thumbor::CryptoURL.new key
198
+
199
+ url = crypto.generate :width => 300, :height => 200, :image => image_url
200
+
201
+ encrypted = url.split('/')[1]
202
+
203
+ decrypted = decrypt_in_thumbor(encrypted)
204
+
205
+ decrypted["horizontal_flip"].should == false
206
+ decrypted["vertical_flip"].should == false
207
+ decrypted["smart"].should == false
208
+ decrypted["meta"].should == false
209
+ decrypted["crop"]["left"].should == 0
210
+ decrypted["crop"]["top"].should == 0
211
+ decrypted["crop"]["right"].should == 0
212
+ decrypted["crop"]["bottom"].should == 0
213
+ decrypted["valign"].should == 'middle'
214
+ decrypted["halign"].should == 'center'
215
+ decrypted["image_hash"].should == image_md5
216
+ decrypted["width"].should == 300
217
+ decrypted["height"].should == 200
218
+
219
+ end
220
+
221
+ it "should allow thumbor to decrypt it properly with meta" do
222
+ crypto = Thumbor::CryptoURL.new key
223
+
224
+ url = crypto.generate :width => 300, :height => 200, :meta => true, :image => image_url
225
+
226
+ encrypted = url.split('/')[1]
227
+
228
+ decrypted = decrypt_in_thumbor(encrypted)
229
+
230
+ decrypted["meta"].should == true
231
+ decrypted["image_hash"].should == image_md5
232
+ decrypted["width"].should == 300
233
+ decrypted["height"].should == 200
234
+
235
+ end
236
+
237
+ it "should allow thumbor to decrypt it properly with smart" do
238
+ crypto = Thumbor::CryptoURL.new key
239
+
240
+ url = crypto.generate :width => 300, :height => 200, :meta => true, :image => image_url, :smart => true
241
+
242
+ encrypted = url.split('/')[1]
243
+
244
+ decrypted = decrypt_in_thumbor(encrypted)
245
+
246
+ decrypted["meta"].should == true
247
+ decrypted["smart"].should == true
248
+ decrypted["image_hash"].should == image_md5
249
+ decrypted["width"].should == 300
250
+ decrypted["height"].should == 200
251
+
252
+ end
253
+
254
+ it "should allow thumbor to decrypt it properly with flip" do
255
+ crypto = Thumbor::CryptoURL.new key
256
+
257
+ url = crypto.generate :width => 300, :height => 200, :meta => true, :image => image_url, :smart => true, :flip => true
258
+
259
+ encrypted = url.split('/')[1]
260
+
261
+ decrypted = decrypt_in_thumbor(encrypted)
262
+
263
+ decrypted["meta"].should == true
264
+ decrypted["smart"].should == true
265
+ decrypted["image_hash"].should == image_md5
266
+ decrypted["width"].should == 300
267
+ decrypted["height"].should == 200
268
+ decrypted["flip_horizontally"] == true
269
+
270
+ end
271
+
272
+ it "should allow thumbor to decrypt it properly with flop" do
273
+ crypto = Thumbor::CryptoURL.new key
274
+
275
+ url = crypto.generate :width => 300, :height => 200, :meta => true, :image => image_url, :smart => true, :flip => true, :flop => true
276
+
277
+ encrypted = url.split('/')[1]
278
+
279
+ decrypted = decrypt_in_thumbor(encrypted)
280
+
281
+ decrypted["meta"].should == true
282
+ decrypted["smart"].should == true
283
+ decrypted["image_hash"].should == image_md5
284
+ decrypted["width"].should == 300
285
+ decrypted["height"].should == 200
286
+ decrypted["flip_horizontally"] == true
287
+ decrypted["flip_vertically"] == true
288
+
289
+ end
290
+
291
+ it "should allow thumbor to decrypt it properly with halign" do
292
+ crypto = Thumbor::CryptoURL.new key
293
+
294
+ url = crypto.generate :width => 300, :height => 200, :meta => true, :image => image_url, :smart => true, :flip => true, :flop => true,
295
+ :halign => 'left'
296
+
297
+ encrypted = url.split('/')[1]
298
+
299
+ decrypted = decrypt_in_thumbor(encrypted)
300
+
301
+ decrypted["meta"].should == true
302
+ decrypted["smart"].should == true
303
+ decrypted["image_hash"].should == image_md5
304
+ decrypted["width"].should == 300
305
+ decrypted["height"].should == 200
306
+ decrypted["flip_horizontally"] == true
307
+ decrypted["flip_vertically"] == true
308
+ decrypted["halign"] == "left"
309
+
310
+ end
311
+
312
+ it "should allow thumbor to decrypt it properly with valign" do
313
+ crypto = Thumbor::CryptoURL.new key
314
+
315
+ url = crypto.generate :width => 300, :height => 200, :meta => true, :image => image_url, :smart => true, :flip => true, :flop => true,
316
+ :halign => 'left', :valign => 'top'
317
+
318
+ encrypted = url.split('/')[1]
319
+
320
+ decrypted = decrypt_in_thumbor(encrypted)
321
+
322
+ decrypted["meta"].should == true
323
+ decrypted["smart"].should == true
324
+ decrypted["image_hash"].should == image_md5
325
+ decrypted["width"].should == 300
326
+ decrypted["height"].should == 200
327
+ decrypted["flip_horizontally"] == true
328
+ decrypted["flip_vertically"] == true
329
+ decrypted["halign"] == "left"
330
+ decrypted["valign"] == "top"
331
+
332
+ end
333
+
334
+ it "should allow thumbor to decrypt it properly with cropping" do
335
+ crypto = Thumbor::CryptoURL.new key
336
+
337
+ url = crypto.generate :width => 300, :height => 200, :image => image_url, :crop => [10, 20, 30, 40]
338
+
339
+ encrypted = url.split('/')[1]
340
+
341
+ decrypted = decrypt_in_thumbor(encrypted)
342
+
343
+ decrypted["horizontal_flip"].should == false
344
+ decrypted["vertical_flip"].should == false
345
+ decrypted["smart"].should == false
346
+ decrypted["meta"].should == false
347
+ decrypted["crop"]["left"].should == 10
348
+ decrypted["crop"]["top"].should == 20
349
+ decrypted["crop"]["right"].should == 30
350
+ decrypted["crop"]["bottom"].should == 40
351
+ decrypted["valign"].should == 'middle'
352
+ decrypted["halign"].should == 'center'
353
+ decrypted["image_hash"].should == image_md5
354
+ decrypted["width"].should == 300
355
+ decrypted["height"].should == 200
356
+
357
+ end
18
358
 
19
- url.should == '/qkLDiIbvtiks0Up9n5PACtmpOfX6dPXw4vP4kJU-jTfyF6y1GJBJyp7CHYh1H3R2/my.domain.com/some/image/url.jpg'
20
- end
21
-
22
359
  end
data/tasks/rspec.rake CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rspec/core/rake_task'
2
2
 
3
3
  RSpec::Core::RakeTask.new(:spec) do |t|
4
- t.rspec_opts = ['color']
4
+ t.rspec_opts = ['--color']
5
5
  t.rcov = false
6
6
  end
7
7
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-thumbor
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 3
8
9
  - 0
9
- - 2
10
- version: 0.0.2
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bernardo Heynemann
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-03 00:00:00 Z
18
+ date: 2011-04-03 00:00:00 -03:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: hoe
@@ -59,6 +60,7 @@ files:
59
60
  - spec/spec_helper.rb
60
61
  - tasks/rspec.rake
61
62
  - .gemtest
63
+ has_rdoc: true
62
64
  homepage: http://github.com/heynemann/ruby-thumbor
63
65
  licenses: []
64
66
 
@@ -89,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
91
  requirements: []
90
92
 
91
93
  rubyforge_project: ruby-thumbor
92
- rubygems_version: 1.7.1
94
+ rubygems_version: 1.6.2
93
95
  signing_key:
94
96
  specification_version: 3
95
97
  summary: ruby-thumbor is the client to the thumbor imaging service (http://github.com/globocom/thumbor).