ungulate 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/bin/ungulate_server.rb +19 -0
- data/features/camels.jpg +0 -0
- data/features/cope_with_empty_queue.feature +10 -0
- data/features/image_resize.feature +30 -0
- data/features/step_definitions/command_steps.rb +10 -0
- data/features/step_definitions/queue_steps.rb +32 -0
- data/features/step_definitions/version_steps.rb +9 -0
- data/features/support.rb +2 -0
- data/lib/ungulate.rb +85 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/ungulate_spec.rb +248 -0
- data/ungulate.gemspec +74 -0
- metadata +137 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Camel Punch Limited
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= Ungulate
|
2
|
+
|
3
|
+
According to Wikipedia, this can mean "hoofed animal". Camels have hooves.
|
4
|
+
|
5
|
+
This is a simple queue runner that expects a YAML-encoded job description for RMagick. Documentation: read the code, for now.
|
6
|
+
|
7
|
+
== Note on Patches/Pull Requests
|
8
|
+
|
9
|
+
* Fork the project.
|
10
|
+
* Make your feature addition or bug fix.
|
11
|
+
* Add tests for it. This is important so I don't break it in a
|
12
|
+
future version unintentionally.
|
13
|
+
* Commit, do not mess with rakefile, version, or history.
|
14
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
15
|
+
* Send me a pull request. Bonus points for topic branches.
|
16
|
+
|
17
|
+
== Copyright
|
18
|
+
|
19
|
+
Copyright (c) 2010 Camel Punch Limited. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "ungulate"
|
8
|
+
gem.summary = %Q{Process images using Amazon SQS and S3}
|
9
|
+
gem.description = %Q{WIP}
|
10
|
+
gem.email = "andrew@camelpunch.com"
|
11
|
+
gem.homepage = "http://github.com/camelpunch/ungulate"
|
12
|
+
gem.authors = ["Andrew Bruce"]
|
13
|
+
gem.add_dependency "right_aws", ">= 1.10.0"
|
14
|
+
gem.add_dependency "rmagick", ">= 2.12.2"
|
15
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
16
|
+
gem.add_development_dependency "cucumber", ">= 0.6.2"
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'spec/rake/spectask'
|
25
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
28
|
+
end
|
29
|
+
|
30
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
31
|
+
spec.libs << 'lib' << 'spec'
|
32
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
+
spec.rcov = true
|
34
|
+
end
|
35
|
+
|
36
|
+
task :spec => :check_dependencies
|
37
|
+
|
38
|
+
task :default => :spec
|
39
|
+
|
40
|
+
require 'rake/rdoctask'
|
41
|
+
Rake::RDocTask.new do |rdoc|
|
42
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "ungulate #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ungulate'
|
4
|
+
|
5
|
+
if ARGV[0].nil?
|
6
|
+
$stderr.puts "Must provide a queue name after calling the server"
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
logger = Logger.new STDERR
|
11
|
+
|
12
|
+
loop do
|
13
|
+
begin
|
14
|
+
sleep 1
|
15
|
+
Ungulate.run(ARGV[0])
|
16
|
+
rescue StandardError => e
|
17
|
+
logger.error e.message
|
18
|
+
end
|
19
|
+
end
|
data/features/camels.jpg
ADDED
Binary file
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Feature: Image resize
|
2
|
+
As a developer
|
3
|
+
I want Ungulate to resize images
|
4
|
+
So that I don't have to do it in my application
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given an empty queue
|
8
|
+
|
9
|
+
Scenario: Run queue on image key with no path separator
|
10
|
+
Given a request to resize "image.jpg" to sizes:
|
11
|
+
| label | width | height |
|
12
|
+
| large | 200 | 100 |
|
13
|
+
| small | 100 | 50 |
|
14
|
+
When I run Ungulate
|
15
|
+
Then there should be the following public versions:
|
16
|
+
| key |
|
17
|
+
| image_large.jpg |
|
18
|
+
| image_small.jpg |
|
19
|
+
|
20
|
+
Scenario: Run queue on image key with path separator
|
21
|
+
Given a request to resize "some/path/to/image.jpg" to sizes:
|
22
|
+
| label | width | height |
|
23
|
+
| large | 200 | 100 |
|
24
|
+
| small | 100 | 50 |
|
25
|
+
When I run Ungulate
|
26
|
+
Then there should be the following public versions:
|
27
|
+
| key |
|
28
|
+
| some/path/to/image_large.jpg |
|
29
|
+
| some/path/to/image_small.jpg |
|
30
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Given /^an empty queue$/ do
|
2
|
+
sqs = RightAws::SqsGen2.new(ENV['AMAZON_ACCESS_KEY_ID'],
|
3
|
+
ENV['AMAZON_SECRET_ACCESS_KEY'])
|
4
|
+
@queue_name = 'ungulate-test-queue'
|
5
|
+
@q = sqs.queue @queue_name
|
6
|
+
@q.clear
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^a request to resize "([^\"]*)" to sizes:$/ do |key, table|
|
10
|
+
@bucket_name = "ungulate-test"
|
11
|
+
|
12
|
+
@s3 = RightAws::S3.new(ENV['AMAZON_ACCESS_KEY_ID'],
|
13
|
+
ENV['AMAZON_SECRET_ACCESS_KEY'])
|
14
|
+
@bucket = @s3.bucket @bucket_name
|
15
|
+
@bucket.put key, File.open('features/camels.jpg').read
|
16
|
+
|
17
|
+
|
18
|
+
versions = table.rows.inject({}) do |hash, row|
|
19
|
+
label, width, height = row
|
20
|
+
hash[label] = [:resize_to_fit, width, height]
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
|
24
|
+
message = {
|
25
|
+
:bucket => @bucket_name,
|
26
|
+
:key => key,
|
27
|
+
:versions => versions
|
28
|
+
}.to_yaml
|
29
|
+
|
30
|
+
@q.send_message(message)
|
31
|
+
end
|
32
|
+
|
data/features/support.rb
ADDED
data/lib/ungulate.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'right_aws'
|
3
|
+
require 'RMagick'
|
4
|
+
|
5
|
+
module Ungulate
|
6
|
+
def self.logger
|
7
|
+
@logger ||= Logger.new STDOUT
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.run(queue_name)
|
11
|
+
logger.info "Checking for job on #{queue_name}"
|
12
|
+
Job.pop(queue_name).process
|
13
|
+
end
|
14
|
+
|
15
|
+
class Job
|
16
|
+
attr_accessor :bucket, :key, :queue, :versions
|
17
|
+
|
18
|
+
def self.s3
|
19
|
+
@s3 ||=
|
20
|
+
RightAws::S3.new(ENV['AMAZON_ACCESS_KEY_ID'],
|
21
|
+
ENV['AMAZON_SECRET_ACCESS_KEY'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.sqs
|
25
|
+
@sqs ||=
|
26
|
+
RightAws::SqsGen2.new(ENV['AMAZON_ACCESS_KEY_ID'],
|
27
|
+
ENV['AMAZON_SECRET_ACCESS_KEY'])
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.pop(queue_name)
|
31
|
+
job = new
|
32
|
+
job.queue = sqs.queue queue_name
|
33
|
+
message = job.queue.pop
|
34
|
+
attributes = YAML.load message.to_s
|
35
|
+
job.attributes = attributes if attributes
|
36
|
+
job
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@logger = Ungulate.logger
|
41
|
+
self.versions = []
|
42
|
+
end
|
43
|
+
|
44
|
+
def attributes=(options)
|
45
|
+
self.bucket = Job.s3.bucket(options[:bucket])
|
46
|
+
self.key = options[:key]
|
47
|
+
self.versions = options[:versions]
|
48
|
+
end
|
49
|
+
|
50
|
+
def processed_versions
|
51
|
+
@processed_versions ||=
|
52
|
+
versions.map do |name, instruction|
|
53
|
+
method, x, y = instruction
|
54
|
+
image = Magick::Image.from_blob(source).first
|
55
|
+
@logger.info "Performing #{method} with #{x}, #{y}"
|
56
|
+
[name, image.send(method, x, y)]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def source
|
61
|
+
if @source
|
62
|
+
@source
|
63
|
+
else
|
64
|
+
@logger.info "Grabbing source image #{key}"
|
65
|
+
@source = bucket.get key
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def process
|
70
|
+
return false if processed_versions.empty?
|
71
|
+
processed_versions.each do |version, image|
|
72
|
+
version_key = version_key version
|
73
|
+
@logger.info "Storing #{version} @ #{version_key}"
|
74
|
+
bucket.put(version_key, image.to_blob, {}, 'public-read')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def version_key(version)
|
79
|
+
dirname = File.dirname(key)
|
80
|
+
extname = File.extname(key)
|
81
|
+
basename = File.basename(key, extname)
|
82
|
+
"#{dirname}/#{basename}_#{version}#{extname}".sub(/^\.\//, '')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
module Ungulate
|
4
|
+
describe "run" do
|
5
|
+
before do
|
6
|
+
@versions = {
|
7
|
+
:thumb => [ :resize_to_fit, 100, 200 ],
|
8
|
+
:large => [ :resize_to_fit, 200, 300 ],
|
9
|
+
}
|
10
|
+
|
11
|
+
@data = mock('Data')
|
12
|
+
@job = mock('Job',
|
13
|
+
:versions => @versions,
|
14
|
+
:source => @data,
|
15
|
+
:process => nil,
|
16
|
+
:store => nil)
|
17
|
+
|
18
|
+
Job.stub(:pop).and_return(@job)
|
19
|
+
|
20
|
+
@image = mock('RMagick::Image')
|
21
|
+
|
22
|
+
@datum = mock('Datum')
|
23
|
+
@data_array = [@datum]
|
24
|
+
|
25
|
+
Magick::Image.stub(:from_blob).with(@data).and_return(@data_array)
|
26
|
+
end
|
27
|
+
|
28
|
+
after { Ungulate.run('queuename') }
|
29
|
+
|
30
|
+
it "should pop a job from the provided queue" do
|
31
|
+
Job.should_receive(:pop).with('queuename')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should process the job" do
|
35
|
+
@job.should_receive(:process)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Job do
|
40
|
+
before do
|
41
|
+
ENV['AMAZON_ACCESS_KEY_ID'] = 'test-key-id'
|
42
|
+
ENV['AMAZON_SECRET_ACCESS_KEY'] = 'test-secret'
|
43
|
+
@bucket = mock('Bucket')
|
44
|
+
@sqs = mock('SqsGen2')
|
45
|
+
@s3 = mock('S3')
|
46
|
+
@q = mock('Queue')
|
47
|
+
@versions = {
|
48
|
+
:thumb => [ :resize_to_fit, 100, 200 ],
|
49
|
+
:large => [ :resize_to_fit, 200, 300 ],
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
its(:versions) { should == [] }
|
54
|
+
|
55
|
+
describe :sqs do
|
56
|
+
before do
|
57
|
+
RightAws::SqsGen2.stub(:new).with('test-key-id', 'test-secret').and_return(@sqs)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return a SqsGen2 instance using environment variables" do
|
61
|
+
Job.sqs.should == @sqs
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should memoize" do
|
65
|
+
Job.instance_variable_set('@sqs', :cache)
|
66
|
+
Job.sqs.should == :cache
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :pop do
|
71
|
+
before do
|
72
|
+
@job_attributes = {
|
73
|
+
:bucket => 'test-bucket',
|
74
|
+
:key => 'test-key',
|
75
|
+
:versions => @versions
|
76
|
+
}
|
77
|
+
|
78
|
+
@sqs.stub(:queue).with('test-queue').and_return(@q)
|
79
|
+
|
80
|
+
message = mock('Message', :to_s => :message_data)
|
81
|
+
|
82
|
+
@q.stub(:pop).and_return(message)
|
83
|
+
YAML.stub(:load).with(:message_data).and_return(:attributes)
|
84
|
+
|
85
|
+
Job.stub(:sqs).and_return(@sqs)
|
86
|
+
Job.stub(:s3).and_return(@s3)
|
87
|
+
|
88
|
+
@job = mock('Job', :attributes= => nil, :queue= => nil, :queue => @q)
|
89
|
+
Job.stub(:new).and_return(@job)
|
90
|
+
end
|
91
|
+
|
92
|
+
after { Job.pop('test-queue') }
|
93
|
+
|
94
|
+
it "should set attributes" do
|
95
|
+
@job.should_receive(:attributes=).with(:attributes)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should set the queue" do
|
99
|
+
@job.should_receive(:queue=).with(@q)
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when YAML.load returns false" do
|
103
|
+
before do
|
104
|
+
YAML.stub(:load).with(:message_data).and_return(false)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should not set attributes" do
|
108
|
+
@job.should_not_receive(:attributes=)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe :s3 do
|
114
|
+
before do
|
115
|
+
RightAws::S3.stub(:new).with('test-key-id', 'test-secret').and_return(@s3)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return a S3 instance using environment variables" do
|
119
|
+
Job.s3.should == @s3
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should memoize" do
|
123
|
+
Job.instance_variable_set('@s3', :cache)
|
124
|
+
Job.s3.should == :cache
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe :attributes= do
|
129
|
+
subject do
|
130
|
+
Job.stub_chain(:s3, :bucket).with('hello').and_return(@bucket)
|
131
|
+
|
132
|
+
job = Job.new
|
133
|
+
job.attributes = {
|
134
|
+
:bucket => 'hello',
|
135
|
+
:key => 'path/to/filename.gif',
|
136
|
+
:versions => @versions
|
137
|
+
}
|
138
|
+
job
|
139
|
+
end
|
140
|
+
|
141
|
+
its(:bucket) { should == @bucket }
|
142
|
+
its(:key) { should == 'path/to/filename.gif' }
|
143
|
+
its(:versions) { should == @versions }
|
144
|
+
end
|
145
|
+
|
146
|
+
describe :source do
|
147
|
+
subject do
|
148
|
+
job = Job.new
|
149
|
+
job.stub(:key).and_return('test-key')
|
150
|
+
job.stub_chain(:bucket, :get).with('test-key').and_return(:s3_data)
|
151
|
+
job.source
|
152
|
+
end
|
153
|
+
|
154
|
+
it { should == :s3_data }
|
155
|
+
|
156
|
+
it "should memoize" do
|
157
|
+
job = Job.new
|
158
|
+
job.instance_variable_set('@source', :cache)
|
159
|
+
job.source.should == :cache
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe :processed_versions do
|
164
|
+
subject do
|
165
|
+
job = Job.new
|
166
|
+
versions = {
|
167
|
+
:large => [ :resize_to_fit, 100, 200 ],
|
168
|
+
:small => [ :resize_to_fill, 64, 64 ],
|
169
|
+
}
|
170
|
+
job.stub(:versions).and_return(versions)
|
171
|
+
job.stub(:key).and_return('someimage.jpg')
|
172
|
+
|
173
|
+
job.stub(:source).and_return(:data)
|
174
|
+
@source_image = mock('Image')
|
175
|
+
Magick::Image.stub(:from_blob).with(:data).and_return([@source_image])
|
176
|
+
|
177
|
+
@source_image.stub(:resize_to_fit).with(100, 200).and_return(:large_image)
|
178
|
+
@source_image.stub(:resize_to_fill).with(64, 64).and_return(:small_image)
|
179
|
+
|
180
|
+
job.processed_versions
|
181
|
+
end
|
182
|
+
|
183
|
+
it { should include([:large, :large_image]) }
|
184
|
+
it { should include([:small, :small_image]) }
|
185
|
+
|
186
|
+
it "should memoize" do
|
187
|
+
job = Job.new
|
188
|
+
job.instance_variable_set('@processed_versions', :cache)
|
189
|
+
job.processed_versions.should == :cache
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe :process do
|
194
|
+
subject do
|
195
|
+
job = Job.new
|
196
|
+
@big = mock('Image', :to_blob => 'bigdata')
|
197
|
+
@little = mock('Image', :to_blob => 'littledata')
|
198
|
+
job.stub(:processed_versions).and_return([[:big, @big], [:little, @little]])
|
199
|
+
job.stub(:bucket).and_return(@bucket)
|
200
|
+
job.stub(:version_key).with(:big).and_return('path/to/someimage_big.jpg')
|
201
|
+
job.stub(:version_key).with(:little).and_return('path/to/someimage_little.jpg')
|
202
|
+
job
|
203
|
+
end
|
204
|
+
|
205
|
+
after { subject.process }
|
206
|
+
|
207
|
+
it "should send each processed version to S3" do
|
208
|
+
@bucket.should_receive(:put).with('path/to/someimage_big.jpg',
|
209
|
+
'bigdata',
|
210
|
+
{},
|
211
|
+
'public-read')
|
212
|
+
@bucket.should_receive(:put).with('path/to/someimage_little.jpg',
|
213
|
+
'littledata',
|
214
|
+
{},
|
215
|
+
'public-read')
|
216
|
+
end
|
217
|
+
|
218
|
+
context "empty array" do
|
219
|
+
before do
|
220
|
+
subject.stub(:processed_versions).and_return([])
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should not break" do
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe :version_key do
|
229
|
+
subject do
|
230
|
+
job = Job.new
|
231
|
+
job.stub(:key).and_return('path/to/some/file_name.png')
|
232
|
+
job.version_key(:extra_large)
|
233
|
+
end
|
234
|
+
|
235
|
+
it { should == 'path/to/some/file_name_extra_large.png' }
|
236
|
+
|
237
|
+
context "no leading path" do
|
238
|
+
subject do
|
239
|
+
job = Job.new
|
240
|
+
job.stub(:key).and_return('file_name.png')
|
241
|
+
job.version_key(:extra_large)
|
242
|
+
end
|
243
|
+
|
244
|
+
it { should == 'file_name_extra_large.png' }
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
data/ungulate.gemspec
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ungulate}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Andrew Bruce"]
|
12
|
+
s.date = %q{2010-04-07}
|
13
|
+
s.default_executable = %q{ungulate_server.rb}
|
14
|
+
s.description = %q{WIP}
|
15
|
+
s.email = %q{andrew@camelpunch.com}
|
16
|
+
s.executables = ["ungulate_server.rb"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/ungulate_server.rb",
|
29
|
+
"features/camels.jpg",
|
30
|
+
"features/cope_with_empty_queue.feature",
|
31
|
+
"features/image_resize.feature",
|
32
|
+
"features/step_definitions/command_steps.rb",
|
33
|
+
"features/step_definitions/queue_steps.rb",
|
34
|
+
"features/step_definitions/version_steps.rb",
|
35
|
+
"features/support.rb",
|
36
|
+
"lib/ungulate.rb",
|
37
|
+
"spec/spec.opts",
|
38
|
+
"spec/spec_helper.rb",
|
39
|
+
"spec/ungulate_spec.rb",
|
40
|
+
"ungulate.gemspec"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/camelpunch/ungulate}
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.3.6}
|
46
|
+
s.summary = %q{Process images using Amazon SQS and S3}
|
47
|
+
s.test_files = [
|
48
|
+
"spec/spec_helper.rb",
|
49
|
+
"spec/ungulate_spec.rb"
|
50
|
+
]
|
51
|
+
|
52
|
+
if s.respond_to? :specification_version then
|
53
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
54
|
+
s.specification_version = 3
|
55
|
+
|
56
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
57
|
+
s.add_runtime_dependency(%q<right_aws>, [">= 1.10.0"])
|
58
|
+
s.add_runtime_dependency(%q<rmagick>, [">= 2.12.2"])
|
59
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
60
|
+
s.add_development_dependency(%q<cucumber>, [">= 0.6.2"])
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<right_aws>, [">= 1.10.0"])
|
63
|
+
s.add_dependency(%q<rmagick>, [">= 2.12.2"])
|
64
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
65
|
+
s.add_dependency(%q<cucumber>, [">= 0.6.2"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<right_aws>, [">= 1.10.0"])
|
69
|
+
s.add_dependency(%q<rmagick>, [">= 2.12.2"])
|
70
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
71
|
+
s.add_dependency(%q<cucumber>, [">= 0.6.2"])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ungulate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Andrew Bruce
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-07 00:00:00 +01:00
|
18
|
+
default_executable: ungulate_server.rb
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: right_aws
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 10
|
30
|
+
- 0
|
31
|
+
version: 1.10.0
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rmagick
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 2
|
43
|
+
- 12
|
44
|
+
- 2
|
45
|
+
version: 2.12.2
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 2
|
58
|
+
- 9
|
59
|
+
version: 1.2.9
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: cucumber
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
- 6
|
72
|
+
- 2
|
73
|
+
version: 0.6.2
|
74
|
+
type: :development
|
75
|
+
version_requirements: *id004
|
76
|
+
description: WIP
|
77
|
+
email: andrew@camelpunch.com
|
78
|
+
executables:
|
79
|
+
- ungulate_server.rb
|
80
|
+
extensions: []
|
81
|
+
|
82
|
+
extra_rdoc_files:
|
83
|
+
- LICENSE
|
84
|
+
- README.rdoc
|
85
|
+
files:
|
86
|
+
- .document
|
87
|
+
- .gitignore
|
88
|
+
- LICENSE
|
89
|
+
- README.rdoc
|
90
|
+
- Rakefile
|
91
|
+
- VERSION
|
92
|
+
- bin/ungulate_server.rb
|
93
|
+
- features/camels.jpg
|
94
|
+
- features/cope_with_empty_queue.feature
|
95
|
+
- features/image_resize.feature
|
96
|
+
- features/step_definitions/command_steps.rb
|
97
|
+
- features/step_definitions/queue_steps.rb
|
98
|
+
- features/step_definitions/version_steps.rb
|
99
|
+
- features/support.rb
|
100
|
+
- lib/ungulate.rb
|
101
|
+
- spec/spec.opts
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/ungulate_spec.rb
|
104
|
+
- ungulate.gemspec
|
105
|
+
has_rdoc: true
|
106
|
+
homepage: http://github.com/camelpunch/ungulate
|
107
|
+
licenses: []
|
108
|
+
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options:
|
111
|
+
- --charset=UTF-8
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
version: "0"
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
requirements: []
|
129
|
+
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.3.6
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: Process images using Amazon SQS and S3
|
135
|
+
test_files:
|
136
|
+
- spec/spec_helper.rb
|
137
|
+
- spec/ungulate_spec.rb
|