filter_rename 1.0.0 → 1.1.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 +14 -0
- data/filter_rename.gemspec +4 -4
- data/lib/filter_rename/cli.rb +1 -1
- data/lib/filter_rename/config.rb +7 -3
- data/lib/filter_rename/filename.rb +14 -1
- data/lib/filter_rename/filetype/mp3_filename.rb +9 -7
- data/lib/filter_rename/filter_base.rb +116 -35
- data/lib/filter_rename/filters.rb +261 -90
- data/lib/filter_rename/utils.rb +31 -1
- data/lib/filter_rename/version.rb +1 -1
- data/lib/filter_rename.rb +8 -5
- data/lib/filter_rename.yaml +7 -3
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0772829a453b3d53a307e213ea42d969c6f5f6598a47ca8c19236b2eae7d46fb'
|
4
|
+
data.tar.gz: ac03f34f6eca2f5650bc283f7c139e4f8032cf87a25134b810eda5716a9577de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a33e3231cdc186f63cacb21ef752ca78b136a76f64c138ec02cf58470d2ebb02afc35dc5e0a22dbce2a712a93e184faf1a962cce66ab2ef948771fe2f546789
|
7
|
+
data.tar.gz: d08e371afb6cea91b7cef9a228b8e8f4f49bcf3c618b6d1ae0b32664539b744d41a9f02d97fc5537bcc60fa00348f3da54cb10679ba23571beda6c1cf18a5293
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# These are supported funding model platforms
|
2
|
+
|
3
|
+
github: [fabiomux]
|
4
|
+
#patreon: # Replace with a single Patreon username
|
5
|
+
#open_collective: # Replace with a single Open Collective username
|
6
|
+
#ko_fi: # Replace with a single Ko-fi username
|
7
|
+
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
8
|
+
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
9
|
+
#liberapay: # Replace with a single Liberapay username
|
10
|
+
#issuehunt: # Replace with a single IssueHunt username
|
11
|
+
#otechie: # Replace with a single Otechie username
|
12
|
+
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
13
|
+
custom: ['https://www.buymeacoffee.com/DCkNYFg']
|
14
|
+
|
data/filter_rename.gemspec
CHANGED
@@ -9,16 +9,16 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Fabio Mucciante"]
|
10
10
|
spec.email = ["fabio.mucciante@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{
|
12
|
+
spec.summary = %q{File renaming tool which make use of a chain of actions called filters.}
|
13
|
+
spec.description = %q{FilterRename is a bulk renaming tool, based on the concept of filters as small operations to perform over sections of the full filename logically represented in targets.}
|
14
14
|
spec.homepage = "https://github.com/fabiomux/filter_rename"
|
15
15
|
spec.license = "GPL-3.0"
|
16
16
|
|
17
17
|
spec.metadata = {
|
18
18
|
"bug_tracker_uri" => "https://github.com/fabiomux/filter_rename/issues",
|
19
|
-
|
19
|
+
"changelog_uri" => "https://freeaptitude.altervista.org/projects/filter-rename.htm#changelog",
|
20
20
|
"documentation_uri" => "https://www.rubydoc.info/gems/filter_rename/#{spec.version}",
|
21
|
-
"homepage_uri" => "https://
|
21
|
+
"homepage_uri" => "https://freeaptitude.altervista.org/projects/filter-rename.html",
|
22
22
|
#"mailing_list_uri" => "",
|
23
23
|
"source_code_uri" => "https://github.com/fabiomux/filter_rename",
|
24
24
|
"wiki_uri" => "https://github.com/fabiomux/filter_rename/wiki"
|
data/lib/filter_rename/cli.rb
CHANGED
data/lib/filter_rename/config.rb
CHANGED
@@ -53,12 +53,14 @@ module FilterRename
|
|
53
53
|
|
54
54
|
|
55
55
|
class GlobalConfig
|
56
|
-
attr_reader :date_format, :hash_type, :counter_length, :counter_start, :targets,
|
56
|
+
attr_reader :date_format, :hash_type, :hash_on_tags, :hash_if_exists, :counter_length, :counter_start, :targets,
|
57
57
|
:pdf_metadata, :image_metadata, :mp3_metadata
|
58
58
|
|
59
59
|
def initialize(cfg)
|
60
60
|
@date_format = cfg[:date_format] || '%Y-%m-%d'
|
61
|
-
@hash_type =
|
61
|
+
@hash_type = cfg[:hash_type].to_sym || :md5
|
62
|
+
@hash_on_tags = cfg[:hash_on_tags] || false
|
63
|
+
@hash_if_exists = cfg[:hash_if_exists] || false
|
62
64
|
@counter_length = cfg[:counter_length] || 4
|
63
65
|
@counter_start = cfg[:counter_start] || 0
|
64
66
|
@targets = cfg[:targets].to_sym || :short
|
@@ -70,10 +72,12 @@ module FilterRename
|
|
70
72
|
|
71
73
|
|
72
74
|
class FilterConfig
|
73
|
-
attr_accessor
|
75
|
+
attr_accessor :word_separator, :number_separator, :occurrence_separator, :target, :ignore_case, :lang, :grep, :grep_on, :grep_exclude, :grep_target
|
74
76
|
|
75
77
|
def initialize(cfg)
|
76
78
|
@word_separator = cfg[:word_separator] || ' '
|
79
|
+
@number_separator = cfg[:number_separator] || '.'
|
80
|
+
@occurrence_separator = cfg[:occurrence_separator] || '-'
|
77
81
|
@target = cfg[:target].to_sym || :name
|
78
82
|
@ignore_case = cfg[:ignore_case].nil? ? true : cfg[:ignore_case].to_boolean
|
79
83
|
@lang = (cfg[:lang] || :en).to_sym
|
@@ -2,6 +2,8 @@ module FilterRename
|
|
2
2
|
|
3
3
|
class Filename
|
4
4
|
|
5
|
+
attr_reader :original
|
6
|
+
|
5
7
|
def self.has_writable_tags
|
6
8
|
false
|
7
9
|
end
|
@@ -11,6 +13,7 @@ module FilterRename
|
|
11
13
|
@@count += 1
|
12
14
|
@cfg = cfg
|
13
15
|
|
16
|
+
@original = fname
|
14
17
|
load_filename_data(fname)
|
15
18
|
end
|
16
19
|
|
@@ -100,6 +103,14 @@ module FilterRename
|
|
100
103
|
res
|
101
104
|
end
|
102
105
|
|
106
|
+
def writable?(tag)
|
107
|
+
instance_variable_get("@#{tag}".to_sym).writable?
|
108
|
+
end
|
109
|
+
|
110
|
+
def custom?(tag)
|
111
|
+
instance_variable_get("@#{tag}".to_sym).custom?
|
112
|
+
end
|
113
|
+
|
103
114
|
def values
|
104
115
|
res = {}
|
105
116
|
instance_variables.each do |v|
|
@@ -135,7 +146,9 @@ module FilterRename
|
|
135
146
|
|
136
147
|
[@count, @ctime, @mtime, @size, @pretty_size].map(&:readonly!)
|
137
148
|
|
138
|
-
|
149
|
+
[@ext, @name, @path, @folder, @path, @count, @ctime, @size, @pretty_size].map(&:basic!)
|
150
|
+
|
151
|
+
metatag_to_var!('hash', calculate_hash(@cfg.hash_type), true) if @cfg.hash_on_tags
|
139
152
|
end
|
140
153
|
end
|
141
154
|
|
@@ -16,9 +16,9 @@ module FilterRename
|
|
16
16
|
|
17
17
|
def ==(dest)
|
18
18
|
super &&
|
19
|
-
([ @title, @artist, @album, @track, @comments, @year, @genre ] ==
|
19
|
+
([ @title, @artist, @album, @track, @comments, @year, @genre, @genre_s ] ==
|
20
20
|
[ dest.get_string(:title), dest.get_string(:artist), dest.get_string(:album), dest.get_string(:track),
|
21
|
-
dest.get_string(:comments), dest.get_string(:year), dest.get_string(:genre) ])
|
21
|
+
dest.get_string(:comments), dest.get_string(:year), dest.get_string(:genre), dest.get_string(:genre_s) ])
|
22
22
|
end
|
23
23
|
|
24
24
|
def rename!(dest)
|
@@ -26,8 +26,8 @@ module FilterRename
|
|
26
26
|
|
27
27
|
Mp3Info.open(full_filename) do |mp3|
|
28
28
|
old_data.merge!({ title: mp3.tag.title, artist: mp3.tag.artist, album: mp3.tag.album,
|
29
|
-
|
30
|
-
genre_s: mp3.tag.genre_s })
|
29
|
+
track: mp3.tag.tracknum, comments: mp3.tag.comments, year: mp3.tag.year,
|
30
|
+
genre: mp3.tag.genre, genre_s: mp3.tag.genre_s })
|
31
31
|
|
32
32
|
mp3.tag.title = dest.get_string(:title)
|
33
33
|
mp3.tag.artist = dest.get_string(:artist)
|
@@ -35,8 +35,8 @@ module FilterRename
|
|
35
35
|
mp3.tag.tracknum = dest.get_string(:track)
|
36
36
|
mp3.tag.comments = dest.get_string(:comments).to_s
|
37
37
|
mp3.tag.year = dest.get_string(:year)
|
38
|
-
mp3.tag.
|
39
|
-
|
38
|
+
mp3.tag.genre = dest.get_string(:genre).to_i % 256
|
39
|
+
mp3.tag.genre_s = dest.get_string(:genre_s)
|
40
40
|
end
|
41
41
|
|
42
42
|
load_mp3_data(full_filename)
|
@@ -53,6 +53,7 @@ module FilterRename
|
|
53
53
|
Comments: #{Differ.diff_by_word(dest.get_string(:comments).to_s, @comments.to_s)}
|
54
54
|
Year: #{Differ.diff_by_word(dest.get_string(:year).to_s, @year.to_s)}
|
55
55
|
Genre: #{Differ.diff_by_word(dest.get_string(:genre).to_s, @genre.to_s)}
|
56
|
+
GenreS: #{Differ.diff_by_word(dest.get_string(:genre_s).to_s, @genre_s.to_s)}
|
56
57
|
"
|
57
58
|
end
|
58
59
|
|
@@ -67,7 +68,8 @@ module FilterRename
|
|
67
68
|
@track = mp3info.tag.tracknum.to_i
|
68
69
|
@comments = mp3info.tag.comments.to_s
|
69
70
|
@year = mp3info.tag.year.to_i
|
70
|
-
@genre = mp3info.tag.
|
71
|
+
@genre = mp3info.tag.genre.to_i
|
72
|
+
@genre_s = mp3info.tag.genre_s.to_s
|
71
73
|
|
72
74
|
# read only stuff
|
73
75
|
@vbr = (mp3info.tag.vbr ? 'vbr' : '')
|
@@ -71,7 +71,7 @@ module FilterRename
|
|
71
71
|
super @cfg.target, value
|
72
72
|
else
|
73
73
|
super target, value
|
74
|
-
end
|
74
|
+
end unless value.nil?
|
75
75
|
end
|
76
76
|
|
77
77
|
def get_string(target = nil)
|
@@ -91,20 +91,39 @@ module FilterRename
|
|
91
91
|
str
|
92
92
|
end
|
93
93
|
|
94
|
+
def current_target
|
95
|
+
@cfg.target.to_s
|
96
|
+
end
|
94
97
|
end
|
95
98
|
|
96
99
|
|
97
100
|
module IndexedParams
|
98
101
|
|
99
|
-
|
102
|
+
attr_reader :params, :params_expanded, :items
|
103
|
+
|
104
|
+
def normalize_index(idx)
|
105
|
+
max_length = items.length
|
106
|
+
raise IndexOutOfRange, [idx, max_length] if idx.to_i > max_length || idx.to_i < -max_length
|
107
|
+
|
108
|
+
if idx.to_i.positive?
|
109
|
+
idx = idx.to_i.pred # % max_length
|
110
|
+
elsif idx.to_i.negative?
|
111
|
+
idx = idx.to_i + max_length # % max_length
|
112
|
+
end
|
113
|
+
idx.to_i
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_indexes
|
100
117
|
indexes = []
|
101
118
|
params_length = (indexed_params == 0) ? params.length : indexed_params
|
102
119
|
|
103
120
|
params[0..params_length.pred].each do |x|
|
104
121
|
if x =~ /\.\./
|
105
|
-
indexes = indexes + Range.new(*(x.split('..').map {|y|
|
122
|
+
indexes = indexes + Range.new(*(x.split('..').map { |y| normalize_index(y) })).map { |i| i }
|
123
|
+
elsif x =~ /:/
|
124
|
+
indexes = indexes + x.split(':').map { |y| normalize_index(y) }
|
106
125
|
else
|
107
|
-
indexes <<
|
126
|
+
indexes << normalize_index(x)
|
108
127
|
end
|
109
128
|
|
110
129
|
end
|
@@ -112,18 +131,37 @@ module FilterRename
|
|
112
131
|
indexes
|
113
132
|
end
|
114
133
|
|
134
|
+
def string_to_loop
|
135
|
+
get_string
|
136
|
+
end
|
137
|
+
|
115
138
|
def indexed_params
|
116
139
|
1
|
117
140
|
end
|
141
|
+
|
142
|
+
def self_targeted?
|
143
|
+
false
|
144
|
+
end
|
145
|
+
|
146
|
+
def filter(params)
|
147
|
+
@params = params
|
148
|
+
@items = indexed_items
|
149
|
+
@params_expanded = get_indexes
|
150
|
+
|
151
|
+
res = loop_items
|
152
|
+
|
153
|
+
if self_targeted?
|
154
|
+
super get_string
|
155
|
+
else
|
156
|
+
super res
|
157
|
+
end
|
158
|
+
end
|
118
159
|
end
|
119
160
|
|
120
161
|
|
121
162
|
class FilterWord < FilterBase
|
122
|
-
include IndexedParams
|
123
163
|
|
124
|
-
|
125
|
-
super loop_words(get_string, get_indexes(params, :word_idx), params)
|
126
|
-
end
|
164
|
+
include IndexedParams
|
127
165
|
|
128
166
|
|
129
167
|
private
|
@@ -132,56 +170,99 @@ module FilterRename
|
|
132
170
|
get_config(:word_separator)
|
133
171
|
end
|
134
172
|
|
135
|
-
def
|
136
|
-
|
137
|
-
idx = idx.to_i.pred
|
138
|
-
elsif idx.to_i.negative?
|
139
|
-
idx = idx.to_i + str.split(ws).length
|
140
|
-
end
|
141
|
-
idx.to_i
|
173
|
+
def indexed_items
|
174
|
+
string_to_loop.split(ws)
|
142
175
|
end
|
143
176
|
|
144
|
-
def
|
145
|
-
str =
|
177
|
+
def loop_items
|
178
|
+
str = items.clone
|
146
179
|
|
147
|
-
|
148
|
-
str[idx] = send :filtered_word, str[idx],
|
180
|
+
params_expanded.each_with_index do |idx, param_num|
|
181
|
+
str[idx] = send :filtered_word, str[idx], param_num.next
|
149
182
|
end
|
150
183
|
|
151
184
|
str.delete_if(&:nil?).join(ws)
|
152
185
|
end
|
153
|
-
|
154
186
|
end
|
155
187
|
|
188
|
+
|
156
189
|
class FilterNumber < FilterBase
|
157
190
|
|
158
191
|
include IndexedParams
|
159
192
|
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def ns
|
197
|
+
get_config(:number_separator)
|
198
|
+
end
|
199
|
+
|
200
|
+
def indexed_items
|
201
|
+
string_to_loop.get_numbers
|
202
|
+
end
|
203
|
+
|
204
|
+
def loop_items
|
205
|
+
str = string_to_loop
|
206
|
+
numbers = items.clone
|
207
|
+
|
208
|
+
params_expanded.each_with_index do |idx, param_idx|
|
209
|
+
numbers[idx] = self.send :filtered_number, numbers[idx], param_idx.next
|
210
|
+
end
|
211
|
+
str = str.map_number_with_index do |num, i|
|
212
|
+
numbers[i]
|
213
|
+
end
|
214
|
+
|
215
|
+
str
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
class FilterRegExp < FilterBase
|
221
|
+
|
160
222
|
def filter(params)
|
161
|
-
super
|
223
|
+
super loop_regex(get_string, params)
|
162
224
|
end
|
163
225
|
|
164
226
|
|
165
227
|
private
|
166
228
|
|
167
|
-
def
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
idx = idx.to_i.pred
|
229
|
+
def loop_regex(str, params)
|
230
|
+
str = str.gsub(Regexp.new(wrap_regex(params[0]), get_config(:ignore_case).to_boolean)) do |x|
|
231
|
+
matches = Regexp.last_match.clone
|
232
|
+
self.send(:filtered_regexp, matches.to_a.delete_if(&:nil?), params).to_s.gsub(/\\([0-9]+)/) { |y| matches[$1.to_i] }
|
172
233
|
end
|
173
|
-
|
234
|
+
|
235
|
+
str
|
174
236
|
end
|
175
237
|
|
176
|
-
|
177
|
-
arr_index.each_with_index do |idx, param_idx|
|
178
|
-
str = str.map_number_with_index do |num, i|
|
179
|
-
if idx == i
|
180
|
-
num = self.send :filtered_number, num, params, param_idx.next
|
181
|
-
end
|
238
|
+
end
|
182
239
|
|
183
|
-
|
184
|
-
|
240
|
+
|
241
|
+
class FilterOccurrence < FilterBase
|
242
|
+
|
243
|
+
include IndexedParams
|
244
|
+
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
def os
|
249
|
+
get_config(:occurrence_separator)
|
250
|
+
end
|
251
|
+
|
252
|
+
def indexed_items
|
253
|
+
string_to_loop.scan(Regexp.new(params[indexed_params]))
|
254
|
+
end
|
255
|
+
|
256
|
+
def loop_items
|
257
|
+
str = string_to_loop
|
258
|
+
regexp = Regexp.new(params[indexed_params])
|
259
|
+
occurences = items.clone
|
260
|
+
|
261
|
+
params_expanded.each_with_index do |idx, param_idx|
|
262
|
+
occurences[idx] = self.send :filtered_occurrence, occurences[idx], param_idx.next
|
263
|
+
end
|
264
|
+
str = str.gsub(regexp).with_index do |item, i|
|
265
|
+
occurences[i]
|
185
266
|
end
|
186
267
|
|
187
268
|
str
|
@@ -32,12 +32,22 @@ module FilterRename
|
|
32
32
|
def self.hint; 'Add NUM to the NTH number'; end
|
33
33
|
def self.params; 'NTH,NUM'; end
|
34
34
|
|
35
|
-
def filtered_number(num,
|
35
|
+
def filtered_number(num, param_num)
|
36
36
|
num.to_i + params[1].to_i
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
|
41
|
+
class AddNumberFrom < FilterNumber
|
42
|
+
def self.hint; 'Add the number from TARGET to the NTH'; end
|
43
|
+
def self.params; 'NTH;TARGET'; end
|
44
|
+
|
45
|
+
def filtered_number(num, param_num)
|
46
|
+
num.to_i + get_string(params[1]).to_i
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
41
51
|
class Append < FilterBase
|
42
52
|
def self.hint; 'Append the TEXT to the current target'; end
|
43
53
|
def self.params; 'TEXT'; end
|
@@ -85,7 +95,11 @@ module FilterRename
|
|
85
95
|
def self.hint; 'Append the NTH number to TARGET'; end
|
86
96
|
def self.params; 'NTH,TARGET'; end
|
87
97
|
|
88
|
-
def
|
98
|
+
def self_targeted?
|
99
|
+
params[-1] == current_target
|
100
|
+
end
|
101
|
+
|
102
|
+
def filtered_number(num, param_num)
|
89
103
|
str = get_string(params[1])
|
90
104
|
set_string("#{str}#{num}", params[1])
|
91
105
|
num
|
@@ -97,7 +111,7 @@ module FilterRename
|
|
97
111
|
def self.hint; 'Append the TEXT to the NTH number'; end
|
98
112
|
def self.params; 'NTH,TEXT'; end
|
99
113
|
|
100
|
-
def filtered_number(num,
|
114
|
+
def filtered_number(num, param_num)
|
101
115
|
"#{num}#{params[1]}"
|
102
116
|
end
|
103
117
|
end
|
@@ -107,7 +121,7 @@ module FilterRename
|
|
107
121
|
def self.hint; 'Append the TEXT to the NTH word'; end
|
108
122
|
def self.params; 'NTH,TEXT'; end
|
109
123
|
|
110
|
-
def filtered_word(word,
|
124
|
+
def filtered_word(word, param_num)
|
111
125
|
word + params[1]
|
112
126
|
end
|
113
127
|
end
|
@@ -117,10 +131,17 @@ module FilterRename
|
|
117
131
|
def self.hint; 'Append the NTH word from TARGET'; end
|
118
132
|
def self.params; 'NTH,TARGET'; end
|
119
133
|
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
134
|
+
def string_to_loop
|
135
|
+
get_string(params[1])
|
136
|
+
end
|
137
|
+
|
138
|
+
def self_targeted?
|
139
|
+
true
|
140
|
+
end
|
141
|
+
|
142
|
+
def filtered_word(word, param_num)
|
143
|
+
set_string([get_string, word].join(ws))
|
144
|
+
word
|
124
145
|
end
|
125
146
|
end
|
126
147
|
|
@@ -129,7 +150,11 @@ module FilterRename
|
|
129
150
|
def self.hint; 'Append the NTH word to TARGET'; end
|
130
151
|
def self.params; 'NTH,TARGET'; end
|
131
152
|
|
132
|
-
def
|
153
|
+
def self_targeted?
|
154
|
+
params[-1] == current_target
|
155
|
+
end
|
156
|
+
|
157
|
+
def filtered_word(word, param_num)
|
133
158
|
set_string([get_string(params[1]), word].join(ws), params[1])
|
134
159
|
word
|
135
160
|
end
|
@@ -147,6 +172,16 @@ module FilterRename
|
|
147
172
|
end
|
148
173
|
|
149
174
|
|
175
|
+
class CapitalizeWord < FilterWord
|
176
|
+
def self.hint; 'Capitalize the NTH word'; end
|
177
|
+
def self.params; 'NTH'; end
|
178
|
+
|
179
|
+
def filtered_word(word, param_num)
|
180
|
+
word.capitalize
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
150
185
|
class CopyFrom < FilterBase
|
151
186
|
def self.hint; 'Copy the text from TARGET'; end
|
152
187
|
def self.params; 'TARGET'; end
|
@@ -158,23 +193,46 @@ module FilterRename
|
|
158
193
|
|
159
194
|
|
160
195
|
class CopyNumberTo < FilterNumber
|
161
|
-
def self.hint; '
|
196
|
+
def self.hint; 'Copy the NTH number to TARGET'; end
|
162
197
|
def self.params; 'NTH,TARGET'; end
|
163
198
|
|
164
|
-
def
|
199
|
+
def self_targeted?
|
200
|
+
params[-1] == current_target
|
201
|
+
end
|
202
|
+
|
203
|
+
def filtered_number(num, param_num)
|
165
204
|
set_string(num, params[1])
|
166
205
|
num
|
167
206
|
end
|
168
207
|
end
|
169
208
|
|
170
209
|
|
171
|
-
class
|
172
|
-
def self.hint; 'Copy the
|
210
|
+
class CopyOccurrenceTo < FilterOccurrence
|
211
|
+
def self.hint; 'Copy the NTH occurrence of REGEX to TARGET'; end
|
212
|
+
def self.params; 'NTH,REGEX,TARGET'; end
|
213
|
+
|
214
|
+
def self_targeted?
|
215
|
+
params[-1] == current_target
|
216
|
+
end
|
217
|
+
|
218
|
+
def filtered_occurrence(occurrence, param_num)
|
219
|
+
set_string(occurrence, params[-1])
|
220
|
+
occurrence
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
class CopyTo < FilterRegExp
|
226
|
+
def self.hint; 'Copy the text selected by REGEX to TARGET or TARGET_#'; end
|
173
227
|
def self.params; 'REGEX,TARGET'; end
|
174
228
|
|
175
|
-
def
|
176
|
-
|
177
|
-
|
229
|
+
def filtered_regexp(matches, params)
|
230
|
+
if matches.length > 2
|
231
|
+
matches[1..-1].each_with_index { |x, i| set_string(x, "#{params[1]}_#{i.next}") }
|
232
|
+
else
|
233
|
+
set_string(matches[1], params[1])
|
234
|
+
end
|
235
|
+
matches[0]
|
178
236
|
end
|
179
237
|
end
|
180
238
|
|
@@ -185,12 +243,14 @@ module FilterRename
|
|
185
243
|
|
186
244
|
def indexed_params; 2; end
|
187
245
|
|
188
|
-
def filtered_word(word,
|
246
|
+
def filtered_word(word, param_num)
|
189
247
|
case param_num
|
190
248
|
when 1
|
191
249
|
@word = word
|
192
|
-
when
|
193
|
-
word = @word
|
250
|
+
when params_expanded.length
|
251
|
+
word = [@word, word].join(ws)
|
252
|
+
else
|
253
|
+
@word = [@word, word].join(ws)
|
194
254
|
end
|
195
255
|
|
196
256
|
word
|
@@ -198,14 +258,12 @@ module FilterRename
|
|
198
258
|
end
|
199
259
|
|
200
260
|
|
201
|
-
class Delete <
|
261
|
+
class Delete < FilterRegExp
|
202
262
|
def self.hint; 'Remove the text matching REGEX'; end
|
203
|
-
def self.params; '
|
263
|
+
def self.params; 'REGEX'; end
|
204
264
|
|
205
|
-
def
|
206
|
-
|
207
|
-
super get_string.gsub(Regexp.new(par, get_config(:ignore_case).to_boolean), '')
|
208
|
-
end
|
265
|
+
def filtered_regexp(matches, params)
|
266
|
+
''
|
209
267
|
end
|
210
268
|
end
|
211
269
|
|
@@ -214,17 +272,27 @@ module FilterRename
|
|
214
272
|
def self.hint; 'Remove the NTH number'; end
|
215
273
|
def self.params; 'NTH'; end
|
216
274
|
|
217
|
-
def filtered_number(num,
|
275
|
+
def filtered_number(num, param_num)
|
218
276
|
''
|
219
277
|
end
|
220
278
|
end
|
221
279
|
|
222
280
|
|
281
|
+
class DeleteOccurrence < FilterOccurrence
|
282
|
+
def self.hint; 'Delete the NTH occurrence of REGEXP'; end
|
283
|
+
def self.params; 'NTH,REGEXP'; end
|
284
|
+
|
285
|
+
def filtered_occurrence(occurrence, param_num)
|
286
|
+
nil
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
|
223
291
|
class DeleteWord < FilterWord
|
224
292
|
def self.hint; 'Remove the NTH word'; end
|
225
293
|
def self.params; 'NTH'; end
|
226
294
|
|
227
|
-
def filtered_word(word,
|
295
|
+
def filtered_word(word, param_num)
|
228
296
|
nil
|
229
297
|
end
|
230
298
|
end
|
@@ -234,7 +302,7 @@ module FilterRename
|
|
234
302
|
def self.hint; 'Format the NTH number adding leading zeroes to have LENGTH'; end
|
235
303
|
def self.params; 'NTH,LENGTH'; end
|
236
304
|
|
237
|
-
def filtered_number(num,
|
305
|
+
def filtered_number(num, param_num)
|
238
306
|
num.to_i.to_s.rjust(params[1].to_i, '0')
|
239
307
|
end
|
240
308
|
end
|
@@ -244,7 +312,7 @@ module FilterRename
|
|
244
312
|
def self.hint; 'Insert the WORD after the NTH word'; end
|
245
313
|
def self.params; 'NTH,WORD'; end
|
246
314
|
|
247
|
-
def filtered_word(word,
|
315
|
+
def filtered_word(word, param_num)
|
248
316
|
[word, params[1]].join(ws)
|
249
317
|
end
|
250
318
|
end
|
@@ -254,23 +322,54 @@ module FilterRename
|
|
254
322
|
def self.hint; 'Insert the WORD after the NTH word'; end
|
255
323
|
def self.params; 'NTH,WORD'; end
|
256
324
|
|
257
|
-
def filtered_word(word,
|
325
|
+
def filtered_word(word, param_num)
|
258
326
|
[params[1], word].join(ws)
|
259
327
|
end
|
260
328
|
end
|
261
329
|
|
262
330
|
|
331
|
+
class JoinNumbers < FilterNumber
|
332
|
+
def self.hint; 'Join the words NTH1 and NTH2 and replace the NTH3 number with it'; end
|
333
|
+
def self.params; 'NTH1,NTH2,NTH3'; end
|
334
|
+
|
335
|
+
def indexed_params; 3; end
|
336
|
+
|
337
|
+
def filtered_number(number, param_num)
|
338
|
+
case param_num
|
339
|
+
when 1
|
340
|
+
@number = number
|
341
|
+
number = nil
|
342
|
+
when params_expanded.length
|
343
|
+
number = @number
|
344
|
+
else
|
345
|
+
@number += number
|
346
|
+
number = nil
|
347
|
+
end
|
348
|
+
|
349
|
+
number
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
|
263
354
|
class JoinWords < FilterWord
|
264
|
-
def self.hint; 'Join the words
|
265
|
-
def self.params; 'NTH1,NTH2'; end
|
355
|
+
def self.hint; 'Join the words NTH1 and NTH2 and replace the NTH3 word with it'; end
|
356
|
+
def self.params; 'NTH1,NTH2,NTH3'; end
|
266
357
|
|
267
|
-
def
|
268
|
-
|
269
|
-
|
270
|
-
|
358
|
+
def indexed_params; 3; end
|
359
|
+
|
360
|
+
def filtered_word(word, param_num)
|
361
|
+
case param_num
|
362
|
+
when 1
|
363
|
+
@word = word
|
364
|
+
word = nil
|
365
|
+
when params_expanded.length
|
366
|
+
word = @word
|
367
|
+
else
|
368
|
+
@word += word
|
369
|
+
word = nil
|
370
|
+
end
|
271
371
|
|
272
|
-
|
273
|
-
set_string res.delete_if.with_index { |x, idx| ((istart.next)..(iend.next)).include?(idx) }.join(ws)
|
372
|
+
word
|
274
373
|
end
|
275
374
|
end
|
276
375
|
|
@@ -295,43 +394,77 @@ module FilterRename
|
|
295
394
|
end
|
296
395
|
|
297
396
|
|
298
|
-
class
|
299
|
-
def self.hint; '
|
397
|
+
class LowercaseWord < FilterWord
|
398
|
+
def self.hint; 'Lowercase the NTH word'; end
|
399
|
+
def self.params; 'NTH'; end
|
400
|
+
|
401
|
+
def filtered_word(word, param_num)
|
402
|
+
word.downcase
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
|
407
|
+
class MoveTo < FilterRegExp
|
408
|
+
def self.hint; 'Move the text selected by REGEX to TARGET or TARGET_#'; end
|
300
409
|
def self.params; 'REGEX,TARGET'; end
|
301
410
|
|
302
|
-
def
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
411
|
+
def filtered_regexp(matches, params)
|
412
|
+
if matches.length > 2
|
413
|
+
matches[1..-1].each_with_index { |x, i| set_string(x, "#{params[1]}_#{i.next}") }
|
414
|
+
else
|
415
|
+
set_string(matches[1], params[1])
|
416
|
+
end
|
417
|
+
''
|
307
418
|
end
|
308
419
|
end
|
309
420
|
|
310
421
|
|
311
422
|
class MoveNumberTo < FilterNumber
|
312
|
-
def self.hint; 'Move the NTH number to TARGET'; end
|
423
|
+
def self.hint; 'Move the NTH number to TARGET overwriting it'; end
|
313
424
|
def self.params; 'NTH,TARGET'; end
|
314
425
|
|
315
|
-
def
|
426
|
+
def self_targeted?
|
427
|
+
params[-1] == current_target
|
428
|
+
end
|
429
|
+
|
430
|
+
def filtered_number(num, param_num)
|
316
431
|
set_string(num, params[1])
|
317
432
|
''
|
318
433
|
end
|
319
434
|
end
|
320
435
|
|
321
436
|
|
437
|
+
class MoveOccurrenceTo < FilterOccurrence
|
438
|
+
def self.hint; 'Move the NTH occurrence of REGEX to TARGET overwriting it'; end
|
439
|
+
def self.params; 'NTH,REGEX,TARGET'; end
|
440
|
+
|
441
|
+
def self_targeted?
|
442
|
+
params[-1] == current_target
|
443
|
+
end
|
444
|
+
|
445
|
+
def filtered_occurrence(occurrence, param_num)
|
446
|
+
set_string(occurrence, params[-1])
|
447
|
+
nil
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
|
322
452
|
class MoveWord < FilterWord
|
323
453
|
def self.hint; 'Move the NTH1 word to the NTH2 place'; end
|
324
454
|
def self.params; 'NTH1,NTH2'; end
|
325
455
|
|
326
456
|
def indexed_params; 2; end
|
327
457
|
|
328
|
-
def filtered_word(word,
|
458
|
+
def filtered_word(word, param_num)
|
329
459
|
case param_num
|
330
460
|
when 1
|
331
461
|
@word = word
|
332
462
|
res = nil
|
333
|
-
when
|
463
|
+
when params_expanded.length
|
334
464
|
res = [word, @word].join(ws)
|
465
|
+
else
|
466
|
+
@word = [@word, word].join(ws)
|
467
|
+
res = nil
|
335
468
|
end
|
336
469
|
|
337
470
|
res
|
@@ -340,10 +473,14 @@ module FilterRename
|
|
340
473
|
|
341
474
|
|
342
475
|
class MoveWordTo < FilterWord
|
343
|
-
def self.hint; 'Move the NTH word to TARGET'; end
|
476
|
+
def self.hint; 'Move the NTH word to TARGET overwriting it'; end
|
344
477
|
def self.params; 'NTH,TARGET'; end
|
345
478
|
|
346
|
-
def
|
479
|
+
def self_targeted?
|
480
|
+
params[-1] == current_target
|
481
|
+
end
|
482
|
+
|
483
|
+
def filtered_word(word, param_num)
|
347
484
|
set_string(word, params[1])
|
348
485
|
nil
|
349
486
|
end
|
@@ -354,7 +491,7 @@ module FilterRename
|
|
354
491
|
def self.hint; 'Multiply the NTH number with NUM'; end
|
355
492
|
def self.params; 'NTH,NUM'; end
|
356
493
|
|
357
|
-
def filtered_number(num,
|
494
|
+
def filtered_number(num, param_num)
|
358
495
|
num.to_i * params[1].to_i
|
359
496
|
end
|
360
497
|
end
|
@@ -384,7 +521,7 @@ module FilterRename
|
|
384
521
|
def self.hint; 'Prepend the TEXT to the NTH number'; end
|
385
522
|
def self.params; 'NTH,TEXT'; end
|
386
523
|
|
387
|
-
def filtered_number(num,
|
524
|
+
def filtered_number(num, param_num)
|
388
525
|
"#{params[1]}#{num}"
|
389
526
|
end
|
390
527
|
end
|
@@ -394,32 +531,48 @@ module FilterRename
|
|
394
531
|
def self.hint; 'Prepend the TEXT to the NTH word'; end
|
395
532
|
def self.params; 'NTH,TEXT'; end
|
396
533
|
|
397
|
-
def filtered_word(word,
|
534
|
+
def filtered_word(word, param_num)
|
398
535
|
params[1] + word
|
399
536
|
end
|
400
537
|
end
|
401
538
|
|
402
539
|
|
403
|
-
class
|
540
|
+
class PrependWordFrom < FilterWord
|
541
|
+
def self.hint; 'Prepend with TARGET the NTH word'; end
|
542
|
+
def self.params; 'NTH,TARGET'; end
|
543
|
+
|
544
|
+
def string_to_loop
|
545
|
+
get_string(params[1])
|
546
|
+
end
|
547
|
+
|
548
|
+
def self_targeted?
|
549
|
+
true
|
550
|
+
end
|
551
|
+
|
552
|
+
def filtered_word(word, param_num)
|
553
|
+
set_string([word, get_string].join(ws))
|
554
|
+
word
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
|
559
|
+
class Replace < FilterRegExp
|
404
560
|
def self.hint; 'Replace the text matching REGEX with REPLACE'; end
|
405
561
|
def self.params; 'REGEX,REPLACE'; end
|
406
562
|
|
407
|
-
def
|
408
|
-
|
409
|
-
super get_string.gsub(regexp, params[1])
|
563
|
+
def filtered_regexp(matches, params)
|
564
|
+
params[1]
|
410
565
|
end
|
411
566
|
end
|
412
567
|
|
413
568
|
|
414
|
-
class ReplaceFrom <
|
569
|
+
class ReplaceFrom < FilterRegExp
|
415
570
|
def self.hint; 'Replace the REGEX matching text with the TARGET content'; end
|
416
571
|
def self.params; 'REGEX,TARGET'; end
|
417
572
|
|
418
|
-
def
|
419
|
-
|
420
|
-
super get_string.gsub(regexp, get_string(params[1]).to_s)
|
573
|
+
def filtered_regexp(matches, params)
|
574
|
+
get_string(params[1]).to_s
|
421
575
|
end
|
422
|
-
|
423
576
|
end
|
424
577
|
|
425
578
|
|
@@ -427,17 +580,27 @@ module FilterRename
|
|
427
580
|
def self.hint; 'Replace the NTH number with NUMBER'; end
|
428
581
|
def self.params; 'NTH,NUMBER'; end
|
429
582
|
|
430
|
-
def filtered_number(num,
|
583
|
+
def filtered_number(num, param_num)
|
431
584
|
params[1]
|
432
585
|
end
|
433
586
|
end
|
434
587
|
|
435
588
|
|
589
|
+
class ReplaceOccurrence < FilterOccurrence
|
590
|
+
def self.hint; 'Replace the NTH occurrence of REGEXP with TEXT'; end
|
591
|
+
def self.params; 'NTH,REGEXP,TEXT'; end
|
592
|
+
|
593
|
+
def filtered_occurrence(occurrence, param_num)
|
594
|
+
params[2]
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
598
|
+
|
436
599
|
class ReplaceWord < FilterWord
|
437
600
|
def self.hint; 'Replace the NTH word with TEXT'; end
|
438
601
|
def self.params; 'NTH,TEXT'; end
|
439
602
|
|
440
|
-
def filtered_word(word,
|
603
|
+
def filtered_word(word, param_num)
|
441
604
|
params[1]
|
442
605
|
end
|
443
606
|
end
|
@@ -522,7 +685,7 @@ module FilterRename
|
|
522
685
|
def self.hint; 'Split the NTH word using a REGEX with capturing groups'; end
|
523
686
|
def self.params; 'NTH,REGEX'; end
|
524
687
|
|
525
|
-
def filtered_word(word,
|
688
|
+
def filtered_word(word, param_num)
|
526
689
|
word.scan(Regexp.new(wrap_regex(params[1]), get_config(:ignore_case))).pop.to_a.join(ws)
|
527
690
|
end
|
528
691
|
end
|
@@ -544,13 +707,17 @@ module FilterRename
|
|
544
707
|
|
545
708
|
def indexed_params; 2; end
|
546
709
|
|
547
|
-
def filtered_number(num,
|
710
|
+
def filtered_number(num, param_num)
|
548
711
|
case param_num
|
549
712
|
when 1
|
550
713
|
@number = num.clone
|
551
|
-
|
552
|
-
|
714
|
+
@last_number = get_string.get_number(params_expanded[-1].to_i)
|
715
|
+
num = @last_number
|
716
|
+
when params_expanded.length
|
553
717
|
num = @number
|
718
|
+
else
|
719
|
+
@number = [@number, num].join(ns)
|
720
|
+
num = @last_number
|
554
721
|
end
|
555
722
|
|
556
723
|
num
|
@@ -562,15 +729,19 @@ module FilterRename
|
|
562
729
|
def self.hint; 'Swap the NTH1 word with the NTH2'; end
|
563
730
|
def self.params; 'NTH1,NTH2'; end
|
564
731
|
|
565
|
-
def
|
732
|
+
def indexed_params; 2; end
|
566
733
|
|
567
|
-
def filtered_word(word,
|
734
|
+
def filtered_word(word, param_num)
|
568
735
|
case param_num
|
569
736
|
when 1
|
570
737
|
@word = word.clone
|
571
|
-
|
572
|
-
|
738
|
+
@last_word = get_string.split(ws)[params_expanded[-1]]
|
739
|
+
word = @last_word
|
740
|
+
when params_expanded.length
|
573
741
|
word = @word
|
742
|
+
else
|
743
|
+
@word = [@word, word].join(ws)
|
744
|
+
word = nil
|
574
745
|
end
|
575
746
|
|
576
747
|
word
|
@@ -627,32 +798,32 @@ module FilterRename
|
|
627
798
|
end
|
628
799
|
|
629
800
|
|
630
|
-
class
|
801
|
+
class UppercaseWord < FilterWord
|
802
|
+
def self.hint; 'Uppercase the NTH word'; end
|
803
|
+
def self.params; 'NTH'; end
|
804
|
+
|
805
|
+
def filtered_word(word, param_num)
|
806
|
+
word.upcase
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
|
811
|
+
class Wrap < FilterRegExp
|
631
812
|
def self.hint; 'Wrap the text matching REGEX with SEPARATOR1 and SEPARATOR2'; end
|
632
813
|
def self.params; 'REGEX,SEPARATOR1,SEPARATOR2'; end
|
633
814
|
|
634
|
-
def
|
635
|
-
params[
|
636
|
-
regexp = Regexp.new("(#{params[0]})", get_config(:ignore_case).to_boolean)
|
637
|
-
super get_string.gsub(regexp, "#{params[1]}\\1#{params[2]}")
|
815
|
+
def filtered_regexp(matches, params)
|
816
|
+
"#{params[1]}#{matches[0]}#{params[2]}"
|
638
817
|
end
|
639
818
|
end
|
640
819
|
|
641
820
|
|
642
821
|
class WrapWords < FilterWord
|
643
|
-
def self.hint; 'Wrap the
|
644
|
-
def self.params; '
|
822
|
+
def self.hint; 'Wrap the NTH word with SEPARATOR1 and SEPARATOR2'; end
|
823
|
+
def self.params; 'NTH,SEPARATOR1,SEPARATOR2'; end
|
645
824
|
|
646
|
-
def
|
647
|
-
|
648
|
-
def filtered_word(word, params, param_num)
|
649
|
-
case param_num
|
650
|
-
when 1
|
651
|
-
word = "#{params[2]}#{word}"
|
652
|
-
when 2
|
653
|
-
word = "#{word}#{params[3]}"
|
654
|
-
end
|
655
|
-
word
|
825
|
+
def filtered_word(word, param_num)
|
826
|
+
"#{params[1]}#{word}#{params[2]}"
|
656
827
|
end
|
657
828
|
end
|
658
829
|
end
|
data/lib/filter_rename/utils.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'date'
|
2
|
+
require 'digest'
|
2
3
|
|
3
4
|
module FilterRename
|
4
5
|
|
@@ -20,6 +21,15 @@ module FilterRename
|
|
20
21
|
|
21
22
|
module ReadableVariables
|
22
23
|
|
24
|
+
def basic!
|
25
|
+
@custom = false
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def custom?
|
30
|
+
@custom == true || @custom == nil
|
31
|
+
end
|
32
|
+
|
23
33
|
def readonly!
|
24
34
|
@writable = false
|
25
35
|
self
|
@@ -112,6 +122,10 @@ module FilterRename
|
|
112
122
|
def get_number(idx)
|
113
123
|
self.scan(/\d+/)[idx]
|
114
124
|
end
|
125
|
+
|
126
|
+
def get_numbers
|
127
|
+
self.scan(/\d+/)
|
128
|
+
end
|
115
129
|
end
|
116
130
|
|
117
131
|
|
@@ -171,7 +185,7 @@ module FilterRename
|
|
171
185
|
old_source = old_data.empty? ? fp.source.values : old_data
|
172
186
|
|
173
187
|
fp.dest.values.each do |k, v|
|
174
|
-
puts " #{k}: ".bold.green + (old_source[k]
|
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))
|
175
189
|
end
|
176
190
|
end
|
177
191
|
|
@@ -179,6 +193,16 @@ module FilterRename
|
|
179
193
|
Messages.error "<#{fp.source.filename}> can't be renamed in <#{fp.dest.filename}>, it exists!"
|
180
194
|
end
|
181
195
|
|
196
|
+
def self.file_hash(fp, hash_type, cached = nil)
|
197
|
+
raise UnknownHashCode, hash_type unless [:sha1, :sha2, :md5].include?(hash_type.to_sym)
|
198
|
+
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)
|
201
|
+
|
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)}"
|
204
|
+
end
|
205
|
+
|
182
206
|
def self.short_targets(ff)
|
183
207
|
self.list [ff.targets[:readonly].map { |s| "<#{s.to_s.delete('@')}>"}.join(', ')], :red, '-'
|
184
208
|
self.list [ff.targets[:writable].map { |s| "<#{s.to_s.delete('@')}>"}.join(', ')], :green, '+'
|
@@ -208,6 +232,12 @@ module FilterRename
|
|
208
232
|
end
|
209
233
|
end
|
210
234
|
|
235
|
+
class IndexOutOfRange < StandardError
|
236
|
+
def initialize(values)
|
237
|
+
super "Invalid index '#{values[0]}' out of the range 1..#{values[1]}, -#{values[1]}..-1"
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
211
241
|
class UnknownHashCode < StandardError
|
212
242
|
def initialize(hash_type)
|
213
243
|
super "Invalid hash type: #{hash_type}"
|
data/lib/filter_rename.rb
CHANGED
@@ -48,8 +48,11 @@ module FilterRename
|
|
48
48
|
if old_data[:full_filename]
|
49
49
|
Messages.renamed!(old_data, fp.dest)
|
50
50
|
Messages.changed_tags(fp, old_data, false) if fp.source.class.has_writable_tags
|
51
|
-
|
51
|
+
elsif fp.source.class.has_writable_tags
|
52
52
|
Messages.changed_tags(fp, old_data)
|
53
|
+
else
|
54
|
+
Messages.file_exists(fp)
|
55
|
+
Messages.file_hash(fp, @cfg.global.hash_type) if @cfg.global.hash_if_exists
|
53
56
|
end
|
54
57
|
|
55
58
|
else
|
@@ -77,7 +80,7 @@ module FilterRename
|
|
77
80
|
raise MissingFiles if @files.empty?
|
78
81
|
|
79
82
|
@filters.expand_macros!(@cfg.macro)
|
80
|
-
cache =
|
83
|
+
cache = {}
|
81
84
|
|
82
85
|
Messages.label "Dry Run:"
|
83
86
|
@files.each do |src|
|
@@ -86,16 +89,17 @@ module FilterRename
|
|
86
89
|
|
87
90
|
if fp.unchanged?
|
88
91
|
Messages.skipping(fp)
|
89
|
-
elsif (cache.include?(fp.dest.full_filename) || fp.dest.exists?)
|
92
|
+
elsif (cache.keys.include?(fp.dest.full_filename) || fp.dest.exists?)
|
90
93
|
if fp.source.full_filename == fp.dest.full_filename
|
91
94
|
Messages.changed_tags(fp)
|
92
95
|
else
|
93
96
|
Messages.file_exists(fp)
|
97
|
+
Messages.file_hash(fp, @cfg.global.hash_type, cache[fp.dest.full_filename]) if @cfg.global.hash_if_exists
|
94
98
|
end
|
95
99
|
else
|
96
100
|
Messages.renamed(fp)
|
97
101
|
Messages.changed_tags(fp, {}, false) if fp.source.class.has_writable_tags
|
98
|
-
cache
|
102
|
+
cache[fp.dest.full_filename] = fp.dest
|
99
103
|
end
|
100
104
|
end
|
101
105
|
end
|
@@ -131,7 +135,6 @@ module FilterRename
|
|
131
135
|
end
|
132
136
|
end
|
133
137
|
end
|
134
|
-
|
135
138
|
end
|
136
139
|
|
137
140
|
end
|
data/lib/filter_rename.yaml
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
---
|
2
2
|
:global:
|
3
|
-
:hash_type: :
|
3
|
+
:hash_type: :md5
|
4
|
+
:hash_on_tags: false
|
5
|
+
:hash_if_exists: true
|
4
6
|
:date_format: '%Y-%m-%d'
|
5
7
|
:counter_length: 3
|
6
8
|
:counter_start: 0
|
@@ -10,6 +12,8 @@
|
|
10
12
|
:filter:
|
11
13
|
:lang: :en
|
12
14
|
:word_separator: " "
|
15
|
+
:number_separator: '.'
|
16
|
+
:occurrence_separator: '-'
|
13
17
|
:target: :name
|
14
18
|
:ignore_case: true
|
15
19
|
:grep: '.*'
|
@@ -113,7 +117,7 @@
|
|
113
117
|
- '\1 \2'
|
114
118
|
append_issue:
|
115
119
|
:move_to:
|
116
|
-
- '(Issue
|
120
|
+
- 'Volume +([0-9]+)|Issue +([0-9]+)'
|
117
121
|
- 'tmp'
|
118
122
|
:template:
|
119
123
|
- '<name> #<tmp>'
|
@@ -144,7 +148,7 @@
|
|
144
148
|
- ignore_case:false
|
145
149
|
-
|
146
150
|
:replace:
|
147
|
-
- "([A-Z])([a-z!']+)"
|
151
|
+
- "(?<![A-Z])([A-Z])([a-z!',-]+)"
|
148
152
|
- " \\1\\2 "
|
149
153
|
-
|
150
154
|
:replace:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: filter_rename
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fabio Mucciante
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -136,8 +136,9 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
-
description:
|
140
|
-
|
139
|
+
description: FilterRename is a bulk renaming tool, based on the concept of filters
|
140
|
+
as small operations to perform over sections of the full filename logically represented
|
141
|
+
in targets.
|
141
142
|
email:
|
142
143
|
- fabio.mucciante@gmail.com
|
143
144
|
executables:
|
@@ -145,6 +146,7 @@ executables:
|
|
145
146
|
extensions: []
|
146
147
|
extra_rdoc_files: []
|
147
148
|
files:
|
149
|
+
- ".github/FUNDING.yml"
|
148
150
|
- ".gitignore"
|
149
151
|
- ".rspec"
|
150
152
|
- ".travis.yml"
|
@@ -176,8 +178,9 @@ licenses:
|
|
176
178
|
- GPL-3.0
|
177
179
|
metadata:
|
178
180
|
bug_tracker_uri: https://github.com/fabiomux/filter_rename/issues
|
179
|
-
|
180
|
-
|
181
|
+
changelog_uri: https://freeaptitude.altervista.org/projects/filter-rename.htm#changelog
|
182
|
+
documentation_uri: https://www.rubydoc.info/gems/filter_rename/1.1.0
|
183
|
+
homepage_uri: https://freeaptitude.altervista.org/projects/filter-rename.html
|
181
184
|
source_code_uri: https://github.com/fabiomux/filter_rename
|
182
185
|
wiki_uri: https://github.com/fabiomux/filter_rename/wiki
|
183
186
|
post_install_message:
|
@@ -195,8 +198,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
198
|
- !ruby/object:Gem::Version
|
196
199
|
version: '0'
|
197
200
|
requirements: []
|
198
|
-
rubygems_version: 3.
|
201
|
+
rubygems_version: 3.2.19
|
199
202
|
signing_key:
|
200
203
|
specification_version: 4
|
201
|
-
summary:
|
204
|
+
summary: File renaming tool which make use of a chain of actions called filters.
|
202
205
|
test_files: []
|