kanoko 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c507e252c2624f4482ad7e29ac990c0a698300f5
4
- data.tar.gz: 416bc6b1987141e93dcb646e83e571434e6bea71
3
+ metadata.gz: 951798a023b45334f2180ac2a616bb1f66c90f7e
4
+ data.tar.gz: 5185345e9249e30edea76b5fad351b11fde1d48b
5
5
  SHA512:
6
- metadata.gz: fc89740eacc7b58c509b2cf8d84405945eb1fb1e3e2dc1eb6cd5a158c5f7f43d7b4719ab1d20de31cb231feb7c18a842f360fc6dad40159fa67c0c7215f92e18
7
- data.tar.gz: 0f05b0052f0784639d6a42564bf04ee06b709860cbf6ace572fff11cb145cffaedd692b3eeca3c4096d1ca8a5d013454dec952b1db9a6c11c9a54c53b814dfcf
6
+ metadata.gz: 59c18db72d747e198ee233e93d54a728283c2057ad36895b8cb51dbd16cb35e30d875842e37e877413a56fe0f93f5ee160b9de2775ea9277dfcae24710f4d861
7
+ data.tar.gz: db41f1f05a3ff41c872ca1d9ede236486cbff8ec0b5805f89b67ce0fea9cb7b0e73c152d4178dd4c9fa6f4ca80050f2a914b7fa4073fbcc2c179518ec4430b4f
data/README.md CHANGED
@@ -3,6 +3,8 @@ kanoko
3
3
 
4
4
  [![Build Status](https://travis-ci.org/spice-life/kanoko.svg?branch=master)](https://travis-ci.org/spice-life/kanoko)
5
5
 
6
+ ![logo](https://raw.githubusercontent.com/spice-life/kanoko/master/logo.png)
7
+
6
8
  **kanoko** is an active image generate application.
7
9
 
8
10
  # Quick Start
@@ -20,6 +20,7 @@ module Kanoko
20
20
  def configure=(value)
21
21
  @configure = value
22
22
  end
23
+ module_function :configure=
23
24
 
24
25
  def path_for(*function, src)
25
26
  hash = make_hash(*function, src)
@@ -31,22 +31,30 @@ require 'kanoko'
31
31
  module Kanoko
32
32
  module Application
33
33
  class Convert < Sinatra::Application
34
+
34
35
  # /123abc456def=/resize/200x200/crop/100x100/path/to/src
35
36
  get '/:hash/*' do
36
- request_uri = URI.parse env["REQUEST_URI"]
37
+ request_uri = URI.parse(env["REQUEST_URI"] || "/#{params[:captures].join('/')}")
37
38
  hash = params[:hash]
38
39
  unless params[:splat]
39
40
  logger.error "invalid url #{request_uri}"
40
41
  return 400
41
42
  end
43
+
42
44
  splat = params[:splat][0]
43
- function = Function.new splat
44
- hint_src = splat[function.to_path.length..-1]
45
+ argument = ArgumentParser.new splat
46
+
47
+ hint_src = splat[argument.path.length..-1]
48
+ unless hint_src
49
+ logger.error "invalid url #{request_uri}"
50
+ return 400
51
+ end
52
+
45
53
  hint_index = request_uri.to_s.index(hint_src)
46
54
  src_path = request_uri.to_s[hint_index..-1]
47
55
 
48
- unless hash == Kanoko.make_hash(*(function.to_a.flatten), src_path)
49
- logger.error "hash check failed #{[*(function.to_a.flatten), src_path]}"
56
+ unless hash == Kanoko.make_hash(*(argument.to_a.flatten), src_path)
57
+ logger.error "hash check failed #{[*(argument.to_a.flatten), src_path]}"
50
58
  return 400
51
59
  end
52
60
 
@@ -61,50 +69,14 @@ module Kanoko
61
69
  src_file.fdatasync
62
70
 
63
71
  Tempfile.open("dst") do |dst_file|
64
- default_env = {"OMP_NUM_THREADS" => "1"}
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
97
- end
98
-
99
72
  system_command = [
100
- default_env,
101
- command,
102
- default_options,
103
- options,
73
+ {"OMP_NUM_THREADS" => "1"},
74
+ 'convert',
75
+ '-depth', '8',
76
+ argument.options,
104
77
  src_file.path,
105
78
  dst_file.path
106
79
  ].flatten
107
-
108
80
  result = system *system_command
109
81
 
110
82
  unless result
@@ -152,8 +124,12 @@ module Kanoko
152
124
  end
153
125
  end
154
126
  end
127
+
128
+ error 404 do
129
+ ""
130
+ end
155
131
  end
156
132
  end
157
133
  end
158
134
 
159
- require 'kanoko/application/convert/function'
135
+ require 'kanoko/application/convert/argument_parser'
@@ -0,0 +1,45 @@
1
+ require 'kanoko/application/convert/function'
2
+
3
+ module Kanoko
4
+ module Application
5
+ class Convert
6
+ class ArgumentParser
7
+ include Enumerable
8
+ extend Forwardable
9
+ def_delegators :@args, :each, :to_a
10
+
11
+ attr_reader :options
12
+
13
+ def initialize(args)
14
+ @args, @options = ArgumentParser.parse args
15
+ end
16
+
17
+ def to_path
18
+ map { |i| "/#{i.join('/')}" }.join
19
+ end
20
+ alias path to_path
21
+
22
+ private
23
+
24
+ class << self
25
+ def parse(path)
26
+ args = []
27
+ options = []
28
+ items = path.split('/')
29
+ while item = items.shift
30
+ id = item.to_sym
31
+ if Function.list.include?(id)
32
+ function = Function.new
33
+ method = function.method(id)
34
+ arg = items.shift(method.arity)
35
+ options.concat method.call(*arg)
36
+ args.push [id, *arg]
37
+ end
38
+ end
39
+ [args, options]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,36 +1,49 @@
1
1
  module Kanoko
2
2
  module Application
3
3
  class Convert
4
+ # You can make customize function.
5
+ # It just make or overwhrite instance method.
6
+ # example:
7
+ # class Kanoko::Application::Convert::Function
8
+ # # get "/new_func/new_value"
9
+ # # => add imagemagick option
10
+ # # -new-option new_value
11
+ # def new_func(arg)
12
+ # ['-new-option', arg]
13
+ # end
14
+ # end
4
15
  class Function
5
- include Enumerable
6
- extend Forwardable
7
- def_delegators :@args, :each, :to_a, :to_h
16
+ class << self
17
+ def list
18
+ instance_methods(false)
19
+ end
20
+ end
8
21
 
9
- def initialize(args)
10
- @args = parse args
22
+ def crop(arg)
23
+ [
24
+ '-crop', arg
25
+ ]
11
26
  end
12
27
 
13
- def to_path
14
- paths = []
15
- @args.each do |func, arg|
16
- paths << "/#{func}/#{arg}"
17
- end
18
- paths.join
28
+ def fill(arg)
29
+ [
30
+ '-gravity', 'north',
31
+ '-extent', arg,
32
+ '-background', 'transparent',
33
+ ]
19
34
  end
20
35
 
21
- private
36
+ def resize(arg)
37
+ [
38
+ '-define', "jpeg:size=#{arg}",
39
+ '-thumbnail', arg,
40
+ ]
41
+ end
22
42
 
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
43
+ def auto_orient
44
+ [
45
+ '-auto-orient'
46
+ ]
34
47
  end
35
48
  end
36
49
  end
@@ -1,3 +1,3 @@
1
1
  module Kanoko
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
Binary file
@@ -0,0 +1,7 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'minitest/autorun'
4
+ require 'stringio'
5
+ require "rack/test"
6
+ require "exifr"
7
+ require "kanoko/application/convert"
@@ -1,9 +1,4 @@
1
- require 'digest/sha1'
2
- require 'stringio'
3
- require 'minitest/autorun'
4
- require "rack/test"
5
- require "exifr"
6
- require "kanoko/application/convert"
1
+ require 'helper'
7
2
 
8
3
  class TestKanokoApplicationConvert < Minitest::Test
9
4
  include Rack::Test::Methods
@@ -23,7 +18,6 @@ class TestKanokoApplicationConvert < Minitest::Test
23
18
  end
24
19
 
25
20
  def setup
26
- ENV['RACK_ENV'] = 'test'
27
21
  Kanoko.configure.digest_func = "sha1"
28
22
  Kanoko.configure.secret_key = "test"
29
23
  end
@@ -35,29 +29,71 @@ class TestKanokoApplicationConvert < Minitest::Test
35
29
  end
36
30
 
37
31
  def test_resize
38
- url = Kanoko.path_for(:resize, "10x10", "src.jpg")
39
- get url, {}, {"REQUEST_URI" => url}
32
+ path = Kanoko.path_for(:resize, "10x10", "src.jpg")
33
+ get path
40
34
  assert last_response.ok?
41
35
  assert 0 < last_response.body.length
42
36
  assert_jpeg File.read("test/resize.jpg"), last_response.body
43
37
  end
44
38
 
45
39
  def test_resize_and_crop
46
- url = Kanoko.path_for(:resize, "10x10", :crop, "5x5+1+1", "src.jpg")
47
- get url, {}, {"REQUEST_URI" => url}
40
+ path = Kanoko.path_for(:resize, "10x10", :crop, "5x5+1+1", "src.jpg")
41
+ get path
48
42
  assert last_response.ok?
49
43
  assert 0 < last_response.body.length
50
44
  assert_jpeg File.read("test/resize_and_crop.jpg"), last_response.body
51
45
  end
52
46
 
53
- def test_not_found
54
- get "/nothing"
55
- assert_equal 404, last_response.status
47
+ def test_auto_orient
48
+ path = Kanoko.path_for(:auto_orient, "src.jpg")
49
+ get path
50
+ assert last_response.ok?
51
+ assert 0 < last_response.body.length
52
+ assert_jpeg File.read("test/src.jpg"), last_response.body
53
+ end
56
54
 
57
- post "/nothing"
58
- assert_equal 404, last_response.status
55
+ def test_resize_and_auto_orient
56
+ path = Kanoko.path_for(:resize, "10x10", :auto_orient, "src.jpg")
57
+ get path
58
+ assert last_response.ok?
59
+ assert 0 < last_response.body.length
60
+ assert_jpeg File.read("test/resize.jpg"), last_response.body
61
+ end
59
62
 
60
- delete "/nothing"
63
+ def test_undefined_func
64
+ path = Kanoko.path_for(:undefined, "10x10", "src.jpg")
65
+ get path
66
+ assert_equal 400, last_response.status
67
+ assert_equal "", last_response.body
68
+ end
69
+
70
+ def test_root_not_found
71
+ path = "/"
72
+ get path
61
73
  assert_equal 404, last_response.status
74
+ assert_equal "", last_response.body
75
+ end
76
+
77
+ def test_invalid_path
78
+ path = "/invalid/path/to/src"
79
+ get path
80
+ assert_equal 400, last_response.status
81
+ assert_equal "", last_response.body
82
+ end
83
+
84
+ class Kanoko::Application::Convert::Function
85
+ def method_for_500
86
+ ['-undefined-imagemagick-option']
87
+ end
88
+ end
89
+
90
+ def test_500
91
+ path = Kanoko.path_for(:method_for_500, "src.jpg")
92
+ out, err = capture_subprocess_io do
93
+ get path
94
+ end
95
+ assert_equal 500, last_response.status
96
+ assert_equal "", last_response.body
97
+ assert_match /convert: unrecognized option `-undefined-imagemagick-option'/, err
62
98
  end
63
99
  end
@@ -0,0 +1,58 @@
1
+ require 'helper'
2
+
3
+ class TestKanokoApplicationConvertArgumentParser < Minitest::Test
4
+ include Kanoko::Application
5
+ class Kanoko::Application::Convert::Function
6
+ def empty_option
7
+ []
8
+ end
9
+ def one_option
10
+ ['func1']
11
+ end
12
+ def one_arg_and_one_option(arg)
13
+ ['func2', arg]
14
+ end
15
+ end
16
+
17
+ def test_empty
18
+ a = Convert::ArgumentParser.new("")
19
+ assert_equal [], a.to_a
20
+ assert_equal [], a.options
21
+ assert_equal "", a.path
22
+ end
23
+
24
+ def test_empty_option
25
+ a = Convert::ArgumentParser.new("empty_option/10x10")
26
+ assert_equal [[:empty_option]], a.to_a
27
+ assert_equal [], a.options
28
+ assert_equal "/empty_option", a.path
29
+ end
30
+
31
+ def test_one_option
32
+ a = Convert::ArgumentParser.new("one_option/10x10")
33
+ assert_equal [[:one_option]], a.to_a
34
+ assert_equal "/one_option", a.path
35
+ assert_equal ['func1'], a.options
36
+ end
37
+
38
+ def test_one_arg_and_one_option
39
+ a = Convert::ArgumentParser.new("one_arg_and_one_option/10x10")
40
+ assert_equal [[:one_arg_and_one_option, '10x10']], a.to_a
41
+ assert_equal "/one_arg_and_one_option/10x10", a.path
42
+ assert_equal ['func2', '10x10'], a.options
43
+ end
44
+
45
+ def test_one_option_and_one_arg_and_one_option
46
+ a = Convert::ArgumentParser.new("one_option/one_arg_and_one_option/10x10")
47
+ assert_equal [[:one_option], [:one_arg_and_one_option, '10x10']], a.to_a
48
+ assert_equal "/one_option/one_arg_and_one_option/10x10", a.path
49
+ assert_equal ['func1', 'func2', '10x10'], a.options
50
+ end
51
+
52
+ def test_nothing
53
+ a = Convert::ArgumentParser.new("nothing/10x10")
54
+ assert_equal [], a.to_a
55
+ assert_equal "", a.path
56
+ assert_equal [], a.options
57
+ end
58
+ end
@@ -1,5 +1,4 @@
1
- require 'minitest/autorun'
2
- require 'kanoko/configure'
1
+ require 'helper'
3
2
 
4
3
  class TestKanokoConfigure < Minitest::Test
5
4
  def setup
@@ -1,5 +1,4 @@
1
- require 'minitest/autorun'
2
- require 'kanoko'
1
+ require 'helper'
3
2
 
4
3
  class TestKanoko < Minitest::Test
5
4
  def setup
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.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-11 00:00:00.000000000 Z
11
+ date: 2015-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -110,14 +110,18 @@ files:
110
110
  - kanoko.gemspec
111
111
  - lib/kanoko.rb
112
112
  - lib/kanoko/application/convert.rb
113
+ - lib/kanoko/application/convert/argument_parser.rb
113
114
  - lib/kanoko/application/convert/function.rb
114
115
  - lib/kanoko/configure.rb
115
116
  - lib/kanoko/errors.rb
116
117
  - lib/kanoko/version.rb
118
+ - logo.png
119
+ - test/helper.rb
117
120
  - test/resize.jpg
118
121
  - test/resize_and_crop.jpg
119
122
  - test/src.jpg
120
123
  - test/test_application_convert.rb
124
+ - test/test_application_convert_argumentparser.rb
121
125
  - test/test_configure.rb
122
126
  - test/test_kanoko.rb
123
127
  homepage: https://github.com/spice-life/kanoko
@@ -145,9 +149,11 @@ signing_key:
145
149
  specification_version: 4
146
150
  summary: kanoko is a active image generater library.
147
151
  test_files:
152
+ - test/helper.rb
148
153
  - test/resize.jpg
149
154
  - test/resize_and_crop.jpg
150
155
  - test/src.jpg
151
156
  - test/test_application_convert.rb
157
+ - test/test_application_convert_argumentparser.rb
152
158
  - test/test_configure.rb
153
159
  - test/test_kanoko.rb