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
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