image_genie 0.2.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.
- data/Manifest +12 -0
- data/README.rdoc +0 -0
- data/Rakefile +21 -0
- data/image_genie.gemspec +33 -0
- data/lib/image_genie.rb +49 -0
- data/lib/image_genie/base.rb +63 -0
- data/lib/image_genie/command.rb +11 -0
- data/lib/image_genie/convert.rb +33 -0
- data/lib/image_genie/identify.rb +33 -0
- data/lib/image_genie/montage.rb +57 -0
- data/lib/image_genie/verify.rb +27 -0
- data/test/test_helper.rb +11 -0
- data/test/unit/base_test.rb +61 -0
- metadata +106 -0
data/Manifest
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Manifest
|
2
|
+
README.rdoc
|
3
|
+
Rakefile
|
4
|
+
lib/image_genie.rb
|
5
|
+
lib/image_genie/base.rb
|
6
|
+
lib/image_genie/command.rb
|
7
|
+
lib/image_genie/convert.rb
|
8
|
+
lib/image_genie/identify.rb
|
9
|
+
lib/image_genie/montage.rb
|
10
|
+
lib/image_genie/verify.rb
|
11
|
+
test/test_helper.rb
|
12
|
+
test/unit/base_test.rb
|
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
require 'rake/testtask'
|
5
|
+
|
6
|
+
Echoe.new('image_genie', '0.2.0') do |p|
|
7
|
+
p.description = "ImageGenie - Simple Wrapper for command line ImageMagick"
|
8
|
+
p.url = "https://github.com/bkimble"
|
9
|
+
p.author = "Billy Kimble"
|
10
|
+
p.email = "basslines@gmail.com"
|
11
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
12
|
+
p.development_dependencies = ["open4"]
|
13
|
+
end
|
14
|
+
|
15
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
16
|
+
|
17
|
+
Rake::TestTask.new(:test) do |t|
|
18
|
+
t.libs << 'test'
|
19
|
+
t.test_files = FileList['test/**/*_test.rb']
|
20
|
+
t.verbose = true
|
21
|
+
end
|
data/image_genie.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{image_genie}
|
5
|
+
s.version = "0.2.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Billy Kimble"]
|
9
|
+
s.date = %q{2011-02-08}
|
10
|
+
s.description = %q{ImageGenie - Simple Wrapper for command line ImageMagick}
|
11
|
+
s.email = %q{basslines@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/image_genie.rb", "lib/image_genie/base.rb", "lib/image_genie/command.rb", "lib/image_genie/convert.rb", "lib/image_genie/identify.rb", "lib/image_genie/montage.rb", "lib/image_genie/verify.rb"]
|
13
|
+
s.files = ["Manifest", "README.rdoc", "Rakefile", "lib/image_genie.rb", "lib/image_genie/base.rb", "lib/image_genie/command.rb", "lib/image_genie/convert.rb", "lib/image_genie/identify.rb", "lib/image_genie/montage.rb", "lib/image_genie/verify.rb", "test/test_helper.rb", "test/unit/base_test.rb", "image_genie.gemspec"]
|
14
|
+
s.homepage = %q{https://github.com/bkimble}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Image_genie", "--main", "README"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{image_genie}
|
18
|
+
s.rubygems_version = %q{1.4.2}
|
19
|
+
s.summary = %q{ImageGenie - Simple Wrapper for command line ImageMagick}
|
20
|
+
s.test_files = ["test/test_helper.rb", "test/unit/base_test.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<open4>, [">= 0"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<open4>, [">= 0"])
|
29
|
+
end
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<open4>, [">= 0"])
|
32
|
+
end
|
33
|
+
end
|
data/lib/image_genie.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'open4'
|
2
|
+
|
3
|
+
# ImageGenie -- a simple wrapper for ImageMagick.
|
4
|
+
# Billy Kimble 2011
|
5
|
+
|
6
|
+
# Usage:
|
7
|
+
#
|
8
|
+
# ImageGenie.convert(src=<File>, options)
|
9
|
+
# converts a file at src.path with command line options given as options, and returns a handle to a tempfile containing the
|
10
|
+
# contents of the converted file. Raises an exception with the errors if it can't find the file or has problems converting it.
|
11
|
+
#
|
12
|
+
# ImageGenie.montage(filenames=[], options)
|
13
|
+
# combines all files contained in filenames into a montage (mosaic) image, and returns a tempfile handle to the contents of the montage.
|
14
|
+
# Raises an exception with the errors if any 1 of the files in filenames has errors.
|
15
|
+
#
|
16
|
+
# ImageGenie.identify(filename=<String>, options)
|
17
|
+
# identifies the file and returns a hash containing:
|
18
|
+
# :filename, :format, :dimensions, :geometry, :bit, :image_class, :colors, :filesize, :usertime, :identify_time
|
19
|
+
# Raises an exception with the errors if it can't find the file or has problems identfying it.
|
20
|
+
#
|
21
|
+
# ImageGenie.verify(filename=<String>, options)
|
22
|
+
# verifies that the file pointed to by filename is valid. Returns true on success, or an an exception with the errors
|
23
|
+
# if it can't find the file or has problems identfying it
|
24
|
+
|
25
|
+
module ImageGenie
|
26
|
+
class UnableToLocateBinaryError < StandardError; end;
|
27
|
+
# Autoload any modules defined in classes in the image_genie directory.
|
28
|
+
module_path = [File.dirname(__FILE__),self.name.underscore,'*'].join('/')
|
29
|
+
Dir[module_path].each do |file|
|
30
|
+
constant_name = File.basename(file,'.rb').camelcase.to_sym
|
31
|
+
autoload constant_name, file
|
32
|
+
end
|
33
|
+
|
34
|
+
module ClassMethods
|
35
|
+
# Make helper methods
|
36
|
+
[:convert,:montage,:identify,:verify].each do |method|
|
37
|
+
define_method(method) do |*splat|
|
38
|
+
module_name = "#{self.name}::#{method.to_s.capitalize}"
|
39
|
+
target = module_name.constantize
|
40
|
+
target.run(*splat)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class << self
|
46
|
+
include ClassMethods
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ImageGenie
|
2
|
+
class Base
|
3
|
+
|
4
|
+
# Discover ImageMagick paths on the current system
|
5
|
+
def self.paths
|
6
|
+
if !@paths
|
7
|
+
@paths = {:identify => "",:montage => "",:convert => ""}
|
8
|
+
@paths.keys.each do |program|
|
9
|
+
command = "which #{program}"
|
10
|
+
pid, stdin, stdout, stderr = Open4::popen4(command)
|
11
|
+
path = stdout.read.strip
|
12
|
+
@paths[program] = path
|
13
|
+
end
|
14
|
+
end
|
15
|
+
@paths
|
16
|
+
end
|
17
|
+
|
18
|
+
# Eventually I want this method to accept a model that encapsulates its command execution logic.
|
19
|
+
def self.execute(command)
|
20
|
+
logger.info("Executing #{command}")
|
21
|
+
pid, stdin, stdout, stderr = Open4::popen4(command)
|
22
|
+
yield pid,stdin,stdout,stderr
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.path_for(program)
|
26
|
+
paths[program.to_sym]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.make_command(command,*args)
|
30
|
+
command.strip!
|
31
|
+
components = [command]
|
32
|
+
args.each do |component|
|
33
|
+
components << case (component.class.name)
|
34
|
+
when 'Hash': make_flags(component)
|
35
|
+
when 'Array': make_args(component)
|
36
|
+
else " #{component}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
components.compact.join(' ')
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.make_args(args)
|
43
|
+
args = [args] if !args.is_a?(Array)
|
44
|
+
return nil if args.empty?
|
45
|
+
args.join(' ')
|
46
|
+
end
|
47
|
+
|
48
|
+
# There is probably a better library to handle creation of command line flags,
|
49
|
+
# but this works for now.
|
50
|
+
def self.make_flags(options={})
|
51
|
+
return nil if options.empty?
|
52
|
+
options.collect{|k,v| "-#{k} #{v}"}.join(' ')
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.logger
|
56
|
+
@log ||= TimestampedBufferedLogger.new(Rails.root.join('log','image_genie.log'))
|
57
|
+
end
|
58
|
+
|
59
|
+
def logger
|
60
|
+
self.class.logger
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ImageGenie
|
2
|
+
class ConvertError < StandardError; end;
|
3
|
+
class Convert < Command
|
4
|
+
def self.run(src, options={})
|
5
|
+
raise(UnableToLocateBinaryError, 'convert') if path_for(:convert).blank?
|
6
|
+
|
7
|
+
logger.info("#{self.name} Attempting to convert #{src.path}")
|
8
|
+
|
9
|
+
begin
|
10
|
+
raise Errno::ENOENT,"#{src.path}" unless File.exists?(src.path)
|
11
|
+
rescue Errno::ENOENT => e
|
12
|
+
logger.error("#{self.name} #{e.message}")
|
13
|
+
raise
|
14
|
+
end
|
15
|
+
|
16
|
+
format = File.extname(src.path).downcase.gsub(/\.|\?/,'')
|
17
|
+
|
18
|
+
command = "#{path_for(:convert)} #{make_flags(options)} #{format}:#{src.path} #{format}:-"
|
19
|
+
temp_image_file = Tempfile.new([src.original_filename,".#{format}"])
|
20
|
+
|
21
|
+
execute(command) do |pid,stdin,stdout,stderr|
|
22
|
+
while line = stdout.gets
|
23
|
+
temp_image_file.puts line
|
24
|
+
end
|
25
|
+
ignored, status = Process::waitpid2 pid
|
26
|
+
handle_errors(stderr,status,ConvertError)
|
27
|
+
end
|
28
|
+
|
29
|
+
temp_image_file.rewind
|
30
|
+
return temp_image_file
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Verify an image is valid by calling 'identify' on it and testing for errors on the return.
|
2
|
+
module ImageGenie
|
3
|
+
class IdentifyError < StandardError; end;
|
4
|
+
class Identify < Command
|
5
|
+
def self.run(filename, options={})
|
6
|
+
raise(UnableToLocateBinaryError, 'identify') if path_for(:identify).blank?
|
7
|
+
|
8
|
+
begin
|
9
|
+
raise Errno::ENOENT,"#{filename}" unless File.exists?(filename)
|
10
|
+
rescue Errno::ENOENT => e
|
11
|
+
logger.error("#{self.name} #{e.message}")
|
12
|
+
raise
|
13
|
+
end
|
14
|
+
|
15
|
+
command = "#{path_for(:identify)} #{filename}"
|
16
|
+
output = ''
|
17
|
+
|
18
|
+
# We test for STDERR content
|
19
|
+
execute(command) do |pid,stdin,stdout,stderr|
|
20
|
+
while !stdout.eof?
|
21
|
+
output += stdout.readline
|
22
|
+
end
|
23
|
+
|
24
|
+
ignored, status = Process::waitpid2 pid
|
25
|
+
handle_errors(stderr,status,IdentifyError)
|
26
|
+
end
|
27
|
+
|
28
|
+
fields = [:filename,:format,:dimensions,:geometry,:bit,:image_class,:colors,:filesize,:usertime,:identify_time]
|
29
|
+
return Hash[fields.zip(stdout.read.split(' '))]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ImageGenie
|
2
|
+
class MontageError < StandardError; end;
|
3
|
+
class Montage < Command
|
4
|
+
attr_accessor :filenames,:filename,:options
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
self.filenames = []
|
8
|
+
self.options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def self.run(filenames, options={})
|
13
|
+
raise(UnableToLocateBinaryError, 'montage') if path_for(:montage).blank?
|
14
|
+
# Montage hates when you attempt to give it files with a path in it, so we
|
15
|
+
# need to change to the system specified temp directory to do our work.
|
16
|
+
Dir.chdir(Dir::tmpdir)
|
17
|
+
# Create a temp file that will be all component files of this montage
|
18
|
+
temp_image_file = Tempfile.new(['montage','.jpg'])
|
19
|
+
temp_image_list_file = Tempfile.new(['montage_image_filenames','.txt'])
|
20
|
+
temp_image_list_file.puts filenames.join("\n")
|
21
|
+
temp_image_list_file.rewind
|
22
|
+
|
23
|
+
logger.info("#{self.name} Attempting to make a montage of #{filenames.size} files")
|
24
|
+
|
25
|
+
command = make_command(path_for(:montage), "@\"#{File.basename(temp_image_list_file.path)}\"", options, "jpeg:-")
|
26
|
+
|
27
|
+
begin
|
28
|
+
execute(command) do |pid,stdin,stdout,stderr|
|
29
|
+
while !stdout.eof?
|
30
|
+
temp_image_file.puts stdout.readline
|
31
|
+
end
|
32
|
+
temp_image_file.rewind
|
33
|
+
|
34
|
+
# Still foggy on if we need to wait until we read from STDOUT before waiting, or if
|
35
|
+
# we wait until we read STDOUT and STDERR.
|
36
|
+
ignored, status = Process::waitpid2 pid
|
37
|
+
handle_errors(stderr,status,MontageError)
|
38
|
+
end
|
39
|
+
rescue Exception => e
|
40
|
+
# Close the tempfile before raising
|
41
|
+
temp_image_file.close
|
42
|
+
raise
|
43
|
+
ensure
|
44
|
+
logger.info("#{self.name} Cleaning up files")
|
45
|
+
temp_image_list_file.close
|
46
|
+
end
|
47
|
+
|
48
|
+
return temp_image_file
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Verify an image is valid by calling 'identify' on it with verbose turned on ,
|
2
|
+
# and testing for errors on the return.
|
3
|
+
module ImageGenie
|
4
|
+
class VerifyError < StandardError; end;
|
5
|
+
class Verify < Command
|
6
|
+
|
7
|
+
def self.run(filename, options={})
|
8
|
+
raise(UnableToLocateBinaryError, 'identify') if path_for(:identify).blank?
|
9
|
+
|
10
|
+
begin
|
11
|
+
raise Errno::ENOENT,"#{filename}" unless File.exists?(filename)
|
12
|
+
rescue Errno::ENOENT => e
|
13
|
+
logger.error("#{self.name} #{e.message}")
|
14
|
+
raise
|
15
|
+
end
|
16
|
+
|
17
|
+
command = "#{path_for(:identify)} #{filename}"
|
18
|
+
# We test for STDERR content
|
19
|
+
execute(command) do |pid,stdin,stdout,stderr|
|
20
|
+
ignored, status = Process::waitpid2 pid
|
21
|
+
handle_errors(stderr,status,VerifyError)
|
22
|
+
end
|
23
|
+
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'active_support'
|
5
|
+
require 'active_support/inflector' # needed for string methods like underscore
|
6
|
+
require 'open4'
|
7
|
+
require 'mocha'
|
8
|
+
require 'image_genie'
|
9
|
+
|
10
|
+
require 'active_support/testing/declarative'
|
11
|
+
include ActiveSupport::Testing::Declarative # for syntactic sugar of "test 'foo' do .."
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BaseTest < Test::Unit::TestCase
|
4
|
+
test "path for when path exists" do
|
5
|
+
ImageGenie::Base.expects(:paths).returns({:convert => "/some/dir/convert", :montage => "/some/dir/montage"}).times(2)
|
6
|
+
assert_equal("/some/dir/convert", ImageGenie::Base.path_for(:convert))
|
7
|
+
assert_equal("/some/dir/montage", ImageGenie::Base.path_for(:montage))
|
8
|
+
end
|
9
|
+
|
10
|
+
test "path for when path doesnt exist" do
|
11
|
+
ImageGenie::Base.expects(:paths).returns({:convert => "/some/dir/convert", :montage => "/some/dir/montage"})
|
12
|
+
assert_equal(nil, ImageGenie::Base.path_for(:identify))
|
13
|
+
end
|
14
|
+
|
15
|
+
test "make command with args only" do
|
16
|
+
command = "some_command"
|
17
|
+
args = ["abc","def"]
|
18
|
+
assert_equal("some_command abc def", ImageGenie::Base.make_command(command,args))
|
19
|
+
end
|
20
|
+
|
21
|
+
test "make command with flags only" do
|
22
|
+
command = "some_command"
|
23
|
+
flags = {:foo => 1, :bar => 2}
|
24
|
+
assert_equal("some_command -foo 1 -bar 2", ImageGenie::Base.make_command(command,flags))
|
25
|
+
end
|
26
|
+
|
27
|
+
test "make command" do
|
28
|
+
command = "some_command"
|
29
|
+
args = ["abc","def"]
|
30
|
+
flags = {:foo => 1, :bar => 2}
|
31
|
+
assert_equal("some_command -foo 1 -bar 2 abc def", ImageGenie::Base.make_command(command,flags,args))
|
32
|
+
end
|
33
|
+
|
34
|
+
test "make command with no flags or args" do
|
35
|
+
command = "some_command"
|
36
|
+
args = []
|
37
|
+
flags = {}
|
38
|
+
assert_equal("some_command", ImageGenie::Base.make_command(command))
|
39
|
+
end
|
40
|
+
|
41
|
+
test "make flags" do
|
42
|
+
flags = {:foo => 1, :bar => 2}
|
43
|
+
assert_equal("-foo 1 -bar 2", ImageGenie::Base.make_flags(flags))
|
44
|
+
end
|
45
|
+
|
46
|
+
test "make flags with nothing" do
|
47
|
+
flags = {}
|
48
|
+
assert_equal(nil, ImageGenie::Base.make_flags(flags))
|
49
|
+
end
|
50
|
+
|
51
|
+
test "make args" do
|
52
|
+
args = ["abc","def"]
|
53
|
+
assert_equal("abc def", ImageGenie::Base.make_args(args))
|
54
|
+
end
|
55
|
+
|
56
|
+
test "make args with nothing" do
|
57
|
+
args = []
|
58
|
+
assert_equal(nil, ImageGenie::Base.make_args(args))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: image_genie
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Billy Kimble
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-08 00:00:00 -08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: open4
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
description: ImageGenie - Simple Wrapper for command line ImageMagick
|
36
|
+
email: basslines@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
- lib/image_genie.rb
|
44
|
+
- lib/image_genie/base.rb
|
45
|
+
- lib/image_genie/command.rb
|
46
|
+
- lib/image_genie/convert.rb
|
47
|
+
- lib/image_genie/identify.rb
|
48
|
+
- lib/image_genie/montage.rb
|
49
|
+
- lib/image_genie/verify.rb
|
50
|
+
files:
|
51
|
+
- Manifest
|
52
|
+
- README.rdoc
|
53
|
+
- Rakefile
|
54
|
+
- lib/image_genie.rb
|
55
|
+
- lib/image_genie/base.rb
|
56
|
+
- lib/image_genie/command.rb
|
57
|
+
- lib/image_genie/convert.rb
|
58
|
+
- lib/image_genie/identify.rb
|
59
|
+
- lib/image_genie/montage.rb
|
60
|
+
- lib/image_genie/verify.rb
|
61
|
+
- test/test_helper.rb
|
62
|
+
- test/unit/base_test.rb
|
63
|
+
- image_genie.gemspec
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: https://github.com/bkimble
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options:
|
70
|
+
- --line-numbers
|
71
|
+
- --inline-source
|
72
|
+
- --title
|
73
|
+
- Image_genie
|
74
|
+
- --main
|
75
|
+
- README
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 11
|
93
|
+
segments:
|
94
|
+
- 1
|
95
|
+
- 2
|
96
|
+
version: "1.2"
|
97
|
+
requirements: []
|
98
|
+
|
99
|
+
rubyforge_project: image_genie
|
100
|
+
rubygems_version: 1.4.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: ImageGenie - Simple Wrapper for command line ImageMagick
|
104
|
+
test_files:
|
105
|
+
- test/test_helper.rb
|
106
|
+
- test/unit/base_test.rb
|