easytag 0.3.1 → 0.4.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/CHANGELOG.md +33 -0
- data/README.md +1 -1
- data/easytag.gemspec +1 -1
- data/lib/easytag/attributes/base.rb +68 -28
- data/lib/easytag/attributes/mp3.rb +231 -7
- data/lib/easytag/attributes/mp4.rb +205 -13
- data/lib/easytag/base.rb +3 -3
- data/lib/easytag/interfaces/base.rb +12 -9
- data/lib/easytag/interfaces/mp3.rb +4 -9
- data/lib/easytag/interfaces/mp4.rb +4 -10
- data/lib/easytag/util.rb +33 -3
- data/lib/easytag/version.rb +2 -2
- data/test/test_consistency.rb +48 -7
- data/test/test_mp3.rb +37 -8
- data/test/test_mp4.rb +28 -6
- data/test/test_util.rb +17 -2
- metadata +3 -3
@@ -1,20 +1,14 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
require 'easytag/attributes/mp4'
|
4
2
|
|
5
3
|
module EasyTag::Interfaces
|
6
4
|
class MP4 < Base
|
5
|
+
ATTRIB_ARGS = EasyTag::Attributes::MP4_ATTRIB_ARGS
|
6
|
+
ATTRIB_CLASS = EasyTag::Attributes::MP4Attribute
|
7
|
+
|
7
8
|
def initialize(file)
|
8
9
|
@info = TagLib::MP4::File.new(file)
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
attrib = EasyTag::Attributes::MP4Attribute.new(attrib_args)
|
13
|
-
define_method(attrib.name) do
|
14
|
-
instance_variable_get(attrib.ivar) ||
|
15
|
-
instance_variable_set(attrib.ivar, attrib.call(self))
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
12
|
+
self.build_attributes(ATTRIB_CLASS, ATTRIB_ARGS)
|
19
13
|
end
|
20
14
|
end
|
data/lib/easytag/util.rb
CHANGED
@@ -2,6 +2,9 @@ require 'date'
|
|
2
2
|
|
3
3
|
module EasyTag
|
4
4
|
module Utilities
|
5
|
+
YEAR_RE = /(1[89]|20)\d{2}/ # 1800-2099
|
6
|
+
MONTH_RE = /(0[1-9]|1[0-2])/ # 01-12
|
7
|
+
DAY_RE = /(0[1-9]|[12][0-9]|3[01])/ # matches 01-31
|
5
8
|
|
6
9
|
# get_datetime
|
7
10
|
#
|
@@ -9,13 +12,19 @@ module EasyTag
|
|
9
12
|
def self.get_datetime(date_str)
|
10
13
|
return nil if date_str.nil?
|
11
14
|
|
15
|
+
# DateTime can't handle 00, so replace days/months that are 00 with 01
|
16
|
+
# (currently only works with YYYY-MM-DD)
|
17
|
+
until date_str[/\-(00)\-?/].nil?
|
18
|
+
date_str[/\-(00)\-?/, 1] = '01'
|
19
|
+
end
|
20
|
+
|
12
21
|
# check for known possible formats
|
13
22
|
case date_str
|
14
|
-
when
|
23
|
+
when /^#{YEAR_RE}$/
|
15
24
|
datetime = DateTime.strptime(date_str, '%Y')
|
16
|
-
when
|
25
|
+
when /^#{YEAR_RE}\-#{MONTH_RE}$/ # YYYY-MM
|
17
26
|
datetime = DateTime.strptime(date_str, '%Y-%m')
|
18
|
-
when
|
27
|
+
when /^#{YEAR_RE}#{DAY_RE}#{MONTH_RE}$/ # YYYYDDMM (TYER+TDAT)
|
19
28
|
datetime = DateTime.strptime(date_str, '%Y%d%m')
|
20
29
|
else
|
21
30
|
datetime = nil
|
@@ -30,6 +39,12 @@ module EasyTag
|
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
42
|
+
# try to get the year at the least (don't attempt if date_str is a year)
|
43
|
+
if datetime.nil? && !date_str.match(YEAR_RE).to_s.eql?(date_str)
|
44
|
+
warn 'Falling back to year-only parsing'
|
45
|
+
datetime = get_datetime(date_str.match(YEAR_RE).to_s)
|
46
|
+
end
|
47
|
+
|
33
48
|
datetime
|
34
49
|
end
|
35
50
|
|
@@ -51,6 +66,7 @@ module EasyTag
|
|
51
66
|
end
|
52
67
|
|
53
68
|
def self.normalize_string(str)
|
69
|
+
str = str.to_s
|
54
70
|
# downcase string
|
55
71
|
str.downcase!
|
56
72
|
# we want snakecase
|
@@ -59,5 +75,19 @@ module EasyTag
|
|
59
75
|
str.gsub(/\W/, '')
|
60
76
|
end
|
61
77
|
|
78
|
+
def self.normalize_object(object)
|
79
|
+
if object.is_a?(String)
|
80
|
+
normalize_string(object)
|
81
|
+
elsif object.is_a?(Symbol)
|
82
|
+
normalize_string(object.to_s).to_sym
|
83
|
+
elsif object.is_a?(Array)
|
84
|
+
new_array = []
|
85
|
+
object.each { |item| new_array << normalize_object(item) }
|
86
|
+
new_array
|
87
|
+
else
|
88
|
+
object
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
62
92
|
end
|
63
93
|
end
|
data/lib/easytag/version.rb
CHANGED
data/test/test_consistency.rb
CHANGED
@@ -90,15 +90,15 @@ class TestConsistencyMP302 < Test::Unit::TestCase
|
|
90
90
|
def test_tags
|
91
91
|
cases = [
|
92
92
|
['She Lives in My Lap', @mp3.title],
|
93
|
-
[
|
93
|
+
['', @mp3.title_sort_order],
|
94
94
|
['OutKast feat. Rosario Dawson', @mp3.artist],
|
95
95
|
['OutKast feat. Dawson, Rosario', @mp3.artist_sort_order],
|
96
96
|
['OutKast', @mp3.album_artist],
|
97
|
-
|
97
|
+
['', @mp3.album_artist_sort_order],
|
98
98
|
['Speakerboxxx / The Love Below', @mp3.album],
|
99
|
-
[
|
99
|
+
['', @mp3.album_sort_order],
|
100
100
|
[[], @mp3.comments],
|
101
|
-
[
|
101
|
+
['', @mp3.genre],
|
102
102
|
[2003, @mp3.year],
|
103
103
|
[[8, 21], @mp3.track_num],
|
104
104
|
[[2, 2], @mp3.disc_num],
|
@@ -107,7 +107,7 @@ class TestConsistencyMP302 < Test::Unit::TestCase
|
|
107
107
|
['Arista', @mp3.label],
|
108
108
|
[true, @mp3.compilation?],
|
109
109
|
[0, @mp3.bpm],
|
110
|
-
['B0000AGWFX', @mp3.
|
110
|
+
['B0000AGWFX', @mp3.asin],
|
111
111
|
]
|
112
112
|
|
113
113
|
cases.each do |c|
|
@@ -126,6 +126,26 @@ class TestConsistencyMP302 < Test::Unit::TestCase
|
|
126
126
|
assert_equal(23, @mp3.original_date.day)
|
127
127
|
end
|
128
128
|
|
129
|
+
def test_musicbrainz_data
|
130
|
+
cases = [
|
131
|
+
[['album'], @mp3.musicbrainz_album_type],
|
132
|
+
['73fdb566-a9b1-494c-9f32-51768ec9fd27',
|
133
|
+
@mp3.musicbrainz_album_artist_id],
|
134
|
+
[["73fdb566-a9b1-494c-9f32-51768ec9fd27",
|
135
|
+
"9facf8dc-df23-4561-85c5-ece75d692f21"], @mp3.musicbrainz_artist_id],
|
136
|
+
['468cd19e-d55c-46a2-a5a6-66292d2f0a90', @mp3.musicbrainz_album_id],
|
137
|
+
['fa64febd-61e0-346e-aaa2-04564ed4f0a3',
|
138
|
+
@mp3.musicbrainz_release_group_id],
|
139
|
+
['US', @mp3.musicbrainz_album_release_country],
|
140
|
+
['official', @mp3.musicbrainz_album_status],
|
141
|
+
]
|
142
|
+
|
143
|
+
cases.each do |c|
|
144
|
+
expected, actual = c
|
145
|
+
assert_equal(expected, actual)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
129
149
|
def test_album_art
|
130
150
|
assert_equal(1, @mp3.album_art.count)
|
131
151
|
|
@@ -164,14 +184,17 @@ class TestConsistency02 < Test::Unit::TestCase
|
|
164
184
|
:label,
|
165
185
|
:compilation?,
|
166
186
|
:bpm,
|
187
|
+
:asin,
|
188
|
+
:conductor,
|
189
|
+
:remixer,
|
190
|
+
:mood,
|
167
191
|
]
|
168
192
|
|
169
193
|
cases.each do |c|
|
170
|
-
puts c
|
194
|
+
#puts c
|
171
195
|
assert_equal(@mp3.send(c), @mp4.send(c))
|
172
196
|
end
|
173
197
|
|
174
|
-
assert_equal(@mp3.user_info[:asin], @mp4.user_info[:asin])
|
175
198
|
end
|
176
199
|
|
177
200
|
def test_date
|
@@ -188,5 +211,23 @@ class TestConsistency02 < Test::Unit::TestCase
|
|
188
211
|
assert_equal(img_mp3.data, img_mp4.data)
|
189
212
|
end
|
190
213
|
|
214
|
+
def test_musicbrainz_data
|
215
|
+
cases = [
|
216
|
+
:musicbrainz_album_artist_id,
|
217
|
+
:musicbrainz_album_id,
|
218
|
+
:musicbrainz_album_release_country,
|
219
|
+
:musicbrainz_album_status,
|
220
|
+
:musicbrainz_album_type,
|
221
|
+
:musicbrainz_artist_id,
|
222
|
+
:musicbrainz_release_group_id,
|
223
|
+
:musicbrainz_track_id,
|
224
|
+
]
|
225
|
+
|
226
|
+
cases.each do |c|
|
227
|
+
#puts c
|
228
|
+
assert_equal(@mp3.send(c), @mp4.send(c))
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
191
232
|
end
|
192
233
|
|
data/test/test_mp3.rb
CHANGED
@@ -18,7 +18,7 @@ class TestID3v1OnlyMP3 < Test::Unit::TestCase
|
|
18
18
|
assert_equal(1988, @f.year)
|
19
19
|
assert_equal(1988, @f.date.year)
|
20
20
|
assert_equal(true, @f.album_art.empty?)
|
21
|
-
assert_equal(
|
21
|
+
assert_equal('', @f.apple_id)
|
22
22
|
assert_equal([3, 0], @f.track_num)
|
23
23
|
assert_equal([0, 0], @f.disc_num)
|
24
24
|
|
@@ -39,7 +39,7 @@ class TestID3v2OnlyMP3 < Test::Unit::TestCase
|
|
39
39
|
assert_equal(1988, @f.year)
|
40
40
|
assert_equal(1988, @f.date.year)
|
41
41
|
assert_equal(true, @f.album_art.empty?)
|
42
|
-
assert_equal(
|
42
|
+
assert_equal('', @f.apple_id)
|
43
43
|
assert_equal([3, 0], @f.track_num)
|
44
44
|
assert_equal([0, 0], @f.disc_num)
|
45
45
|
|
@@ -52,18 +52,47 @@ class TestNoTagsMP3 < Test::Unit::TestCase
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def test_tags
|
55
|
-
assert_equal(
|
56
|
-
assert_equal(
|
57
|
-
assert_equal(
|
58
|
-
assert_equal(
|
55
|
+
assert_equal('', @f.title)
|
56
|
+
assert_equal('', @f.artist)
|
57
|
+
assert_equal('', @f.album)
|
58
|
+
assert_equal('', @f.album_artist)
|
59
59
|
assert_equal([], @f.comments)
|
60
|
-
assert_equal(
|
60
|
+
assert_equal('', @f.genre)
|
61
61
|
assert_equal(0, @f.year)
|
62
62
|
assert_equal(nil, @f.date)
|
63
63
|
assert_equal(true, @f.album_art.empty?)
|
64
|
-
assert_equal(
|
64
|
+
assert_equal('', @f.apple_id)
|
65
65
|
assert_equal([0, 0], @f.track_num)
|
66
66
|
assert_equal([0, 0], @f.disc_num)
|
67
|
+
assert_equal('', @f.conductor)
|
68
|
+
assert_equal('', @f.remixer)
|
69
|
+
assert_equal('', @f.mood)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_musicbrainz_data
|
73
|
+
assert_equal('', @f.musicbrainz_album_artist_id)
|
74
|
+
assert_equal('', @f.musicbrainz_album_status)
|
75
|
+
assert_equal('', @f.musicbrainz_release_group_id)
|
76
|
+
assert_equal('', @f.musicbrainz_album_id)
|
77
|
+
assert_equal([], @f.musicbrainz_album_type)
|
78
|
+
assert_equal('', @f.musicbrainz_track_id)
|
79
|
+
assert_equal('', @f.musicbrainz_album_release_country)
|
80
|
+
assert_equal([], @f.musicbrainz_artist_id)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_aliases
|
84
|
+
assert_equal(@f.length, @f.duration)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_audio_properties
|
88
|
+
assert_equal(4, @f.duration)
|
89
|
+
assert_equal(74, @f.bitrate)
|
90
|
+
assert_equal(44100, @f.sample_rate)
|
91
|
+
assert_equal(2, @f.channels)
|
92
|
+
assert_equal(true, @f.original?)
|
93
|
+
assert_equal(3, @f.layer)
|
94
|
+
assert_equal(false, @f.copyrighted?)
|
95
|
+
assert_equal(false, @f.protection_enabled?)
|
67
96
|
end
|
68
97
|
|
69
98
|
end
|
data/test/test_mp4.rb
CHANGED
@@ -10,18 +10,40 @@ class TestNoTagsMP4 < Test::Unit::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_tags
|
13
|
-
assert_equal(
|
14
|
-
assert_equal(
|
15
|
-
assert_equal(
|
16
|
-
assert_equal(
|
13
|
+
assert_equal('', @f.title)
|
14
|
+
assert_equal('', @f.artist)
|
15
|
+
assert_equal('', @f.album)
|
16
|
+
assert_equal('', @f.album_artist)
|
17
17
|
assert_equal([], @f.comments)
|
18
|
-
assert_equal(
|
18
|
+
assert_equal('', @f.genre)
|
19
19
|
assert_equal(0, @f.year)
|
20
20
|
assert_equal(nil, @f.date)
|
21
21
|
assert_equal(true, @f.album_art.empty?)
|
22
|
-
assert_equal(
|
22
|
+
assert_equal('', @f.apple_id)
|
23
23
|
assert_equal([0, 0], @f.track_num)
|
24
24
|
assert_equal([0, 0], @f.disc_num)
|
25
|
+
assert_equal('', @f.conductor)
|
26
|
+
assert_equal('', @f.remixer)
|
27
|
+
assert_equal('', @f.mood)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_musicbrainz_data
|
31
|
+
assert_equal('', @f.musicbrainz_album_artist_id)
|
32
|
+
assert_equal('', @f.musicbrainz_album_status)
|
33
|
+
assert_equal('', @f.musicbrainz_release_group_id)
|
34
|
+
assert_equal('', @f.musicbrainz_album_id)
|
35
|
+
assert_equal([], @f.musicbrainz_album_type)
|
36
|
+
assert_equal('', @f.musicbrainz_track_id)
|
37
|
+
assert_equal('', @f.musicbrainz_album_release_country)
|
38
|
+
assert_equal([], @f.musicbrainz_artist_id)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_audio_properties
|
42
|
+
assert_equal(4, @f.duration)
|
43
|
+
assert_equal(176, @f.bitrate)
|
44
|
+
assert_equal(44100, @f.sample_rate)
|
45
|
+
assert_equal(2, @f.channels)
|
46
|
+
assert_equal(16, @f.bits_per_sample)
|
25
47
|
end
|
26
48
|
|
27
49
|
end
|
data/test/test_util.rb
CHANGED
@@ -24,18 +24,33 @@ class TestUtilities < Test::Unit::TestCase
|
|
24
24
|
assert_equal(7, date.day)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
27
|
+
def test_get_datetime04
|
28
28
|
date = EasyTag::Utilities.get_datetime('19880711')
|
29
29
|
assert_equal(1988, date.year)
|
30
30
|
assert_equal(11, date.month)
|
31
31
|
assert_equal(7, date.day)
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
34
|
+
def test_get_datetime05
|
35
35
|
date = EasyTag::Utilities.get_datetime('')
|
36
36
|
assert_equal(nil, date)
|
37
37
|
end
|
38
38
|
|
39
|
+
def test_get_datetime06
|
40
|
+
date = EasyTag::Utilities.get_datetime('2000-00-00')
|
41
|
+
assert_equal(2000, date.year)
|
42
|
+
assert_equal(1, date.month)
|
43
|
+
assert_equal(1, date.day)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_get_datetime07
|
47
|
+
date = EasyTag::Utilities.get_datetime('2006-99-99')
|
48
|
+
assert_equal(2006, date.year)
|
49
|
+
assert_equal(1, date.month)
|
50
|
+
assert_equal(1, date.day)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
39
54
|
def test_get_int_pair
|
40
55
|
assert_equal([0, 0], EasyTag::Utilities.get_int_pair(''))
|
41
56
|
assert_equal([0, 0], EasyTag::Utilities.get_int_pair(nil))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easytag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Lucas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: taglib-ruby
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: |2
|
70
|
-
EasyTag is an
|
70
|
+
EasyTag is an abstract interface to the TagLib audio tagging library.
|
71
71
|
It is designed to provide a simple and consistent API regardless
|
72
72
|
of file format being read.
|
73
73
|
email:
|