kanoko 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +2 -0
- data/lib/kanoko.rb +1 -0
- data/lib/kanoko/application/convert.rb +22 -46
- data/lib/kanoko/application/convert/argument_parser.rb +45 -0
- data/lib/kanoko/application/convert/function.rb +36 -23
- data/lib/kanoko/version.rb +1 -1
- data/logo.png +0 -0
- data/test/helper.rb +7 -0
- data/test/test_application_convert.rb +53 -17
- data/test/test_application_convert_argumentparser.rb +58 -0
- data/test/test_configure.rb +1 -2
- data/test/test_kanoko.rb +1 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 951798a023b45334f2180ac2a616bb1f66c90f7e
|
4
|
+
data.tar.gz: 5185345e9249e30edea76b5fad351b11fde1d48b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59c18db72d747e198ee233e93d54a728283c2057ad36895b8cb51dbd16cb35e30d875842e37e877413a56fe0f93f5ee160b9de2775ea9277dfcae24710f4d861
|
7
|
+
data.tar.gz: db41f1f05a3ff41c872ca1d9ede236486cbff8ec0b5805f89b67ce0fea9cb7b0e73c152d4178dd4c9fa6f4ca80050f2a914b7fa4073fbcc2c179518ec4430b4f
|
data/README.md
CHANGED
@@ -3,6 +3,8 @@ kanoko
|
|
3
3
|
|
4
4
|
[](https://travis-ci.org/spice-life/kanoko)
|
5
5
|
|
6
|
+

|
7
|
+
|
6
8
|
**kanoko** is an active image generate application.
|
7
9
|
|
8
10
|
# Quick Start
|
data/lib/kanoko.rb
CHANGED
@@ -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
|
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
|
-
|
44
|
-
|
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(*(
|
49
|
-
logger.error "hash check failed #{[*(
|
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
|
-
|
101
|
-
|
102
|
-
|
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/
|
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
|
-
|
6
|
-
|
7
|
-
|
16
|
+
class << self
|
17
|
+
def list
|
18
|
+
instance_methods(false)
|
19
|
+
end
|
20
|
+
end
|
8
21
|
|
9
|
-
def
|
10
|
-
|
22
|
+
def crop(arg)
|
23
|
+
[
|
24
|
+
'-crop', arg
|
25
|
+
]
|
11
26
|
end
|
12
27
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
28
|
+
def fill(arg)
|
29
|
+
[
|
30
|
+
'-gravity', 'north',
|
31
|
+
'-extent', arg,
|
32
|
+
'-background', 'transparent',
|
33
|
+
]
|
19
34
|
end
|
20
35
|
|
21
|
-
|
36
|
+
def resize(arg)
|
37
|
+
[
|
38
|
+
'-define', "jpeg:size=#{arg}",
|
39
|
+
'-thumbnail', arg,
|
40
|
+
]
|
41
|
+
end
|
22
42
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
data/lib/kanoko/version.rb
CHANGED
data/logo.png
ADDED
Binary file
|
data/test/helper.rb
ADDED
@@ -1,9 +1,4 @@
|
|
1
|
-
require '
|
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
|
-
|
39
|
-
get
|
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
|
-
|
47
|
-
get
|
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
|
54
|
-
|
55
|
-
|
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
|
-
|
58
|
-
|
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
|
-
|
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
|
data/test/test_configure.rb
CHANGED
data/test/test_kanoko.rb
CHANGED
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.
|
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
|
+
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
|