id3tag 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -5
  3. data/lib/id3tag.rb +11 -4
  4. data/lib/id3tag/audio_file.rb +7 -1
  5. data/lib/id3tag/configuration.rb +2 -0
  6. data/lib/id3tag/id3_v2_frame_parser.rb +12 -8
  7. data/lib/id3tag/version.rb +1 -1
  8. metadata +7 -96
  9. data/.document +0 -5
  10. data/.gitignore +0 -8
  11. data/.rspec +0 -1
  12. data/.travis.yml +0 -15
  13. data/Gemfile +0 -4
  14. data/Rakefile +0 -24
  15. data/id3tag.gemspec +0 -28
  16. data/spec/features/can_read_non_audio_files_spec.rb +0 -17
  17. data/spec/features/can_read_tag_v1_spec.rb +0 -15
  18. data/spec/fixtures/id3v1_and_v2.mp3 +0 -0
  19. data/spec/fixtures/id3v1_with_track_nr.mp3 +0 -0
  20. data/spec/fixtures/id3v1_without_track_nr.mp3 +0 -0
  21. data/spec/fixtures/id3v2.mp3 +0 -0
  22. data/spec/fixtures/pov_20131018-2100a.mp3.v1_tag_body +0 -0
  23. data/spec/fixtures/pov_20131018-2100a.mp3.v2_3_tag_body +0 -0
  24. data/spec/fixtures/signals_1.mp3.v2_3_tag_body +0 -0
  25. data/spec/id3tag_extract_tags +0 -18
  26. data/spec/lib/id3tag/audio_file_spec.rb +0 -131
  27. data/spec/lib/id3tag/frames/util/genre_name_by_id_finder_spec.rb +0 -18
  28. data/spec/lib/id3tag/frames/v1/comments_frame_spec.rb +0 -39
  29. data/spec/lib/id3tag/frames/v1/genre_frame_spec.rb +0 -20
  30. data/spec/lib/id3tag/frames/v1/text_frame_spec.rb +0 -14
  31. data/spec/lib/id3tag/frames/v1/track_nr_frame_spec.rb +0 -19
  32. data/spec/lib/id3tag/frames/v2/basic_frame_spec.rb +0 -140
  33. data/spec/lib/id3tag/frames/v2/comments_frame_spec.rb +0 -45
  34. data/spec/lib/id3tag/frames/v2/frame_fabricator_spec.rb +0 -70
  35. data/spec/lib/id3tag/frames/v2/frame_flags_spec.rb +0 -588
  36. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_24_spec.rb +0 -26
  37. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24_spec.rb +0 -48
  38. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_spec.rb +0 -13
  39. data/spec/lib/id3tag/frames/v2/genre_frame_spec.rb +0 -61
  40. data/spec/lib/id3tag/frames/v2/picture_frame_spec.rb +0 -127
  41. data/spec/lib/id3tag/frames/v2/text_frame_spec.rb +0 -89
  42. data/spec/lib/id3tag/frames/v2/unique_file_id_frame_spec.rb +0 -31
  43. data/spec/lib/id3tag/frames/v2/user_text_frame_spec.rb +0 -34
  44. data/spec/lib/id3tag/id3_v1_frame_parser_spec.rb +0 -71
  45. data/spec/lib/id3tag/id3_v2_frame_parser_spec.rb +0 -32
  46. data/spec/lib/id3tag/id3_v2_tag_header_spec.rb +0 -149
  47. data/spec/lib/id3tag/id3tag_spec.rb +0 -17
  48. data/spec/lib/id3tag/io_util_spec.rb +0 -30
  49. data/spec/lib/id3tag/number_util_spec.rb +0 -32
  50. data/spec/lib/id3tag/string_util_spec.rb +0 -81
  51. data/spec/lib/id3tag/synchsafe_integer_spec.rb +0 -14
  52. data/spec/lib/id3tag/tag_spec.rb +0 -352
  53. data/spec/spec_helper.rb +0 -23
  54. data/spec/support/mp3_fixtures.rb +0 -4
  55. data/standard_documents/id3v2-00.txt +0 -1657
  56. data/standard_documents/id3v2.3.0.txt +0 -2022
  57. data/standard_documents/id3v2.4.0-frames.txt +0 -1732
  58. 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