id3lib-ruby 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, "]"