id3lib-ruby 0.5.0 → 0.6.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.
@@ -9,7 +9,7 @@ require 'id3lib/accessors'
9
9
  # Have a look at ID3Lib::Tag for an introduction on how to use this library.
10
10
  #
11
11
  module ID3Lib
12
- VERSION = '0.5.0'
12
+ VERSION = '0.6.0'
13
13
 
14
14
  # ID3 version 1. All V constants can be used with the methods
15
15
  # new, update! or strip! of ID3Lib::Tag.
@@ -69,7 +69,8 @@ module ID3Lib
69
69
  #
70
70
  # There are a number of accessors for text frames like
71
71
  # title, performer, album, track, year, comment and genre. Have a look
72
- # at ID3Lib::Accessors for a complete list.
72
+ # at ID3Lib::Accessors for a complete list. They can only be used for
73
+ # text that is encoded with ISO-8859-1.
73
74
  #
74
75
  # tag.title #=> "Shy Boi"
75
76
  #
@@ -95,13 +96,17 @@ module ID3Lib
95
96
  # # Also raises an exception:
96
97
  # tag.find{ |f| f[:id] == :TLAN }[:text]
97
98
  #
98
- # Because only text frames can be set with accessors, you have to add
99
- # special frames by hand.
99
+ # Because only ISO-8859-1 encoded text frames can be set with accessors, you
100
+ # have to add special frames by hand.
100
101
  #
101
102
  # # Add two comments
102
103
  # tag << {:id => :COMM, :text => 'chunky bacon'}
103
104
  # tag << {:id => :COMM, :text => 'really.'}
104
105
  #
106
+ # # Add an UTF-16 text frame with BOM (byte order mark)
107
+ # tag << {:id => :TIT2, :text => "\xff\xfe\x60\x4f\x7d\x59",
108
+ # :textenc => 1}
109
+ #
105
110
  # # Add an attached picture
106
111
  # cover = {
107
112
  # :id => :APIC,
@@ -206,6 +211,21 @@ module ID3Lib
206
211
  f ? f[:text] : nil
207
212
  end
208
213
 
214
+ #
215
+ # Get the text of a user frame specified by _description_.
216
+ # Returns nil if the frame can't be found.
217
+ #
218
+ # tag.user_frame_text('MusicBrainz Album Id')
219
+ # #=> "f0d6c31f-8f9f-47fe-b5f5-3b96746b48fa"
220
+ #
221
+ # tag.user_frame_text('MusicBrainz Album Artist Id')
222
+ # #=> nil
223
+ #
224
+ def user_frame_text(description)
225
+ f = find{ |f| f[:id] == :TXXX && f[:description] == description }
226
+ f ? f[:text] : nil
227
+ end
228
+
209
229
  #
210
230
  # Set the text of a frame. First, all frames with the specified _id_ are
211
231
  # deleted and then a new frame with _text_ is appended.
Binary file
Binary file
@@ -31,6 +31,23 @@ class TestReading < Test::Unit::TestCase
31
31
  assert_equal 'Pop', @tag.genre
32
32
  end
33
33
 
34
+ def test_frame_text
35
+ assert_equal 'Dummy Title', @tag.frame_text(:TIT2)
36
+ assert_equal 'Dummy Artist', @tag.frame_text(:TPE1)
37
+ assert_equal 'Dummy Album', @tag.frame_text(:TALB)
38
+ assert_equal '1/10', @tag.frame_text(:TRCK)
39
+ assert_equal '2000', @tag.frame_text(:TYER)
40
+ assert_equal 'Dummy Comment', @tag.frame_text(:COMM)
41
+ assert_equal 'Pop', @tag.frame_text(:TCON)
42
+ assert_equal nil, @tag.frame_text(:AENC)
43
+ end
44
+
45
+ def test_user_frame_text
46
+ album_id = @tag.user_frame_text('MusicBrainz Album Id')
47
+ assert_equal '992dc19a-5631-40f5-b252-fbfedbc328a9', album_id
48
+ assert_equal nil, @tag.user_frame_text('Inexistent')
49
+ end
50
+
34
51
  def test_comments
35
52
  one, two = @tag.comment_frames
36
53
  assert_not_nil one
@@ -54,6 +54,16 @@ class TestUnicode < Test::Unit::TestCase
54
54
  assert_equal "\x4f\x60\x59\x7d", @tag.title
55
55
  end
56
56
 
57
+ def test_reading_lyrics
58
+ @tag = ID3Lib::Tag.new('test/data/unicode.mp3', ID3Lib::V2)
59
+ lyrics = @tag.find{ |f| f[:id] == :USLT }
60
+ assert_equal 1, lyrics[:textenc]
61
+ assert_equal "zho", lyrics[:language]
62
+ # This is "U+6771 U+4EAC" (Tokyo) in UTF-16BE
63
+ tokyo = "\x67\x71\x4e\xac"
64
+ assert_equal tokyo, lyrics[:text]
65
+ end
66
+
57
67
  def test_invalid_data
58
68
  nonstr = 1
59
69
  @tag.reject!{ |f| f[:id] == :TIT2 }
@@ -175,7 +175,7 @@ class TestWriting < Test::Unit::TestCase
175
175
  assert_equal 2176, File.size(Temp)
176
176
  @tag.padding = false
177
177
  @tag.update!
178
- assert_equal 348, File.size(Temp)
178
+ assert_equal 416, File.size(Temp)
179
179
  end
180
180
 
181
181
  def test_failing_update
metadata CHANGED
@@ -1,37 +1,123 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
3
- specification_version: 1
4
2
  name: id3lib-ruby
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.5.0
7
- date: 2006-12-16 00:00:00 +01:00
8
- summary: id3lib-ruby provides a Ruby interface to the id3lib C++ library for easily editing ID3 tags (v1 and v2) like with pyid3lib.
9
- require_paths:
10
- - lib
11
- email: robinstocker@rubyforge.org
12
- homepage: http://id3lib-ruby.rubyforge.org
13
- rubyforge_project: id3lib-ruby
14
- description:
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
25
10
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
11
  authors:
30
12
  - Robin Stocker
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-16 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: |
22
+ = id3lib-ruby
23
+
24
+ id3lib-ruby provides a Ruby interface to the id3lib C++ library for easily
25
+ editing ID3 tags (v1 and v2) of MP3 audio files.
26
+
27
+ The class documentation starts at ID3Lib::Tag.
28
+
29
+
30
+ == Features
31
+
32
+ * Read and write ID3v1 and ID3v2 tags
33
+ * Simple interface for adding, changing and removing frames
34
+ * Quick access to common text frames like title and performer
35
+ * Custom data frames like attached picture (APIC)
36
+ * Pretty complete coverage of id3lib's features
37
+ * UTF-16 support (warning: id3lib writes broken UTF-16 frames)
38
+ * Windows binary gem available
39
+
40
+ The CHANGES file contains a list of changes between versions.
41
+
42
+
43
+ == Installation
44
+
45
+ See INSTALL.
46
+
47
+
48
+ == Online Information
49
+
50
+ The home of id3lib-ruby is http://id3lib-ruby.rubyforge.org
51
+
52
+
53
+ == Usage
54
+
55
+ require 'rubygems'
56
+ require 'id3lib'
57
+
58
+ # Load a tag from a file
59
+ tag = ID3Lib::Tag.new('talk.mp3')
60
+
61
+ # Get and set text frames with convenience methods
62
+ tag.title #=> "Talk"
63
+ tag.album = 'X&Y'
64
+ tag.track = '5/13'
65
+
66
+ # Tag is a subclass of Array and each frame is a Hash
67
+ tag[0]
68
+ #=> { :id => :TPE1, :textenc => 0, :text => "Coldplay" }
69
+
70
+ # Get the number of frames
71
+ tag.length #=> 7
72
+
73
+ # Remove all comment frames
74
+ tag.delete_if{ |frame| frame[:id] == :COMM }
75
+
76
+ # Get info about APIC frame to see which fields are allowed
77
+ ID3Lib::Info.frame(:APIC)
78
+ #=> [ 2, :APIC, "Attached picture",
79
+ #=> [:textenc, :mimetype, :picturetype, :description, :data] ]
80
+
81
+ # Add an attached picture frame
82
+ cover = {
83
+ :id => :APIC,
84
+ :mimetype => 'image/jpeg',
85
+ :picturetype => 3,
86
+ :description => 'A pretty picture',
87
+ :textenc => 0,
88
+ :data => File.read('cover.jpg')
89
+ }
90
+ tag << cover
91
+
92
+ # Last but not least, apply changes
93
+ tag.update!
94
+
95
+
96
+ == Licence
97
+
98
+ This library has Ruby's licence:
99
+
100
+ http://www.ruby-lang.org/en/LICENSE.txt
101
+
102
+
103
+ == Author
104
+
105
+ Robin Stocker <robinstocker at rubyforge.org>
106
+
107
+ email: robinstocker@rubyforge.org
108
+ executables: []
109
+
110
+ extensions:
111
+ - ext/id3lib_api/extconf.rb
112
+ extra_rdoc_files:
113
+ - README
114
+ - INSTALL
115
+ - TODO
116
+ - CHANGES
31
117
  files:
32
- - lib/id3lib.rb
33
118
  - lib/id3lib/accessors.rb
34
119
  - lib/id3lib/info.rb
120
+ - lib/id3lib.rb
35
121
  - test/test_unicode.rb
36
122
  - test/test_writing.rb
37
123
  - test/test_reading.rb
@@ -41,34 +127,48 @@ files:
41
127
  - Rakefile
42
128
  - usage.rb
43
129
  - setup.rb
44
- - ext/extconf.rb
45
- - ext/generate_info.rb
46
- - ext/id3lib_api_wrap.cxx
47
- - ext/id3lib_api.i
48
- - ext/Rakefile
130
+ - ext/id3lib_api/extconf.rb
131
+ - ext/id3lib_api/id3lib_api_wrap.cxx
132
+ - ext/id3lib_api/id3lib_api.i
133
+ - ext/id3lib_api/Rakefile
49
134
  - README
50
135
  - INSTALL
51
136
  - TODO
52
137
  - CHANGES
53
- test_files:
54
- - test/test_unicode.rb
55
- - test/test_writing.rb
56
- - test/test_reading.rb
138
+ has_rdoc: true
139
+ homepage: http://id3lib-ruby.rubyforge.org
140
+ licenses: []
141
+
142
+ post_install_message:
57
143
  rdoc_options:
58
144
  - --inline-source
59
145
  - --line-numbers
60
146
  - --main
61
147
  - README
62
- extra_rdoc_files:
63
- - README
64
- - INSTALL
65
- - TODO
66
- - CHANGES
67
- executables: []
68
-
69
- extensions:
70
- - ext/extconf.rb
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ segments:
155
+ - 0
156
+ version: "0"
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ segments:
162
+ - 0
163
+ version: "0"
71
164
  requirements:
72
165
  - id3lib C++ library
73
- dependencies: []
74
-
166
+ rubyforge_project: id3lib-ruby
167
+ rubygems_version: 1.3.6
168
+ signing_key:
169
+ specification_version: 3
170
+ summary: id3lib-ruby provides a Ruby interface to the id3lib C++ library for easily editing ID3 tags (v1 and v2) of MP3 audio files.
171
+ test_files:
172
+ - test/test_unicode.rb
173
+ - test/test_writing.rb
174
+ - test/test_reading.rb
@@ -1,20 +0,0 @@
1
- require 'mkmf'
2
-
3
- def error msg
4
- message msg + "\n"
5
- abort
6
- end
7
-
8
- unless have_library('stdc++')
9
- error "You must have libstdc++ installed."
10
- end
11
-
12
- unless have_library('z')
13
- error "You must have zlib installed."
14
- end
15
-
16
- unless have_header('id3.h') and have_library('id3', 'ID3Tag_New')
17
- error "You must have id3lib installed in order to use id3lib-ruby."
18
- end
19
-
20
- create_makefile('id3lib_api')
@@ -1,127 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- require 'enumerator'
4
- require 'pathname'
5
-
6
-
7
- id3lib_dir = Pathname.new(ARGV.first || '/home/robin/tmp/id3lib-3.8.3')
8
-
9
- globals_file = File.read(id3lib_dir + 'include/id3/globals.h')
10
- field_file = File.read(id3lib_dir + 'src/field.cpp')
11
-
12
- def field_symbol(enum_name)
13
- f = enum_name[/ID3FN_(.*)/, 1].downcase
14
- if f == 'id'
15
- :identifier
16
- else
17
- f.to_sym
18
- end
19
- end
20
-
21
-
22
- field_groups = {}
23
- allowed_fields = {}
24
-
25
- field_file.scan(/ID3_FieldDef (\w+)[^\{]+\{(.+?)\};/m) do |group, body|
26
- fields = []
27
- body.scan(/\{\W+(\w+)/) do |field_name, _|
28
- next if field_name == "ID3FN_NOFIELD"
29
- fields << field_name
30
- end
31
- fields.uniq!
32
- fields.map!{ |f| field_symbol(f) }
33
- field_groups[group] = fields
34
- end
35
-
36
- field_file.scan(/ID3_FrameDef ID3_FrameDefs[^\{]+\{(.+?)\};/m) do |body, _|
37
- body.each_line do |line|
38
- values = line.split(/\s*,\s*/)
39
- next unless values.size > 1
40
- frame = values[2].delete('"')
41
- group = values[5]
42
- next if frame.empty?
43
- allowed_fields[frame.to_sym] = field_groups[group]
44
- end
45
- end
46
-
47
-
48
- field_info = []
49
- frame_info = []
50
- genre_info = []
51
-
52
- globals_file.scan(/ID3_ENUM\((\w+)\)\s+\{\s+(.+?)\s+\}/m) do |name, enum|
53
- case name
54
- when 'ID3_FieldID'
55
- id = 0
56
- enum.scan(/([^\s,]+)(?: = (\d+),|,)\s*\/\*\*< ([^*]+)\s+\*\//m) do |field, newid, description|
57
- id = newid.to_i if newid
58
-
59
- field = field_symbol(field)
60
- field_info << [id, field, description]
61
-
62
- id += 1
63
- end
64
- when 'ID3_FrameID'
65
- id = 0
66
- enum.scan(/\/\* (\S+) \*\/ [^\s,]+(?: = (\d+),|,)\s*\/\*\*< ([^*]+)\s+\*\//m) do |frame, newid, description|
67
- id = newid.to_i if newid
68
- frame = (frame == '????') ? :____ : frame.to_sym
69
-
70
- fields = allowed_fields[frame] || []
71
-
72
- frame_info << [id, frame, description, fields]
73
- id += 1
74
- end
75
- end
76
- end
77
-
78
- globals_file.scan(/(ID3_v1_genre_description).+?\{(.+?)\}/m) do |name, list|
79
- id = 0
80
- list.scan(/"([^"]+)"/) do |genre|
81
- genre_info << genre.first
82
- id += 1
83
- end
84
- end
85
-
86
-
87
- def indent level, text
88
- puts ' ' * level + text
89
- end
90
-
91
- indent 4, "Frames = ["
92
- frame_info.each do |f|
93
- comment = case f[1]
94
- when :____ : "# Special frames"
95
- when :TALB : "# Text information frames"
96
- when :UFID : "# Special frames again"
97
- when :WCOM : "# URL link frames"
98
- end
99
- indent 6, comment if comment
100
- indent 6, f.inspect + ","
101
- end
102
- indent 4, "]"
103
-
104
- indent 4, "FramesByID = {"
105
- frame_info.each do |f|
106
- indent 6, f[1].inspect + " => Frames[" + f[0].to_s + "],"
107
- end
108
- indent 4, "}"
109
-
110
- indent 4, "Fields = ["
111
- field_info.each do |f|
112
- indent 6, f.inspect + ","
113
- end
114
- indent 4, "]"
115
-
116
- indent 4, "FieldsByID = {"
117
- field_info.each do |f|
118
- indent 6, f[1].inspect.ljust(16) + " => Fields[" + f[0].to_s + "],"
119
- end
120
- indent 4, "}"
121
-
122
- indent 4, "Genres = ["
123
- genre_info.each_slice(4) do |gs|
124
- indent 6, "# Winamp extensions" if gs.first == "Folk"
125
- indent 6, gs.map{ |g| g.inspect }.join(", ") + ","
126
- end
127
- indent 4, "]"