id3tag 0.10.0 → 0.13.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -6
  3. data/lib/id3tag.rb +14 -4
  4. data/lib/id3tag/audio_file.rb +10 -4
  5. data/lib/id3tag/configuration.rb +43 -2
  6. data/lib/id3tag/configuration_struct.rb +13 -0
  7. data/lib/id3tag/encoding_util.rb +1 -1
  8. data/lib/id3tag/frames/v2/text_frame.rb +4 -2
  9. data/lib/id3tag/id3_v2_frame_parser.rb +13 -9
  10. data/lib/id3tag/string_util.rb +1 -1
  11. data/lib/id3tag/version.rb +1 -1
  12. metadata +21 -110
  13. data/.document +0 -5
  14. data/.gitignore +0 -8
  15. data/.rspec +0 -1
  16. data/.travis.yml +0 -14
  17. data/Gemfile +0 -4
  18. data/Rakefile +0 -24
  19. data/id3tag.gemspec +0 -28
  20. data/spec/features/can_read_non_audio_files_spec.rb +0 -17
  21. data/spec/features/can_read_tag_v1_spec.rb +0 -15
  22. data/spec/fixtures/id3v1_and_v2.mp3 +0 -0
  23. data/spec/fixtures/id3v1_with_track_nr.mp3 +0 -0
  24. data/spec/fixtures/id3v1_without_track_nr.mp3 +0 -0
  25. data/spec/fixtures/id3v2.mp3 +0 -0
  26. data/spec/fixtures/pov_20131018-2100a.mp3.v1_tag_body +0 -0
  27. data/spec/fixtures/pov_20131018-2100a.mp3.v2_3_tag_body +0 -0
  28. data/spec/fixtures/signals_1.mp3.v2_3_tag_body +0 -0
  29. data/spec/id3tag_extract_tags +0 -18
  30. data/spec/lib/id3tag/audio_file_spec.rb +0 -131
  31. data/spec/lib/id3tag/frames/util/genre_name_by_id_finder_spec.rb +0 -18
  32. data/spec/lib/id3tag/frames/v1/comments_frame_spec.rb +0 -39
  33. data/spec/lib/id3tag/frames/v1/genre_frame_spec.rb +0 -20
  34. data/spec/lib/id3tag/frames/v1/text_frame_spec.rb +0 -14
  35. data/spec/lib/id3tag/frames/v1/track_nr_frame_spec.rb +0 -19
  36. data/spec/lib/id3tag/frames/v2/basic_frame_spec.rb +0 -140
  37. data/spec/lib/id3tag/frames/v2/comments_frame_spec.rb +0 -45
  38. data/spec/lib/id3tag/frames/v2/frame_fabricator_spec.rb +0 -70
  39. data/spec/lib/id3tag/frames/v2/frame_flags_spec.rb +0 -588
  40. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_24_spec.rb +0 -26
  41. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24_spec.rb +0 -48
  42. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_spec.rb +0 -13
  43. data/spec/lib/id3tag/frames/v2/genre_frame_spec.rb +0 -61
  44. data/spec/lib/id3tag/frames/v2/picture_frame_spec.rb +0 -127
  45. data/spec/lib/id3tag/frames/v2/text_frame_spec.rb +0 -89
  46. data/spec/lib/id3tag/frames/v2/unique_file_id_frame_spec.rb +0 -31
  47. data/spec/lib/id3tag/frames/v2/user_text_frame_spec.rb +0 -34
  48. data/spec/lib/id3tag/id3_v1_frame_parser_spec.rb +0 -71
  49. data/spec/lib/id3tag/id3_v2_frame_parser_spec.rb +0 -32
  50. data/spec/lib/id3tag/id3_v2_tag_header_spec.rb +0 -149
  51. data/spec/lib/id3tag/id3tag_spec.rb +0 -17
  52. data/spec/lib/id3tag/io_util_spec.rb +0 -30
  53. data/spec/lib/id3tag/number_util_spec.rb +0 -32
  54. data/spec/lib/id3tag/string_util_spec.rb +0 -66
  55. data/spec/lib/id3tag/synchsafe_integer_spec.rb +0 -14
  56. data/spec/lib/id3tag/tag_spec.rb +0 -352
  57. data/spec/spec_helper.rb +0 -23
  58. data/spec/support/mp3_fixtures.rb +0 -4
  59. data/standard_documents/id3v2-00.txt +0 -1657
  60. data/standard_documents/id3v2.3.0.txt +0 -2022
  61. data/standard_documents/id3v2.4.0-frames.txt +0 -1732
  62. data/standard_documents/id3v2.4.0-structure.txt +0 -732
@@ -1,26 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::GenreFrame::GenreParser24 do
5
- describe '#genres' do
6
-
7
- subject { described_class.new(genre_string).genres }
8
-
9
- context "when version is 2.4" do
10
- context "with remix and cover" do
11
- let(:genre_string) { "RX\x00CR" }
12
- it { is_expected.to eq(['Remix', 'Cover']) }
13
- end
14
- context "with refinement and number" do
15
- let(:genre_string) { "ABC\x0017" }
16
- it { is_expected.to eq(['ABC', 'Rock']) }
17
- end
18
- context "with one genre" do
19
- let(:genre_string) { "17" }
20
- it { is_expected.to eq(['Rock']) }
21
- end
22
- end
23
-
24
- end
25
- end
26
-
@@ -1,48 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::GenreFrame::GenreParserPre24 do
5
- describe '#genres' do
6
-
7
- subject { described_class.new(genre_string).genres }
8
-
9
- context "without refinements" do
10
- context "with one genre" do
11
- let(:genre_string) { '(17)' }
12
- it { is_expected.to eq(['Rock']) }
13
- end
14
- context "with multiple genres" do
15
- let(:genre_string) { '(17)(18)' }
16
- it { is_expected.to eq(['Rock', 'Techno']) }
17
- end
18
- context "with remix and cover" do
19
- let(:genre_string) { '(RX)(CR)' }
20
- it { is_expected.to eq(['Remix', 'Cover']) }
21
- end
22
- end
23
- context "with refinements" do
24
- context "with one genre" do
25
- let(:genre_string) { '(17)qwerty' }
26
- it { is_expected.to eq(['qwerty']) }
27
- end
28
- context "with miltiple genres but only 1 refinement" do
29
- let(:genre_string) { '(0)(16)(17)qwerty' }
30
- it { is_expected.to eq(['Blues', 'Reggae', 'qwerty']) }
31
- end
32
- context "with multiple genres" do
33
- let(:genre_string) { '(17)qwerty(18)abcdef' }
34
- it { is_expected.to eq(['qwerty', 'abcdef']) }
35
- end
36
- end
37
- context "with refinement containing '('" do
38
- context "with one genre" do
39
- let(:genre_string) { '(55)((I think...)' }
40
- it { is_expected.to eq(['(I think...)']) }
41
- end
42
- context "with multiple genres" do
43
- let(:genre_string) { '(55)((I think...)(17)' }
44
- it { is_expected.to eq(['(I think...)', 'Rock']) }
45
- end
46
- end
47
- end
48
- end
@@ -1,13 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::GenreFrame::GenreParser do
5
- let(:genre_string) { "17" }
6
- subject { described_class.new(genre_string) }
7
-
8
- describe '#genres' do
9
- it "should raise not implemented error" do
10
- expect { subject.genres }.to raise_error(/genres is not implemented/)
11
- end
12
- end
13
- end
@@ -1,61 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::GenreFrame do
5
- let(:id) { "TCON" }
6
- let(:raw_content) { "\x03(17)" }
7
- let(:flags) { nil }
8
- let(:major_version_number) { 3 }
9
- let(:frame) { described_class.new(id, raw_content, flags, major_version_number) }
10
-
11
- describe '#id' do
12
- subject { frame.id }
13
- it { is_expected.to eq(:TCON) }
14
- end
15
-
16
- describe '#content' do
17
- subject { frame.content }
18
-
19
- context "when tag major version is pre 4" do
20
- let(:major_version_number) { 3 }
21
-
22
- context "when one genre" do
23
- before do
24
- allow_any_instance_of(ID3Tag::Frames::V2::GenreFrame::GenreParserPre24).to receive(:genres) { ['A'] }
25
- end
26
- it { is_expected.to eq('A') }
27
- end
28
- context "when two genres" do
29
- before do
30
- allow_any_instance_of(ID3Tag::Frames::V2::GenreFrame::GenreParserPre24).to receive(:genres) { ['A', 'B'] }
31
- end
32
-
33
- it { is_expected.to eq('A, B') }
34
- end
35
- end
36
-
37
- context "when tag major version is 4" do
38
- let(:major_version_number) { 4 }
39
- before do
40
- allow_any_instance_of(ID3Tag::Frames::V2::GenreFrame::GenreParser24).to receive(:genres) { ['B'] }
41
- end
42
- it { is_expected.to eq('B') }
43
- end
44
- context "when tag major version is 232" do
45
- let(:major_version_number) { 232 }
46
- it "should raise MissingGenreParser error" do
47
- expect { subject }.to raise_error(ID3Tag::Frames::V2::GenreFrame::MissingGenreParser)
48
- end
49
- end
50
- end
51
-
52
- describe '#inspect' do
53
- before do
54
- allow(frame).to receive(:content) { 'Rock' }
55
- end
56
-
57
- it 'should be pretty inspectable' do
58
- expect(frame.inspect).to eq('<ID3Tag::Frames::V2::GenreFrame TCON: Rock>')
59
- end
60
- end
61
- end
@@ -1,127 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::PictureFrame do
5
- let(:separator) { "\x00".force_encoding(target_encoding) }
6
- let(:encoding) { encoding_byte.force_encoding(target_encoding) }
7
- let(:flags) { nil }
8
- let(:target_encoding) { Encoding::UTF_8 }
9
- let(:encoding_byte) { "\x03" }
10
- let(:description) { "picture description" }
11
- let(:picture_type) { "\x03" } # cover_front
12
- let(:frame) { described_class.new(id, raw_content, flags, major_version_number) }
13
- let(:data) { "picture data" }
14
-
15
- context "when PIC frame" do
16
- let(:id) { "PIC" }
17
- let(:major_version_number) { 2 }
18
- let(:format) { "png" }
19
- let(:raw_content) do
20
- encoding_byte + format + picture_type + description + separator + data
21
- end
22
-
23
- describe '#id' do
24
- subject { frame.id }
25
- it { is_expected.to eq(:PIC) }
26
- end
27
-
28
- describe "mime_type" do
29
- subject { frame.mime_type }
30
- it { is_expected.to eq('image/png') }
31
- context "when mime type is blank" do
32
- let(:format) { "\x00\x00\x00" }
33
- it { is_expected.to eq('image/') }
34
- end
35
- end
36
-
37
- describe "#data" do
38
- subject { frame.data }
39
- it { is_expected.to eq("picture data") }
40
- end
41
-
42
- describe "#type" do
43
- subject { frame.type }
44
- it { is_expected.to eq(:cover_front) }
45
- end
46
-
47
- describe "#description" do
48
- subject { frame.description }
49
- it { is_expected.to eq("picture description") }
50
- end
51
-
52
- describe "#content" do
53
- subject { frame.content }
54
- it { is_expected.to eq("picture data") }
55
- end
56
- end
57
-
58
- context "when APIC frame" do
59
- let(:id) { "APIC" }
60
- let(:major_version_number) { 3 }
61
- let(:mime_type) { "image/png" }
62
- let(:raw_content) do
63
- # mime_type is iso 8859-1 so alawys terminated with \x00
64
- encoding_byte + mime_type + "\x00" + picture_type + description + separator + data
65
- end
66
-
67
- describe '#id' do
68
- subject { frame.id }
69
- it { is_expected.to eq(:APIC) }
70
- end
71
-
72
- describe "#data" do
73
- subject { frame.data }
74
- it { is_expected.to eq("picture data") }
75
- end
76
-
77
- describe "#type" do
78
- subject { frame.type }
79
- it { is_expected.to eq(:cover_front) }
80
- end
81
-
82
- describe "#mime_type" do
83
- subject { frame.mime_type }
84
- it { is_expected.to eq("image/png") }
85
- context "when mime type is omitted" do
86
- let(:mime_type) { "\x00" }
87
- subject { frame.mime_type }
88
- it { is_expected.to eq("image/") }
89
- end
90
- end
91
-
92
- describe "#description" do
93
- subject { frame.description }
94
- it { is_expected.to eq("picture description") }
95
- end
96
-
97
- describe "#content" do
98
- subject { frame.content }
99
- it { is_expected.to eq("picture data") }
100
- end
101
-
102
- context "when frame contains link not actual image data" do
103
- let(:raw_content) { "\x02-->\x00\x08\u0000a\u0000b\u0000c" }
104
- subject { frame }
105
-
106
- describe '#link?' do
107
- subject { super().link? }
108
- it { is_expected.to eq(true) }
109
- end
110
-
111
- describe '#mime_type' do
112
- subject { super().mime_type }
113
- it { is_expected.to eq("-->") }
114
- end
115
-
116
- describe '#description' do
117
- subject { super().description }
118
- it { is_expected.to eq("abc") }
119
- end
120
-
121
- describe '#type' do
122
- subject { super().type }
123
- it { is_expected.to eq(:artist) }
124
- end
125
- end
126
- end
127
- end
@@ -1,89 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::TextFrame do
5
- let(:id) { "artist" }
6
- let(:raw_content) { text.encode(target_encoding.to_s).prepend(encoding_byte.force_encoding(target_encoding)) }
7
- let(:flags) { nil }
8
- let(:major_version_number) { 4 }
9
-
10
- let(:frame) { described_class.new(id, raw_content, flags, major_version_number) }
11
- let(:target_encoding) { Encoding::UTF_8 }
12
- let(:encoding_byte) { "\x03" }
13
- let(:text) { "Glāzšķūņrūķīši" }
14
-
15
- describe '#id' do
16
- subject { frame.id }
17
- it { is_expected.to eq(:artist) }
18
- end
19
-
20
- describe '#content' do
21
- subject { frame.content }
22
-
23
- context "when text's last char is null byte" do
24
- let(:target_encoding) { Encoding::UTF_8 }
25
- let(:encoding_byte) { "\x03" }
26
- let(:text) { "Glāzšķūņrūķīši\x00" }
27
- it { is_expected.to eq('Glāzšķūņrūķīši') }
28
- end
29
-
30
- context "when encoding byte is not present" do
31
- let(:encoding_byte) { "" }
32
- it { expect { subject }.to raise_error(ID3Tag::Frames::V2::TextFrame::UnsupportedTextEncoding) }
33
- end
34
-
35
- context "when encoding is ISO08859_1" do
36
- let(:target_encoding) { Encoding::ISO8859_1 }
37
- let(:encoding_byte) { "\x00" }
38
- let(:text) { "some fancy artist" }
39
- it { is_expected.to eq('some fancy artist') }
40
- end
41
-
42
- context "when encoding is UTF_16" do
43
- let(:target_encoding) { Encoding::UTF_16 }
44
- let(:encoding_byte) { "\x01" }
45
- it { is_expected.to eq('Glāzšķūņrūķīši') }
46
- end
47
-
48
- context "when encoding is UTF_16BE" do
49
- let(:target_encoding) { Encoding::UTF_16BE }
50
- let(:encoding_byte) { "\x02" }
51
- it { is_expected.to eq('Glāzšķūņrūķīši') }
52
- end
53
-
54
- context "when encoding is UTF_8" do
55
- let(:target_encoding) { Encoding::UTF_8 }
56
- let(:encoding_byte) { "\x03" }
57
- it { is_expected.to eq('Glāzšķūņrūķīši') }
58
- end
59
-
60
- context "when UTF-16 and missing BOM" do
61
- let(:target_encoding) { Encoding::UTF_8 }
62
- let(:raw_content) { "\x01\x00\x00a\x00b\x00c" }
63
- it "raises error Encoding::InvalidByteSequenceError" do
64
- expect { subject }.to raise_error(Encoding::InvalidByteSequenceError)
65
- end
66
- context "when using global encode options" do
67
- before(:each) do
68
- ID3Tag.configuration do |c|
69
- c.string_encode_options = { :invalid => :replace, :undef => :replace }
70
- end
71
- end
72
- after(:each) do
73
- ID3Tag.configuration do |c|
74
- c.string_encode_options = {}
75
- end
76
- end
77
- it "does not raise error" do
78
- expect { subject }.not_to raise_error
79
- end
80
- end
81
- end
82
- end
83
-
84
- describe '#inspect' do
85
- it 'should be pretty inspectable' do
86
- expect(frame.inspect).to eq('<ID3Tag::Frames::V2::TextFrame artist: Glāzšķūņrūķīši>')
87
- end
88
- end
89
- end
@@ -1,31 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::UniqueFileIdFrame do
5
- let(:id) { "UFID" }
6
- let(:raw_content) { "ZXC\x00foobar" }
7
- let(:flags) { nil }
8
- let(:major_version_number) { 4 }
9
- let(:frame) { described_class.new(id, raw_content, flags, major_version_number) }
10
-
11
- describe '#id' do
12
- subject { frame.id }
13
- it { is_expected.to eq(:UFID) }
14
- end
15
-
16
- describe '#owner_identifier' do
17
- subject { frame.owner_identifier }
18
- it { is_expected.to eq('ZXC') }
19
- end
20
-
21
- describe '#content' do
22
- subject { frame.content }
23
- it { is_expected.to eq('foobar') }
24
- end
25
-
26
- describe '#inspect' do
27
- it 'should be pretty inspectable' do
28
- expect(frame.inspect).to eq('<ID3Tag::Frames::V2::UniqueFileIdFrame UFID: ZXC>')
29
- end
30
- end
31
- end
@@ -1,34 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe ID3Tag::Frames::V2::UserTextFrame do
5
- let(:id) { "TXX" }
6
- let(:raw_content) { text.encode(target_encoding).prepend(encoding_byte.force_encoding(target_encoding)) }
7
- let(:flags) { nil }
8
- let(:major_version_number) { 4 }
9
-
10
- let(:target_encoding) { Encoding::UTF_8 }
11
- let(:encoding_byte) { "\x03" }
12
- let(:text) { "SUPER_FRAME\x00Glāzšķūņrūķīši" }
13
- subject { described_class.new(id, raw_content, flags, major_version_number) }
14
-
15
- describe '#id' do
16
- subject { super().id }
17
- it { is_expected.to eq(:TXX) }
18
- end
19
-
20
- describe '#content' do
21
- subject { super().content }
22
- it { is_expected.to eq('Glāzšķūņrūķīši') }
23
- end
24
-
25
- describe '#description' do
26
- subject { super().description }
27
- it { is_expected.to eq('SUPER_FRAME') }
28
- end
29
-
30
- describe '#inspect' do
31
- subject { super().inspect }
32
- it { is_expected.to eq('<ID3Tag::Frames::V2::UserTextFrame TXX: Glāzšķūņrūķīši>') }
33
- end
34
- end
@@ -1,71 +0,0 @@
1
- require "spec_helper"
2
- describe ID3Tag::ID3V1FrameParser do
3
- let(:mp3_with_v1_0_tag) { mp3_fixture('id3v1_without_track_nr.mp3') }
4
- let(:mp3_with_v1_1_tag) { mp3_fixture('id3v1_with_track_nr.mp3') }
5
- let(:frame_bytes_v1_0) { File.read(mp3_with_v1_0_tag, 125, 579) }
6
- let(:frame_bytes_v1_1) { File.read(mp3_with_v1_1_tag, 125, 579) }
7
- describe "#frames" do
8
- subject { described_class.new(frame_bytes_v1_0).frames }
9
-
10
- describe "common frames between v1.0 and v.1.1" do
11
-
12
- it "should contain title frame" do
13
- frame = subject.select { |frame| frame.id == :title }.first
14
- expect(frame.content).to eq("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaA")
15
- end
16
-
17
- it "should contain artist frame" do
18
- frame = subject.select { |frame| frame.id == :artist }.first
19
- expect(frame.content).to eq("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbB")
20
- end
21
-
22
- it "should contain album frame" do
23
- frame = subject.select { |frame| frame.id == :album }.first
24
- expect(frame.content).to eq("cccccccccccccccccccccccccccccC")
25
- end
26
-
27
- it "should contain year frame" do
28
- frame = subject.select { |frame| frame.id == :year }.first
29
- expect(frame.content).to eq("2003")
30
- end
31
- end
32
-
33
- describe "frames with differences in v1.0 and v1.1" do
34
- context "when reading v1.0 tag" do
35
- it "should contain comments frame" do
36
- frame = subject.select { |frame| frame.id == :comments }.first
37
- expect(frame.content).to eq("dddddddddddddddddddddddddddddD")
38
- end
39
-
40
- it "should contain genre frame" do
41
- frame = subject.select { |frame| frame.id == :genre }.first
42
- expect(frame.content).to eq("Blues")
43
- end
44
-
45
- it "should not contain track nr frame" do
46
- expect(subject.select { |frame| frame.id == :track_nr }.first).to be_nil
47
- end
48
- end
49
- context "when reading v1.1 tag" do
50
- subject { described_class.new(frame_bytes_v1_1).frames }
51
- it "should contain comments frame" do
52
- frame = subject.select { |frame| frame.id == :comments }.first
53
- expect(frame.content).to eq("dddddddddddddddddddddddddddD")
54
- end
55
-
56
- it "should contain track nr frame" do
57
- frame = subject.select { |frame| frame.id == :track_nr }.first
58
- expect(frame.content).to eq("1")
59
- end
60
- end
61
- end
62
- end
63
-
64
- describe "Test with real-world tag" do
65
- let(:tag_body) { File.read mp3_fixture("pov_20131018-2100a.mp3.v1_tag_body") }
66
- subject { described_class.new(tag_body) }
67
- it "have title" do
68
- expect(subject.frames.find { |f| f.id == :title }.content).to eq("pov_20131018-2100a.mp3")
69
- end
70
- end
71
- end