mojo_magick 0.5.5 → 0.6.3

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/init.rb CHANGED
@@ -1,3 +1 @@
1
- require File::expand_path(File::join(File::dirname(__FILE__), 'lib', 'mojo_magick'))
2
-
3
-
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "lib", "mojo_magick"))
@@ -1,15 +1,8 @@
1
1
  module ImageMagick
2
- module Fonts
3
- def get_fonts
4
- @parser ||= MojoMagick::Util::Parser.new
5
- raw_fonts = begin
6
- self.raw_command('identify', '-list font')
7
- rescue Exception => ex
8
- puts ex
9
- puts "Failed to execute font list with raw_command - trying straight up execute"
10
- `convert -list font`
11
- end
12
- @parser.parse_fonts(raw_fonts)
2
+ class Fonts
3
+ def self.all
4
+ raw_fonts = MojoMagick::Commands.raw_command("identify", "-list", "font")
5
+ MojoMagick::Util::FontParser.new(raw_fonts).parse
13
6
  end
14
7
  end
15
8
  end
@@ -1,16 +1,12 @@
1
- cwd = File::dirname(__FILE__)
2
- require 'open3'
3
- initializers_dir = File::expand_path(File::join(cwd, 'initializers'))
4
- Dir.glob(File::join(initializers_dir, '*.rb')).each { |f| require f }
5
- require File::join(cwd, 'mojo_magick/util/parser')
6
- require File::join(cwd, 'mojo_magick/errors')
7
- require File::join(cwd, 'mojo_magick/command_status')
8
- require File::join(cwd, 'image_magick/resource_limits')
9
- require File::join(cwd, 'image_magick/fonts')
10
- require File::join(cwd, 'mojo_magick/opt_builder')
11
- require File::join(cwd, 'mojo_magick/font')
12
- require 'tempfile'
13
-
1
+ require "tempfile"
2
+ require "open3"
3
+ require_relative "./mojo_magick/util/font_parser"
4
+ require_relative "./mojo_magick/errors"
5
+ require_relative "./mojo_magick/command_status"
6
+ require_relative "./mojo_magick/commands"
7
+ require_relative "./image_magick/fonts"
8
+ require_relative "./mojo_magick/opt_builder"
9
+ require_relative "./mojo_magick/font"
14
10
 
15
11
  # MojoMagick is a stateless set of module methods which present a convient interface
16
12
  # for accessing common tasks for ImageMagick command line library.
@@ -36,7 +32,8 @@ require 'tempfile'
36
32
  #
37
33
  # Equivalent to:
38
34
  #
39
- # MojoMagick::raw_command('convert', 'source.jpg -crop 250x250+0+0 +repage -strip -set comment "my favorite file" dest.jpg')
35
+ # MojoMagick::Commands.raw_command('convert', 'source.jpg -crop 250x250+0+0\
36
+ # +repage -strip -set comment "my favorite file" dest.jpg')
40
37
  #
41
38
  # Example #mogrify usage:
42
39
  #
@@ -44,7 +41,7 @@ require 'tempfile'
44
41
  #
45
42
  # Equivalent to:
46
43
  #
47
- # MojoMagick::raw_command('mogrify', '-shave 10x10 image.jpg')
44
+ # MojoMagick::Commands.raw_command('mogrify', '-shave 10x10 image.jpg')
48
45
  #
49
46
  # Example showing some additional options:
50
47
  #
@@ -61,134 +58,150 @@ require 'tempfile'
61
58
  # bang (!) can be appended to command names to use the '+' versions
62
59
  # instead of '-' versions.
63
60
  #
64
- module MojoMagick
65
61
 
66
- # enable resource limiting functionality
67
- extend ImageMagick::ResourceLimits
68
- extend ImageMagick::Fonts
62
+ module MojoMagickDeprecations
63
+ # rubocop:disable Naming/AccessorMethodName
64
+ def get_fonts
65
+ warn "DEPRECATION WARNING: #{__method__} is deprecated and will be removed with the next minor version release."\
66
+ " Please use `available_fonts` instead"
67
+ MojoMagick.available_fonts
68
+ end
69
69
 
70
- def MojoMagick::windows?
71
- mem_fix = 1
72
- !(RUBY_PLATFORM =~ /win32/).nil?
70
+ # rubocop:enable Naming/AccessorMethodName
71
+ ### Moved to `Commands`
72
+ def execute!(*args)
73
+ warn "DEPRECATION WARNING: #{__method__} is deprecated and will be removed with the next minor version release."\
74
+ " Please use `MojoMagick::Commands.execute!` instead"
75
+ MojoMagick::Commands.send(:execute!, *args)
73
76
  end
74
77
 
75
- def MojoMagick::execute(command, args, options = {})
76
- # this suppress error messages to the console
77
- # err_pipe = windows? ? "2>nul" : "2>/dev/null"
78
- begin
79
- execute = "#{command} #{get_limits_as_params} #{args}"
80
- out, outerr, status = Open3.capture3(execute)
81
- CommandStatus.new execute, out, outerr, status
82
- rescue Exception => e
83
- raise MojoError, "#{e.class}: #{e.message}"
84
- end
78
+ def execute(*args)
79
+ warn "DEPRECATION WARNING: #{__method__} is deprecated and will be removed with the next minor version release."\
80
+ " Please use `MojoMagick::Commands.execute!` instead"
81
+ MojoMagick::Commands.send(:execute, *args)
85
82
  end
86
-
87
- def MojoMagick::execute!(command, args, options = {})
88
- # this suppress error messages to the console
89
- # err_pipe = windows? ? "2>nul" : "2>/dev/null"
90
- status = execute(command, args, options)
91
- if !status.success?
92
- err_msg = options[:err_msg] || "MojoMagick command failed: #{command}."
93
- raise(MojoFailed, "#{err_msg} (Exit status: #{status.exit_code})\n Command: #{status.command}\n Error: #{status.error}")
94
- end
95
- status.return_value
83
+
84
+ def raw_command(*args)
85
+ warn "DEPRECATION WARNING: #{__method__} is deprecated and will be removed with the next minor version release."\
86
+ " Please use `MojoMagick::Commands.execute!` instead"
87
+ MojoMagick::Commands.raw_command(*args)
96
88
  end
97
-
98
- def MojoMagick::raw_command(*args)
99
- self.execute! *args
89
+ end
90
+
91
+ module MojoMagick
92
+ extend MojoMagickDeprecations
93
+ def self.windows?
94
+ !RUBY_PLATFORM.include(win32)
100
95
  end
101
96
 
102
- def MojoMagick::shrink(source_file, dest_file, options)
97
+ def self.shrink(source_file, dest_file, options)
103
98
  opts = options.dup
104
99
  opts.delete(:expand_only)
105
- MojoMagick::resize(source_file, dest_file, opts.merge(:shrink_only => true))
100
+ MojoMagick.resize(source_file, dest_file, opts.merge(shrink_only: true))
106
101
  end
107
102
 
108
- def MojoMagick::expand(source_file, dest_file, options)
103
+ def self.expand(source_file, dest_file, options)
109
104
  opts = options.dup
110
105
  opts.delete(:shrink_only)
111
- MojoMagick::resize(source_file, dest_file, opts.merge(:expand_only => true))
106
+ MojoMagick.resize(source_file, dest_file, opts.merge(expand_only: true))
112
107
  end
113
108
 
114
109
  # resizes an image and returns the filename written to
115
110
  # options:
116
111
  # :width / :height => scale to these dimensions
117
- # :scale => pass scale options such as ">" to force shrink scaling only or "!" to force absolute width/height scaling (do not preserve aspect ratio)
112
+ # :scale => pass scale options such as ">" to force shrink scaling only or
113
+ # "!" to force absolute width/height scaling (do not preserve aspect ratio)
118
114
  # :percent => scale image to this percentage (do not specify :width/:height in this case)
119
- def MojoMagick::resize(source_file, dest_file, options)
120
- retval = nil
121
- scale_options = []
122
- scale_options << ">" unless options[:shrink_only].nil?
123
- scale_options << "<" unless options[:expand_only].nil?
124
- scale_options << "!" unless options[:absolute_aspect].nil?
125
- scale_options << "^" unless options[:fill].nil?
126
- scale_options = scale_options.join
127
-
115
+ def self.resize(source_file, dest_file, options)
116
+ scale_options = extract_scale_options(options)
117
+ geometry = extract_geometry_options(options)
128
118
  extras = []
129
- if !options[:width].nil? && !options[:height].nil?
130
- geometry = "#{options[:width]}X#{options[:height]}"
131
- elsif !options[:percent].nil?
132
- geometry = "#{options[:percent]}%"
133
- else
134
- raise MojoMagickError, "Unknown options for method resize: #{options.inspect}"
135
- end
136
119
  if !options[:fill].nil? && !options[:crop].nil?
137
- extras << "-gravity Center"
138
- extras << "-extent #{geometry}"
120
+ extras << "-gravity"
121
+ extras << "Center"
122
+ extras << "-extent"
123
+ extras << geometry.to_s
139
124
  end
140
- retval = raw_command("convert", "\"#{source_file}\" -resize \"#{geometry}#{scale_options}\" #{extras.join(' ')} \"#{dest_file}\"")
125
+ Commands.raw_command("convert",
126
+ source_file,
127
+ "-resize", "#{geometry}#{scale_options}",
128
+ *extras, dest_file)
141
129
  dest_file
142
130
  end
143
131
 
144
- def MojoMagick::available_fonts
132
+ def self.convert(source = nil, dest = nil)
133
+ opts = OptBuilder.new
134
+ opts.file source if source
135
+ yield opts
136
+ opts.file dest if dest
137
+
138
+ Commands.raw_command("convert", *opts.to_a)
139
+ end
140
+
141
+ def self.mogrify(dest = nil)
142
+ opts = OptBuilder.new
143
+ yield opts
144
+ opts.file dest if dest
145
+ Commands.raw_command("mogrify", *opts.to_a)
146
+ end
147
+
148
+ def self.available_fonts
145
149
  # returns width, height of image if available, nil if not
146
150
  Font.all
147
151
  end
148
152
 
153
+ def self.get_format(source_file, format_string)
154
+ Commands.raw_command("identify", "-format", format_string, source_file)
155
+ end
156
+
149
157
  # returns an empty hash or a hash with :width and :height set (e.g. {:width => INT, :height => INT})
150
158
  # raises MojoFailed when results are indeterminate (width and height could not be determined)
151
- def MojoMagick::get_image_size(source_file)
159
+ def self.get_image_size(source_file)
152
160
  # returns width, height of image if available, nil if not
153
- retval = raw_command("identify", "-format \"w:%w h:%h\" \"#{source_file}\"")
154
- return {} if !retval
155
- width = retval.match(%r{w:([0-9]+) })
161
+ retval = get_format(source_file, "w:%w h:%h")
162
+ return {} unless retval
163
+
164
+ width = retval.match(/w:([0-9]+) /)
156
165
  width = width ? width[1].to_i : nil
157
- height = retval.match(%r{h:([0-9]+)})
166
+ height = retval.match(/h:([0-9]+)/)
158
167
  height = height ? height[1].to_i : nil
159
168
  raise(MojoFailed, "Indeterminate results in get_image_size: #{source_file}") if !height || !width
160
- {:width=>width, :height=>height}
161
- end
162
169
 
163
- def MojoMagick::convert(source = nil, dest = nil)
164
- opts = OptBuilder.new
165
- opts.file source if source
166
- yield opts
167
- opts.file dest if dest
168
- raw_command('convert', opts.to_s)
170
+ { width: width, height: height }
169
171
  end
170
172
 
171
- def MojoMagick::mogrify(dest = nil)
172
- opts = OptBuilder.new
173
- yield opts
174
- opts.file dest if dest
175
- raw_command('mogrify', opts.to_s)
173
+ def self.tempfile(*opts)
174
+ data = opts[0]
175
+ rest = opts[1]
176
+ ext = rest && rest[:format]
177
+ file = Tempfile.new(["mojo", ext ? ".#{ext}" : ""])
178
+ file.binmode
179
+ file.write(data)
180
+ file.path
181
+ ensure
182
+ file.close
176
183
  end
177
184
 
178
- def MojoMagick::tempfile(*opts)
179
- begin
180
- data = opts[0]
181
- rest = opts[1]
182
- ext = rest && rest[:format]
183
- file = Tempfile.new(["mojo", ext ? '.' + ext.to_s : ''])
184
- file.binmode
185
- file.write(data)
186
- file.path
187
- rescue Exception => ex
188
- raise
189
- ensure
190
- file.close
185
+ class << self
186
+ private
187
+
188
+ def extract_geometry_options(options)
189
+ if !options[:width].nil? && !options[:height].nil?
190
+ "#{options[:width]}X#{options[:height]}"
191
+ elsif !options[:percent].nil?
192
+ "#{options[:percent]}%"
193
+ else
194
+ raise MojoMagickError, "Resize requires width and height or percentage: #{options.inspect}"
195
+ end
191
196
  end
192
- end
193
197
 
194
- end # MojoMagick
198
+ def extract_scale_options(options)
199
+ [].tap { |scale_options|
200
+ scale_options << ">" unless options[:shrink_only].nil?
201
+ scale_options << "<" unless options[:expand_only].nil?
202
+ scale_options << "!" unless options[:absolute_aspect].nil?
203
+ scale_options << "^" unless options[:fill].nil?
204
+ }.join
205
+ end
206
+ end
207
+ end
@@ -1,10 +1,11 @@
1
1
  module MojoMagick
2
- class CommandStatus < Struct.new(:command, :return_value, :error, :system_status)
2
+ CommandStatus = Struct.new(:command, :return_value, :error, :system_status) do
3
3
  def success?
4
4
  system_status.success?
5
5
  end
6
+
6
7
  def exit_code
7
- system_status.exitstatus || 'unknown'
8
+ system_status.exitstatus || "unknown"
8
9
  end
9
10
  end
10
11
  end
@@ -0,0 +1,32 @@
1
+ require_relative "opt_builder"
2
+
3
+ module MojoMagick
4
+ class Commands
5
+ def self.raw_command(*args)
6
+ execute!(*args)
7
+ end
8
+
9
+ class << self
10
+ private
11
+
12
+ def execute(command, *args)
13
+ execute = "#{command} #{args}"
14
+ out, outerr, status = Open3.capture3(command, *args.map(&:to_s))
15
+ CommandStatus.new execute, out, outerr, status
16
+ rescue StandardError => e
17
+ raise MojoError, "#{e.class}: #{e.message}"
18
+ end
19
+
20
+ def execute!(command, *args)
21
+ status = execute(command, *args)
22
+ unless status.success?
23
+ err_msg = "MojoMagick command failed: #{command}."
24
+ raise(MojoFailed, "#{err_msg} (Exit status: #{status.exit_code})\n" \
25
+ " Command: #{status.command}\n" \
26
+ " Error: #{status.error}")
27
+ end
28
+ status.return_value
29
+ end
30
+ end
31
+ end
32
+ end
@@ -2,4 +2,4 @@ module MojoMagick
2
2
  class MojoMagickException < StandardError; end
3
3
  class MojoError < MojoMagickException; end
4
4
  class MojoFailed < MojoMagickException; end
5
- end
5
+ end
@@ -1,23 +1,20 @@
1
1
  module MojoMagick
2
-
3
2
  class Font
4
-
5
3
  attr_accessor :name, :family, :style, :stretch, :weight, :glyphs
6
4
 
7
5
  def valid?
8
- !(name.nil?)
6
+ !name.nil?
9
7
  end
10
8
 
11
9
  def initialize(property_hash = {})
12
- property_hash.symbolize_keys!
13
- [:name, :family, :style, :stretch, :weight, :glyphs].each do |f|
10
+ %i[name family style stretch weight glyphs].each do |f|
14
11
  setter = "#{f}="
15
- self.send(setter, property_hash[f])
12
+ send(setter, property_hash[f])
16
13
  end
17
14
  end
18
15
 
19
16
  def self.all
20
- ImageMagick::Font.all.map{|font_info| Font.new(font_info)}
17
+ ImageMagick::Fonts.all
21
18
  end
22
19
  end
23
20
  end
@@ -17,9 +17,7 @@ module MojoMagick
17
17
 
18
18
  # Add files to command line, formatted if necessary
19
19
  def file(*args)
20
- args.each do |arg|
21
- add_formatted arg
22
- end
20
+ @opts << args
23
21
  self
24
22
  end
25
23
  alias files file
@@ -29,32 +27,26 @@ module MojoMagick
29
27
  end
30
28
 
31
29
  # annotate takes non-standard args
32
- def annotate(*args)
33
- @opts << '-annotate'
34
- arguments = args.join.split
35
- if arguments.length == 1
36
- arguments.unshift '0'
37
- end
38
- arguments.each do |arg|
39
- add_formatted arg
40
- end
30
+ def annotate(*args, geometry: 0)
31
+ @opts << "-annotate"
32
+ arguments = [args.join]
33
+ arguments.unshift geometry.to_s
34
+ @opts << arguments
41
35
  end
42
36
 
43
37
  # Create a temporary file for the given image and add to command line
44
38
  def format(*args)
45
- @opts << '-format'
46
- args.each do |arg|
47
- add_formatted arg
48
- end
39
+ @opts << "-format"
40
+ @opts << args
49
41
  end
50
42
 
51
43
  def blob(*args)
52
44
  data = args[0]
53
45
  opts = args[1] || {}
54
- opts.each do |k,v|
55
- send(k.to_s,v.to_s)
46
+ opts.each do |k, v|
47
+ send(k.to_s, v.to_s)
56
48
  end
57
- tmpfile = MojoMagick::tempfile(data, opts)
49
+ tmpfile = MojoMagick.tempfile(data, opts)
58
50
  file tmpfile
59
51
  end
60
52
 
@@ -66,31 +58,28 @@ module MojoMagick
66
58
  end
67
59
 
68
60
  # Generic commands. Arguments will be formatted if necessary
61
+ # rubocop:disable Lint/MissingSuper, Style/MissingRespondToMissing
69
62
  def method_missing(command, *args)
70
- if command.to_s[-1, 1] == '!'
71
- @opts << "+#{command.to_s.chop}"
72
- else
73
- @opts << "-#{command}"
74
- end
75
- args.each do |arg|
76
- add_formatted arg
77
- end
63
+ @opts << if command.to_s[-1, 1] == "!"
64
+ "+#{command.to_s.chop}"
65
+ else
66
+ "-#{command}"
67
+ end
68
+ @opts << args
78
69
  self
79
70
  end
80
71
 
81
- def to_s
82
- @opts.join ' '
72
+ # rubocop:enable Lint/MissingSuper, Style/MissingRespondToMissing
73
+ def to_a
74
+ @opts.flatten
83
75
  end
84
76
 
85
77
  protected
86
- def add_formatted(arg)
87
- # Quote anything that would cause problems on *nix or windows
88
- @opts << quoted_arg(arg)
89
- end
90
78
 
91
79
  def quoted_arg(arg)
92
- return arg unless arg =~ /[#'<>^|&();` ]/
93
- [ '"', arg.gsub('"', '\"').gsub("'", "\'"), '"'].join
80
+ return arg unless /[#'<>^|&();` ]/.match?(arg)
81
+
82
+ ['"', arg.gsub('"', '\"').tr("'", "\'"), '"'].join
94
83
  end
95
84
  end
96
85
  end