easytag 0.4.3 → 1.0.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 +11 -0
- data/Gemfile +7 -2
- data/README.md +33 -27
- data/Rakefile +7 -7
- data/easytag.gemspec +2 -4
- data/lib/easytag.rb +12 -2
- data/lib/easytag/attributes/base.rb +32 -128
- data/lib/easytag/attributes/flac.rb +25 -0
- data/lib/easytag/attributes/mp3.rb +91 -554
- data/lib/easytag/attributes/mp4.rb +22 -492
- data/lib/easytag/attributes/ogg.rb +27 -0
- data/lib/easytag/attributes/vorbis.rb +18 -0
- data/lib/easytag/taggers/base.rb +19 -0
- data/lib/easytag/taggers/factory.rb +59 -0
- data/lib/easytag/taggers/flac.rb +23 -0
- data/lib/easytag/taggers/mp3.rb +77 -0
- data/lib/easytag/taggers/mp4.rb +73 -0
- data/lib/easytag/taggers/ogg.rb +25 -0
- data/lib/easytag/taggers/vorbis.rb +66 -0
- data/lib/easytag/util.rb +9 -31
- data/lib/easytag/version.rb +3 -4
- data/scripts/build_attributes_table.rb +34 -0
- data/{test → spec/data}/consistency.01.m4a +0 -0
- data/{test → spec/data}/consistency.01.mp3 +0 -0
- data/spec/data/consistency.flac +0 -0
- data/{test/consistency.02.m4a → spec/data/consistency.m4a} +0 -0
- data/{test/consistency.02.mp3 → spec/data/consistency.mp3} +0 -0
- data/spec/data/consistency.multiple_images.flac +0 -0
- data/{test/no_tags.m4a → spec/data/consistency.multiple_images.m4a} +0 -0
- data/spec/data/consistency.multiple_images.mp3 +0 -0
- data/spec/data/consistency.multiple_images.ogg +0 -0
- data/spec/data/consistency.ogg +0 -0
- data/{test → spec/data}/musicbrainz.m4a +0 -0
- data/spec/data/no_tags.flac +0 -0
- data/spec/data/no_tags.m4a +0 -0
- data/{test → spec/data}/no_tags.mp3 +0 -0
- data/spec/data/no_tags.ogg +0 -0
- data/{test → spec/data}/only_id3v1.mp3 +0 -0
- data/{test → spec/data}/only_id3v2.mp3 +0 -0
- data/spec/flac_tagger_spec.rb +24 -0
- data/spec/mp3_tagger_spec.rb +64 -0
- data/spec/mp4_tagger_spec.rb +22 -0
- data/spec/ogg_tagger_spec.rb +21 -0
- data/spec/shared_examples.rb +115 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/tagger_factory_spec.rb +27 -0
- data/spec/util_spec.rb +47 -0
- metadata +47 -48
- data/lib/easytag/attributes.rb +0 -0
- data/lib/easytag/base.rb +0 -28
- data/lib/easytag/file.rb +0 -44
- data/lib/easytag/interfaces.rb +0 -18
- data/lib/easytag/interfaces/base.rb +0 -24
- data/lib/easytag/interfaces/mp3.rb +0 -48
- data/lib/easytag/interfaces/mp4.rb +0 -14
- data/test/test_consistency.rb +0 -233
- data/test/test_mp3.rb +0 -98
- data/test/test_mp4.rb +0 -49
- data/test/test_util.rb +0 -72
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
require_relative 'vorbis'
|
4
|
+
|
5
|
+
module EasyTag
|
6
|
+
module OggAttributeAccessors
|
7
|
+
def field_reader(attr_name, fields = nil, **opts)
|
8
|
+
fields = attr_name.to_s.upcase if fields.nil?
|
9
|
+
define_method(attr_name) do
|
10
|
+
v = self.class.read_fields(taglib.tag, fields, **opts)
|
11
|
+
self.class.post_process(v, **opts)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def album_art_reader(attr_name, **opts)
|
16
|
+
opts[:returns] = :list
|
17
|
+
define_method(attr_name) do
|
18
|
+
v = self.class.read_fields(taglib.tag, 'METADATA_BLOCK_PICTURE', **opts)
|
19
|
+
v.collect do |b64_data|
|
20
|
+
pic = TagLib::FLAC::Picture.new
|
21
|
+
pic.parse(Base64.decode64(b64_data))
|
22
|
+
EasyTag::Image.new(pic.data)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module EasyTag
|
4
|
+
module VorbisAttributeAccessors
|
5
|
+
include BaseAttributeAccessors
|
6
|
+
|
7
|
+
|
8
|
+
def read_fields(xiph_comment, fields, **opts)
|
9
|
+
fields = Array(fields)
|
10
|
+
fields.each do |field|
|
11
|
+
next unless xiph_comment.contains?(field)
|
12
|
+
data = xiph_comment.field_list_map[field]
|
13
|
+
return opts[:returns] == :list ? data : data.first
|
14
|
+
end
|
15
|
+
opts[:returns] == :list ? [] : nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module EasyTag
|
2
|
+
class BaseTagger
|
3
|
+
attr_reader :taglib
|
4
|
+
|
5
|
+
def year
|
6
|
+
date.nil? ? 0 : date.year
|
7
|
+
end
|
8
|
+
|
9
|
+
def close
|
10
|
+
taglib.close
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(method, *args, **kwargs)
|
14
|
+
warn "#{self.class.name}##{method} does not exist"
|
15
|
+
method.to_s[-1].eql?('?') ? false : nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module EasyTag
|
2
|
+
class TaggerFactory
|
3
|
+
def self.open(file, &block)
|
4
|
+
tagger_klass = tagger_class(file)
|
5
|
+
|
6
|
+
if block_given?
|
7
|
+
tagger = tagger_klass.new(file)
|
8
|
+
begin
|
9
|
+
block.call(tagger)
|
10
|
+
ensure
|
11
|
+
tagger.close
|
12
|
+
end
|
13
|
+
else
|
14
|
+
tagger_klass.new(file)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.tagger_class(file)
|
19
|
+
tagger_klass = tagger_for_filename(file)
|
20
|
+
if tagger_klass.nil?
|
21
|
+
data = nil
|
22
|
+
File.open(file, 'rb') { |fp| data = fp.read(16) }
|
23
|
+
tagger_klass = tagger_for_signature(data.bytes)
|
24
|
+
end
|
25
|
+
|
26
|
+
raise 'Could not determine file type' if tagger_klass.nil?
|
27
|
+
tagger_klass
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.tagger_for_filename(fname)
|
31
|
+
case fname.split('.')[-1].downcase.to_sym
|
32
|
+
when :mp3; MP3Tagger
|
33
|
+
when :mp4, :m4a; MP4Tagger
|
34
|
+
when :flac; FLACTagger
|
35
|
+
when :ogg; OggTagger
|
36
|
+
else; nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.tagger_for_signature(bytes)
|
41
|
+
case
|
42
|
+
when bytes[0...11] == [0, 0, 0, 32, 102, 116, 121, 112, 77, 52, 65] # ...ftypM4A
|
43
|
+
MP4Tagger
|
44
|
+
when bytes[0...11] == [0, 0, 0, 24, 102, 116, 121, 112, 109, 112, 52] # ...ftypmp4
|
45
|
+
MP4Tagger
|
46
|
+
when bytes[0...4] == [102, 76, 97, 67] # fLaC
|
47
|
+
FLACTagger
|
48
|
+
when bytes[0...4] == [79, 103, 103, 83] # OggS
|
49
|
+
OggTagger
|
50
|
+
when bytes[0...3] == [73, 68, 51] # ID3
|
51
|
+
MP3Tagger
|
52
|
+
when bytes[0...2] == [255, 251] # FF FB
|
53
|
+
MP3Tagger
|
54
|
+
else
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'easytag/attributes/flac'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module EasyTag
|
6
|
+
class FLACTagger < BaseTagger
|
7
|
+
extend FLACAttributeAccessors
|
8
|
+
extend VorbisAttributes
|
9
|
+
|
10
|
+
initialize_vorbis_attributes
|
11
|
+
|
12
|
+
audio_prop_reader :length
|
13
|
+
audio_prop_reader :bitrate
|
14
|
+
audio_prop_reader :sample_rate
|
15
|
+
audio_prop_reader :channels
|
16
|
+
audio_prop_reader :sample_width
|
17
|
+
audio_prop_reader :signature
|
18
|
+
|
19
|
+
def initialize(file)
|
20
|
+
@taglib = TagLib::FLAC::File.new(file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'easytag/attributes/mp3'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module EasyTag
|
6
|
+
class MP3Tagger < BaseTagger
|
7
|
+
extend MP3AttributeAccessors
|
8
|
+
|
9
|
+
single_tag_reader :title, 'TIT2', :title
|
10
|
+
single_tag_reader :title_sort_order, %w{TSOT XSOT}
|
11
|
+
single_tag_reader :subtitle, 'TIT3'
|
12
|
+
single_tag_reader :artist, 'TPE1', :artist
|
13
|
+
single_tag_reader :artist_sort_order, %w{TSOP XSOP}
|
14
|
+
single_tag_reader :album, 'TALB', :album
|
15
|
+
single_tag_reader :album_sort_order, %w{TSOA XSOA}
|
16
|
+
single_tag_reader :album_artist, 'TPE2'
|
17
|
+
single_tag_reader :album_artist_sort_order, 'TSO2'
|
18
|
+
single_tag_reader :compilation?, 'TCMP', nil, returns: :bool
|
19
|
+
single_tag_reader :genre, 'TCON', :genre
|
20
|
+
single_tag_reader :disc_subtitle, 'TSST'
|
21
|
+
single_tag_reader :media, 'TMED'
|
22
|
+
single_tag_reader :label, 'TPUB'
|
23
|
+
single_tag_reader :encoded_by, 'TENC'
|
24
|
+
single_tag_reader :encoder_settings, 'TSSE'
|
25
|
+
single_tag_reader :group, 'TIT1'
|
26
|
+
single_tag_reader :composer, 'TCOM'
|
27
|
+
single_tag_reader :conductor, 'TPE3'
|
28
|
+
single_tag_reader :remixer, 'TPE4'
|
29
|
+
single_tag_reader :lyrics, 'USLT'
|
30
|
+
single_tag_reader :lyricist, 'TEXT'
|
31
|
+
single_tag_reader :copyright, 'TCOP'
|
32
|
+
single_tag_reader :bpm, 'TBPM', nil, returns: :int
|
33
|
+
single_tag_reader :mood, 'TMOD'
|
34
|
+
single_tag_reader :isrc, 'TSRC'
|
35
|
+
single_tag_reader :track_number, 'TRCK', :track, cast: :int_pair, extract_list_pos: 0
|
36
|
+
single_tag_reader :total_tracks, 'TRCK', :track, cast: :int_pair, extract_list_pos: 1
|
37
|
+
single_tag_reader :disc_number, 'TPOS', nil, cast: :int_pair, extract_list_pos: 0
|
38
|
+
single_tag_reader :total_discs, 'TPOS', nil, cast: :int_pair, extract_list_pos: 1
|
39
|
+
single_tag_reader :original_date, %w{TDOR TORY}, nil, returns: :datetime
|
40
|
+
|
41
|
+
all_tags_reader :comments, 'COMM', :comment
|
42
|
+
all_tags_reader :album_art, 'APIC'
|
43
|
+
|
44
|
+
audio_prop_reader :length
|
45
|
+
audio_prop_reader :bitrate
|
46
|
+
audio_prop_reader :sample_rate
|
47
|
+
audio_prop_reader :channels
|
48
|
+
audio_prop_reader :copyrighted?
|
49
|
+
audio_prop_reader :layer
|
50
|
+
audio_prop_reader :original?
|
51
|
+
audio_prop_reader :protection_enabled?, :protection_enabled
|
52
|
+
|
53
|
+
user_info_reader :asin, 'ASIN'
|
54
|
+
user_info_reader :script, 'SCRIPT'
|
55
|
+
user_info_reader :barcode, 'BARCODE'
|
56
|
+
user_info_reader :catalog_number, 'CATALOGNUMBER'
|
57
|
+
user_info_reader :musicbrainz_track_id, 'MusicBrainz Release Track Id'
|
58
|
+
user_info_reader :musicbrainz_album_id, 'MusicBrainz Album Id'
|
59
|
+
user_info_reader :musicbrainz_artist_id, 'MusicBrainz Artist Id', returns: :list
|
60
|
+
user_info_reader :musicbrainz_album_artist_id, 'MusicBrainz Album Artist Id'
|
61
|
+
user_info_reader :musicbrainz_trm_id, 'MusicBrainz TRM Id'
|
62
|
+
user_info_reader :musicbrainz_disc_id, 'MusicBrainz Disc Id'
|
63
|
+
user_info_reader :musicbrainz_release_status, 'MusicBrainz Album Status'
|
64
|
+
user_info_reader :musicbrainz_release_type, 'MusicBrainz Album Type', returns: :list
|
65
|
+
user_info_reader :musicbrainz_release_country, 'MusicBrainz Album Release Country'
|
66
|
+
user_info_reader :musicbrainz_release_group_id, 'MusicBrainz Release Group Id'
|
67
|
+
user_info_reader :musicip_puid, 'MusicIP PUID'
|
68
|
+
user_info_reader :musicip_fingerprint, 'MusicMagic Fingerprint'
|
69
|
+
|
70
|
+
ufid_reader :musicbrainz_recording_id, 'http://musicbrainz.org'
|
71
|
+
date_reader :date
|
72
|
+
|
73
|
+
def initialize(file)
|
74
|
+
@taglib = TagLib::MPEG::File.new(file)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'easytag/attributes/mp4'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module EasyTag
|
6
|
+
class MP4Tagger < BaseTagger
|
7
|
+
extend MP4AttributeAccessors
|
8
|
+
|
9
|
+
item_reader :title, '©nam'
|
10
|
+
item_reader :title_sort_order, 'sonm'
|
11
|
+
item_reader :artist, '©ART'
|
12
|
+
item_reader :artist_sort_order, 'soar'
|
13
|
+
item_reader :album_artist, 'aART'
|
14
|
+
item_reader :album_artist_sort_order, 'soaa'
|
15
|
+
item_reader :album, '©alb'
|
16
|
+
item_reader :album_sort_order, 'soal'
|
17
|
+
item_reader :genre, '©gen'
|
18
|
+
item_reader :comments, '©cmt', data_type: :string_list, returns: :list
|
19
|
+
item_reader :lyrics, '©lyr'
|
20
|
+
item_reader :date, '©day', returns: :datetime
|
21
|
+
item_reader :encoded_by, '©enc'
|
22
|
+
item_reader :encoder_settings, '©too'
|
23
|
+
item_reader :group, '©grp'
|
24
|
+
item_reader :compilation?, 'cpil', data_type: :bool
|
25
|
+
item_reader :bpm, 'tmpo', data_type: :int
|
26
|
+
item_reader :mood, 'mood'
|
27
|
+
item_reader :copyright, 'cprt'
|
28
|
+
item_reader :track_number, 'trkn', data_type: :int_pair, cast: :int_pair, extract_list_pos: 0
|
29
|
+
item_reader :total_tracks, 'trkn', data_type: :int_pair, cast: :int_pair, extract_list_pos: 1
|
30
|
+
item_reader :disc_number, 'disk', data_type: :int_pair, cast: :int_pair, extract_list_pos: 0
|
31
|
+
item_reader :total_discs, 'disk', data_type: :int_pair, cast: :int_pair, extract_list_pos: 1
|
32
|
+
item_reader :album_art, 'covr', data_type: :cover_art_list, returns: :list
|
33
|
+
|
34
|
+
item_reader :subtitle, '----:com.apple.iTunes:SUBTITLE'
|
35
|
+
item_reader :disc_subtitle, '----:com.apple.iTunes:DISCSUBTITLE'
|
36
|
+
item_reader :media, '----:com.apple.iTunes:MEDIA'
|
37
|
+
item_reader :label, '----:com.apple.iTunes:LABEL'
|
38
|
+
item_reader :composer, '----:com.apple.iTunes:COMPOSER'
|
39
|
+
item_reader :remixer, '----:com.apple.iTunes:REMIXER'
|
40
|
+
item_reader :conductor, '----:com.apple.iTunes:CONDUCTOR'
|
41
|
+
item_reader :lyricist, '----:com.apple.iTunes:LYRICIST'
|
42
|
+
item_reader :asin, '----:com.apple.iTunes:ASIN'
|
43
|
+
item_reader :isrc, '----:com.apple.iTunes:ISRC'
|
44
|
+
item_reader :script, '----:com.apple.iTunes:SCRIPT'
|
45
|
+
item_reader :barcode, '----:com.apple.iTunes:BARCODE'
|
46
|
+
item_reader :catalog_number, '----:com.apple.iTunes:CATALOGNUMBER'
|
47
|
+
|
48
|
+
item_reader :musicbrainz_recording_id, '----:com.apple.iTunes:MusicBrainz Track Id'
|
49
|
+
item_reader :musicbrainz_track_id, '----:com.apple.iTunes:MusicBrainz Release Track Id'
|
50
|
+
item_reader :musicbrainz_artist_id, '----:com.apple.iTunes:MusicBrainz Artist Id', data_type: :string_list, returns: :list
|
51
|
+
item_reader :musicbrainz_album_artist_id, '----:com.apple.iTunes:MusicBrainz Album Artist Id'
|
52
|
+
item_reader :musicbrainz_album_id, '----:com.apple.iTunes:MusicBrainz Album Id'
|
53
|
+
item_reader :musicbrainz_disc_id, '----:com.apple.iTunes:MusicBrainz Disc Id'
|
54
|
+
item_reader :musicbrainz_trm_id, '----:com.apple.iTunes:MusicBrainz TRM Id'
|
55
|
+
item_reader :musicbrainz_release_group_id, '----:com.apple.iTunes:MusicBrainz Release Group Id'
|
56
|
+
item_reader :musicbrainz_release_status, '----:com.apple.iTunes:MusicBrainz Album Status'
|
57
|
+
item_reader :musicbrainz_release_type, '----:com.apple.iTunes:MusicBrainz Album Type', data_type: :string_list, returns: :list
|
58
|
+
item_reader :musicbrainz_release_country, '----:com.apple.iTunes:MusicBrainz Album Release Country'
|
59
|
+
item_reader :musicip_puid, '----:com.apple.iTunes:MusicIP PUID'
|
60
|
+
item_reader :musicip_fingerprint, '----:com.apple.iTunes:fingerprint'
|
61
|
+
|
62
|
+
audio_prop_reader :length
|
63
|
+
audio_prop_reader :bitrate
|
64
|
+
audio_prop_reader :sample_rate
|
65
|
+
audio_prop_reader :channels
|
66
|
+
audio_prop_reader :bits_per_sample
|
67
|
+
audio_prop_reader :encrypted?
|
68
|
+
|
69
|
+
def initialize(file)
|
70
|
+
@taglib = TagLib::MP4::File.new(file)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'easytag/attributes/ogg'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module EasyTag
|
6
|
+
class OggTagger < BaseTagger
|
7
|
+
extend OggAttributeAccessors
|
8
|
+
extend VorbisAttributes
|
9
|
+
|
10
|
+
initialize_vorbis_attributes
|
11
|
+
|
12
|
+
audio_prop_reader :length
|
13
|
+
audio_prop_reader :bitrate
|
14
|
+
audio_prop_reader :sample_rate
|
15
|
+
audio_prop_reader :channels
|
16
|
+
audio_prop_reader :bitrate_maximum
|
17
|
+
audio_prop_reader :bitrate_minimum
|
18
|
+
audio_prop_reader :bitrate_nominal
|
19
|
+
audio_prop_reader :vorbis_version
|
20
|
+
|
21
|
+
def initialize(file)
|
22
|
+
@taglib = TagLib::Ogg::Vorbis::File.new(file)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'easytag/attributes/vorbis'
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module EasyTag
|
6
|
+
module VorbisAttributes
|
7
|
+
include VorbisAttributeAccessors
|
8
|
+
|
9
|
+
def initialize_vorbis_attributes
|
10
|
+
field_reader :title
|
11
|
+
field_reader :title_sort_order, 'TITLESORT'
|
12
|
+
field_reader :subtitle
|
13
|
+
field_reader :artist
|
14
|
+
field_reader :artist_sort_order, 'ARTISTSORT'
|
15
|
+
field_reader :album
|
16
|
+
field_reader :album_sort_order, 'ALBUMSORT'
|
17
|
+
field_reader :album_artist, 'ALBUMARTIST'
|
18
|
+
field_reader :album_artist_sort_order, 'ALBUMARTISTSORT'
|
19
|
+
field_reader :compilation?, 'COMPILATION', returns: :bool
|
20
|
+
field_reader :genre
|
21
|
+
field_reader :disc_subtitle, 'DISCSUBTITLE'
|
22
|
+
field_reader :media
|
23
|
+
field_reader :label
|
24
|
+
field_reader :encoded_by, 'ENCODEDBY'
|
25
|
+
field_reader :encoder_settings, 'ENCODERSETTINGS'
|
26
|
+
field_reader :group
|
27
|
+
field_reader :composer
|
28
|
+
field_reader :conductor
|
29
|
+
field_reader :remixer
|
30
|
+
field_reader :lyrics
|
31
|
+
field_reader :lyricist
|
32
|
+
field_reader :copyright
|
33
|
+
field_reader :bpm, returns: :int
|
34
|
+
field_reader :mood
|
35
|
+
field_reader :isrc
|
36
|
+
field_reader :track_number, 'TRACKNUMBER', returns: :int
|
37
|
+
field_reader :total_tracks, %w{TRACKTOTAL TOTALTRACKS}, returns: :int
|
38
|
+
field_reader :disc_number, 'DISCNUMBER', returns: :int
|
39
|
+
field_reader :total_discs, %W{DISCTOTAL TOTALDISCS}, returns: :int
|
40
|
+
field_reader :date, returns: :datetime
|
41
|
+
field_reader :original_date, 'ORIGINALDATE', returns: :datetime
|
42
|
+
field_reader :comments, 'COMMENT', returns: :list
|
43
|
+
|
44
|
+
album_art_reader :album_art
|
45
|
+
|
46
|
+
field_reader :asin, 'ASIN'
|
47
|
+
field_reader :script, 'SCRIPT'
|
48
|
+
field_reader :barcode, 'BARCODE'
|
49
|
+
field_reader :catalog_number, 'CATALOGNUMBER'
|
50
|
+
field_reader :musicbrainz_recording_id, 'MUSICBRAINZ_TRACKID'
|
51
|
+
field_reader :musicbrainz_track_id, 'MUSICBRAINZ_RELEASETRACKID'
|
52
|
+
field_reader :musicbrainz_album_id, 'MUSICBRAINZ_ALBUMID'
|
53
|
+
field_reader :musicbrainz_artist_id, 'MUSICBRAINZ_ARTISTID', returns: :list
|
54
|
+
field_reader :musicbrainz_album_artist_id, 'MUSICBRAINZ_ALBUMARTISTID'
|
55
|
+
field_reader :musicbrainz_trm_id, 'MUSICBRAINZ_TRMID'
|
56
|
+
field_reader :musicbrainz_disc_id, 'MUSICBRAINZ_DISCID'
|
57
|
+
field_reader :musicbrainz_release_status, 'RELEASESTATUS'
|
58
|
+
field_reader :musicbrainz_release_type, 'RELEASETYPE', returns: :list
|
59
|
+
field_reader :musicbrainz_release_country, 'RELEASECOUNTRY'
|
60
|
+
field_reader :musicbrainz_release_group_id, 'MUSICBRAINZ_RELEASEGROUPID'
|
61
|
+
field_reader :musicip_puid, 'MUSICIP_PUID'
|
62
|
+
# TODO
|
63
|
+
# field_reader :musicip_fingerprint, 'MusicMagic Fingerprint'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/easytag/util.rb
CHANGED
@@ -50,44 +50,22 @@ module EasyTag
|
|
50
50
|
|
51
51
|
# get_int_pair
|
52
52
|
#
|
53
|
-
# Parses a pos/total string and returns a pair of ints
|
54
|
-
def self.get_int_pair(
|
53
|
+
# Parses a pos/total string and returns a pair of ints (or nils)
|
54
|
+
def self.get_int_pair(input)
|
55
|
+
return input.collect { |i| i.to_i }[0..1] if input.is_a?(Array)
|
56
|
+
|
57
|
+
input = input.to_s
|
55
58
|
pair = [0, 0]
|
56
59
|
|
57
|
-
unless
|
58
|
-
if
|
59
|
-
pair =
|
60
|
+
unless input.nil? || input.empty?
|
61
|
+
if input.include?('/')
|
62
|
+
pair = input.split('/').collect { |it| it.to_i }
|
60
63
|
else
|
61
|
-
pair[0] =
|
64
|
+
pair[0] = input.to_i
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
65
68
|
pair
|
66
69
|
end
|
67
|
-
|
68
|
-
def self.normalize_string(str)
|
69
|
-
str = str.to_s
|
70
|
-
# downcase string
|
71
|
-
str.downcase!
|
72
|
-
# we want snakecase
|
73
|
-
str.gsub!(/\s/, '_')
|
74
|
-
# we only want alphanumeric characters
|
75
|
-
str.gsub(/\W/, '')
|
76
|
-
end
|
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
|
-
|
92
70
|
end
|
93
71
|
end
|