id3tag 0.10.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- coverage
2
- Gemfile.lock
3
- .bundle
4
- tags
5
- vendor/bundle
6
- bin
7
- doc
8
- pkg
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
@@ -1,14 +0,0 @@
1
- language: ruby
2
- before_install:
3
- - gem install bundler
4
- rvm:
5
- - ruby-head
6
- - jruby-head
7
- - 2.4.2
8
- - 2.3.5
9
- - 2.2.8
10
- - jruby-9.1.13.0
11
- matrix:
12
- allow_failures:
13
- - rvm: jruby-head
14
- - rvm: ruby-head
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in id3tag.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
- require 'rspec/core/rake_task'
4
-
5
- RSpec::Core::RakeTask.new(:spec) do |spec|
6
- spec.pattern = FileList['spec/**/*_spec.rb']
7
- end
8
-
9
- RSpec::Core::RakeTask.new(:rcov) do |spec|
10
- spec.pattern = 'spec/**/*_spec.rb'
11
- spec.rcov = true
12
- end
13
-
14
- task :default => :spec
15
-
16
- require 'rdoc/task'
17
- Rake::RDocTask.new do |rdoc|
18
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
19
-
20
- rdoc.rdoc_dir = 'rdoc'
21
- rdoc.title = "id3tag #{version}"
22
- rdoc.rdoc_files.include('README*')
23
- rdoc.rdoc_files.include('lib/**/*.rb')
24
- end
@@ -1,28 +0,0 @@
1
- # coding: utf-8
2
- require File.expand_path('../lib/id3tag/version', __FILE__)
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "id3tag"
6
- s.version = ID3Tag::VERSION
7
- s.authors = ["Krists Ozols"]
8
- s.email = "krists.ozols@gmail.com"
9
- s.description = "Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards"
10
- s.summary = "Native Ruby ID3 tag reader that aims for 100% covarage of ID3v2.x and ID3v1.x standards"
11
- s.homepage = "http://github.com/krists/id3tag"
12
- s.license = "MIT"
13
-
14
- s.files = `git ls-files`.split($/)
15
- s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
- s.extra_rdoc_files = ["LICENSE.txt", "README.md"]
18
- s.require_paths = ["lib"]
19
- s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
20
-
21
- s.add_development_dependency "bundler"
22
- s.add_development_dependency "rake", "~> 12.1.0"
23
- s.add_development_dependency "rdoc", "~> 5.1.0"
24
- s.add_development_dependency "rspec", "~> 3.6.0"
25
- s.add_development_dependency "simplecov", "~> 0.14.1"
26
- s.add_development_dependency 'coveralls', "~> 0.8.21"
27
- s.add_development_dependency 'pry', "~> 0.11.1"
28
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
- require 'tempfile'
3
-
4
- describe 'can read any file and does not raise errors if no tag found' do
5
- subject { ID3Tag.read(Tempfile.new('fake_mp3')) }
6
-
7
- it 'should return blanks' do
8
- expect(subject.title).to eq(nil)
9
- expect(subject.artist).to eq(nil)
10
- expect(subject.album).to eq(nil)
11
- expect(subject.genre).to eq(nil)
12
- expect(subject.year).to eq(nil)
13
- expect(subject.track_nr).to eq(nil)
14
- expect(subject.frames).to eq([])
15
- expect(subject.frame_ids).to eq([])
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'can read v1 info from file' do
4
- let(:mp3_with_v1_1_tag) { mp3_fixture('id3v1_with_track_nr.mp3') }
5
- subject { ID3Tag.read(mp3_with_v1_1_tag) }
6
-
7
- it 'reading file with only v1 tag' do
8
- expect(subject.title).to eq("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaA")
9
- expect(subject.artist).to eq("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbB")
10
- expect(subject.album).to eq("cccccccccccccccccccccccccccccC")
11
- expect(subject.genre).to eq("Blues")
12
- expect(subject.year).to eq("2003")
13
- expect(subject.track_nr).to eq("1")
14
- end
15
- end
Binary file
@@ -1,18 +0,0 @@
1
- #!/usr/bin/ruby
2
- #
3
- $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
4
- require "id3tag"
5
-
6
- ARGV.each do |file|
7
- audio_file = ID3Tag.read(File.open(file, "r")).send(:audio_file)
8
- if audio_file.v1_tag_present?
9
- handle = File.open(file + ".v1_tag_body", "w")
10
- handle.write(audio_file.v1_tag_body)
11
- handle.close
12
- end
13
- if audio_file.v2_tag_present?
14
- handle = File.open(file + ".v2_#{audio_file.v2_tag_major_version_number}_tag_body", "w")
15
- handle.write(audio_file.v2_tag_body)
16
- handle.close
17
- end
18
- end
@@ -1,131 +0,0 @@
1
- require "spec_helper"
2
- describe ID3Tag::AudioFile do
3
- let(:mp3_with_v1_tag) { mp3_fixture('id3v1_without_track_nr.mp3') }
4
- let(:mp3_with_v2_tag) { mp3_fixture('id3v2.mp3') }
5
- let(:mp3_with_v1_and_v2_tags) { mp3_fixture('id3v1_and_v2.mp3') }
6
- let(:broken_mp3) do
7
- file = Tempfile.new("broken_mp3")
8
- file.write("just something..but not enough")
9
- file
10
- end
11
-
12
- describe "Tag presence checking methods" do
13
- context "reading file only with ID3v1 tag" do
14
- subject { described_class.new(mp3_with_v1_tag) }
15
-
16
- describe '#v1_tag_present?' do
17
- subject { super().v1_tag_present? }
18
- it { is_expected.to eq(true) }
19
- end
20
-
21
- describe '#v1_tag_size' do
22
- subject { super().v1_tag_size }
23
- it { is_expected.to eq(125) }
24
- end
25
-
26
-
27
- describe '#v2_tag_present?' do
28
- subject { super().v2_tag_present? }
29
- it { is_expected.to eq(false) }
30
- end
31
-
32
- describe '#v2_tag_size' do
33
- subject { super().v2_tag_size }
34
- it { is_expected.to eq(0) }
35
- end
36
- end
37
-
38
- context "reading file only with ID3v2 tag" do
39
- subject { described_class.new(mp3_with_v2_tag) }
40
-
41
- describe '#v1_tag_present?' do
42
- subject { super().v1_tag_present? }
43
- it { is_expected.to eq(false) }
44
- end
45
-
46
- describe '#v1_tag_size' do
47
- subject { super().v1_tag_size }
48
- it { is_expected.to eq(0) }
49
- end
50
-
51
- describe '#v2_tag_present?' do
52
- subject { super().v2_tag_present? }
53
- it { is_expected.to eq(true) }
54
- end
55
-
56
- describe '#v2_tag_size' do
57
- subject { super().v2_tag_size }
58
- it { is_expected.to eq(246) }
59
- end
60
- end
61
-
62
- context "reading file with ID3v1 and ID3v2 tags" do
63
- subject { described_class.new(mp3_with_v1_and_v2_tags) }
64
-
65
- describe '#v1_tag_present?' do
66
- subject { super().v1_tag_present? }
67
- it { is_expected.to eq(true) }
68
- end
69
-
70
- describe '#v2_tag_present?' do
71
- subject { super().v2_tag_present? }
72
- it { is_expected.to eq(true) }
73
- end
74
- end
75
- end
76
-
77
- describe "#v1_tag_body" do
78
- context "when reading file with alteast 125 bytes" do
79
- subject { described_class.new(mp3_with_v1_tag) }
80
- it "should return last 125 bytes of audio file" do
81
- expect(subject.v1_tag_body).to eq(File.read(mp3_with_v1_tag, 125, 579))
82
- end
83
- end
84
- context "when reading file with size less ID3v1 tag" do
85
- subject { described_class.new(broken_mp3) }
86
- it "should return as much bytes as possible" do
87
- expect(subject.v1_tag_body).to eq(nil)
88
- end
89
- end
90
- end
91
-
92
- describe "#v2_tag_body" do
93
- context "when extended header is not present" do
94
- subject { described_class.new(StringIO.new("ID3\u0003\u0000\u0000\u0000\u0000\u0000\u0003ABC")) }
95
- it "should return frame and padding bytes" do
96
- expect(subject.v2_tag_body).to eq("ABC")
97
- end
98
- end
99
- context "when extended header is present" do
100
- subject { described_class.new(StringIO.new("ID3\u0003\u0000\u0040\u0000\u0000\u0000\u0011" + "\u0000\u0000\u0000\u000A" + ("\u0000" * 10) + "ABC")) }
101
- it "should return frame and padding bytes" do
102
- expect(subject.v2_tag_body).to eq("ABC")
103
- end
104
- context "when tag verison is v.2.4 and extended header size is calculated differently" do
105
- subject { described_class.new(StringIO.new("ID3\u0004\u0000\u0040\u0000\u0000\u0000\u0011" + "\u0000\u0000\u0000\u000A" + ("\u0000" * 6) + "ABC")) }
106
- it "should return frame and padding bytes" do
107
- expect(subject.v2_tag_body).to eq("ABC")
108
- end
109
- end
110
- end
111
- end
112
-
113
- context "when reading file with v2.3.0 tag" do
114
- subject { described_class.new(StringIO.new("ID3\u0003\u0000")) }
115
-
116
- describe '#v2_tag_version' do
117
- subject { super().v2_tag_version }
118
- it { is_expected.to eq '3.0' }
119
- end
120
-
121
- describe '#v2_tag_major_version_number' do
122
- subject { super().v2_tag_major_version_number }
123
- it { is_expected.to eq 3 }
124
- end
125
-
126
- describe '#v2_tag_minor_version_number' do
127
- subject { super().v2_tag_minor_version_number }
128
- it { is_expected.to eq 0 }
129
- end
130
- end
131
- end
@@ -1,18 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ID3Tag::Frames::Util::GenreNames do
4
-
5
- describe 'self#find_by_id' do
6
- subject { described_class.find_by_id(id) }
7
-
8
- context "when calling with id 0 what represents Blues" do
9
- let(:id) { 0 }
10
- it { is_expected.to eq('Blues') }
11
- end
12
-
13
- context "when calling with id 17 what represents Rock" do
14
- let(:id) { 17 }
15
- it { is_expected.to eq('Rock') }
16
- end
17
- end
18
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
- describe ID3Tag::Frames::V1::CommentsFrame do
3
- describe '#id' do
4
- subject { described_class.new('comments', nil).id }
5
- it { is_expected.to eq('comments') }
6
- end
7
-
8
- describe '#content' do
9
- context 'when comment is present' do
10
- subject { described_class.new('comments', 'some comment about the song').content }
11
- it { is_expected.to eq('some comment about the song') }
12
- end
13
-
14
- context 'when comment is not present' do
15
- subject { described_class.new('comments', '').content }
16
- it { is_expected.to eq('') }
17
- end
18
- end
19
-
20
- describe "#text" do
21
- subject { described_class.new('comments', 'some comment about the song') }
22
- it "should be the same as #content" do
23
- allow(subject).to receive(:content) { "ZXC" }
24
- expect(subject.text).to eq(subject.content)
25
- end
26
- end
27
-
28
- describe '#language' do
29
- it 'should be unknown' do
30
- expect(described_class.new('comments', '').language).to eq('unknown')
31
- end
32
- end
33
-
34
- describe '#desciption' do
35
- it 'should be unknown' do
36
- expect(described_class.new('comments', '').desciption).to eq('unknown')
37
- end
38
- end
39
- end
@@ -1,20 +0,0 @@
1
- require 'spec_helper'
2
- describe ID3Tag::Frames::V1::GenreFrame do
3
- describe '#id' do
4
- subject { described_class.new('genre', nil).id }
5
- it { is_expected.to eq('genre') }
6
- end
7
-
8
- describe '#content' do
9
- context 'when genre is blues' do
10
- subject { described_class.new('genre', [0].pack('c')).content }
11
- it { is_expected.to eq('Blues') }
12
- end
13
-
14
- context 'when genre is metal' do
15
- subject { described_class.new('genre', [9].pack('c')).content }
16
- it { is_expected.to eq('Metal') }
17
- end
18
- end
19
- end
20
-
@@ -1,14 +0,0 @@
1
- require 'spec_helper'
2
- describe ID3Tag::Frames::V1::TextFrame do
3
- describe '#id' do
4
- subject { described_class.new('album', nil).id }
5
- it { is_expected.to eq('album') }
6
- end
7
-
8
- describe '#content' do
9
- context 'when containing track artist' do
10
- subject { described_class.new('artist', 'some fancy artist').content }
11
- it { is_expected.to eq('some fancy artist') }
12
- end
13
- end
14
- end
@@ -1,19 +0,0 @@
1
- require 'spec_helper'
2
- describe ID3Tag::Frames::V1::TrackNrFrame do
3
- describe '#id' do
4
- subject { described_class.new('track_nr', nil).id }
5
- it { is_expected.to eq('track_nr') }
6
- end
7
-
8
- describe '#content' do
9
- context 'when nr is 3' do
10
- subject { described_class.new('track_nr', [3].pack('c')).content }
11
- it { is_expected.to eq('3') }
12
- end
13
-
14
- context 'when nr is 11' do
15
- subject { described_class.new('track_nr', [11].pack('c')).content }
16
- it { is_expected.to eq('11') }
17
- end
18
- end
19
- end
@@ -1,140 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ID3Tag::Frames::V2::BasicFrame do
4
- let(:id) { 'foo' }
5
- let(:raw_content) { 'bar' }
6
- let(:flags) { nil }
7
- let(:major_version_number) { 4 }
8
- let(:frame) { described_class.new(id, raw_content, flags, major_version_number) }
9
-
10
- describe '#id' do
11
- subject { frame.id }
12
- it { is_expected.to eq(:foo) }
13
- end
14
-
15
- describe '#content' do
16
- subject { frame.content }
17
- it { is_expected.to eq('bar') }
18
- context "when frame contains unsynchronised content" do
19
- subject { frame }
20
- let(:flags) { [0b00000000, 0b00000010].pack("C2") }
21
- let(:raw_content) { "\xFF\x00\xEE\xEE" }
22
-
23
- describe '#content' do
24
- subject { super().content }
25
- it { is_expected.to eq("\xFF\xEE\xEE") }
26
- end
27
- end
28
- end
29
-
30
- describe '#final_size' do
31
- subject { frame }
32
- context "when all frags nulled" do
33
- let(:raw_content) { 'foo' }
34
- let(:flags) { nil }
35
-
36
- describe '#final_size' do
37
- subject { super().final_size }
38
- it { is_expected.to eq 3 }
39
- end
40
- end
41
- context "when frame is compressed and data length is set" do
42
- let(:flags) { [0b00000000, 0b00001001].pack("C2") }
43
- let(:raw_content) { [55].pack("N") + 'foo' }
44
-
45
- describe '#final_size' do
46
- subject { super().final_size }
47
- it { is_expected.to eq 55 }
48
- end
49
-
50
- describe '#content' do
51
- subject { super().content }
52
- it { is_expected.to eq "foo" }
53
- end
54
- end
55
- end
56
-
57
- describe '#group_id' do
58
- subject { frame }
59
- context "when all frags nulled" do
60
- let(:raw_content) { 'foo' }
61
- let(:flags) { nil }
62
-
63
- describe '#group_id' do
64
- subject { super().group_id }
65
- it { is_expected.to eq nil }
66
- end
67
- end
68
- context "when frame is compressed and data length is set" do
69
- let(:flags) { [0b00000000, 0b01000000].pack("C2") }
70
- let(:raw_content) { [33].pack("C") + 'foo' }
71
-
72
- describe '#content' do
73
- subject { super().content }
74
- it { is_expected.to eq "foo" }
75
- end
76
-
77
- describe '#group_id' do
78
- subject { super().group_id }
79
- it { is_expected.to eq 33 }
80
- end
81
- end
82
- end
83
-
84
- describe '#encryption_id' do
85
- subject { frame }
86
- context "when all frags nulled" do
87
- let(:raw_content) { 'foo' }
88
- let(:flags) { nil }
89
-
90
- describe '#encryption_id' do
91
- subject { super().encryption_id }
92
- it { is_expected.to eq nil }
93
- end
94
- end
95
- context "when frame is compressed and data length is set" do
96
- let(:flags) { [0b00000000, 0b00000100].pack("C2") }
97
- let(:raw_content) { [1].pack("C") + 'foo' }
98
-
99
- describe '#content' do
100
- subject { super().content }
101
- it { is_expected.to eq "foo" }
102
- end
103
-
104
- describe '#encryption_id' do
105
- subject { super().encryption_id }
106
- it { is_expected.to eq 1 }
107
- end
108
- end
109
- end
110
-
111
- describe "frame future query methods" do
112
- subject { frame }
113
- describe "#read_only?" do
114
- it "should delegate to FrameFlags class" do
115
- expect_any_instance_of(ID3Tag::Frames::V2::FrameFlags).to receive(:read_only?)
116
- subject.read_only?
117
- end
118
- end
119
-
120
- describe "#preserve_on_tag_alteration?" do
121
- it "should delegate to FrameFlags class" do
122
- expect_any_instance_of(ID3Tag::Frames::V2::FrameFlags).to receive(:preserve_on_tag_alteration?)
123
- subject.preserve_on_tag_alteration?
124
- end
125
- end
126
-
127
- describe "#preserve_on_file_alteration?" do
128
- it "should delegate to FrameFlags class" do
129
- expect_any_instance_of(ID3Tag::Frames::V2::FrameFlags).to receive(:preserve_on_file_alteration?)
130
- subject.preserve_on_file_alteration?
131
- end
132
- end
133
- end
134
-
135
- describe '#inspect' do
136
- it 'should be pretty inspectable' do
137
- expect(frame.inspect).to eq('<ID3Tag::Frames::V2::BasicFrame foo>')
138
- end
139
- end
140
- end