easytag 0.4.3 → 1.0.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +7 -2
  4. data/README.md +33 -27
  5. data/Rakefile +7 -7
  6. data/easytag.gemspec +2 -4
  7. data/lib/easytag.rb +12 -2
  8. data/lib/easytag/attributes/base.rb +32 -128
  9. data/lib/easytag/attributes/flac.rb +25 -0
  10. data/lib/easytag/attributes/mp3.rb +91 -554
  11. data/lib/easytag/attributes/mp4.rb +22 -492
  12. data/lib/easytag/attributes/ogg.rb +27 -0
  13. data/lib/easytag/attributes/vorbis.rb +18 -0
  14. data/lib/easytag/taggers/base.rb +19 -0
  15. data/lib/easytag/taggers/factory.rb +59 -0
  16. data/lib/easytag/taggers/flac.rb +23 -0
  17. data/lib/easytag/taggers/mp3.rb +77 -0
  18. data/lib/easytag/taggers/mp4.rb +73 -0
  19. data/lib/easytag/taggers/ogg.rb +25 -0
  20. data/lib/easytag/taggers/vorbis.rb +66 -0
  21. data/lib/easytag/util.rb +9 -31
  22. data/lib/easytag/version.rb +3 -4
  23. data/scripts/build_attributes_table.rb +34 -0
  24. data/{test → spec/data}/consistency.01.m4a +0 -0
  25. data/{test → spec/data}/consistency.01.mp3 +0 -0
  26. data/spec/data/consistency.flac +0 -0
  27. data/{test/consistency.02.m4a → spec/data/consistency.m4a} +0 -0
  28. data/{test/consistency.02.mp3 → spec/data/consistency.mp3} +0 -0
  29. data/spec/data/consistency.multiple_images.flac +0 -0
  30. data/{test/no_tags.m4a → spec/data/consistency.multiple_images.m4a} +0 -0
  31. data/spec/data/consistency.multiple_images.mp3 +0 -0
  32. data/spec/data/consistency.multiple_images.ogg +0 -0
  33. data/spec/data/consistency.ogg +0 -0
  34. data/{test → spec/data}/musicbrainz.m4a +0 -0
  35. data/spec/data/no_tags.flac +0 -0
  36. data/spec/data/no_tags.m4a +0 -0
  37. data/{test → spec/data}/no_tags.mp3 +0 -0
  38. data/spec/data/no_tags.ogg +0 -0
  39. data/{test → spec/data}/only_id3v1.mp3 +0 -0
  40. data/{test → spec/data}/only_id3v2.mp3 +0 -0
  41. data/spec/flac_tagger_spec.rb +24 -0
  42. data/spec/mp3_tagger_spec.rb +64 -0
  43. data/spec/mp4_tagger_spec.rb +22 -0
  44. data/spec/ogg_tagger_spec.rb +21 -0
  45. data/spec/shared_examples.rb +115 -0
  46. data/spec/spec_helper.rb +34 -0
  47. data/spec/tagger_factory_spec.rb +27 -0
  48. data/spec/util_spec.rb +47 -0
  49. metadata +47 -48
  50. data/lib/easytag/attributes.rb +0 -0
  51. data/lib/easytag/base.rb +0 -28
  52. data/lib/easytag/file.rb +0 -44
  53. data/lib/easytag/interfaces.rb +0 -18
  54. data/lib/easytag/interfaces/base.rb +0 -24
  55. data/lib/easytag/interfaces/mp3.rb +0 -48
  56. data/lib/easytag/interfaces/mp4.rb +0 -14
  57. data/test/test_consistency.rb +0 -233
  58. data/test/test_mp3.rb +0 -98
  59. data/test/test_mp4.rb +0 -49
  60. data/test/test_util.rb +0 -72
@@ -1,509 +1,39 @@
1
- # encoding: UTF-8
2
1
  require 'easytag/attributes/base'
3
2
 
4
- module EasyTag::Attributes
5
- # type of TagLib::MP4::Item
6
- module ItemType
7
- STRING = 0 # not part of TagLib::MP4::Item, just for convenience
8
- STRING_LIST = 1
9
- BOOL = 2
10
- INT = 3
11
- INT_PAIR = 4
12
- COVER_ART_LIST = 5
13
- end
14
-
15
- class MP4Attribute < BaseAttribute
16
-
17
- def initialize(args)
18
- super(args)
19
-
20
- @item_ids = args[:item_ids]
21
- @item_type = args[:item_type] || ItemType::STRING
22
- end
23
-
24
- private
3
+ module EasyTag
4
+ module MP4AttributeAccessors
5
+ include BaseAttributeAccessors
25
6
 
26
- def item_for_id(id, iface)
27
- iface.info.tag.item_list_map.fetch(id)
7
+ def item_reader(attr_name, key = nil, **opts)
8
+ key = attr_name if key.nil?
9
+ opts[:returns] = opts[:data_type] if opts[:returns].nil? && opts[:cast].nil? # clunky
10
+ define_method(attr_name) do
11
+ v = self.class.read_item(taglib, key, **opts)
12
+ self.class.post_process(v, **opts)
13
+ end
28
14
  end
29
15
 
30
- def data_from_item(item)
31
- case @item_type
32
- when ItemType::STRING
33
- item.to_string_list[0]
34
- when ItemType::STRING_LIST
16
+ def data_from_item(item, **opts)
17
+ case opts[:data_type]
18
+ when :string_list
35
19
  item.to_string_list
36
- when ItemType::BOOL
20
+ when :bool
37
21
  item.to_bool
38
- when ItemType::INT
22
+ when :int
39
23
  item.to_int
40
- when ItemType::INT_PAIR
24
+ when :int_pair
41
25
  item.to_int_pair
42
- when ItemType::COVER_ART_LIST
43
- artwork = []
44
- item.to_cover_art_list.each do |img|
45
- artwork << EasyTag::Image.new(img.data)
46
- end
47
- artwork
26
+ when :cover_art_list
27
+ item.to_cover_art_list.collect { |img| EasyTag::Image.new(img.data) }
48
28
  else
49
- nil
50
- end
51
- end
52
-
53
- # read handlers
54
-
55
- def read_first_item(iface)
56
- item = nil
57
- @item_ids.each do |id|
58
- item = item_for_id(id, iface) if item.nil?
29
+ item.to_string_list[0]
59
30
  end
60
-
61
- data_from_item(item) unless item.nil?
62
31
  end
63
32
 
64
- def read_user_info(iface)
65
- kv_hash = {}
66
- iface.info.tag.item_list_map.to_a.each do |key, item|
67
- match_data = key.match(/\:com.apple.iTunes\:(.*)/)
68
- if match_data
69
- key = match_data[1]
70
- key = Utilities.normalize_string(key) if @options[:normalize]
71
- key = key.to_sym if @options[:to_sym]
72
-
73
- values = item.to_string_list
74
- kv_hash[key] = values.count > 1 ? values : values.first
75
- end
76
- end
77
-
78
- kv_hash
33
+ def read_item(taglib, key, **opts)
34
+ item = taglib.tag.item_list_map[key]
35
+ data_from_item(item, **opts) unless item.nil?
79
36
  end
80
-
81
37
  end
82
38
  end
83
39
 
84
- module EasyTag::Attributes
85
- MP4_ATTRIB_ARGS = [
86
- # title
87
- {
88
- :name => :title,
89
- :item_ids => ['©nam'],
90
- :handler => :read_first_item,
91
- :type => Type::STRING,
92
- },
93
-
94
- # title_sort_order
95
- {
96
- :name => :title_sort_order,
97
- :item_ids => ['sonm'],
98
- :handler => :read_first_item,
99
- :type => Type::STRING,
100
- },
101
-
102
- # artist
103
- {
104
- :name => :artist,
105
- :item_ids => ['©ART'],
106
- :handler => :read_first_item,
107
- :type => Type::STRING,
108
- },
109
-
110
- # artist_sort_order
111
- {
112
- :name => :artist_sort_order,
113
- :item_ids => ['soar'],
114
- :handler => :read_first_item,
115
- :type => Type::STRING,
116
- },
117
-
118
- # album_artist
119
- {
120
- :name => :album_artist,
121
- :item_ids => ['aART'],
122
- :handler => :read_first_item,
123
- :type => Type::STRING,
124
- },
125
-
126
- # album_artist_sort_order
127
- {
128
- :name => :album_artist_sort_order,
129
- :item_ids => ['soaa'],
130
- :handler => :read_first_item,
131
- :type => Type::STRING,
132
- },
133
-
134
- # album
135
- {
136
- :name => :album,
137
- :item_ids => ['©alb'],
138
- :handler => :read_first_item,
139
- :type => Type::STRING,
140
- },
141
-
142
- # album_sort_order
143
- {
144
- :name => :album_sort_order,
145
- :item_ids => ['soal'],
146
- :handler => :read_first_item,
147
- :type => Type::STRING,
148
- },
149
-
150
- # genre
151
- {
152
- :name => :genre,
153
- :item_ids => ['©gen'],
154
- :handler => :read_first_item,
155
- :type => Type::STRING,
156
- },
157
-
158
- # comments
159
- {
160
- :name => :comments,
161
- :item_ids => ['©cmt'],
162
- :handler => :read_first_item,
163
- :item_type => ItemType::STRING_LIST,
164
- :default => [],
165
- },
166
-
167
- # comment
168
- {
169
- :name => :comment,
170
- :handler => lambda { |iface| iface.comments.first },
171
- :type => Type::STRING,
172
- },
173
-
174
- # lyrics
175
- {
176
- :name => :lyrics,
177
- :item_ids => ['©lyr'],
178
- :handler => :read_first_item,
179
- :type => Type::STRING,
180
- },
181
-
182
- # date
183
- {
184
- :name => :date,
185
- :item_ids => ['©day'],
186
- :handler => :read_first_item,
187
- :type => Type::DATETIME,
188
- :default => nil,
189
- },
190
-
191
- # original_date
192
- {
193
- :name => :original_date,
194
- :handler => :read_default,
195
- :type => Type::DATETIME,
196
-
197
- },
198
-
199
- # year
200
- {
201
- :name => :year,
202
- :handler => lambda { |iface| iface.date.nil? ? 0 : iface.date.year }
203
- },
204
-
205
- # apple_id
206
- {
207
- :name => :apple_id,
208
- :item_ids => ['apid'],
209
- :handler => :read_first_item,
210
- :type => Type::STRING,
211
- },
212
-
213
- # encoded_by
214
- {
215
- :name => :encoded_by,
216
- :item_ids => ['©enc'],
217
- :handler => :read_first_item,
218
- :type => Type::STRING,
219
- },
220
-
221
- # encoder_settings
222
- {
223
- :name => :encoder_settings,
224
- :item_ids => ['©too'],
225
- :handler => :read_first_item,
226
- :type => Type::STRING,
227
- },
228
-
229
- # group
230
- {
231
- :name => :group,
232
- :item_ids => ['©grp'],
233
- :handler => :read_first_item,
234
- :type => Type::STRING,
235
- },
236
-
237
- # compilation?
238
- {
239
- :name => :compilation?,
240
- :item_ids => ['cpil'],
241
- :handler => :read_first_item,
242
- :type => Type::BOOLEAN,
243
- :item_type => ItemType::BOOL,
244
- },
245
-
246
- # bpm
247
- {
248
- :name => :bpm,
249
- :item_ids => ['tmpo'],
250
- :handler => :read_first_item,
251
- :item_type => ItemType::INT,
252
- :default => 0,
253
- },
254
-
255
- # mood
256
- {
257
- :name => :mood,
258
- :item_ids => ['mood'],
259
- :handler => :read_first_item,
260
- :item_type => ItemType::STRING,
261
- :type => Type::STRING,
262
- },
263
-
264
- # copyright
265
- {
266
- :name => :copyright,
267
- :item_ids => ['cprt'],
268
- :handler => :read_first_item,
269
- :type => Type::STRING,
270
- },
271
-
272
- # track_num
273
- {
274
- :name => :track_num,
275
- :item_ids => ['trkn'],
276
- :handler => :read_first_item,
277
- :item_type => ItemType::INT_PAIR,
278
- :default => [0, 0],
279
- },
280
-
281
- # disc_num
282
- {
283
- :name => :disc_num,
284
- :item_ids => ['disk'],
285
- :handler => :read_first_item,
286
- :item_type => ItemType::INT_PAIR,
287
- :default => [0, 0],
288
- },
289
-
290
- # album_art
291
- {
292
- :name => :album_art,
293
- :item_ids => ['covr'],
294
- :handler => :read_first_item,
295
- :item_type => ItemType::COVER_ART_LIST,
296
- :default => [],
297
- },
298
-
299
- # user_info
300
- {
301
- :name => :user_info,
302
- :handler => :read_user_info,
303
- :default => {},
304
- },
305
-
306
- # user_info_normalized
307
- {
308
- :name => :user_info_normalized,
309
- :handler => :read_user_info,
310
- :default => {},
311
- :options => {:normalize => true, :to_sym => true},
312
- },
313
-
314
- # subtitle
315
- {
316
- :name => :subtitle,
317
- :handler => :user_info_lookup,
318
- :handler_opts => {:key => :subtitle},
319
- :type => Type::STRING,
320
- },
321
-
322
- # disc_subtitle
323
- {
324
- :name => :disc_subtitle,
325
- :handler => :user_info_lookup,
326
- :handler_opts => {:key => :discsubtitle},
327
- :type => Type::STRING,
328
- },
329
-
330
- # media
331
- {
332
- :name => :media,
333
- :handler => :user_info_lookup,
334
- :handler_opts => {:key => :media},
335
- :type => Type::STRING,
336
- },
337
-
338
- # label
339
- {
340
- :name => :label,
341
- :handler => :user_info_lookup,
342
- :handler_opts => {:key => :label},
343
- :type => Type::STRING,
344
- },
345
-
346
- # composer
347
- {
348
- :name => :composer,
349
- :handler => :user_info_lookup,
350
- :handler_opts => {:key => :composer},
351
- :type => Type::STRING,
352
- },
353
-
354
- # conductor
355
- {
356
- :name => :conductor,
357
- :handler => :user_info_lookup,
358
- :handler_opts => {:key => :conductor},
359
- :type => Type::STRING,
360
- },
361
-
362
- # remixer
363
- {
364
- :name => :remixer,
365
- :handler => :user_info_lookup,
366
- :handler_opts => {:key => :remixer},
367
- :type => Type::STRING,
368
- },
369
-
370
- # lyricist
371
- {
372
- :name => :lyricist,
373
- :handler => :user_info_lookup,
374
- :handler_opts => {:key => :lyricist},
375
- :type => Type::STRING,
376
- },
377
-
378
- # asin
379
- {
380
- :name => :asin,
381
- :handler => :user_info_lookup,
382
- :handler_opts => {:key => :asin},
383
- :type => Type::STRING,
384
- },
385
-
386
- #
387
- # MusicBrainz Attributes
388
- #
389
-
390
- # musicbrainz_track_id
391
- {
392
- :name => :musicbrainz_track_id,
393
- :handler => :user_info_lookup,
394
- :handler_opts => {:key => :musicbrainz_track_id},
395
- :type => Type::STRING,
396
- },
397
-
398
- # musicbrainz_album_artist_id
399
- {
400
- :name => :musicbrainz_album_artist_id,
401
- :handler => :user_info_lookup,
402
- :handler_opts => {:key => :musicbrainz_album_artist_id},
403
- :type => Type::STRING,
404
- },
405
-
406
- # musicbrainz_artist_id
407
- {
408
- :name => :musicbrainz_artist_id,
409
- :handler => :user_info_lookup,
410
- :handler_opts => {:key => :musicbrainz_artist_id},
411
- :type => Type::LIST,
412
- },
413
-
414
- # musicbrainz_album_id
415
- {
416
- :name => :musicbrainz_album_id,
417
- :handler => :user_info_lookup,
418
- :handler_opts => {:key => :musicbrainz_album_id},
419
- :type => Type::STRING,
420
- },
421
-
422
- # musicbrainz_album_status
423
- {
424
- :name => :musicbrainz_album_status,
425
- :handler => :user_info_lookup,
426
- :handler_opts => {:key => :musicbrainz_album_status},
427
- :type => Type::STRING,
428
- },
429
-
430
- # musicbrainz_album_type
431
- {
432
- :name => :musicbrainz_album_type,
433
- :handler => :user_info_lookup,
434
- :handler_opts => {:key => :musicbrainz_album_type},
435
- :type => Type::LIST,
436
- },
437
-
438
-
439
- # musicbrainz_release_group_id
440
- {
441
- :name => :musicbrainz_release_group_id,
442
- :handler => :user_info_lookup,
443
- :handler_opts => {:key => :musicbrainz_release_group_id},
444
- :type => Type::STRING,
445
- },
446
-
447
- # musicbrainz_album_release_country
448
- {
449
- :name => :musicbrainz_album_release_country,
450
- :handler => :user_info_lookup,
451
- :handler_opts => {:key => :musicbrainz_album_release_country},
452
- :type => Type::STRING,
453
- },
454
-
455
- #
456
- # Audio Properties
457
- #
458
-
459
- # length
460
- {
461
- :name => :length,
462
- :aliases => [:duration],
463
- :handler => :read_audio_property,
464
- :handler_opts => {:key => :length},
465
- :type => Type::INT,
466
- },
467
-
468
- # bitrate
469
- {
470
- :name => :bitrate,
471
- :handler => :read_audio_property,
472
- :handler_opts => {:key => :bitrate},
473
- :type => Type::INT,
474
- },
475
-
476
- # sample_rate
477
- {
478
- :name => :sample_rate,
479
- :handler => :read_audio_property,
480
- :handler_opts => {:key => :sample_rate},
481
- :type => Type::INT,
482
- },
483
-
484
- # channels
485
- {
486
- :name => :channels,
487
- :handler => :read_audio_property,
488
- :handler_opts => {:key => :channels},
489
- :type => Type::INT,
490
- },
491
-
492
- # bits_per_sample
493
- {
494
- :name => :bits_per_sample,
495
- :handler => :read_audio_property,
496
- :handler_opts => {:key => :bits_per_sample},
497
- :type => Type::INT,
498
- },
499
-
500
- # NOTE: Not supported by ruby-easytag 0.6.0
501
- ## encrypted?
502
- #{
503
- #:name => :encrypted?,
504
- #:handler => :read_audio_property,
505
- #:handler_opts => {:key => :encrypted?},
506
- #:type => Type::BOOLEAN,
507
- #},
508
- ]
509
- end