tagomatic 0.1.0 → 0.1.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.
- data/.idea/inspectionProfiles/profiles_settings.xml +3 -2
- data/VERSION +1 -1
- data/lib/monkey/id3v2.rb +15 -0
- data/lib/tagomatic/format_compiler.rb +3 -3
- data/lib/tagomatic/format_matcher.rb +10 -6
- data/lib/tagomatic/info_updater.rb +2 -1
- data/lib/tagomatic/logger.rb +6 -1
- data/lib/tagomatic/options.rb +1 -0
- data/lib/tagomatic/options_parser.rb +5 -2
- data/lib/tagomatic/tagger.rb +70 -20
- metadata +3 -2
@@ -1,7 +1,8 @@
|
|
1
1
|
<component name="InspectionProjectProfileManager">
|
2
2
|
<settings>
|
3
3
|
<option name="PROJECT_PROFILE" value="Project Default" />
|
4
|
-
<option name="
|
5
|
-
<
|
4
|
+
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
|
5
|
+
<scopes />
|
6
|
+
<list size="0" />
|
6
7
|
</settings>
|
7
8
|
</component>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/lib/monkey/id3v2.rb
ADDED
@@ -4,12 +4,12 @@ module Tagomatic
|
|
4
4
|
|
5
5
|
FORMAT_REGEXP_ARTIST = '([^\/]+)'
|
6
6
|
FORMAT_REGEXP_ALBUM = '([^\/]+)'
|
7
|
-
FORMAT_REGEXP_DISC = '([0-9]+)'
|
7
|
+
FORMAT_REGEXP_DISC = '\s*([0-9]+)\s*'
|
8
8
|
FORMAT_REGEXP_GENRE = '([^\/]+)'
|
9
9
|
FORMAT_REGEXP_IGNORE = '([^\/]+)'
|
10
10
|
FORMAT_REGEXP_TITLE = '([^\/]+)'
|
11
|
-
FORMAT_REGEXP_TRACKNUM = '([0-9]+)'
|
12
|
-
FORMAT_REGEXP_YEAR = '([0-9]+)'
|
11
|
+
FORMAT_REGEXP_TRACKNUM = '\s*([0-9]+)\s*'
|
12
|
+
FORMAT_REGEXP_YEAR = '\s*([0-9]+)\s*'
|
13
13
|
|
14
14
|
def initialize(format_matcher_factory)
|
15
15
|
@format_matcher_factory = format_matcher_factory
|
@@ -15,12 +15,7 @@ module Tagomatic
|
|
15
15
|
tags = {}
|
16
16
|
0.upto(@mapping.size) do |index|
|
17
17
|
value = matchdata.captures[index]
|
18
|
-
if value
|
19
|
-
value = value.gsub('_', ' ')
|
20
|
-
parts = value.split(' ')
|
21
|
-
capitalized = parts.map {|p| p.capitalize}
|
22
|
-
value = capitalized.join(' ')
|
23
|
-
end
|
18
|
+
value = normalize(value) if value
|
24
19
|
tags[@mapping[index]] = value
|
25
20
|
end
|
26
21
|
tags
|
@@ -30,6 +25,15 @@ module Tagomatic
|
|
30
25
|
@format
|
31
26
|
end
|
32
27
|
|
28
|
+
protected
|
29
|
+
|
30
|
+
def normalize(value)
|
31
|
+
value = value.gsub('_', ' ')
|
32
|
+
parts = value.split(' ')
|
33
|
+
capitalized = parts.map {|p| p.capitalize}
|
34
|
+
capitalized.join(' ')
|
35
|
+
end
|
36
|
+
|
33
37
|
end
|
34
38
|
|
35
39
|
end
|
data/lib/tagomatic/logger.rb
CHANGED
@@ -8,7 +8,12 @@ module Tagomatic
|
|
8
8
|
|
9
9
|
def error(message, optional_exception = nil)
|
10
10
|
puts "ERROR: #{message}"
|
11
|
-
|
11
|
+
exception optional_exception if optional_exception
|
12
|
+
end
|
13
|
+
|
14
|
+
def exception(exception)
|
15
|
+
$stderr.puts exception.to_s
|
16
|
+
$stderr.puts exception.backtrace
|
12
17
|
end
|
13
18
|
|
14
19
|
def verbose(message)
|
data/lib/tagomatic/options.rb
CHANGED
@@ -53,11 +53,14 @@ module Tagomatic
|
|
53
53
|
@options[:formats] << format
|
54
54
|
end
|
55
55
|
|
56
|
+
opts.on("-c", "--cleantags", "Clean up tags by removing artist and album from title for example.") do |cleantags|
|
57
|
+
@options[:cleantags]= cleantags
|
58
|
+
end
|
56
59
|
opts.on("-k", "--cleartags", "Clear any existing v1 and v2 tags.") do |cleartags|
|
57
|
-
@options[:cleartags
|
60
|
+
@options[:cleartags]= cleartags
|
58
61
|
end
|
59
62
|
opts.on("-e", "--errorstops", "Stop execution if an error occurs.") do |errorstops|
|
60
|
-
@options[:errorstops
|
63
|
+
@options[:errorstops]= errorstops
|
61
64
|
end
|
62
65
|
opts.on("-s", "--guess", "Use format guessing. Can be combined with --format.") do |guess|
|
63
66
|
@options[:guess] = guess
|
data/lib/tagomatic/tagger.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require 'monkey/id3v2'
|
1
4
|
require 'tagomatic/info_updater'
|
2
5
|
|
3
6
|
module Tagomatic
|
@@ -14,24 +17,31 @@ module Tagomatic
|
|
14
17
|
FORMAT_ID_YEAR = 'y'
|
15
18
|
|
16
19
|
KNOWN_FORMATS = [
|
17
|
-
"%g/%a/%b
|
18
|
-
"%g/%a/%b
|
19
|
-
"%g/%a/%b
|
20
|
-
|
21
|
-
"%g/%a/%b
|
22
|
-
"%g/%a/%b
|
23
|
-
|
24
|
-
|
25
|
-
"%g/%a
|
26
|
-
"%g/%a
|
27
|
-
|
28
|
-
|
29
|
-
"%g/%a/%b/%n
|
30
|
-
"%g/%a/%b/%n
|
20
|
+
"%g/%a/%b/CD%d/%n-%t.mp3",
|
21
|
+
"%g/%a/%b/CD%d/%n%t.mp3",
|
22
|
+
"%g/%a/%b/CD%d/%t.mp3",
|
23
|
+
"%g/%a/%b/cd%d/%n-%t.mp3",
|
24
|
+
"%g/%a/%b/cd%d/%n%t.mp3",
|
25
|
+
"%g/%a/%b/cd%d/%t.mp3",
|
26
|
+
|
27
|
+
"%g/%a/%b[%y]/%a-%b-%n-%t.mp3",
|
28
|
+
"%g/%a/%b[%y]/%n-%t.mp3",
|
29
|
+
"%g/%a/%b[%y]/%n%t.mp3",
|
30
|
+
|
31
|
+
"%g/%a/%b(%y)/%a-%b-%n-%t.mp3",
|
32
|
+
"%g/%a/%b(%y)/%n-%t.mp3",
|
33
|
+
"%g/%a/%b(%y)/%n%t.mp3",
|
34
|
+
|
35
|
+
"%g/%a/(%y)%b/%a-%b-%n-%t.mp3",
|
36
|
+
"%g/%a/(%y)%b/%n-%t.mp3",
|
37
|
+
"%g/%a/(%y)%b/%n%t.mp3",
|
38
|
+
|
39
|
+
"%g/%a/%b/%a-%b-%n-%t.mp3",
|
31
40
|
"%g/%a/%b/%n-%t.mp3",
|
41
|
+
"%g/%a/%b/%n%t.mp3",
|
32
42
|
|
33
|
-
"%a
|
34
|
-
"%
|
43
|
+
"%g/%a/%b/%t.mp3",
|
44
|
+
"%g/%a/%b/%t.MP3",
|
35
45
|
]
|
36
46
|
|
37
47
|
def initialize(options, compiler, mp3info, info_updater_factory, logger)
|
@@ -43,12 +53,13 @@ module Tagomatic
|
|
43
53
|
end
|
44
54
|
|
45
55
|
def process!(file_path)
|
46
|
-
file_path.gsub '_', ' ' if @options[:underscores]
|
47
|
-
|
48
56
|
@logger.verbose "tagging #{file_path}"
|
49
57
|
|
50
58
|
prepare_for_current_file(file_path)
|
59
|
+
replace_underscores if @options[:underscores]
|
51
60
|
apply_formats
|
61
|
+
clean_tags if @options[:cleantags]
|
62
|
+
normalize_tags
|
52
63
|
apply_forced_tags
|
53
64
|
try_updating_mp3file
|
54
65
|
end
|
@@ -60,6 +71,17 @@ module Tagomatic
|
|
60
71
|
@tags = nil
|
61
72
|
end
|
62
73
|
|
74
|
+
def replace_underscores
|
75
|
+
folder_path = File.dirname(@file_path)
|
76
|
+
file_name = File.basename(@file_path)
|
77
|
+
clean = file_name.gsub('_', ' ')
|
78
|
+
return if clean == file_name
|
79
|
+
@logger.verbose "renaming #{file_name} to #{clean}"
|
80
|
+
FileUtils.cd folder_path
|
81
|
+
FileUtils.mv file_name, clean
|
82
|
+
@file_path = File.join(folder_path, clean)
|
83
|
+
end
|
84
|
+
|
63
85
|
def apply_formats
|
64
86
|
apply_custom_formats if custom_formats_available?
|
65
87
|
apply_known_formats if no_tags_set? and guessing_allowed?
|
@@ -105,6 +127,33 @@ module Tagomatic
|
|
105
127
|
formats.map! { |f| f.is_a?(FormatMatcher) ? f : @compiler.compile_format(f) }
|
106
128
|
end
|
107
129
|
|
130
|
+
def clean_tags
|
131
|
+
artist = @tags['a']
|
132
|
+
artist = Regexp.compile("[ -]*#{Regexp.escape(artist)}[ -]*", Regexp::IGNORECASE) if artist
|
133
|
+
|
134
|
+
album = @tags['b']
|
135
|
+
album = album.sub(artist, '') if artist and album
|
136
|
+
@tags['b'] = album unless album.nil? or album.empty?
|
137
|
+
|
138
|
+
album = Regexp.compile("[ -]*#{Regexp.escape(album)}[ -]*", Regexp::IGNORECASE) if album
|
139
|
+
|
140
|
+
title = @tags['t']
|
141
|
+
title = title.sub(artist, '') if artist and title
|
142
|
+
title = title.sub(album, '') if album and title
|
143
|
+
@tags['t'] = title unless title.nil? or title.empty?
|
144
|
+
end
|
145
|
+
|
146
|
+
def normalize_tags
|
147
|
+
normalized = Hash.new
|
148
|
+
@tags.each do |tag, value|
|
149
|
+
next if value.nil?
|
150
|
+
parts = value.gsub('_', ' ').split(' ')
|
151
|
+
capitalized = parts.map {|p| p.capitalize}
|
152
|
+
normalized[tag] = capitalized.join(' ')
|
153
|
+
end
|
154
|
+
@tags = normalized
|
155
|
+
end
|
156
|
+
|
108
157
|
def apply_forced_tags
|
109
158
|
@tags ||= Hash.new
|
110
159
|
@tags[:album] if @options[:album]
|
@@ -164,6 +213,7 @@ module Tagomatic
|
|
164
213
|
end
|
165
214
|
|
166
215
|
updater.apply if updater.dirty?
|
216
|
+
puts "updated #{@file_path}" if updater.dirty?
|
167
217
|
end
|
168
218
|
|
169
219
|
def show_tags
|
@@ -174,9 +224,9 @@ module Tagomatic
|
|
174
224
|
output << '/b='
|
175
225
|
output << ( @mp3.tag.album || '<album>' )
|
176
226
|
output << '/y='
|
177
|
-
output << ( @mp3.tag.year ? "#{@mp3.
|
227
|
+
output << ( @mp3.tag.year ? "#{@mp3.tag.year}" : '<year>' )
|
178
228
|
output << '/n='
|
179
|
-
output << ( @mp3.tag.tracknum ? "#{@mp3.
|
229
|
+
output << ( @mp3.tag.tracknum ? "#{@mp3.tag.tracknum}" : '<tracknum>' )
|
180
230
|
output << '/t='
|
181
231
|
output << ( @mp3.tag.title || '<title>' )
|
182
232
|
puts output
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tagomatic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Lukic
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- Rakefile
|
91
91
|
- VERSION
|
92
92
|
- bin/tagomatic
|
93
|
+
- lib/monkey/id3v2.rb
|
93
94
|
- lib/monkey/string.rb
|
94
95
|
- lib/tagomatic/format_compiler.rb
|
95
96
|
- lib/tagomatic/format_matcher.rb
|
@@ -138,5 +139,5 @@ signing_key:
|
|
138
139
|
specification_version: 3
|
139
140
|
summary: Simple command-line mp3 tagger based on mp3info gem. Supports folder-specific configuration files.
|
140
141
|
test_files:
|
141
|
-
- test/test_tagomatic.rb
|
142
142
|
- test/helper.rb
|
143
|
+
- test/test_tagomatic.rb
|