mm_tool 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ module MmTool
2
+
3
+ require 'pastel'
4
+
5
+ #------------------------------------------------------------
6
+ # Constants to help with output
7
+ #------------------------------------------------------------
8
+ C = Pastel.new(enabled: $stdout.tty? && $stderr.tty?)
9
+
10
+ class OutputHelper
11
+
12
+ #------------------------------------------------------------
13
+ # Return a string: with a hanging indent of hang: and a
14
+ # right margin of margin:.
15
+ #------------------------------------------------------------
16
+ def self.hanging_string( string:, hang: 0, margin: 78 )
17
+ indent_spaces = " " * hang
18
+ result = []
19
+
20
+ # Each individual paragraph should end with two newlines; therefore convert
21
+ # individual newlines into spaces, and break the paragraphs into a split.
22
+ string.gsub(/\n\n/, "\f").gsub(/\n/, " ").split(/\f/).each do |line|
23
+
24
+ buffer = ''
25
+ line.split(/\s/).each do |word|
26
+
27
+ word = ' ' if word.length == 0
28
+
29
+ len_buffer = buffer.gsub(/\e\[([;\d]+)?m/, '').length
30
+
31
+ if len_buffer == 0 || buffer[-1] == ' '
32
+ added_word = word
33
+ else
34
+ added_word = ' ' + word
35
+ end
36
+
37
+ len_word = added_word.gsub(/\e\[([;\d]+)?m/, '').length
38
+
39
+ width = result.count == 0 ? margin : margin - hang
40
+
41
+ if len_buffer + len_word <= width
42
+ buffer = buffer + added_word
43
+ else
44
+ if result.count == 0
45
+ result << buffer + "\n"
46
+ else
47
+ result << indent_spaces + buffer + "\n"
48
+ end
49
+ buffer = word
50
+ end
51
+
52
+ end # line
53
+
54
+ if result.count == 0
55
+ result << buffer + "\n\n"
56
+ else
57
+ result << indent_spaces + buffer + "\n\n"
58
+ end
59
+
60
+ end
61
+
62
+ result.join[0...-1]
63
+ end
64
+
65
+ #------------------------------------------------------------
66
+ # Displays an error message and returns from subroutine.
67
+ # ------------------------------------------------------------
68
+ def self.print_error(message)
69
+ width = [TTY::Screen.width, 61].max - 1
70
+ STDERR.puts self.hanging_string(string: message, hang: 3, margin: width)
71
+ end
72
+
73
+ #------------------------------------------------------------
74
+ # Displays an error message and exits the program.
75
+ # ------------------------------------------------------------
76
+ def self.print_error_and_exit(message)
77
+ self.print_error(message)
78
+ exit 1
79
+ end
80
+
81
+ #------------------------------------------------------------
82
+ # Gather the basic dimensions required for output. We'll
83
+ # support a minimum width of 60, which is reasonable for any
84
+ # modern console, and allows enough room for fairly long
85
+ # argument examples. If STDOUT is not to a console, then
86
+ # adjust to 80 columns.
87
+ # ------------------------------------------------------------
88
+ def self.console_width
89
+ $stdout.tty? ? [TTY::Screen.width, 60].max : 80
90
+ end
91
+
92
+ end # class
93
+
94
+ #------------------------------------------------------------
95
+ # Output bool as YES/NO/NOTHING
96
+ # ------------------------------------------------------------
97
+ class ::TrueClass
98
+ def human
99
+ "YES"
100
+ end
101
+ end
102
+
103
+ #------------------------------------------------------------
104
+ # Output bool as YES/NO/NOTHING
105
+ # ------------------------------------------------------------
106
+ class ::FalseClass
107
+ def human
108
+ "NO"
109
+ end
110
+ end
111
+
112
+ #------------------------------------------------------------
113
+ # Output bool as YES/NO/NOTHING
114
+ # ------------------------------------------------------------
115
+ class ::NilClass
116
+ def human
117
+ "NOTHING"
118
+ end
119
+ end
120
+
121
+ end # module
@@ -0,0 +1,377 @@
1
+ module MmTool
2
+
3
+ #=============================================================================
4
+ # This module consolidates all of the default options for MmTool.
5
+ #=============================================================================
6
+
7
+ PATH_IGNORE_LIST = File.join(Dir.home, '.mm_tool', 'ignored_file_list.txt')
8
+ PATH_USER_DEFAULTS = File.join(Dir.home, '.mm_tool', 'com.balthisar.mm_tool.rc')
9
+
10
+ #noinspection RubyResolve
11
+ USER_DEFAULTS = {
12
+
13
+ #----------------------------
14
+ # Main Options
15
+ #----------------------------
16
+
17
+ :help => {
18
+ :default => nil,
19
+ :value => nil,
20
+ :arg_short => '-h',
21
+ :arg_long => '--help',
22
+ :arg_format => nil,
23
+ :item_label => nil,
24
+ :help_group => 'Main Options',
25
+ :help_desc => <<~HEREDOC
26
+ Shows this help information
27
+ HEREDOC
28
+ },
29
+
30
+ :container_files => {
31
+ :default => %w(mp4 mkv avi 3gp flv),
32
+ :value => nil,
33
+ :arg_short => nil,
34
+ :arg_long => '--containers',
35
+ :arg_format => '<extensions>',
36
+ :item_label => 'Media Filetypes',
37
+ :help_group => 'Main Options',
38
+ :help_desc => <<~HEREDOC
39
+ A comma-separated list of file extensions assumed to be media files when examining directories. The
40
+ default is #{C.bold('%s')}. You can still pass individual files, such as subtitles, that are different
41
+ container formats.
42
+ HEREDOC
43
+ },
44
+
45
+ :scan_type => {
46
+ :default => 'normal',
47
+ :value => nil,
48
+ :arg_short => nil,
49
+ :arg_long => '--scan',
50
+ :arg_format => '<scan_type>',
51
+ :item_label => 'Scan Type',
52
+ :help_group => 'Main Options',
53
+ :help_desc => <<~HEREDOC
54
+ Type of files for which to show results, when this program is given a directory. #{C.bold('normal')}
55
+ will display results of files that have some change proposed to them, or have some other characteristic
56
+ that merits review. #{C.bold('all')} will display all media files, even if there's nothing interesting
57
+ about them (however, ignore-flagged files will be ignored. #{C.bold('flagged')} will show data for all
58
+ ignore-flagged files. #{C.bold('quality')} will show results only for files not meeting quality
59
+ thresholds. The default is #{C.bold('%s')}.
60
+ HEREDOC
61
+ },
62
+
63
+ :ignore_titles => {
64
+ :default => false,
65
+ :value => nil,
66
+ :arg_short => nil,
67
+ :arg_long => '--ignore-titles',
68
+ :arg_format => nil,
69
+ :item_label => 'Ignore Title Metadata',
70
+ :help_group => 'Main Options',
71
+ :help_desc => <<~HEREDOC
72
+ This program normally finds that files or streams with titles are interesting, because they're usually
73
+ mangled or have scene information. Once you've curated your library, though, they can clutter up the
74
+ results of this program. Set this option to ignore titles when deciding to show you a file or not.
75
+ HEREDOC
76
+ },
77
+
78
+ :info_header => {
79
+ :default => true,
80
+ :value => nil,
81
+ :arg_short => '-i',
82
+ :arg_long => '--no-info-header',
83
+ :arg_format => nil,
84
+ :item_label => nil,
85
+ :help_group => 'Main Options',
86
+ :help_desc => <<~HEREDOC
87
+ Don't show the information header indicating much of the configuration at the beginning of the output.
88
+ HEREDOC
89
+ },
90
+
91
+ :version => {
92
+ :default => false,
93
+ :value => nil,
94
+ :arg_short => nil,
95
+ :arg_long => '--version',
96
+ :arg_format => nil,
97
+ :help_group => 'Main Options',
98
+ :help_desc => <<~HEREDOC
99
+ Show version of this program.
100
+ HEREDOC
101
+ },
102
+
103
+ #----------------------------
104
+ # Command-like Options
105
+ #----------------------------
106
+
107
+ :ignore_files => {
108
+ :default => false,
109
+ :value => nil,
110
+ :arg_short => nil,
111
+ :arg_long => '--ignore-files',
112
+ :arg_format => nil,
113
+ :item_label => nil,
114
+ :help_group => 'Command-like Options',
115
+ :help_desc => <<~HEREDOC
116
+ Files following this command will not be inspected; instead, they will be added to the persistent list
117
+ of files to be ignored. You can use #{C.bold('--no-ignore-files')} to flip this flag back off for
118
+ subsequent files on the command line.
119
+ HEREDOC
120
+ },
121
+
122
+ :unignore_files => {
123
+ :default => false,
124
+ :value => nil,
125
+ :arg_short => nil,
126
+ :arg_long => '--unignore-files',
127
+ :arg_format => nil,
128
+ :item_label => nil,
129
+ :help_group => 'Command-like Options',
130
+ :help_desc => <<~HEREDOC
131
+ Files following this command will be removed from the persistent list of files to be ignored.
132
+ You can use #{C.bold('--no-unignore-files')} to flip this flag back off for subsequent files on the
133
+ command line.
134
+ HEREDOC
135
+ },
136
+
137
+ :transcode => {
138
+ :default => false,
139
+ :value => nil,
140
+ :arg_short => '-t',
141
+ :arg_long => '--transcode',
142
+ :arg_format => nil,
143
+ :item_label => 'Emit Transcode Script',
144
+ :help_group => 'Command-like Options',
145
+ :help_desc => <<~HEREDOC
146
+ Write transcoding instructions. Containers and streams that are not in preferred formats will be
147
+ transcoded; streams that are not in the preferred language will be dropped, unless they are the
148
+ only video or only audio stream. Transcoding instructions will be written to a temporary file.
149
+ HEREDOC
150
+ },
151
+
152
+ :stop_processing => {
153
+ :default => false,
154
+ :value => nil,
155
+ :arg_short => nil,
156
+ :arg_long => '--',
157
+ :arg_format => nil,
158
+ :item_label => nil,
159
+ :help_group => 'Command-like Options',
160
+ :help_desc => <<~HEREDOC
161
+ Stops further processing of input arguments, which can be useful in scripting environments.
162
+ HEREDOC
163
+ },
164
+
165
+ #----------------------------
166
+ # Media Options
167
+ #----------------------------
168
+
169
+ :containers_preferred => {
170
+ :default => %w(mkv mp4),
171
+ :value => nil,
172
+ :arg_short => nil,
173
+ :arg_long => '--containers-preferred',
174
+ :arg_format => '<extensions>',
175
+ :item_label => 'Preferred Containers',
176
+ :help_group => 'Media Options',
177
+ :help_desc => <<~HEREDOC
178
+ A comma-separated list of file extensions defining preferred media containers. If the container
179
+ is not one of these types, then it will be reported. If #{C.bold('--transcode')} is specified, and
180
+ a file is a non-preferred container, then it will be transcoded to the #{C.underline('first')} item
181
+ in this list. The default is #{C.bold('%s')}.
182
+ HEREDOC
183
+ },
184
+
185
+ :codecs_audio_preferred => {
186
+ :default => %w(aac ac3 eac3),
187
+ :value => nil,
188
+ :arg_short => nil,
189
+ :arg_long => '--codecs-audio-preferred',
190
+ :arg_format => '<codecs>',
191
+ :item_label => 'Preferred Audio Codecs',
192
+ :help_group => 'Media Options',
193
+ :help_desc => <<~HEREDOC
194
+ A comma-separated list of preferred audio codecs. Streams of this codec will not be transcoded.
195
+ If #{C.bold('--transcode')} is specified, and the codec of the stream is not on this list, then
196
+ the stream will be transcoded to the #{C.underline('first')} item in this list. The default
197
+ is #{C.bold('%s')}.
198
+ HEREDOC
199
+ },
200
+
201
+ :codecs_video_preferred => {
202
+ :default => %w(hevc h265 h264),
203
+ :value => nil,
204
+ :arg_short => nil,
205
+ :arg_long => '--codecs-video-preferred',
206
+ :arg_format => '<codecs>',
207
+ :item_label => 'Preferred Video Codecs',
208
+ :help_group => 'Media Options',
209
+ :help_desc => <<~HEREDOC
210
+ A comma-separated list of preferred audio codecs. Streams of this codec will not be transcoded.
211
+ If #{C.bold('--transcode')} is specified, and the codec of the stream is not on this list, then
212
+ the stream will be transcoded to the #{C.underline('first')} item in this list. The default
213
+ is #{C.bold('%s')}.
214
+ HEREDOC
215
+ },
216
+
217
+ :codecs_subs_preferred => {
218
+ :default => %w(subrip mov_text),
219
+ :value => nil,
220
+ :arg_short => nil,
221
+ :arg_long => '--codecs-subs-preferred',
222
+ :arg_format => '<codecs>',
223
+ :item_label => 'Preferred Subtitle Codecs',
224
+ :help_group => 'Media Options',
225
+ :help_desc => <<~HEREDOC
226
+ A comma-separated list of preferred audio codecs. Streams of this codec will not be transcoded.
227
+ If #{C.bold('--transcode')} is specified, and the codec of the stream is not on this list, then
228
+ the stream will be transcoded to the #{C.underline('first')} item in this list. The default
229
+ is #{C.bold('%s')}.
230
+ HEREDOC
231
+ },
232
+
233
+ :keep_langs_audio => {
234
+ :default => %w(und eng spa chi zho),
235
+ :value => nil,
236
+ :arg_short => nil,
237
+ :arg_long => '--keep-langs-audio',
238
+ :arg_format => '<langs>',
239
+ :item_label => 'Keep Audio Languages',
240
+ :help_group => 'Media Options',
241
+ :help_desc => <<~HEREDOC
242
+ A comma-separated list of languages whose audio streams should not be discarded. If
243
+ #{C.bold('--transcode')} is specified, audio streams with languages that are not on this list
244
+ will be discarded unless it is the only stream. Use the special language code #{C.bold('und')}
245
+ to ensure that streams without a designated language are not discarded! The default is #{C.bold('%s')}.
246
+ HEREDOC
247
+ },
248
+
249
+ :keep_langs_video => {
250
+ :default => %w(und eng spa chi zho),
251
+ :value => nil,
252
+ :arg_short => nil,
253
+ :arg_long => '--keep-langs-video',
254
+ :arg_format => '<langs>',
255
+ :item_label => 'Keep Video Languages',
256
+ :help_group => 'Media Options',
257
+ :help_desc => <<~HEREDOC
258
+ A comma-separated list of languages whose video streams should not be discarded. If
259
+ #{C.bold('--transcode')} is specified, video streams with languages that are not on this list
260
+ will be discarded unless it is the only stream. Use the special language code #{C.bold('und')}
261
+ to ensure that streams without a designated language are not discarded! The default is #{C.bold('%s')}.
262
+ HEREDOC
263
+ },
264
+
265
+ :keep_langs_subs => {
266
+ :default => %w(und eng spa chi zho),
267
+ :value => nil,
268
+ :arg_short => nil,
269
+ :arg_long => '--keep-langs-subs',
270
+ :arg_format => '<langs>',
271
+ :item_label => 'Keep Subtitle Languages',
272
+ :help_group => 'Media Options',
273
+ :help_desc => <<~HEREDOC
274
+ A comma-separated list of languages whose subtitles should not be discarded. If
275
+ #{C.bold('--transcode')} is specified, subtitles of languages that are not on this list
276
+ will be discarded. Use the special language code #{C.bold('und')} to ensure that streams
277
+ without a designated language are not discarded! The default is #{C.bold('%s')}.
278
+ See also #{C.bold('--codec-subs-preferred')}, whose condition is AND with this condition
279
+ (both must be true to pass through the subtitle).
280
+ HEREDOC
281
+ },
282
+
283
+ :use_external_subs => {
284
+ :default => true,
285
+ :value => nil,
286
+ :arg_short => nil,
287
+ :arg_long => '--no-use-external-subs',
288
+ :arg_format => nil,
289
+ :item_label => 'Add External Subs',
290
+ :help_group => 'Media Options',
291
+ :help_desc => <<~HEREDOC
292
+ Prohibit handling of external subtitle files. Normally, valid subtitle files with the
293
+ same name as the movie will be added to inspections. Valid files are in the SRT format
294
+ and either do not include a language extension (which will be treated as
295
+ #{C.bold('--undefined-language')}), or include a language extension specified by
296
+ #{C.bold('--keep-langs-subs')}.
297
+ HEREDOC
298
+ },
299
+
300
+ #----------------------------
301
+ # Transcoding Options
302
+ #----------------------------
303
+
304
+ :suffix => {
305
+ :default => '-original',
306
+ :value => nil,
307
+ :arg_short => nil,
308
+ :arg_long => '--suffix',
309
+ :arg_format => '<suffix>',
310
+ :item_label => 'Original File Suffix',
311
+ :help_group => 'Transcoding Options',
312
+ :help_desc => <<~HEREDOC
313
+ When #{C.bold('--transcode')} is specified, new files will be written using the original filename
314
+ and applicable extension, and the original file will be renamed plus this suffix. The default
315
+ is #{C.bold('%s')}.
316
+ HEREDOC
317
+ },
318
+
319
+ :undefined_language => {
320
+ :default => 'eng',
321
+ :value => nil,
322
+ :arg_short => nil,
323
+ :arg_long => '--undefined-language',
324
+ :arg_format => '<lang>',
325
+ :item_label => 'Undefined Language is',
326
+ :help_group => 'Transcoding Options',
327
+ :help_desc => <<~HEREDOC
328
+ When #{C.bold('--transcode')} is specified, streams in the new file that have an undefined language
329
+ identified will be set to this option's value. The default is #{C.bold('%s')}.
330
+ HEREDOC
331
+ },
332
+
333
+ :fix_undefined_language => {
334
+ :default => true,
335
+ :value => nil,
336
+ :arg_short => '-u',
337
+ :arg_long => '--no-fix-undefined-language',
338
+ :arg_format => nil,
339
+ :item_label => 'Fix Undefined Language',
340
+ :help_group => 'Transcoding Options',
341
+ :help_desc => <<~HEREDOC
342
+ Prevent this program from fixing undefined languages assigned to streams. See #{C.bold('--undefined-language')}.
343
+ HEREDOC
344
+ },
345
+
346
+ #----------------------------
347
+ # Quality Options
348
+ #----------------------------
349
+
350
+ :min_width => {
351
+ :default => '1920',
352
+ :value => nil,
353
+ :arg_short => nil,
354
+ :arg_long => '--min-width',
355
+ :arg_format => '<width>',
356
+ :item_label => 'Minimum Video Width',
357
+ :help_group => 'Quality Options',
358
+ :help_desc => <<~HEREDOC
359
+ Specify the minimum width that is considered acceptable quality. The default is #{C.bold('%s')}.
360
+ HEREDOC
361
+ },
362
+
363
+ :min_channels => {
364
+ :default => '6',
365
+ :value => nil,
366
+ :arg_short => nil,
367
+ :arg_long => '--min-channels',
368
+ :arg_format => '<channels>',
369
+ :item_label => 'Minimum Audio Channels',
370
+ :help_group => 'Quality Options',
371
+ :help_desc => <<~HEREDOC
372
+ Specify the minimum number of audio channels that are considered acceptable quality. The default is #{C.bold('%s')}.
373
+ HEREDOC
374
+ },
375
+ }
376
+
377
+ end # module