mega-quick-box 0.0.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 +7 -0
- data/mega-quick-box.gemspec +12 -0
- data/mini_magick-5.3.1/MIT-LICENSE +21 -0
- data/mini_magick-5.3.1/README.md +558 -0
- data/mini_magick-5.3.1/Rakefile +18 -0
- data/mini_magick-5.3.1/lib/mini_magick/configuration.rb +101 -0
- data/mini_magick-5.3.1/lib/mini_magick/image/info.rb +151 -0
- data/mini_magick-5.3.1/lib/mini_magick/image.rb +609 -0
- data/mini_magick-5.3.1/lib/mini_magick/shell.rb +53 -0
- data/mini_magick-5.3.1/lib/mini_magick/tool.rb +274 -0
- data/mini_magick-5.3.1/lib/mini_magick/utilities.rb +33 -0
- data/mini_magick-5.3.1/lib/mini_magick/version.rb +17 -0
- data/mini_magick-5.3.1/lib/mini_magick.rb +40 -0
- metadata +53 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'mini_magick/utilities'
|
|
2
|
+
require 'logger'
|
|
3
|
+
|
|
4
|
+
module MiniMagick
|
|
5
|
+
module Configuration
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Uses [GraphicsMagick](http://www.graphicsmagick.org/) instead of
|
|
9
|
+
# ImageMagick, by prefixing commands with `gm` instead of `magick`.
|
|
10
|
+
#
|
|
11
|
+
# @return [Boolean]
|
|
12
|
+
attr_accessor :graphicsmagick
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Adds a prefix to the CLI command.
|
|
16
|
+
# For example, you could use `firejail` to run all commands in a sandbox.
|
|
17
|
+
# Can be a string, or an array of strings.
|
|
18
|
+
# e.g. 'firejail', or ['firejail', '--force']
|
|
19
|
+
#
|
|
20
|
+
# @return [String]
|
|
21
|
+
# @return [Array<String>]
|
|
22
|
+
#
|
|
23
|
+
attr_accessor :cli_prefix
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Adds environment variables to every CLI command call.
|
|
27
|
+
# For example, you could use it to set `LD_PRELOAD="/path/to/libsomething.so"`.
|
|
28
|
+
# Must be a hash of strings keyed to valid environment variable name strings.
|
|
29
|
+
# e.g. {'MY_ENV' => 'my value'}
|
|
30
|
+
#
|
|
31
|
+
# @return [Hash]
|
|
32
|
+
#
|
|
33
|
+
attr_accessor :cli_env
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# If set to true, Open3 will restrict system calls to access only
|
|
37
|
+
# environment variables defined in :cli_env, plus HOME, PATH, and LANG
|
|
38
|
+
# since those are required for such system calls. It will not pass on any
|
|
39
|
+
# other environment variables from the system.
|
|
40
|
+
#
|
|
41
|
+
# @return [Boolean]
|
|
42
|
+
#
|
|
43
|
+
attr_accessor :restricted_env
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# If you don't want commands to take too long, you can set a timeout (in
|
|
47
|
+
# seconds).
|
|
48
|
+
#
|
|
49
|
+
# @return [Integer]
|
|
50
|
+
#
|
|
51
|
+
attr_accessor :timeout
|
|
52
|
+
##
|
|
53
|
+
# Logger for commands, default is `Logger.new($stdout)`, but you can
|
|
54
|
+
# override it, for example if you want the logs to be written to a file.
|
|
55
|
+
#
|
|
56
|
+
# @return [Logger]
|
|
57
|
+
#
|
|
58
|
+
attr_accessor :logger
|
|
59
|
+
##
|
|
60
|
+
# Temporary directory used by MiniMagick, default is `Dir.tmpdir`, but
|
|
61
|
+
# you can override it.
|
|
62
|
+
#
|
|
63
|
+
# @return [String]
|
|
64
|
+
#
|
|
65
|
+
attr_accessor :tmpdir
|
|
66
|
+
|
|
67
|
+
##
|
|
68
|
+
# If set to `false`, it will not raise errors when ImageMagick returns
|
|
69
|
+
# status code different than 0. Defaults to `true`.
|
|
70
|
+
#
|
|
71
|
+
# @return [Boolean]
|
|
72
|
+
#
|
|
73
|
+
attr_accessor :errors
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# If set to `false`, it will not forward warnings from ImageMagick to
|
|
77
|
+
# standard error.
|
|
78
|
+
attr_accessor :warnings
|
|
79
|
+
|
|
80
|
+
def self.extended(base)
|
|
81
|
+
base.tmpdir = Dir.tmpdir
|
|
82
|
+
base.errors = true
|
|
83
|
+
base.logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
|
84
|
+
base.warnings = true
|
|
85
|
+
base.cli_env = {}.freeze
|
|
86
|
+
base.restricted_env = false
|
|
87
|
+
base.graphicsmagick = false
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# @yield [self]
|
|
92
|
+
# @example
|
|
93
|
+
# MiniMagick.configure do |config|
|
|
94
|
+
# config.timeout = 5
|
|
95
|
+
# end
|
|
96
|
+
#
|
|
97
|
+
def configure
|
|
98
|
+
yield self
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module MiniMagick
|
|
4
|
+
class Image
|
|
5
|
+
# @private
|
|
6
|
+
class Info
|
|
7
|
+
ASCII_ENCODED_EXIF_KEYS = %w[ExifVersion FlashPixVersion]
|
|
8
|
+
|
|
9
|
+
def initialize(path)
|
|
10
|
+
@path = path
|
|
11
|
+
@info = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def [](value, *args)
|
|
15
|
+
case value
|
|
16
|
+
when "format", "width", "height", "dimensions", "size", "human_size"
|
|
17
|
+
cheap_info(value)
|
|
18
|
+
when "colorspace"
|
|
19
|
+
colorspace
|
|
20
|
+
when "resolution"
|
|
21
|
+
resolution(*args)
|
|
22
|
+
when "signature"
|
|
23
|
+
signature
|
|
24
|
+
when /^EXIF\:/i
|
|
25
|
+
raw_exif(value)
|
|
26
|
+
when "exif"
|
|
27
|
+
exif
|
|
28
|
+
when "data"
|
|
29
|
+
data
|
|
30
|
+
else
|
|
31
|
+
raw(value)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def clear
|
|
36
|
+
@info.clear
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def cheap_info(value)
|
|
40
|
+
@info.fetch(value) do
|
|
41
|
+
format, width, height, size = parse_warnings(self["%m %w %h %b"]).split(" ")
|
|
42
|
+
|
|
43
|
+
path = @path
|
|
44
|
+
path = path.match(/\[\d+\]$/).pre_match if path =~ /\[\d+\]$/
|
|
45
|
+
|
|
46
|
+
@info.update(
|
|
47
|
+
"format" => format,
|
|
48
|
+
"width" => Integer(width),
|
|
49
|
+
"height" => Integer(height),
|
|
50
|
+
"dimensions" => [Integer(width), Integer(height)],
|
|
51
|
+
"size" => File.size(path),
|
|
52
|
+
"human_size" => size,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@info.fetch(value)
|
|
56
|
+
end
|
|
57
|
+
rescue ArgumentError, TypeError
|
|
58
|
+
raise MiniMagick::Invalid, "image data can't be read"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def parse_warnings(raw_info)
|
|
62
|
+
return raw_info unless raw_info.split("\n").size > 1
|
|
63
|
+
|
|
64
|
+
raw_info.split("\n").each do |line|
|
|
65
|
+
# must match "%m %w %h %b"
|
|
66
|
+
return line if line.match?(/^[A-Z]+ \d+ \d+ \d+(|\.\d+)([KMGTPEZY]{0,1})B$/)
|
|
67
|
+
end
|
|
68
|
+
raise TypeError
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def colorspace
|
|
72
|
+
@info["colorspace"] ||= self["%r"]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def resolution(unit = nil)
|
|
76
|
+
output = identify do |b|
|
|
77
|
+
b.units unit if unit
|
|
78
|
+
b.format "%x %y"
|
|
79
|
+
end
|
|
80
|
+
output.split(" ").map(&:to_i)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def raw_exif(value)
|
|
84
|
+
self["%[#{value}]"]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def exif
|
|
88
|
+
@info["exif"] ||= (
|
|
89
|
+
hash = {}
|
|
90
|
+
output = self["%[EXIF:*]"]
|
|
91
|
+
|
|
92
|
+
output.each_line do |line|
|
|
93
|
+
line = line.chomp("\n")
|
|
94
|
+
|
|
95
|
+
if match = line.match(/^exif:/)
|
|
96
|
+
key, value = match.post_match.split("=", 2)
|
|
97
|
+
value = decode_comma_separated_ascii_characters(value) if ASCII_ENCODED_EXIF_KEYS.include?(key)
|
|
98
|
+
hash[key] = value
|
|
99
|
+
else
|
|
100
|
+
hash[hash.keys.last] << "\n#{line}"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
hash
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def raw(value)
|
|
109
|
+
@info["raw:#{value}"] ||= identify { |b| b.format(value) }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def signature
|
|
113
|
+
@info["signature"] ||= self["%#"]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def data
|
|
117
|
+
@info["data"] ||= (
|
|
118
|
+
json = MiniMagick.convert do |convert|
|
|
119
|
+
convert << path
|
|
120
|
+
convert << "json:"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
data = JSON.parse(json)
|
|
124
|
+
data = data.fetch(0) if data.is_a?(Array)
|
|
125
|
+
data.fetch("image")
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def identify
|
|
130
|
+
MiniMagick.identify do |builder|
|
|
131
|
+
yield builder if block_given?
|
|
132
|
+
builder << path
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
def decode_comma_separated_ascii_characters(encoded_value)
|
|
139
|
+
return encoded_value unless encoded_value.include?(',')
|
|
140
|
+
encoded_value.scan(/\d+/).map(&:to_i).map(&:chr).join
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def path
|
|
144
|
+
value = @path
|
|
145
|
+
value += "[0]" unless value =~ /\[\d+\]$/
|
|
146
|
+
value
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|