thumbkit 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +0 -2
- data/lib/thumbkit/processor/collection.rb +84 -0
- data/lib/thumbkit/processor/text.rb +1 -0
- data/lib/thumbkit/processor.rb +1 -0
- data/lib/thumbkit/version.rb +1 -1
- data/lib/thumbkit.rb +10 -5
- data/spec/thumbkit/processor/collection_spec.rb +81 -0
- data/spec/thumbkit/processor/text_spec.rb +5 -0
- data/spec/thumbkit_spec.rb +7 -1
- metadata +4 -1
data/README.md
CHANGED
@@ -158,8 +158,6 @@ of the extension of the output file provided.
|
|
158
158
|
|
159
159
|
### Composite thumbnails
|
160
160
|
|
161
|
-
NOT YET IMPLEMENTED
|
162
|
-
|
163
161
|
```ruby
|
164
162
|
composite = Thumbkit.new(['path/to/audio.mp3', 'path/to/text_file.txt'])
|
165
163
|
composite.write_thumbnail('path/to/collection.png')
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Thumbkit::Processor::Collection < Thumbkit::Processor
|
2
|
+
|
3
|
+
alias_method :paths, :path
|
4
|
+
|
5
|
+
def determine_outfile
|
6
|
+
raise ArgumentError, 'Thumbkit: At output file must be provided for collections'
|
7
|
+
end
|
8
|
+
|
9
|
+
def write
|
10
|
+
sources = generate_each
|
11
|
+
command = build_montage_command(sources)
|
12
|
+
run(command)
|
13
|
+
|
14
|
+
command = build_resize_command(outfile)
|
15
|
+
run(command)
|
16
|
+
|
17
|
+
outfile
|
18
|
+
end
|
19
|
+
|
20
|
+
def collection
|
21
|
+
self.paths.map do |path|
|
22
|
+
Thumbkit.new(path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def generate_each
|
29
|
+
collection.map do |thumbkit|
|
30
|
+
outdir = File.dirname(outfile)
|
31
|
+
output_filename = File.basename(thumbkit.processor_instance.outfile)
|
32
|
+
|
33
|
+
thumbkit.write_thumbnail(File.join(outdir, output_filename), options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# montage arabic.png greek.png png_file.png -geometry '1x1<+0+0' collection.png; open collection.png
|
39
|
+
def build_montage_command(sources)
|
40
|
+
MiniMagick::CommandBuilder.new('montage').tap do |montage|
|
41
|
+
sources.each do |source|
|
42
|
+
montage << source
|
43
|
+
end
|
44
|
+
|
45
|
+
montage.geometry '1x1<+0+0'
|
46
|
+
|
47
|
+
montage.background options[:colors][:background]
|
48
|
+
montage.gravity(options[:gravity] || 'Center')
|
49
|
+
|
50
|
+
montage << outfile
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_resize_command(outfile)
|
55
|
+
MiniMagick::CommandBuilder.new('mogrify').tap do |resize|
|
56
|
+
resize.resize "#{ options[:width] }x#{ options[:height] }>"
|
57
|
+
resize.background options[:colors][:background]
|
58
|
+
resize.extent "#{ options[:width] }x#{ options[:height] }"
|
59
|
+
resize << outfile
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Mostly copied from MiniMagick
|
64
|
+
def run(command_builder)
|
65
|
+
command = command_builder.command
|
66
|
+
|
67
|
+
sub = Subexec.run(command, timeout: MiniMagick.timeout)
|
68
|
+
|
69
|
+
if sub.exitstatus != 0
|
70
|
+
|
71
|
+
# Raise the appropriate error
|
72
|
+
if sub.output =~ /no decode delegate/i || sub.output =~ /did not return an image/i
|
73
|
+
raise MiniMagick::Invalid, sub.output
|
74
|
+
else
|
75
|
+
# TODO: should we do something different if the command times out ...?
|
76
|
+
# its definitely better for logging.. otherwise we dont really know
|
77
|
+
raise MiniMagick::Error, "Command (#{command.inspect.gsub("\\", "")}) failed: #{{:status_code => sub.exitstatus, :output => sub.output}.inspect}"
|
78
|
+
end
|
79
|
+
else
|
80
|
+
sub.output
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -73,6 +73,7 @@ class Thumbkit::Processor::Text < Thumbkit::Processor
|
|
73
73
|
mogrify << '+repage'
|
74
74
|
# This extra gravity call prevents left-to-right text from rendering centered
|
75
75
|
mogrify.gravity 'NorthWest'
|
76
|
+
mogrify << '+strip'
|
76
77
|
mogrify.write outfile
|
77
78
|
mogrify << "label:@#{path}"
|
78
79
|
end
|
data/lib/thumbkit/processor.rb
CHANGED
data/lib/thumbkit/version.rb
CHANGED
data/lib/thumbkit.rb
CHANGED
@@ -5,8 +5,6 @@ class Thumbkit
|
|
5
5
|
autoload :Options, 'thumbkit/options'
|
6
6
|
autoload :Adapters, 'thumbkit/adapters'
|
7
7
|
|
8
|
-
attr_accessor :path, :filename, :type
|
9
|
-
|
10
8
|
def self.defaults
|
11
9
|
@defaults ||= Thumbkit::Options.new({
|
12
10
|
width: 200,
|
@@ -31,10 +29,17 @@ class Thumbkit
|
|
31
29
|
Thumbkit::Processor.processors
|
32
30
|
end
|
33
31
|
|
32
|
+
attr_accessor :path, :filename, :type
|
33
|
+
|
34
34
|
def initialize(path)
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
if Array === path
|
36
|
+
@processor = Thumbkit::Processor::Collection
|
37
|
+
@path = path.map { |p| File.expand_path(p) }
|
38
|
+
else
|
39
|
+
@path = File.expand_path(path)
|
40
|
+
@filename = File.basename(@path)
|
41
|
+
@type = File.extname(@filename)[1..-1]
|
42
|
+
end
|
38
43
|
end
|
39
44
|
|
40
45
|
def processor
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Thumbkit::Processor::Collection do
|
4
|
+
|
5
|
+
let(:fixtures) {
|
6
|
+
['png_file.png', 'text_file.txt', 'jpg_file.jpg', '16Hz-20kHz-Exp-1f-5sec.mp3']
|
7
|
+
}
|
8
|
+
let(:paths) { fixtures.map { |fixture| File.expand_path(path_to_fixture(fixture)) } }
|
9
|
+
let(:options) { {} }
|
10
|
+
let(:processor) { Thumbkit::Processor::Collection.new(paths, outfile, options) }
|
11
|
+
subject { processor }
|
12
|
+
|
13
|
+
describe '#determine_outfile' do
|
14
|
+
let(:outfile) { nil }
|
15
|
+
it 'raises an error' do
|
16
|
+
expect { processor.determine_outfile }.to raise_error(ArgumentError)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#collection' do
|
21
|
+
let(:outfile) { path_for_output('collection.png').to_s }
|
22
|
+
subject { processor.collection }
|
23
|
+
|
24
|
+
it 'returns an array of ThumbkitS' do
|
25
|
+
subject.should be_kind_of(Array)
|
26
|
+
subject.each { |e| e.should be_kind_of(Thumbkit) }
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'there are 4 of them' do
|
30
|
+
subject.size.should == 4
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'they haz the right paths' do
|
34
|
+
subject.map(&:path).should == paths
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#write' do
|
39
|
+
let(:outfile) { path_for_output('collection.png').to_s }
|
40
|
+
subject { processor.write }
|
41
|
+
|
42
|
+
it 'returns the path of the outfile' do
|
43
|
+
subject.should == outfile
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'writes a file' do
|
47
|
+
File.should exist(subject)
|
48
|
+
end
|
49
|
+
|
50
|
+
its_size_should_be('200x200')
|
51
|
+
its_mimetype_should_be('image/png')
|
52
|
+
|
53
|
+
context 'with only 3 sources' do
|
54
|
+
let(:outfile) { path_for_output('collection-3.png').to_s }
|
55
|
+
let(:fixtures) {
|
56
|
+
['png_file.png', 'text_file.txt', 'jpg_file.jpg']
|
57
|
+
}
|
58
|
+
|
59
|
+
it 'writes a file' do
|
60
|
+
File.should exist(subject)
|
61
|
+
end
|
62
|
+
|
63
|
+
its_size_should_be('200x200')
|
64
|
+
its_mimetype_should_be('image/png')
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with only 5 sources' do
|
68
|
+
let(:outfile) { path_for_output('collection-5.png').to_s }
|
69
|
+
let(:fixtures) {
|
70
|
+
['16Hz-20kHz-Exp-1f-5sec.mp3', 'arabic.txt', 'png_file.png', 'text_file.txt', 'jpg_file.jpg']
|
71
|
+
}
|
72
|
+
|
73
|
+
it 'writes a file' do
|
74
|
+
File.should exist(subject)
|
75
|
+
end
|
76
|
+
|
77
|
+
its_size_should_be('200x200')
|
78
|
+
its_mimetype_should_be('image/png')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -40,6 +40,11 @@ describe Thumbkit::Processor::Text do
|
|
40
40
|
File.should exist(subject)
|
41
41
|
end
|
42
42
|
|
43
|
+
it "doesn't have label in the metadata" do
|
44
|
+
result = `identify -verbose #{ subject }|grep label:`.chomp
|
45
|
+
result.should be_empty
|
46
|
+
end
|
47
|
+
|
43
48
|
its_size_should_be('200x200')
|
44
49
|
its_mimetype_should_be('image/png')
|
45
50
|
|
data/spec/thumbkit_spec.rb
CHANGED
@@ -18,8 +18,14 @@ describe Thumbkit do
|
|
18
18
|
its(:processor) { should == Thumbkit::Processor::Audio }
|
19
19
|
its(:type) { should == 'mp3' }
|
20
20
|
end
|
21
|
-
end
|
22
21
|
|
22
|
+
context 'with an array' do
|
23
|
+
let(:files) { [path_to_fixture('16Hz-20kHz-Exp-1f-5sec.mp3'), path_to_fixture('text_file.txt')] }
|
24
|
+
subject { Thumbkit.new files }
|
25
|
+
|
26
|
+
its(:processor) { should == Thumbkit::Processor::Collection }
|
27
|
+
end
|
28
|
+
end
|
23
29
|
|
24
30
|
describe Thumbkit, '.defaults' do
|
25
31
|
subject { Thumbkit.defaults }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thumbkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- lib/thumbkit/options.rb
|
31
31
|
- lib/thumbkit/processor.rb
|
32
32
|
- lib/thumbkit/processor/audio.rb
|
33
|
+
- lib/thumbkit/processor/collection.rb
|
33
34
|
- lib/thumbkit/processor/image.rb
|
34
35
|
- lib/thumbkit/processor/text.rb
|
35
36
|
- lib/thumbkit/version.rb
|
@@ -43,6 +44,7 @@ files:
|
|
43
44
|
- spec/spec_helper.rb
|
44
45
|
- spec/thumbkit/options_spec.rb
|
45
46
|
- spec/thumbkit/processor/audio_spec.rb
|
47
|
+
- spec/thumbkit/processor/collection_spec.rb
|
46
48
|
- spec/thumbkit/processor/image_spec.rb
|
47
49
|
- spec/thumbkit/processor/text_spec.rb
|
48
50
|
- spec/thumbkit/processor_spec.rb
|
@@ -83,6 +85,7 @@ test_files:
|
|
83
85
|
- spec/spec_helper.rb
|
84
86
|
- spec/thumbkit/options_spec.rb
|
85
87
|
- spec/thumbkit/processor/audio_spec.rb
|
88
|
+
- spec/thumbkit/processor/collection_spec.rb
|
86
89
|
- spec/thumbkit/processor/image_spec.rb
|
87
90
|
- spec/thumbkit/processor/text_spec.rb
|
88
91
|
- spec/thumbkit/processor_spec.rb
|