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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +5 -3
- data/.github/workflows/gem-push.yml +46 -0
- data/.github/workflows/main.yml +32 -0
- data/.rubocop.yml +84 -0
- data/Gemfile +15 -1
- data/README.md +83 -39
- data/Rakefile +7 -1
- data/exe/filter_rename +1 -1
- data/filter_rename.gemspec +23 -25
- data/lib/filter_rename/cli.rb +121 -61
- data/lib/filter_rename/config.rb +218 -49
- data/lib/filter_rename/filename.rb +50 -39
- data/lib/filter_rename/filename_factory.rb +22 -17
- data/lib/filter_rename/filetype/audio_filename.rb +86 -0
- data/lib/filter_rename/filetype/image_filename.rb +18 -12
- data/lib/filter_rename/filetype/mp3_filename.rb +18 -18
- data/lib/filter_rename/filetype/pdf_filename.rb +19 -12
- data/lib/filter_rename/filter_base.rb +89 -69
- data/lib/filter_rename/filter_pipe.rb +20 -15
- data/lib/filter_rename/filters.rb +570 -273
- data/lib/filter_rename/utils.rb +288 -117
- data/lib/filter_rename/version.rb +3 -1
- data/lib/filter_rename.rb +95 -32
- data/lib/filter_rename.yaml +20 -10
- metadata +28 -41
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "delegate"
|
|
4
|
+
require "keisan"
|
|
4
5
|
|
|
6
|
+
module FilterRename
|
|
7
|
+
#
|
|
5
8
|
# This is the class which handles the list
|
|
6
9
|
# of filters.
|
|
10
|
+
#
|
|
7
11
|
class FilterList
|
|
8
12
|
attr_reader :filters
|
|
9
13
|
|
|
@@ -12,35 +16,34 @@ module FilterRename
|
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
def expand_macros!(macro)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@filters.insert(i + z, k.to_s.to_filter => v)
|
|
26
|
-
end
|
|
27
|
-
z += 1
|
|
19
|
+
@filters.each_with_index do |names, idx|
|
|
20
|
+
next unless names.keys[0] == FilterRename::MacroConfig
|
|
21
|
+
|
|
22
|
+
z = 1
|
|
23
|
+
names.values.pop.each do |n|
|
|
24
|
+
macro.get_macro(n).each do |k, v|
|
|
25
|
+
if v.nil? # Array
|
|
26
|
+
@filters.insert(idx + z, k.keys[0].to_s.to_filter => k[k.keys[0]])
|
|
27
|
+
else # Hash
|
|
28
|
+
@filters.insert(idx + z, k.to_s.to_filter => v)
|
|
28
29
|
end
|
|
29
|
-
|
|
30
|
+
z += 1
|
|
30
31
|
end
|
|
32
|
+
@filters[idx] = nil
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
@filters.delete_if(&:nil?)
|
|
35
37
|
end
|
|
36
|
-
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
#
|
|
41
|
+
# The base class for all type of
|
|
42
|
+
# filters.
|
|
43
|
+
#
|
|
40
44
|
class FilterBase < SimpleDelegator
|
|
41
|
-
|
|
42
45
|
def initialize(obj, options)
|
|
43
|
-
super
|
|
46
|
+
super(obj)
|
|
44
47
|
@dest = obj # useful for macros
|
|
45
48
|
@cfg = options[:cfg]
|
|
46
49
|
@words = options[:words]
|
|
@@ -51,15 +54,15 @@ module FilterRename
|
|
|
51
54
|
end
|
|
52
55
|
|
|
53
56
|
def set_config(name, value)
|
|
54
|
-
raise InvalidFilterSetting, name unless @cfg.instance_variables.include?("@#{name}"
|
|
57
|
+
raise InvalidFilterSetting, name unless @cfg.instance_variables.include?(:"@#{name}")
|
|
55
58
|
|
|
56
|
-
@cfg.instance_variable_set
|
|
59
|
+
@cfg.instance_variable_set "@#{name}", value
|
|
57
60
|
end
|
|
58
61
|
|
|
59
62
|
def get_config(name)
|
|
60
|
-
raise InvalidFilterSetting, name unless @cfg.instance_variables.include?("@#{name}"
|
|
63
|
+
raise InvalidFilterSetting, name unless @cfg.instance_variables.include?(:"@#{name}")
|
|
61
64
|
|
|
62
|
-
@cfg.instance_variable_get
|
|
65
|
+
@cfg.instance_variable_get "@#{name}"
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
def filter(value)
|
|
@@ -67,18 +70,20 @@ module FilterRename
|
|
|
67
70
|
end
|
|
68
71
|
|
|
69
72
|
def set_string(value, target = nil)
|
|
73
|
+
return if value.nil?
|
|
74
|
+
|
|
70
75
|
if target.nil?
|
|
71
|
-
super
|
|
76
|
+
super(@cfg.target, value)
|
|
72
77
|
else
|
|
73
|
-
super
|
|
74
|
-
end
|
|
78
|
+
super(target, value)
|
|
79
|
+
end
|
|
75
80
|
end
|
|
76
81
|
|
|
77
82
|
def get_string(target = nil)
|
|
78
83
|
if target.nil?
|
|
79
|
-
super
|
|
84
|
+
super(@cfg.target)
|
|
80
85
|
else
|
|
81
|
-
super
|
|
86
|
+
super
|
|
82
87
|
end
|
|
83
88
|
end
|
|
84
89
|
|
|
@@ -96,9 +101,11 @@ module FilterRename
|
|
|
96
101
|
end
|
|
97
102
|
end
|
|
98
103
|
|
|
99
|
-
|
|
104
|
+
#
|
|
105
|
+
# Mixin module for all those filters
|
|
106
|
+
# that make use of indexes.
|
|
107
|
+
#
|
|
100
108
|
module IndexedParams
|
|
101
|
-
|
|
102
109
|
attr_reader :params, :params_expanded, :items
|
|
103
110
|
|
|
104
111
|
def normalize_index(idx)
|
|
@@ -106,26 +113,25 @@ module FilterRename
|
|
|
106
113
|
raise IndexOutOfRange, [idx, max_length] if idx.to_i > max_length || idx.to_i < -max_length
|
|
107
114
|
|
|
108
115
|
if idx.to_i.positive?
|
|
109
|
-
idx = idx.to_i.pred
|
|
116
|
+
idx = idx.to_i.pred # % max_length
|
|
110
117
|
elsif idx.to_i.negative?
|
|
111
118
|
idx = idx.to_i + max_length # % max_length
|
|
112
119
|
end
|
|
113
120
|
idx.to_i
|
|
114
121
|
end
|
|
115
122
|
|
|
116
|
-
def
|
|
123
|
+
def indexes
|
|
117
124
|
indexes = []
|
|
118
|
-
params_length =
|
|
125
|
+
params_length = indexed_params.zero? ? params.length : indexed_params
|
|
119
126
|
|
|
120
127
|
params[0..params_length.pred].each do |x|
|
|
121
128
|
if x =~ /\.\./
|
|
122
|
-
indexes
|
|
129
|
+
indexes += Range.new(*(x.split("..").map { |y| normalize_index(y) })).map { |idx| idx }
|
|
123
130
|
elsif x =~ /:/
|
|
124
|
-
indexes
|
|
131
|
+
indexes += x.split(":").map { |y| normalize_index(y) }
|
|
125
132
|
else
|
|
126
133
|
indexes << normalize_index(x)
|
|
127
134
|
end
|
|
128
|
-
|
|
129
135
|
end
|
|
130
136
|
|
|
131
137
|
indexes
|
|
@@ -146,24 +152,25 @@ module FilterRename
|
|
|
146
152
|
def filter(params)
|
|
147
153
|
@params = params
|
|
148
154
|
@items = indexed_items
|
|
149
|
-
@params_expanded =
|
|
155
|
+
@params_expanded = indexes
|
|
150
156
|
|
|
151
157
|
res = loop_items
|
|
152
158
|
|
|
153
159
|
if self_targeted?
|
|
154
|
-
super
|
|
160
|
+
super(get_string)
|
|
155
161
|
else
|
|
156
|
-
super
|
|
162
|
+
super(res)
|
|
157
163
|
end
|
|
158
164
|
end
|
|
159
165
|
end
|
|
160
166
|
|
|
161
|
-
|
|
167
|
+
#
|
|
168
|
+
# Base class for all the word
|
|
169
|
+
# oriented filters
|
|
170
|
+
#
|
|
162
171
|
class FilterWord < FilterBase
|
|
163
|
-
|
|
164
172
|
include IndexedParams
|
|
165
173
|
|
|
166
|
-
|
|
167
174
|
private
|
|
168
175
|
|
|
169
176
|
def ws
|
|
@@ -185,11 +192,28 @@ module FilterRename
|
|
|
185
192
|
end
|
|
186
193
|
end
|
|
187
194
|
|
|
188
|
-
|
|
195
|
+
#
|
|
196
|
+
# Base class for all the number oriented
|
|
197
|
+
# filters.
|
|
198
|
+
#
|
|
189
199
|
class FilterNumber < FilterBase
|
|
190
|
-
|
|
191
200
|
include IndexedParams
|
|
192
201
|
|
|
202
|
+
def self.calculator(num, expr)
|
|
203
|
+
@@calc ||= Keisan::Calculator.new
|
|
204
|
+
begin
|
|
205
|
+
@@calc.evaluate("gt()")
|
|
206
|
+
rescue StandardError
|
|
207
|
+
@@calc.define_function!(:gt, ->(x) { num > x })
|
|
208
|
+
@@calc.define_function!(:lt, ->(x) { num < x })
|
|
209
|
+
@@calc.define_function!(:gte, ->(x) { num >= x })
|
|
210
|
+
@@calc.define_function!(:lte, ->(x) { num <= x })
|
|
211
|
+
@@calc.define_function!(:inc, ->(x) { num + x })
|
|
212
|
+
@@calc.define_function!(:mult, ->(x) { num * x })
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
@@calc.evaluate(expr)
|
|
216
|
+
end
|
|
193
217
|
|
|
194
218
|
private
|
|
195
219
|
|
|
@@ -198,7 +222,7 @@ module FilterRename
|
|
|
198
222
|
end
|
|
199
223
|
|
|
200
224
|
def indexed_items
|
|
201
|
-
string_to_loop.
|
|
225
|
+
string_to_loop.numbers
|
|
202
226
|
end
|
|
203
227
|
|
|
204
228
|
def loop_items
|
|
@@ -206,43 +230,42 @@ module FilterRename
|
|
|
206
230
|
numbers = items.clone
|
|
207
231
|
|
|
208
232
|
params_expanded.each_with_index do |idx, param_idx|
|
|
209
|
-
numbers[idx] =
|
|
233
|
+
numbers[idx] = send :filtered_number, numbers[idx], param_idx.next
|
|
210
234
|
end
|
|
211
|
-
str
|
|
212
|
-
numbers[
|
|
235
|
+
str.map_number_with_index do |_num, idx|
|
|
236
|
+
numbers[idx]
|
|
213
237
|
end
|
|
214
|
-
|
|
215
|
-
str
|
|
216
238
|
end
|
|
217
239
|
end
|
|
218
240
|
|
|
219
|
-
|
|
241
|
+
#
|
|
242
|
+
# Base class for all the Regexp
|
|
243
|
+
# oriented filters.
|
|
244
|
+
#
|
|
220
245
|
class FilterRegExp < FilterBase
|
|
221
|
-
|
|
222
246
|
def filter(params)
|
|
223
|
-
super
|
|
247
|
+
super(loop_regex(get_string, params))
|
|
224
248
|
end
|
|
225
249
|
|
|
226
|
-
|
|
227
250
|
private
|
|
228
251
|
|
|
229
252
|
def loop_regex(str, params)
|
|
230
|
-
str
|
|
253
|
+
str.gsub(Regexp.new(wrap_regex(params[0]), get_config(:ignore_case).to_boolean)) do |_x|
|
|
231
254
|
matches = Regexp.last_match.clone
|
|
232
|
-
|
|
255
|
+
send(:filtered_regexp, matches.to_a.delete_if(&:nil?), params).to_s.gsub(/\\([0-9]+)/) do |_y|
|
|
256
|
+
matches[::Regexp.last_match(1).to_i]
|
|
257
|
+
end
|
|
233
258
|
end
|
|
234
|
-
|
|
235
|
-
str
|
|
236
259
|
end
|
|
237
|
-
|
|
238
260
|
end
|
|
239
261
|
|
|
240
|
-
|
|
262
|
+
#
|
|
263
|
+
# Base class for all the occurence
|
|
264
|
+
# oriented filters.
|
|
265
|
+
#
|
|
241
266
|
class FilterOccurrence < FilterBase
|
|
242
|
-
|
|
243
267
|
include IndexedParams
|
|
244
268
|
|
|
245
|
-
|
|
246
269
|
private
|
|
247
270
|
|
|
248
271
|
def os
|
|
@@ -259,14 +282,11 @@ module FilterRename
|
|
|
259
282
|
occurences = items.clone
|
|
260
283
|
|
|
261
284
|
params_expanded.each_with_index do |idx, param_idx|
|
|
262
|
-
occurences[idx] =
|
|
285
|
+
occurences[idx] = send :filtered_occurrence, occurences[idx], param_idx.next
|
|
263
286
|
end
|
|
264
|
-
str
|
|
265
|
-
occurences[
|
|
287
|
+
str.gsub(regexp).with_index do |_idxtem, _i|
|
|
288
|
+
occurences[idx]
|
|
266
289
|
end
|
|
267
|
-
|
|
268
|
-
str
|
|
269
290
|
end
|
|
270
291
|
end
|
|
271
|
-
|
|
272
292
|
end
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module FilterRename
|
|
4
|
+
#
|
|
5
|
+
# Class that handles the filters
|
|
6
|
+
# applying them one after one.
|
|
7
|
+
#
|
|
3
8
|
class FilterPipe
|
|
4
9
|
attr_reader :source, :dest
|
|
5
10
|
|
|
@@ -8,27 +13,25 @@ module FilterRename
|
|
|
8
13
|
@cfg = cfg.filter.clone
|
|
9
14
|
@source = FilenameFactory.create(fname, cfg.global)
|
|
10
15
|
@dest = Marshal.load(Marshal.dump(@source))
|
|
11
|
-
@filters =
|
|
16
|
+
@filters = filters.instance_of?(Array) ? filters : filters.filters
|
|
12
17
|
@words = cfg.words
|
|
13
18
|
end
|
|
14
19
|
|
|
15
20
|
def changed?
|
|
16
|
-
!
|
|
21
|
+
!unchanged?
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
def unchanged?
|
|
20
25
|
@source == @dest
|
|
21
26
|
end
|
|
22
|
-
|
|
27
|
+
alias identical? unchanged?
|
|
23
28
|
|
|
24
29
|
def diff
|
|
25
30
|
@source.diff(@dest)
|
|
26
31
|
end
|
|
27
32
|
|
|
28
33
|
def apply
|
|
29
|
-
|
|
30
|
-
@filters.each_with_index do |f, i|
|
|
31
|
-
|
|
34
|
+
@filters.each_with_index do |f, _i|
|
|
32
35
|
filter = f.keys.pop
|
|
33
36
|
params = f.values.pop
|
|
34
37
|
|
|
@@ -37,7 +40,6 @@ module FilterRename
|
|
|
37
40
|
else
|
|
38
41
|
filter.new(@dest, cfg: @cfg, words: @words).filter(params) unless skip?
|
|
39
42
|
end
|
|
40
|
-
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
self
|
|
@@ -50,15 +52,18 @@ module FilterRename
|
|
|
50
52
|
private
|
|
51
53
|
|
|
52
54
|
def skip?
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
grep_on = @cfg.grep_on_dest ? :dest : :source
|
|
56
|
+
unmatched = if %i[full_filename full_path filename].include? @cfg.grep_target.to_sym
|
|
57
|
+
instance_variable_get("@#{grep_on}")
|
|
58
|
+
.send(@cfg.grep_target.to_sym)
|
|
59
|
+
.match(Regexp.new(@cfg.grep)).nil?
|
|
60
|
+
else
|
|
61
|
+
instance_variable_get("@#{grep_on}")
|
|
62
|
+
.get_string(@cfg.grep_target)
|
|
63
|
+
.match(Regexp.new(@cfg.grep)).nil?
|
|
64
|
+
end
|
|
58
65
|
|
|
59
66
|
@cfg.grep_exclude.to_s.to_boolean ? !unmatched : unmatched
|
|
60
67
|
end
|
|
61
|
-
|
|
62
68
|
end
|
|
63
|
-
|
|
64
69
|
end
|