dmap 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +16 -1
- data/Rakefile +1 -1
- data/lib/dmap.rb +134 -131
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -21,7 +21,7 @@ We all love examples, so here's an example of how to use this module:
|
|
21
21
|
# You can load from any IO source:
|
22
22
|
d = DMAP::Element(open("your_dmap"))
|
23
23
|
p d
|
24
|
-
# => <
|
24
|
+
# => <MINM: "I'm a string!">
|
25
25
|
|
26
26
|
# Or write out what you want in code:
|
27
27
|
d = DMAP::Element.new("msrv",[DMAP::Element.new('minm',"I'm a string!")])
|
@@ -37,6 +37,21 @@ We all love examples, so here's an example of how to use this module:
|
|
37
37
|
|
38
38
|
p d
|
39
39
|
# => <MSRV: [<MINM: "I'm a string!">, <ASDM: Fri Nov 06 11:18:29 +0000 2009>, <ASTM: 123>]>
|
40
|
+
|
41
|
+
# Ooh! And there's more, if you're parsing a DMAP and it's very large, this
|
42
|
+
# library plays nice and only parses the bits you need so far:
|
43
|
+
d = DMAP::Element(open("your_array-like_dmap"))
|
44
|
+
p d
|
45
|
+
# => <MSRV: Some unparsed DMAP elements>
|
46
|
+
# Calling any method of the array that requires knowledge of its contents
|
47
|
+
# will automagically parse what's required, or you can call it explicitly:
|
48
|
+
d.parse_dmap
|
49
|
+
p d
|
50
|
+
# => <MSRV: [<MINM: "I'm a string!">,<MSRV: Some unparsed DMAP elements>]>
|
51
|
+
# Or, if you'd rather not have to worry you can just tell arrays to parse immediately:
|
52
|
+
DMAP::Array.parse_immediately = true
|
53
|
+
# Just remember you have to do this before you start any parsing in order for it to have an effect
|
54
|
+
|
40
55
|
|
41
56
|
If you want to allow parsing of more tags, you're probably not going to want to go there right now (I'm likely to change the way this works) but if you just specify a new constant in the DMAP module, who's name is the 4-byte code, set it to an array like [:string, 'domain.app.name'].
|
42
57
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "dmap"
|
8
|
-
gem.version = "0.1.
|
8
|
+
gem.version = "0.1.5"
|
9
9
|
gem.summary = %Q{Parses Apple's DMAP strings (4-byte serialization method)}
|
10
10
|
gem.description = %Q{Apple uses a system of serialization (I think its called dmap…) where a 4-byte string tells of the information following, both its type and what it represents. Its used in the DAAP (Protocol), QuickTime mov structure and doubtless many other places.}
|
11
11
|
gem.email = "jphastings@gmail.com"
|
data/lib/dmap.rb
CHANGED
@@ -48,6 +48,10 @@ module DMAP
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
def is_dmap?
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
51
55
|
def close_stream
|
52
56
|
begin
|
53
57
|
@io.close
|
@@ -126,7 +130,6 @@ module DMAP
|
|
126
130
|
# it later if the contents are requested
|
127
131
|
class Array < Array
|
128
132
|
attr_reader :unparsed_data
|
129
|
-
attr_accessor :parse_immediately
|
130
133
|
@@parse_immediately = false
|
131
134
|
|
132
135
|
def self.parse_immediately
|
@@ -150,7 +153,7 @@ module DMAP
|
|
150
153
|
rescue NoMethodError
|
151
154
|
begin
|
152
155
|
array_or_io.each do |element|
|
153
|
-
if element.
|
156
|
+
if element.is_dmap?
|
154
157
|
self.push element
|
155
158
|
else
|
156
159
|
raise "Thisneeds to be a DMAP::Element. #{element.inspect}"
|
@@ -278,154 +281,154 @@ module DMAP
|
|
278
281
|
end
|
279
282
|
end
|
280
283
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
+
#F�CH = [:number, 'dmap.haschildcontainers']
|
285
|
+
ABAL = [:list, 'daap.browsealbumlisting']
|
286
|
+
ABAR = [:list, 'daap.browseartistlisting']
|
287
|
+
ABCP = [:list, 'daap.browsecomposerlisting']
|
288
|
+
ABGN = [:list, 'daap.browsegenrelisting']
|
289
|
+
ABPL = [:number, 'daap.baseplaylist']
|
290
|
+
ABRO = [:list, 'daap.databasebrowse']
|
291
|
+
ADBS = [:list, 'daap.databasesongs']
|
292
|
+
AEAI = [:number, 'com.apple.itunes.itms-artistid']
|
293
|
+
AECI = [:number, 'com.apple.itunes.itms-composerid']
|
294
|
+
AECR = [:string, 'com.apple.itunes.content-rating']
|
295
|
+
AEEN = [:string, 'com.apple.itunes.episode-num-str']
|
296
|
+
AEES = [:number, 'com.apple.itunes.episode-sort']
|
297
|
+
AEFP = [:number, 'com.apple.itunes.req-fplay']
|
298
|
+
AEGD = [:number, 'com.apple.itunes.gapless-enc-dr']
|
299
|
+
AEGE = [:number, 'com.apple.itunes.gapless-enc-del']
|
300
|
+
AEGH = [:number, 'com.apple.itunes.gapless-heur']
|
301
|
+
AEGI = [:number, 'com.apple.itunes.itms-genreid']
|
302
|
+
AEGR = [:number, 'com.apple.itunes.gapless-resy']
|
284
303
|
AEGU = [:number, 'com.apple.itunes.gapless-dur']
|
285
|
-
|
304
|
+
AEHD = [:number, 'com.apple.itunes.is-hd-video']
|
305
|
+
AEHV = [:number, 'com.apple.itunes.has-video']
|
306
|
+
AEMK = [:number, 'com.apple.itunes.mediakind']
|
307
|
+
AENN = [:string, 'com.apple.itunes.network-name']
|
308
|
+
AENV = [:number, 'com.apple.itunes.norm-volume']
|
309
|
+
AEPC = [:number, 'com.apple.itunes.is-podcast']
|
310
|
+
AEPI = [:number, 'com.apple.itunes.itms-playlistid']
|
311
|
+
AEPP = [:number, 'com.apple.itunes.is-podcast-playlist']
|
312
|
+
AEPS = [:number, 'com.apple.itunes.special-playlist']
|
313
|
+
AESF = [:number, 'com.apple.itunes.itms-storefrontid']
|
314
|
+
AESG = [:number, 'com.apple.itunes.saved-genius']
|
315
|
+
AESI = [:number, 'com.apple.itunes.itms-songid']
|
286
316
|
AESN = [:string, 'com.apple.itunes.series-name']
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
ASBT = [:number, 'daap.songbeatsperminute']
|
291
|
-
AEGE = [:number, 'com.apple.itunes.gapless-enc-del']
|
292
|
-
MSTO = [:signed, 'dmap.utcoffset']
|
293
|
-
ABAR = [:list, 'daap.browseartistlisting']
|
294
|
-
MCNA = [:string, 'dmap.contentcodesname']
|
295
|
-
ASEQ = [:string, 'daap.songeqpreset']
|
317
|
+
AESP = [:number, 'com.apple.itunes.smart-playlist']
|
318
|
+
AESU = [:number, 'com.apple.itunes.season-num']
|
319
|
+
AESV = [:number, 'com.apple.itunes.music-sharing-version']
|
296
320
|
AGRP = [:string, 'daap.songgrouping']
|
297
|
-
|
298
|
-
|
299
|
-
AEGR = [:number, 'com.apple.itunes.gapless-resy']
|
300
|
-
ASSZ = [:number, 'daap.songsize']
|
301
|
-
MSTT = [:number, 'dmap.status']
|
302
|
-
MCTC = [:number, 'dmap.containercount']
|
303
|
-
ASGP = [:number, 'daap.songgapless']
|
321
|
+
APLY = [:list, 'daap.databaseplaylists']
|
322
|
+
APRM = [:number, 'daap.playlistrepeatmode']
|
304
323
|
APRO = [:version,'daap.protocolversion']
|
305
|
-
|
306
|
-
MSBR = [:number, 'dmap.supportsbrowse']
|
307
|
-
ASTN = [:number, 'daap.songtracknumber']
|
308
|
-
ASCR = [:number, 'daap.songcontentrating']
|
309
|
-
AEMK = [:number, 'com.apple.itunes.mediakind']
|
310
|
-
MUDL = [:list, 'dmap.deletedidlisting']
|
324
|
+
APSM = [:number, 'daap.playlistshufflemode']
|
311
325
|
APSO = [:list, 'daap.playlistsongs']
|
312
|
-
|
313
|
-
|
314
|
-
ASLC = [:string, 'daap.songlongcontentdescription']
|
315
|
-
MSEX = [:number, 'dmap.supportsextensions']
|
316
|
-
ASYR = [:number, 'daap.songyear']
|
317
|
-
ASDA = [:time, 'daap.songdateadded']
|
318
|
-
AEPC = [:number, 'com.apple.itunes.is-podcast']
|
319
|
-
MUTY = [:number, 'dmap.updatetype']
|
320
|
-
MIKD = [:number, 'dmap.itemkind']
|
321
|
-
ASRV = [:signed, 'daap.songrelativevolume']
|
326
|
+
ARIF = [:list, 'daap.resolveinfo']
|
327
|
+
ARSV = [:list, 'daap.resolve']
|
322
328
|
ASAA = [:string, 'daap.songalbumartist']
|
323
|
-
|
324
|
-
|
325
|
-
AEPS = [:number, 'com.apple.itunes.special-playlist']
|
326
|
-
CEJC = [:signed, 'com.apple.itunes.jukebox-client-vote']
|
327
|
-
ASDC = [:number, 'daap.songdisccount']
|
328
|
-
MLCL = [:list, 'dmap.listing']
|
329
|
-
ASSA = [:string, 'daap.sortartist']
|
329
|
+
ASAI = [:number, 'daap.songalbumid']
|
330
|
+
ASAL = [:string, 'daap.songalbum']
|
330
331
|
ASAR = [:string, 'daap.songartist']
|
331
|
-
|
332
|
-
|
333
|
-
ASDN = [:number, 'daap.songdiscnumber']
|
334
|
-
AESG = [:number, 'com.apple.itunes.saved-genius']
|
335
|
-
MLOG = [:list, 'dmap.loginresponse']
|
336
|
-
ASSN = [:string, 'daap.sortname']
|
332
|
+
ASBK = [:number, 'daap.bookmarkable']
|
333
|
+
ASBO = [:number, 'daap.songbookmark']
|
337
334
|
ASBR = [:number, 'daap.songbitrate']
|
338
|
-
|
339
|
-
ASDT = [:string, 'daap.songdescription']
|
340
|
-
AESP = [:number, 'com.apple.itunes.smart-playlist']
|
341
|
-
ABAL = [:list, 'daap.browsealbumlisting']
|
342
|
-
MBCL = [:list, 'dmap.bag']
|
343
|
-
MPRO = [:version,'dmap.protocolversion']
|
344
|
-
ASSS = [:string, 'daap.sortseriesname']
|
335
|
+
ASBT = [:number, 'daap.songbeatsperminute']
|
345
336
|
ASCD = [:number, 'daap.songcodectype']
|
346
|
-
|
347
|
-
|
348
|
-
ABCP = [:list, 'daap.browsecomposerlisting']
|
349
|
-
MCNM = [:number, 'dmap.contentcodesnumber']
|
350
|
-
ASFM = [:string, 'daap.songformat']
|
351
|
-
MSAL = [:number, 'dmap.supportsautologout']
|
352
|
-
ASTC = [:number, 'daap.songtrackcount']
|
337
|
+
ASCM = [:string, 'daap.songcomment']
|
338
|
+
ASCN = [:string, 'daap.songcontentdescription']
|
353
339
|
ASCO = [:number, 'daap.songcompilation']
|
354
|
-
|
355
|
-
|
356
|
-
MCTI = [:number, 'dmap.containeritemid']
|
357
|
-
ASHP = [:number, 'daap.songhasbeenplayed']
|
358
|
-
MSDC = [:number, 'dmap.databasescount']
|
359
|
-
AENN = [:string, 'com.apple.itunes.network-name']
|
360
|
-
ASUL = [:string, 'daap.songdataurl']
|
340
|
+
ASCP = [:string, 'daap.songcomposer']
|
341
|
+
ASCR = [:number, 'daap.songcontentrating']
|
361
342
|
ASCS = [:number, 'daap.songcodecsubtype']
|
362
|
-
|
343
|
+
ASCT = [:string, 'daap.songcategory']
|
344
|
+
ASDA = [:time, 'daap.songdateadded']
|
345
|
+
ASDB = [:number, 'daap.songdisabled']
|
346
|
+
ASDC = [:number, 'daap.songdisccount']
|
347
|
+
ASDK = [:number, 'daap.songdatakind']
|
348
|
+
ASDM = [:time, 'daap.songdatemodified']
|
349
|
+
ASDN = [:number, 'daap.songdiscnumber']
|
350
|
+
ASDP = [:time, 'daap.songdatepurchased']
|
351
|
+
ASDR = [:time, 'daap.songdatereleased']
|
352
|
+
ASDT = [:string, 'daap.songdescription']
|
353
|
+
ASED = [:number, 'daap.songextradata']
|
354
|
+
ASEQ = [:string, 'daap.songeqpreset']
|
355
|
+
ASFM = [:string, 'daap.songformat']
|
356
|
+
ASGN = [:string, 'daap.songgenre']
|
357
|
+
ASGP = [:number, 'daap.songgapless']
|
358
|
+
ASHP = [:number, 'daap.songhasbeenplayed']
|
359
|
+
ASKY = [:string, 'daap.songkeywords']
|
360
|
+
ASLC = [:string, 'daap.songlongcontentdescription']
|
363
361
|
ASLS = [:number, 'daap.songlongsize']
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
362
|
+
ASPU = [:string, 'daap.songpodcasturl']
|
363
|
+
ASRV = [:signed, 'daap.songrelativevolume']
|
364
|
+
ASSA = [:string, 'daap.sortartist']
|
365
|
+
ASSC = [:string, 'daap.sortcomposer']
|
366
|
+
ASSL = [:string, 'daap.sortalbumartist']
|
367
|
+
ASSN = [:string, 'daap.sortname']
|
368
|
+
ASSP = [:number, 'daap.songstoptime']
|
369
|
+
ASSR = [:number, 'daap.songsamplerate']
|
370
|
+
ASSS = [:string, 'daap.sortseriesname']
|
371
|
+
ASST = [:number, 'daap.songstarttime']
|
372
|
+
ASSU = [:string, 'daap.sortalbum']
|
373
|
+
ASSZ = [:number, 'daap.songsize']
|
374
|
+
ASTC = [:number, 'daap.songtrackcount']
|
375
|
+
ASTM = [:number, 'daap.songtime']
|
376
|
+
ASTN = [:number, 'daap.songtracknumber']
|
377
|
+
ASUL = [:string, 'daap.songdataurl']
|
378
|
+
ASUR = [:number, 'daap.songuserrating']
|
379
|
+
ASYR = [:number, 'daap.songyear']
|
369
380
|
ATED = [:number, 'daap.supportsextradata']
|
370
|
-
|
371
|
-
|
372
|
-
AECR = [:string, 'com.apple.itunes.content-rating']
|
373
|
-
ASAI = [:number, 'daap.songalbumid']
|
374
|
-
MSML = [:list, 'unknown_msml']
|
375
|
-
ASDK = [:number, 'daap.songdatakind']
|
376
|
-
AESU = [:number, 'com.apple.itunes.season-num']
|
381
|
+
AVDB = [:list, 'daap.serverdatabases']
|
382
|
+
CEJC = [:signed, 'com.apple.itunes.jukebox-client-vote']
|
377
383
|
CEJI = [:number, 'com.apple.itunes.jukebox-current']
|
378
|
-
|
379
|
-
ASSC = [:string, 'daap.sortcomposer']
|
380
|
-
ASBK = [:number, 'daap.bookmarkable']
|
381
|
-
AEFP = [:number, 'com.apple.itunes.req-fplay']
|
382
|
-
MSRS = [:number, 'dmap.supportsresolve']
|
384
|
+
CEJS = [:signed, 'com.apple.itunes.jukebox-score']
|
383
385
|
CEJV = [:number, 'com.apple.itunes.jukebox-vote']
|
384
|
-
|
385
|
-
AESI = [:number, 'com.apple.itunes.itms-songid']
|
386
|
-
MPCO = [:number, 'dmap.parentcontainerid']
|
387
|
-
AEGD = [:number, 'com.apple.itunes.gapless-enc-dr']
|
388
|
-
ASSP = [:number, 'daap.songstoptime']
|
389
|
-
MSTM = [:number, 'dmap.timeoutinterval']
|
386
|
+
MBCL = [:list, 'dmap.bag']
|
390
387
|
MCCR = [:list, 'dmap.contentcodesresponse']
|
391
|
-
|
392
|
-
|
393
|
-
MRCO = [:number, 'dmap.returnedcount']
|
394
|
-
AEGI = [:number, 'com.apple.itunes.itms-genreid']
|
395
|
-
ASST = [:number, 'daap.songstarttime']
|
396
|
-
ASCM = [:string, 'daap.songcomment']
|
397
|
-
MSTS = [:string, 'dmap.statusstring']
|
398
|
-
ASGN = [:string, 'daap.songgenre']
|
399
|
-
APRM = [:number, 'daap.playlistrepeatmode']
|
400
|
-
ABGN = [:list, 'daap.browsegenrelisting']
|
388
|
+
MCNA = [:string, 'dmap.contentcodesname']
|
389
|
+
MCNM = [:number, 'dmap.contentcodesnumber']
|
401
390
|
MCON = [:list, 'dmap.container']
|
402
|
-
|
403
|
-
|
404
|
-
ASCP = [:string, 'daap.songcomposer']
|
405
|
-
AEHV = [:number, 'com.apple.itunes.has-video']
|
406
|
-
MTCO = [:number, 'dmap.specifiedtotalcount']
|
407
|
-
ABRO = [:list, 'daap.databasebrowse']
|
391
|
+
MCTC = [:number, 'dmap.containercount']
|
392
|
+
MCTI = [:number, 'dmap.containeritemid']
|
408
393
|
MCTY = [:number, 'dmap.contentcodestype']
|
409
|
-
|
410
|
-
|
411
|
-
MSED = [:number, 'unknown_msed']
|
412
|
-
ASCT = [:string, 'daap.songcategory']
|
413
|
-
AENV = [:number, 'com.apple.itunes.norm-volume']
|
414
|
-
ASUR = [:number, 'daap.songuserrating']
|
415
|
-
MUSR = [:number, 'dmap.serverrevision']
|
394
|
+
MDCL = [:list, 'dmap.dictionary']
|
395
|
+
MEDS = [:number, 'dmap.editcommandssupported']
|
416
396
|
MIID = [:number, 'dmap.itemid']
|
417
|
-
|
418
|
-
|
419
|
-
MSLR = [:number, 'dmap.loginrequired']
|
420
|
-
AVDB = [:list, 'daap.serverdatabases']
|
421
|
-
ASDB = [:number, 'daap.songdisabled']
|
422
|
-
AEPP = [:number, 'com.apple.itunes.is-podcast-playlist']
|
397
|
+
MIKD = [:number, 'dmap.itemkind']
|
398
|
+
MIMC = [:number, 'dmap.itemcount']
|
423
399
|
MINM = [:string, 'dmap.itemname']
|
424
|
-
|
425
|
-
|
426
|
-
|
400
|
+
MLCL = [:list, 'dmap.listing']
|
401
|
+
MLID = [:number, 'dmap.sessionid']
|
402
|
+
MLOG = [:list, 'dmap.loginresponse']
|
403
|
+
MPCO = [:number, 'dmap.parentcontainerid']
|
404
|
+
MPER = [:number, 'dmap.persistentid']
|
405
|
+
MPRO = [:version,'dmap.protocolversion']
|
406
|
+
MRCO = [:number, 'dmap.returnedcount']
|
407
|
+
MSAL = [:number, 'dmap.supportsautologout']
|
408
|
+
MSAS = [:number, 'dmap.authenticationschemes']
|
409
|
+
MSAU = [:number, 'dmap.authenticationmethod']
|
410
|
+
MSBR = [:number, 'dmap.supportsbrowse']
|
411
|
+
MSDC = [:number, 'dmap.databasescount']
|
412
|
+
MSED = [:number, 'unknown_msed']
|
413
|
+
MSEX = [:number, 'dmap.supportsextensions']
|
414
|
+
MSIX = [:number, 'dmap.supportsindex']
|
415
|
+
MSLR = [:number, 'dmap.loginrequired']
|
416
|
+
MSMA = [:number, 'unknown_msma']
|
417
|
+
MSML = [:list, 'unknown_msml']
|
427
418
|
MSPI = [:number, 'dmap.supportspersistentids']
|
428
|
-
|
429
|
-
|
430
|
-
|
419
|
+
MSQY = [:number, 'dmap.supportsquery']
|
420
|
+
MSRS = [:number, 'dmap.supportsresolve']
|
421
|
+
MSRV = [:list, 'dmap.serverinforesponse']
|
422
|
+
MSTC = [:time, 'dmap.utctime']
|
423
|
+
MSTM = [:number, 'dmap.timeoutinterval']
|
424
|
+
MSTO = [:signed, 'dmap.utcoffset']
|
425
|
+
MSTS = [:string, 'dmap.statusstring']
|
426
|
+
MSTT = [:number, 'dmap.status']
|
427
|
+
MSUP = [:number, 'dmap.supportsupdate']
|
428
|
+
MTCO = [:number, 'dmap.specifiedtotalcount']
|
429
|
+
MUDL = [:list, 'dmap.deletedidlisting']
|
430
|
+
MUPD = [:list, 'dmap.updateresponse']
|
431
|
+
MUSR = [:number, 'dmap.serverrevision']
|
432
|
+
MUTY = [:number, 'dmap.updatetype']
|
433
|
+
MLIT = [:list, 'dmap.listingitem']
|
431
434
|
end
|