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.
@@ -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