kanoko 0.0.4 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 174aaa5dc844a02ce0fe1bc7d99aabddffbc8db5
4
- data.tar.gz: b78fe145753b4104900984eccc76d7259da3922e
3
+ metadata.gz: c507e252c2624f4482ad7e29ac990c0a698300f5
4
+ data.tar.gz: 416bc6b1987141e93dcb646e83e571434e6bea71
5
5
  SHA512:
6
- metadata.gz: 3d980fb390493a82e79718a41054486272b9e0390bf6a963e877c4fbe92aada2fd197d3f74045cd80d5a6352383f94109db67d328c53a8f15f49ffdc5dbbbdc8
7
- data.tar.gz: ae4bc45b643ae3f19233377b242c497bfa7bd27366f2fcb2ecf3b4319809a20ff24aa21605336271404b2f1b399ef1bfb468a0748258e9b5b720ac4b2800489d
6
+ metadata.gz: fc89740eacc7b58c509b2cf8d84405945eb1fb1e3e2dc1eb6cd5a158c5f7f43d7b4719ab1d20de31cb231feb7c18a842f360fc6dad40159fa67c0c7215f92e18
7
+ data.tar.gz: 0f05b0052f0784639d6a42564bf04ee06b709860cbf6ace572fff11cb145cffaedd692b3eeca3c4096d1ca8a5d013454dec952b1db9a6c11c9a54c53b814dfcf
data/kanoko.gemspec CHANGED
@@ -21,4 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency "rack-test"
25
+ spec.add_development_dependency "exifr"
24
26
  end
data/lib/kanoko.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'uri'
2
2
  require 'kanoko/configure'
3
+ require 'kanoko/errors'
4
+ require 'kanoko/version'
3
5
 
4
6
  module Kanoko
5
7
  # example:
@@ -19,9 +21,9 @@ module Kanoko
19
21
  @configure = value
20
22
  end
21
23
 
22
- def path_for(func, args, src)
23
- hash = make_hash(func, args, src)
24
- "/#{hash}/#{[func, args].map{|i| URI.encode_www_form_component(i)}.join('/')}/#{src}"
24
+ def path_for(*function, src)
25
+ hash = make_hash(*function, src)
26
+ "/#{hash}/#{function.map{ |i| URI.encode_www_form_component(i) }.join('/')}/#{src}"
25
27
  end
26
28
  module_function :path_for
27
29
 
@@ -31,14 +31,22 @@ require 'kanoko'
31
31
  module Kanoko
32
32
  module Application
33
33
  class Convert < Sinatra::Application
34
- get '/:hash/:func/:args/*' do
34
+ # /123abc456def=/resize/200x200/crop/100x100/path/to/src
35
+ get '/:hash/*' do
36
+ request_uri = URI.parse env["REQUEST_URI"]
35
37
  hash = params[:hash]
36
- func = params[:func]
37
- args = params[:args]
38
- src_path = env["REQUEST_URI"].sub(%r{/.*?/.*?/.*?/(.*)}, '\1')
38
+ unless params[:splat]
39
+ logger.error "invalid url #{request_uri}"
40
+ return 400
41
+ end
42
+ splat = params[:splat][0]
43
+ function = Function.new splat
44
+ hint_src = splat[function.to_path.length..-1]
45
+ hint_index = request_uri.to_s.index(hint_src)
46
+ src_path = request_uri.to_s[hint_index..-1]
39
47
 
40
- unless hash == Kanoko.make_hash(func, args, src_path)
41
- logger.error "hash check failed #{[func, args, src_path]}"
48
+ unless hash == Kanoko.make_hash(*(function.to_a.flatten), src_path)
49
+ logger.error "hash check failed #{[*(function.to_a.flatten), src_path]}"
42
50
  return 400
43
51
  end
44
52
 
@@ -51,36 +59,59 @@ module Kanoko
51
59
  Tempfile.open("src") do |src_file|
52
60
  src_file.write res.body
53
61
  src_file.fdatasync
62
+
54
63
  Tempfile.open("dst") do |dst_file|
55
64
  default_env = {"OMP_NUM_THREADS" => "1"}
56
- result = case func.to_sym
57
-
58
- when :crop
59
- system(default_env,
60
- 'convert',
61
- '-thumbnail', "#{args}^",
62
- '-gravity', 'north',
63
- '-extent', args,
64
- '-background', 'transparent',
65
- '-depth', '8',
66
- src_file.path, dst_file.path)
67
-
68
- when :resize
69
- system(default_env,
70
- 'convert',
71
- '-thumbnail', args,
72
- '-depth', '8',
73
- src_file.path, dst_file.path)
74
-
75
- else
76
- logger.error "undefined func #{func}"
77
- return 400
65
+ command = 'convert'
66
+ default_options = [
67
+ '-depth', '8'
68
+ ]
69
+ options = []
70
+
71
+ function.each do |name, arg|
72
+ func_options = case name.to_sym
73
+ when :crop
74
+ [
75
+ '-crop', arg
76
+ ]
77
+
78
+ when :fill
79
+ [
80
+ '-gravity', 'north',
81
+ '-extent', arg,
82
+ '-background', 'transparent',
83
+ ]
84
+
85
+ when :resize
86
+ [
87
+ '-define', "jpeg:size=#{arg}",
88
+ '-thumbnail', arg,
89
+ ]
90
+
91
+ else
92
+ logger.error "undefined func #{name}"
93
+ return 400
94
+ end
95
+
96
+ options.concat func_options
78
97
  end
79
98
 
99
+ system_command = [
100
+ default_env,
101
+ command,
102
+ default_options,
103
+ options,
104
+ src_file.path,
105
+ dst_file.path
106
+ ].flatten
107
+
108
+ result = system *system_command
109
+
80
110
  unless result
81
111
  logger.error "command fail $?=#{$?.inspect}"
82
112
  return 500
83
113
  end
114
+
84
115
  dst_file.read
85
116
  end
86
117
  end
@@ -113,9 +144,16 @@ module Kanoko
113
144
 
114
145
  def after_response(res)
115
146
  res.each do |key, value|
116
- headers[key] ||= value
147
+ case key.downcase
148
+ when "status"
149
+ next
150
+ else
151
+ headers[key] ||= value
152
+ end
117
153
  end
118
154
  end
119
155
  end
120
156
  end
121
157
  end
158
+
159
+ require 'kanoko/application/convert/function'
@@ -0,0 +1,38 @@
1
+ module Kanoko
2
+ module Application
3
+ class Convert
4
+ class Function
5
+ include Enumerable
6
+ extend Forwardable
7
+ def_delegators :@args, :each, :to_a, :to_h
8
+
9
+ def initialize(args)
10
+ @args = parse args
11
+ end
12
+
13
+ def to_path
14
+ paths = []
15
+ @args.each do |func, arg|
16
+ paths << "/#{func}/#{arg}"
17
+ end
18
+ paths.join
19
+ end
20
+
21
+ private
22
+
23
+ def parse(args)
24
+ hash = {}
25
+ items = args.split('/')
26
+ items.each_slice(2) do |funcname, arg|
27
+ if funcname.match(/\./)
28
+ break
29
+ else
30
+ hash[funcname.to_sym] = arg.to_s
31
+ end
32
+ end
33
+ hash
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Kanoko
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
data/test/resize.jpg ADDED
Binary file
Binary file
data/test/src.jpg ADDED
Binary file
@@ -0,0 +1,63 @@
1
+ require 'digest/sha1'
2
+ require 'stringio'
3
+ require 'minitest/autorun'
4
+ require "rack/test"
5
+ require "exifr"
6
+ require "kanoko/application/convert"
7
+
8
+ class TestKanokoApplicationConvert < Minitest::Test
9
+ include Rack::Test::Methods
10
+
11
+ class TestApp < Kanoko::Application::Convert
12
+ class ResponseMock < Struct.new(:body)
13
+ end
14
+ def http_get(uri)
15
+ ResponseMock.new(File.read "test/src.jpg")
16
+ end
17
+ def after_response(res)
18
+ end
19
+ end
20
+
21
+ def app
22
+ TestApp.new
23
+ end
24
+
25
+ def setup
26
+ ENV['RACK_ENV'] = 'test'
27
+ Kanoko.configure.digest_func = "sha1"
28
+ Kanoko.configure.secret_key = "test"
29
+ end
30
+
31
+ def assert_jpeg(expected, actual)
32
+ expected_exif = EXIFR::JPEG.new(StringIO.new(expected))
33
+ actual_exif = EXIFR::JPEG.new(StringIO.new(actual))
34
+ assert_equal expected_exif.to_hash, actual_exif.to_hash
35
+ end
36
+
37
+ def test_resize
38
+ url = Kanoko.path_for(:resize, "10x10", "src.jpg")
39
+ get url, {}, {"REQUEST_URI" => url}
40
+ assert last_response.ok?
41
+ assert 0 < last_response.body.length
42
+ assert_jpeg File.read("test/resize.jpg"), last_response.body
43
+ end
44
+
45
+ def test_resize_and_crop
46
+ url = Kanoko.path_for(:resize, "10x10", :crop, "5x5+1+1", "src.jpg")
47
+ get url, {}, {"REQUEST_URI" => url}
48
+ assert last_response.ok?
49
+ assert 0 < last_response.body.length
50
+ assert_jpeg File.read("test/resize_and_crop.jpg"), last_response.body
51
+ end
52
+
53
+ def test_not_found
54
+ get "/nothing"
55
+ assert_equal 404, last_response.status
56
+
57
+ post "/nothing"
58
+ assert_equal 404, last_response.status
59
+
60
+ delete "/nothing"
61
+ assert_equal 404, last_response.status
62
+ end
63
+ end
data/test/test_kanoko.rb CHANGED
@@ -26,8 +26,14 @@ class TestKanoko < Minitest::Test
26
26
 
27
27
  def test_path_for_with_default_hash_proc
28
28
  change_hash_proc(proc{ "aaa" }) do
29
- assert_equal "/aaa/test_func/test_args/test_path", Kanoko.path_for(:test_func, "test_args", "test_path")
30
- assert_equal "/aaa/test_func/%2F%3F-_%3D%21%40%23%3C%3E%5C//?-_=!@#<>\\", Kanoko.path_for(:test_func, "/?-_=!@#<>\\", "/?-_=!@#<>\\")
29
+ path = Kanoko.path_for(:test_func, "test_args", "test_path")
30
+ assert_equal "/aaa/test_func/test_args/test_path", path
31
+
32
+ path = Kanoko.path_for(:test_func, "/?-_=!@#<>\\", "/?-_=!@#<>\\")
33
+ assert_equal "/aaa/test_func/%2F%3F-_%3D%21%40%23%3C%3E%5C//?-_=!@#<>\\", path
34
+
35
+ path = Kanoko.path_for(:test_func, "test_args", :test_func2, "test_args2", "test_path")
36
+ assert_equal "/aaa/test_func/test_args/test_func2/test_args2/test_path", path
31
37
  end
32
38
  end
33
39
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kanoko
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-11 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: exifr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description: kanoko is a active image generater library.
70
98
  email:
71
99
  - co000ri@gmail.com
@@ -82,9 +110,14 @@ files:
82
110
  - kanoko.gemspec
83
111
  - lib/kanoko.rb
84
112
  - lib/kanoko/application/convert.rb
113
+ - lib/kanoko/application/convert/function.rb
85
114
  - lib/kanoko/configure.rb
86
115
  - lib/kanoko/errors.rb
87
116
  - lib/kanoko/version.rb
117
+ - test/resize.jpg
118
+ - test/resize_and_crop.jpg
119
+ - test/src.jpg
120
+ - test/test_application_convert.rb
88
121
  - test/test_configure.rb
89
122
  - test/test_kanoko.rb
90
123
  homepage: https://github.com/spice-life/kanoko
@@ -112,5 +145,9 @@ signing_key:
112
145
  specification_version: 4
113
146
  summary: kanoko is a active image generater library.
114
147
  test_files:
148
+ - test/resize.jpg
149
+ - test/resize_and_crop.jpg
150
+ - test/src.jpg
151
+ - test/test_application_convert.rb
115
152
  - test/test_configure.rb
116
153
  - test/test_kanoko.rb