filter_rename 1.1.0 → 1.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.
@@ -1,33 +1,45 @@
1
- require 'date'
2
- require 'digest'
1
+ # frozen_string_literal: true
3
2
 
4
- module FilterRename
3
+ require "date"
4
+ require "digest"
5
5
 
6
- FILE_SIZES = ['B', 'KB', 'MB', 'GB', 'TB']
6
+ #
7
+ # Util classes collection.
8
+ #
9
+ module FilterRename
10
+ FILE_SIZES = %w[B KB MB GB TB].freeze
7
11
 
8
- class Boolean; end
12
+ class Boolean; end # rubocop:disable Lint/EmptyClass
9
13
 
14
+ #
15
+ # Transform a TrueClass to boolean.
16
+ #
10
17
  class ::TrueClass
11
18
  def to_boolean
12
- self.to_s.to_boolean
19
+ to_s.to_boolean
13
20
  end
14
21
  end
15
22
 
23
+ #
24
+ # Transform a FalseClass to boolean.
25
+ #
16
26
  class ::FalseClass
17
27
  def to_boolean
18
- self.to_s.to_boolean
28
+ to_s.to_boolean
19
29
  end
20
30
  end
21
31
 
32
+ #
33
+ # Mixin for readable variables.
34
+ #
22
35
  module ReadableVariables
23
-
24
36
  def basic!
25
37
  @custom = false
26
38
  self
27
39
  end
28
40
 
29
41
  def custom?
30
- @custom == true || @custom == nil
42
+ @custom == true || @custom.nil?
31
43
  end
32
44
 
33
45
  def readonly!
@@ -36,7 +48,7 @@ module FilterRename
36
48
  end
37
49
 
38
50
  def writable?
39
- @writable || @writable == nil
51
+ @writable || @writable.nil?
40
52
  end
41
53
  end
42
54
 
@@ -44,45 +56,112 @@ module FilterRename
44
56
  include ReadableVariables
45
57
  end
46
58
 
59
+ #
60
+ # String class patch.
61
+ #
47
62
  class ::String
48
63
  include ReadableVariables
49
64
 
50
- def black; "\033[30m#{self}\033[0m" end
51
- def red; "\033[31m#{self}\033[0m" end
52
- def green; "\033[32m#{self}\033[0m" end
53
- def yellow; "\033[33m#{self}\033[0m" end
54
- def blue; "\033[34m#{self}\033[0m" end
55
- def magenta; "\033[35m#{self}\033[0m" end
56
- def cyan; "\033[36m#{self}\033[0m" end
57
- def gray; "\033[37m#{self}\033[0m" end
58
- def bg_black; "\033[40m#{self}\0330m" end
59
- def bg_red; "\033[41m#{self}\033[0m" end
60
- def bg_green; "\033[42m#{self}\033[0m" end
61
- def bg_brown; "\033[43m#{self}\033[0m" end
62
- def bg_blue; "\033[44m#{self}\033[0m" end
63
- def bg_magenta; "\033[45m#{self}\033[0m" end
64
- def bg_cyan; "\033[46m#{self}\033[0m" end
65
- def bg_gray; "\033[47m#{self}\033[0m" end
66
- def bold; "\033[1m#{self}\033[22m" end
67
- def reverse_color; "\033[7m#{self}\033[27m" end
68
- def cr; "\r#{self}" end
69
- def clean; "\e[K#{self}" end
70
- def new_line; "\n#{self}" end
65
+ def black
66
+ "\033[30m#{self}\033[0m"
67
+ end
68
+
69
+ def red
70
+ "\033[31m#{self}\033[0m"
71
+ end
72
+
73
+ def green
74
+ "\033[32m#{self}\033[0m"
75
+ end
76
+
77
+ def yellow
78
+ "\033[33m#{self}\033[0m"
79
+ end
80
+
81
+ def blue
82
+ "\033[34m#{self}\033[0m"
83
+ end
84
+
85
+ def magenta
86
+ "\033[35m#{self}\033[0m"
87
+ end
88
+
89
+ def cyan
90
+ "\033[36m#{self}\033[0m"
91
+ end
92
+
93
+ def gray
94
+ "\033[37m#{self}\033[0m"
95
+ end
96
+
97
+ def bg_black
98
+ "\033[40m#{self}\0330m"
99
+ end
100
+
101
+ def bg_red
102
+ "\033[41m#{self}\033[0m"
103
+ end
104
+
105
+ def bg_green
106
+ "\033[42m#{self}\033[0m"
107
+ end
108
+
109
+ def bg_brown
110
+ "\033[43m#{self}\033[0m"
111
+ end
112
+
113
+ def bg_blue
114
+ "\033[44m#{self}\033[0m"
115
+ end
116
+
117
+ def bg_magenta
118
+ "\033[45m#{self}\033[0m"
119
+ end
120
+
121
+ def bg_cyan
122
+ "\033[46m#{self}\033[0m"
123
+ end
124
+
125
+ def bg_gray
126
+ "\033[47m#{self}\033[0m"
127
+ end
128
+
129
+ def bold
130
+ "\033[1m#{self}\033[22m"
131
+ end
132
+
133
+ def reverse_color
134
+ "\033[7m#{self}\033[27m"
135
+ end
136
+
137
+ def cr
138
+ "\r#{self}"
139
+ end
140
+
141
+ def clean
142
+ "\e[K#{self}"
143
+ end
144
+
145
+ def new_line
146
+ "\n#{self}"
147
+ end
71
148
 
72
149
  def parametrize
73
- self.split(/(?<!\\),/).map { |x| x.gsub('\,', ',') }
150
+ split(/(?<!\\),/).map { |x| x.gsub('\,', ",") }
74
151
  end
75
152
 
153
+ # rubocop:disable Naming/PredicateMethod
76
154
  def to_boolean
77
- self == 'true'
155
+ %w[1 true].include? downcase
78
156
  end
157
+ # rubocop:enable Naming/PredicateMethod
79
158
 
80
159
  def to_filter
81
- Object.const_get("FilterRename::Filters::#{self.to_s.split(/_|-/).map(&:capitalize).join}")
160
+ Object.const_get("FilterRename::Filters::#{to_s.split(/_|-/).map(&:capitalize).join}")
82
161
  end
83
162
 
84
163
  def to_switch
85
- self.scan(/[A-Z][a-z0-9]*/).map(&:downcase).join '-'
164
+ scan(/[A-Z][a-z0-9]*/).map(&:downcase).join "-"
86
165
  end
87
166
 
88
167
  def change_date_format(args)
@@ -93,12 +172,12 @@ module FilterRename
93
172
  long_days = args[:long_days]
94
173
  short_days = args[:short_days]
95
174
 
96
- str = self.clone
175
+ str = clone
97
176
 
98
- regexp = format_src.gsub('<B>', "(#{long_months.join('|')})").gsub('<b>', "(#{short_months.join('|')})")
99
- .gsub('<A>', "(#{long_days.join('|')})").gsub('<a>', "(#{short_days.join('|')})")
100
- .gsub('<Y>', '[0-9]{4,4}').gsub(/<(d|m|y|H|I|M|S|U)>/, '[0-9]{2,2}')
101
- .gsub('<u>', '[0-9]{1,1}')
177
+ regexp = format_src.gsub("<B>", "(#{long_months.join("|")})").gsub("<b>", "(#{short_months.join("|")})")
178
+ .gsub("<A>", "(#{long_days.join("|")})").gsub("<a>", "(#{short_days.join("|")})")
179
+ .gsub("<Y>", "[0-9]{4,4}").gsub(/<(d|m|y|H|I|M|S|U)>/, "[0-9]{2,2}")
180
+ .gsub("<u>", "[0-9]{1,1}")
102
181
 
103
182
  to_replace = str.scan(Regexp.new("(#{regexp})", true))
104
183
 
@@ -113,201 +192,293 @@ module FilterRename
113
192
  str
114
193
  end
115
194
 
116
- def map_number_with_index
117
- self.gsub(/\d+/).with_index do |num, i|
118
- yield num, i
119
- end
195
+ def map_number_with_index(&block)
196
+ gsub(/\d+/).with_index(&block)
120
197
  end
121
198
 
122
199
  def get_number(idx)
123
- self.scan(/\d+/)[idx]
200
+ scan(/\d+/)[idx]
124
201
  end
125
202
 
126
- def get_numbers
127
- self.scan(/\d+/)
203
+ def numbers
204
+ scan(/\d+/)
128
205
  end
129
206
  end
130
207
 
131
-
208
+ #
209
+ # Format the error messages.
210
+ #
132
211
  class Messages
133
-
134
- def self.error(e)
135
- if e.class == String
136
- puts '[E] '.bold.red + e
212
+ def self.error(err)
213
+ if err.instance_of?(String)
214
+ puts "[E] ".bold.red + err
137
215
  else
138
- STDERR.puts 'Error! '.bold.red + e.message
216
+ warn "Error! ".bold.red + err.message
139
217
  end
140
218
  end
141
219
 
142
- def self.warning(m)
143
- puts '[W] '.bold.yellow + m
220
+ def self.warning(msg)
221
+ puts "[W] ".bold.yellow + msg
144
222
  end
145
223
 
146
- def self.ok(m)
147
- puts '[V] '.bold.green + m
224
+ def self.ok(msg)
225
+ puts "[V] ".bold.green + msg
148
226
  end
149
227
 
150
- def self.multi(m)
151
- puts '[*] '.bold.magenta + m
228
+ def self.multi(msg)
229
+ puts "[*] ".bold.magenta + msg
152
230
  end
153
231
 
154
- def self.diff(fp)
155
- puts fp.diff
232
+ def self.diff(fpipe)
233
+ puts fpipe.diff
156
234
  end
157
235
 
158
- def self.renamed(fp)
159
- if fp.source.full_path != fp.dest.full_path
160
- Messages.ok "#{fp.source.filename} #{'>'.bold.green} #{fp.dest.full_filename}"
236
+ def self.renamed(fpipe)
237
+ if fpipe.source.full_path == fpipe.dest.full_path
238
+ Messages.ok "#{fpipe.source.filename} #{">".bold.green} #{fpipe.dest.filename}"
161
239
  else
162
- Messages.ok "#{fp.source.filename} #{'>'.bold.green} #{fp.dest.filename}"
240
+ Messages.ok "#{fpipe.source.filename} #{">".bold.green} #{fpipe.dest.full_filename}"
163
241
  end
164
242
  end
165
243
 
166
244
  def self.renamed!(old_data, renamed)
167
- if old_data[:full_path] != renamed.full_path
168
- Messages.ok "#{old_data[:filename]} #{'>'.bold.green} #{renamed.full_filename}"
245
+ if old_data[:full_path] == renamed.full_path
246
+ Messages.ok "#{old_data[:filename]} #{">".bold.green} #{renamed.filename}"
169
247
  else
170
- Messages.ok "#{old_data[:filename]} #{'>'.bold.green} #{renamed.filename}"
248
+ Messages.ok "#{old_data[:filename]} #{">".bold.green} #{renamed.full_filename}"
171
249
  end
172
250
  end
173
251
 
174
-
175
252
  def self.label(text)
176
- puts "#{'[/]'.bold.blue} #{text}"
253
+ puts "#{"[/]".bold.blue} #{text}"
177
254
  end
178
255
 
179
- def self.skipping(fp)
180
- puts '[X] '.bold.yellow + "Skipping <#{fp.source.filename}>, no changes!"
256
+ def self.skipping(fpipe)
257
+ puts "[X] ".bold.yellow + "Skipping <#{fpipe.source.filename}>, no changes!"
181
258
  end
182
259
 
183
- def self.changed_tags(fp, old_data = {}, header = true)
184
- Messages.ok "<#{fp.source.filename}> tags changed:" if header
185
- old_source = old_data.empty? ? fp.source.values : old_data
260
+ # rubocop:disable Style/HashEachMethods
261
+ # rubocop:disable Style/OptionalBooleanParameter
262
+ def self.changed_tags(fpipe, old_data = {}, header = true)
263
+ Messages.ok "<#{fpipe.source.filename}> tags changed:" if header
264
+ old_source = old_data.empty? ? fpipe.source.values : old_data
186
265
 
187
- fp.dest.values.each do |k, v|
188
- puts " #{k}: ".rjust(15, ' ').bold.green + (old_source[k].to_s.empty? ? ' ~ '.bold.red : old_source[k].to_s) + ' => '.bold.green + v.to_s if ((v.to_s != old_source[k].to_s) && fp.source.writable?(k) && fp.source.custom?(k))
266
+ fpipe.dest.values.each do |k, v|
267
+ next unless (v.to_s != old_source[k].to_s) && fpipe.source.writable?(k) && fpipe.source.custom?(k)
268
+
269
+ puts " #{k}: ".rjust(15, " ")
270
+ .bold.green +
271
+ (if old_source[k].to_s.empty?
272
+ " ~ ".bold.red
273
+ else
274
+ old_source[k].to_s
275
+ end) + " => ".bold.green + v.to_s
189
276
  end
190
277
  end
278
+ # rubocop:enable Style/HashEachMethods
279
+ # rubocop:enable Style/OptionalBooleanParameter
191
280
 
192
- def self.file_exists(fp)
193
- Messages.error "<#{fp.source.filename}> can't be renamed in <#{fp.dest.filename}>, it exists!"
281
+ def self.file_exists(fpipe)
282
+ Messages.error "<#{fpipe.source.filename}> can't be renamed in <#{fpipe.dest.filename}>, it exists!"
194
283
  end
195
284
 
196
- def self.file_hash(fp, hash_type, cached = nil)
197
- raise UnknownHashCode, hash_type unless [:sha1, :sha2, :md5].include?(hash_type.to_sym)
285
+ def self.file_hash(fpipe, hash_type, cached = nil)
286
+ raise UnknownHashCode, hash_type unless %i[sha1 sha2 md5].include?(hash_type.to_sym)
287
+
198
288
  klass = Object.const_get("Digest::#{hash_type.to_s.upcase}")
199
- hash_src = klass.file fp.source.filename
200
- hash_dest = cached ? klass.file(cached.original) : klass.file(fp.dest.filename)
289
+ hash_src = klass.file fpipe.source.filename
290
+ hash_dest = cached ? klass.file(cached.original) : klass.file(fpipe.dest.filename)
201
291
 
202
- puts " #{hash_src == hash_dest ? '[=]'.green : '[>]'.red} #{hash_type.to_s.upcase} source: #{hash_src.to_s.send(hash_src == hash_dest ? :green : :red)}"
203
- puts " #{hash_src == hash_dest ? '[=]'.green : '[<]'.red} #{hash_type.to_s.upcase} dest: #{hash_dest.to_s.send(hash_src == hash_dest ? :green : :red)}"
292
+ puts " #{hash_src == hash_dest ? "[=]".green : "[>]".red} " \
293
+ "#{hash_type.to_s.upcase} source: " \
294
+ "#{hash_src.to_s.send(hash_src == hash_dest ? :green : :red)}"
295
+ puts " #{hash_src == hash_dest ? "[=]".green : "[<]".red} " \
296
+ "#{hash_type.to_s.upcase} dest: " \
297
+ "#{hash_dest.to_s.send(hash_src == hash_dest ? :green : :red)}"
204
298
  end
205
299
 
206
- def self.short_targets(ff)
207
- self.list [ff.targets[:readonly].map { |s| "<#{s.to_s.delete('@')}>"}.join(', ')], :red, '-'
208
- self.list [ff.targets[:writable].map { |s| "<#{s.to_s.delete('@')}>"}.join(', ')], :green, '+'
209
- puts ''
300
+ def self.renaming_summary(renamed, skipped, errors)
301
+ puts ""
302
+ puts "=" * 40
303
+ Messages.ok("Renamed: #{renamed}")
304
+ Messages.warning("Unchanged: #{skipped}")
305
+ Messages.error("Errors: #{errors}")
210
306
  end
211
307
 
212
- def self.long_targets(ff)
213
- self.list ff.targets[:readonly].map { |s| "<#{s.to_s.delete('@')}>" }, :red, '-'
214
- self.list ff.targets[:writable].map { |s| "<#{s.to_s.delete('@')}>" }, :green, '+'
215
- puts ''
308
+ def self.inline_targets(ffilters)
309
+ list [ffilters.targets[:readonly].map { |s| "<#{s.to_s.delete("@")}>" }.join(", ")], :red, "-"
310
+ list [ffilters.targets[:writable].map { |s| "<#{s.to_s.delete("@")}>" }.join(", ")], :green, "+"
311
+ puts ""
216
312
  end
217
313
 
218
- def self.item(i, color = :green, ch = '>')
219
- puts "[#{ch}] ".bold.send(color) + i
314
+ def self.column_targets(ffilters)
315
+ list ffilters.targets[:readonly].map { |s| "<#{s.to_s.delete("@")}>" }, :red, "-"
316
+ list ffilters.targets[:writable].map { |s| "<#{s.to_s.delete("@")}>" }, :green, "+"
317
+ puts ""
220
318
  end
221
319
 
222
- def self.list(items, color = :green, ch = '>')
223
- items.each { |x| Messages.item(x, color, ch) }
320
+ def self.inline_target_values(ffilters)
321
+ values = ffilters.values
322
+
323
+ list [ffilters.targets[:readonly].map { |s| "#{s}: #{values[s]}" }.join(", ")], :red, "-"
324
+ list [ffilters.targets[:writable].map { |s| "#{s}: #{values[s]}" }.join(", ")], :green, "+"
325
+ end
326
+
327
+ def self.column_target_values(ffilters)
328
+ values = ffilters.values
329
+
330
+ list ffilters.targets[:readonly].map { |s| "#{s}: #{values[s]}" }, :red, "-"
331
+ list ffilters.targets[:writable].map { |s| "#{s}: #{values[s]}" }, :green, "+"
332
+ end
333
+
334
+ def self.item(idx, color = :green, char = ">")
335
+ puts "[#{char}] ".bold.send(color) + idx
336
+ end
337
+
338
+ def self.list(items, color = :green, char = ">")
339
+ items.each { |x| Messages.item(x, color, char) }
224
340
  end
225
341
 
226
- def self.config_list(items, color = :green, ch = '>')
227
- items.instance_variables.each { |k| Messages.item("#{k.to_s.gsub(/@/, '')}: #{items.instance_variable_get(k)}", color, ch) }
342
+ def self.config_list(items, color = :green, char = ">")
343
+ items.instance_variables.each do |k|
344
+ Messages.item("#{k.to_s.gsub(/@/, "")}: #{items.instance_variable_get(k)}", color, char)
345
+ end
346
+ end
347
+
348
+ def self.config_multilist(items, color = :green, char = ">")
349
+ items.instance_variables.each do |k|
350
+ Messages.item("#{k.to_s.gsub(/@/, "")}: [#{items.instance_variable_get(k).keys.join(", ")}]", color, char)
351
+ end
228
352
  end
229
353
 
230
- def self.config_multilist(items, color = :green, ch = '>')
231
- items.instance_variables.each { |k| Messages.item("#{k.to_s.gsub(/@/, '')}: [#{items.instance_variable_get(k).keys.join(', ')}]", color, ch) }
354
+ def self.help_option(name, data)
355
+ puts "OPTION:\n #{name}"
356
+ puts "\nDEFAULT VALUE:\n #{data[:default] == " " ? "(SPACE)" : data[:default]}"
357
+ puts "\nDESCRIPTION:\n#{data[:long].split("\n").map { |l| " #{l}" }.join("\n")}"
358
+ puts ""
232
359
  end
233
360
  end
234
361
 
362
+ #
363
+ # Index out of range error.
364
+ #
235
365
  class IndexOutOfRange < StandardError
236
366
  def initialize(values)
237
- super "Invalid index '#{values[0]}' out of the range 1..#{values[1]}, -#{values[1]}..-1"
367
+ super("Invalid index '#{values[0]}' out of the range 1..#{values[1]}, -#{values[1]}..-1")
238
368
  end
239
369
  end
240
370
 
371
+ #
372
+ # Unknown hash error.
373
+ #
241
374
  class UnknownHashCode < StandardError
242
375
  def initialize(hash_type)
243
- super "Invalid hash type: #{hash_type}"
376
+ super("Invalid hash type: #{hash_type}")
244
377
  end
245
378
  end
246
379
 
380
+ #
381
+ # Invalid option as argument.
382
+ #
383
+ class InvalidOption < StandardError
384
+ def initialize(option)
385
+ super("The option #{option} doesn't exist")
386
+ end
387
+ end
388
+
389
+ #
390
+ # Invalid macro error.
391
+ #
247
392
  class InvalidMacro < StandardError
248
393
  def initialize(macro)
249
- super "Invalid macro: #{macro}"
394
+ super("Invalid macro: #{macro}")
250
395
  end
251
396
  end
252
397
 
398
+ #
399
+ # Invalid target error.
400
+ #
253
401
  class InvalidTarget < StandardError
254
402
  def initialize(target)
255
- super "Invalid target: #{target}"
403
+ super("Invalid target: #{target}")
256
404
  end
257
405
  end
258
406
 
407
+ #
408
+ # Invalid filter setting error.
409
+ #
259
410
  class InvalidFilterSetting < StandardError
260
411
  def initialize(name)
261
- super "Invalid configuration setting: #{name}"
412
+ super("Invalid configuration setting: #{name}")
262
413
  end
263
414
  end
264
415
 
416
+ #
417
+ # Invalid word's group.
418
+ #
265
419
  class InvalidWordsGroup < StandardError
266
420
  def initialize(group)
267
- super "Invalid words group: #{group}"
421
+ super("Invalid words group: #{group}")
268
422
  end
269
423
  end
270
424
 
425
+ #
426
+ # Invalid words section.
427
+ #
271
428
  class InvalidWordsSection < StandardError
272
429
  def initialize(group, section)
273
- super "Invalid words section for #{group}: #{section}"
430
+ super("Invalid words section for #{group}: #{section}")
274
431
  end
275
432
  end
276
433
 
434
+ #
435
+ # Invalid words index.
436
+ #
277
437
  class InvalidWordsIndex < StandardError
278
438
  def initialize(group, section, idx)
279
- super "Missing the item #{idx + 1} in #{group}/#{section} words section"
439
+ super("Missing the item #{idx + 1} in #{group}/#{section} words section")
280
440
  end
281
441
  end
282
442
 
443
+ #
444
+ # File not found error.
445
+ #
283
446
  class FileNotFound < StandardError
284
447
  def initialize(filename)
285
- super "File not found: #{filename}"
448
+ super("File not found: #{filename}")
286
449
  end
287
450
  end
288
451
 
452
+ #
453
+ # Missing files error.
454
+ #
289
455
  class MissingFiles < StandardError
290
456
  def initialize
291
- super 'No filenames specified'
457
+ super("No filenames specified")
292
458
  end
293
459
  end
294
460
 
461
+ #
462
+ # Existing file error.
463
+ #
295
464
  class ExistingFile < StandardError
296
465
  def initialize(filename)
297
- super "The file #{filename} already exists and won't be overwrite"
466
+ super("The file #{filename} already exists and won't be overwrite")
298
467
  end
299
468
  end
300
469
 
470
+ #
471
+ # Ctrl + C message error.
472
+ #
301
473
  class Interruption < StandardError
302
474
  def initialize
303
- super 'Ok ok... Exiting!'
475
+ super("Ok ok... Exiting!")
304
476
  end
305
477
  end
306
478
 
479
+ Differ.format = :color
307
480
 
308
- Differ.format = :color
309
-
310
- Signal.trap('INT') { raise Interruption }
481
+ Signal.trap("INT") { raise Interruption }
311
482
 
312
- Signal.trap('TERM') { raise Interruption }
483
+ Signal.trap("TERM") { raise Interruption }
313
484
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FilterRename
2
- VERSION = '1.1.0'
4
+ VERSION = "1.2.0"
3
5
  end