daapclient 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/README +63 -0
  2. data/doc/classes/Net/DAAP/Client.html +251 -0
  3. data/doc/classes/Net/DAAP/Client.src/M000003.html +20 -0
  4. data/doc/classes/Net/DAAP/Client.src/M000004.html +25 -0
  5. data/doc/classes/Net/DAAP/Client.src/M000005.html +33 -0
  6. data/doc/classes/Net/DAAP/Client.src/M000006.html +37 -0
  7. data/doc/classes/Net/DAAP/Client.src/M000007.html +20 -0
  8. data/doc/classes/Net/DAAP/Client.src/M000008.html +24 -0
  9. data/doc/classes/Net/DAAP/DAAPv2.html +165 -0
  10. data/doc/classes/Net/DAAP/DAAPv2.src/M000015.html +30 -0
  11. data/doc/classes/Net/DAAP/DAAPv2.src/M000016.html +21 -0
  12. data/doc/classes/Net/DAAP/DAAPv3.html +178 -0
  13. data/doc/classes/Net/DAAP/DAAPv3.src/M000017.html +30 -0
  14. data/doc/classes/Net/DAAP/DAAPv3.src/M000018.html +23 -0
  15. data/doc/classes/Net/DAAP/DMAP.html +189 -0
  16. data/doc/classes/Net/DAAP/DMAP.src/M000012.html +20 -0
  17. data/doc/classes/Net/DAAP/DMAP.src/M000013.html +18 -0
  18. data/doc/classes/Net/DAAP/DMAP.src/M000014.html +24 -0
  19. data/doc/classes/Net/DAAP/Database.html +224 -0
  20. data/doc/classes/Net/DAAP/Database.src/M000009.html +25 -0
  21. data/doc/classes/Net/DAAP/Database.src/M000010.html +21 -0
  22. data/doc/classes/Net/DAAP/Database.src/M000011.html +35 -0
  23. data/doc/classes/Net/DAAP/Playlist.html +192 -0
  24. data/doc/classes/Net/DAAP/Playlist.src/M000001.html +24 -0
  25. data/doc/classes/Net/DAAP/Playlist.src/M000002.html +30 -0
  26. data/doc/classes/Net/DAAP/Song.html +208 -0
  27. data/doc/classes/Net/DAAP/Song.src/M000019.html +27 -0
  28. data/doc/classes/Net/DAAP/Song.src/M000020.html +19 -0
  29. data/doc/classes/Net/DAAP.html +168 -0
  30. data/doc/classes/Net.html +127 -0
  31. data/doc/created.rid +1 -0
  32. data/doc/files/CHANGELOG.html +110 -0
  33. data/doc/files/LICENSE.html +531 -0
  34. data/doc/files/README.html +176 -0
  35. data/doc/files/lib/net/daap/database_rb.html +101 -0
  36. data/doc/files/lib/net/daap/dmap_rb.html +101 -0
  37. data/doc/files/lib/net/daap/playlist_rb.html +101 -0
  38. data/doc/files/lib/net/daap/song_rb.html +101 -0
  39. data/doc/files/lib/net/daap_rb.html +114 -0
  40. data/doc/fr_class_index.html +35 -0
  41. data/doc/fr_file_index.html +34 -0
  42. data/doc/fr_method_index.html +46 -0
  43. data/doc/index.html +24 -0
  44. data/doc/rdoc-style.css +208 -0
  45. data/lib/CVS/Entries +1 -0
  46. data/lib/CVS/Repository +1 -0
  47. data/lib/CVS/Root +1 -0
  48. data/lib/net/CVS/Entries +2 -0
  49. data/lib/net/CVS/Repository +1 -0
  50. data/lib/net/CVS/Root +1 -0
  51. data/lib/net/daap/CVS/Entries +5 -0
  52. data/lib/net/daap/CVS/Repository +1 -0
  53. data/lib/net/daap/CVS/Root +1 -0
  54. data/lib/net/daap/database.rb +69 -0
  55. data/lib/net/daap/dmap.rb +575 -0
  56. data/lib/net/daap/playlist.rb +36 -0
  57. data/lib/net/daap/song.rb +27 -0
  58. data/lib/net/daap.rb +234 -0
  59. data/test/CVS/Entries +4 -0
  60. data/test/CVS/Repository +1 -0
  61. data/test/CVS/Root +1 -0
  62. data/test/data/CVS/Entries +1 -0
  63. data/test/data/CVS/Repository +1 -0
  64. data/test/data/CVS/Root +1 -0
  65. data/test/data/mt-daapd/079aca35773150da9fd98db10c7fd0c0.txt +0 -0
  66. data/test/data/mt-daapd/2972f65088b42a06b5d3ca089d71791d.txt +0 -0
  67. data/test/data/mt-daapd/440c2217e6207c54c317c296f71f9769.txt +0 -0
  68. data/test/data/mt-daapd/4d1ce9f941cbd823ed06f1f1baa5a3b9.txt +0 -0
  69. data/test/data/mt-daapd/7bded8b540fd082f102d25e181b47bc4.txt +0 -0
  70. data/test/data/mt-daapd/CVS/Entries +11 -0
  71. data/test/data/mt-daapd/CVS/Repository +1 -0
  72. data/test/data/mt-daapd/CVS/Root +1 -0
  73. data/test/data/mt-daapd/b3e894b87111bdba88e4765967f4b45a.txt +0 -0
  74. data/test/data/mt-daapd/d56b699830e77ba53855679cb1d252da.txt +0 -0
  75. data/test/data/mt-daapd/e61ce3062cb76770658896b778ad06cd.txt +0 -0
  76. data/test/data/mt-daapd/e9a8e709c2116651157182f130207048.txt +0 -0
  77. data/test/data/mt-daapd/f9073959a0afacebfab7e3bf19c2714a.txt +0 -0
  78. data/test/tc_client.rb +148 -0
  79. data/test/tc_protocol.rb +49 -0
  80. data/test/ts_daap.rb +6 -0
  81. metadata +148 -0
@@ -0,0 +1,575 @@
1
+ module Net
2
+ module DAAP
3
+ # This class decodes responses from the DAAP server in to useful data
4
+ # structures.
5
+ class DMAP
6
+ def initialize(args)
7
+ @daap = args[:daap]
8
+ load_types
9
+ update_content_codes
10
+ end
11
+
12
+ def find(data, to_find)
13
+ seek(unpack(data), to_find)
14
+ end
15
+
16
+ def flat_list(data)
17
+ struct = unpack(data)
18
+ hash_list = Hash.new
19
+ flat_list = flat_list_traverse(struct)
20
+ 0.step(flat_list.length - 1, 2) do |i|
21
+ hash_list[flat_list[i]] = flat_list[i + 1]
22
+ end
23
+ hash_list
24
+ end
25
+
26
+ private
27
+ TYPE_TO_UNPACK = {
28
+ 1 => 'c',
29
+ 3 => 'n',
30
+ 5 => 'N',
31
+ 7 => 'Q',
32
+ 9 => 'a*',
33
+ 10 => 'N',
34
+ 11 => 'nn',
35
+ 42 => 'a*'
36
+ }
37
+
38
+ def update_content_codes
39
+ content_codes = unpack(@daap.do_get("content-codes"))
40
+ mccr = seek(content_codes, "dmap.contentcodesresponse")
41
+ mccr.each do |mdcl_rec|
42
+ next unless mdcl_rec[0] == 'dmap.dictionary'
43
+ name = id = type = nil
44
+ mdcl_rec[1].each do |f|
45
+ id = f[1] if f[0] == 'dmap.contentcodesnumber'
46
+ name = f[1] if f[0] == 'dmap.contentcodesname'
47
+ type = f[1] if f[0] == 'dmap.contentcodestype'
48
+ end
49
+ type = 9 if id == 'mcnm'
50
+ type = 42 if id == 'pfdt'
51
+ @types[id] = { 'NAME' => name, 'ID' => id, 'TYPE' => type }
52
+ end
53
+ #@types = short
54
+ @types
55
+ end
56
+
57
+ def flat_list_traverse(struct, list = [], prefix = '')
58
+ struct.each do |element|
59
+ 0.step(element.length - 1, 2) do |i|
60
+ tag, data = element[i], element[i + 1]
61
+ if data.class == Array
62
+ flat_list_traverse(data, list, "#{prefix}/#{tag}")
63
+ else
64
+ list << "#{prefix}/#{tag}"
65
+ list << data
66
+ end
67
+ end
68
+ end
69
+ list
70
+ end
71
+
72
+ def unpack(buffer = nil)
73
+ tags = []
74
+
75
+ buffer = @code unless buffer
76
+
77
+ while(buffer.length > 0)
78
+ tag, len = buffer.unpack("a4N")
79
+ data = buffer[8...8+len]
80
+
81
+ buffer[0...8+len] = ''
82
+
83
+ type = @types[tag]['TYPE']
84
+
85
+ if type == 12
86
+ data = unpack(data)
87
+ elsif type == 7
88
+ n1, n2 = data.unpack("N2")
89
+ data = n1 << 32
90
+ data += n2
91
+ else
92
+ data = data.unpack(TYPE_TO_UNPACK[type])
93
+ end
94
+
95
+ if data.class == Array && data.length == 1 && data[0].class != Array || type == 11
96
+ tmp = [ @types[tag]['NAME'], data[0]]
97
+ else
98
+ tmp = [ @types[tag]['NAME'], data]
99
+ end
100
+
101
+ tags << tmp
102
+ end
103
+ tags
104
+ end
105
+
106
+ def seek(struct, to_find)
107
+ while( to_find != nil && to_find.length > 0 )
108
+ top, to_find = to_find.split('/', 2)
109
+
110
+ found = nil
111
+ struct.each do |element|
112
+ if element[0] == top
113
+ found = element[1]
114
+ end
115
+ end
116
+ return unless found
117
+ struct = found
118
+ end
119
+ return struct
120
+ end
121
+
122
+
123
+ def load_types
124
+ @types =
125
+ {
126
+ 'abal' => {
127
+ 'ID' => 'abal',
128
+ 'NAME' => 'daap.browsealbumlisting',
129
+ 'TYPE' => 12
130
+ },
131
+ 'abar' => {
132
+ 'ID' => 'abar',
133
+ 'NAME' => 'daap.browseartistlisting',
134
+ 'TYPE' => 12
135
+ },
136
+ 'abcp' => {
137
+ 'ID' => 'abcp',
138
+ 'NAME' => 'daap.browsecomposerlisting',
139
+ 'TYPE' => 12
140
+ },
141
+ 'abgn' => {
142
+ 'ID' => 'abgn',
143
+ 'NAME' => 'daap.browsegenrelisting',
144
+ 'TYPE' => 12
145
+ },
146
+ 'abpl' => {
147
+ 'ID' => 'abpl',
148
+ 'NAME' => 'daap.baseplaylist',
149
+ 'TYPE' => 1
150
+ },
151
+ 'abro' => {
152
+ 'ID' => 'abro',
153
+ 'NAME' => 'daap.databasebrowse',
154
+ 'TYPE' => 12
155
+ },
156
+ 'adbs' => {
157
+ 'ID' => 'adbs',
158
+ 'NAME' => 'daap.databasesongs',
159
+ 'TYPE' => 12
160
+ },
161
+ 'aeNV' => {
162
+ 'ID' => 'aeNV',
163
+ 'NAME' => 'com.apple.itunes.norm-volume',
164
+ 'TYPE' => 5
165
+ },
166
+ 'aeSP' => {
167
+ 'ID' => 'aeSP',
168
+ 'NAME' => 'com.apple.itunes.smart-playlist',
169
+ 'TYPE' => 1
170
+ },
171
+ 'aply' => {
172
+ 'ID' => 'aply',
173
+ 'NAME' => 'daap.databaseplaylists',
174
+ 'TYPE' => 12
175
+ },
176
+ 'apro' => {
177
+ 'ID' => 'apro',
178
+ 'NAME' => 'daap.protocolversion',
179
+ 'TYPE' => 11
180
+ },
181
+ 'apso' => {
182
+ 'ID' => 'apso',
183
+ 'NAME' => 'daap.playlistsongs',
184
+ 'TYPE' => 12
185
+ },
186
+ 'arif' => {
187
+ 'ID' => 'arif',
188
+ 'NAME' => 'daap.resolveinfo',
189
+ 'TYPE' => 12
190
+ },
191
+ 'arsv' => {
192
+ 'ID' => 'arsv',
193
+ 'NAME' => 'daap.resolve',
194
+ 'TYPE' => 12
195
+ },
196
+ 'asal' => {
197
+ 'ID' => 'asal',
198
+ 'NAME' => 'daap.songalbum',
199
+ 'TYPE' => 9
200
+ },
201
+ 'asar' => {
202
+ 'ID' => 'asar',
203
+ 'NAME' => 'daap.songartist',
204
+ 'TYPE' => 9
205
+ },
206
+ 'asbr' => {
207
+ 'ID' => 'asbr',
208
+ 'NAME' => 'daap.songbitrate',
209
+ 'TYPE' => 3
210
+ },
211
+ 'asbt' => {
212
+ 'ID' => 'asbt',
213
+ 'NAME' => 'daap.songbeatsperminute',
214
+ 'TYPE' => 3
215
+ },
216
+ 'ascm' => {
217
+ 'ID' => 'ascm',
218
+ 'NAME' => 'daap.songcomment',
219
+ 'TYPE' => 9
220
+ },
221
+ 'asco' => {
222
+ 'ID' => 'asco',
223
+ 'NAME' => 'daap.songcompilation',
224
+ 'TYPE' => 1
225
+ },
226
+ 'ascp' => {
227
+ 'ID' => 'ascp',
228
+ 'NAME' => 'daap.songcomposer',
229
+ 'TYPE' => 9
230
+ },
231
+ 'asda' => {
232
+ 'ID' => 'asda',
233
+ 'NAME' => 'daap.songdateadded',
234
+ 'TYPE' => 10
235
+ },
236
+ 'asdb' => {
237
+ 'ID' => 'asdb',
238
+ 'NAME' => 'daap.songdisabled',
239
+ 'TYPE' => 1
240
+ },
241
+ 'asdc' => {
242
+ 'ID' => 'asdc',
243
+ 'NAME' => 'daap.songdisccount',
244
+ 'TYPE' => 3
245
+ },
246
+ 'asdk' => {
247
+ 'ID' => 'asdk',
248
+ 'NAME' => 'daap.songdatakind',
249
+ 'TYPE' => 1
250
+ },
251
+ 'asdm' => {
252
+ 'ID' => 'asdm',
253
+ 'NAME' => 'daap.songdatemodified',
254
+ 'TYPE' => 10
255
+ },
256
+ 'asdn' => {
257
+ 'ID' => 'asdn',
258
+ 'NAME' => 'daap.songdiscnumber',
259
+ 'TYPE' => 3
260
+ },
261
+ 'asdt' => {
262
+ 'ID' => 'asdt',
263
+ 'NAME' => 'daap.songdescription',
264
+ 'TYPE' => 9
265
+ },
266
+ 'aseq' => {
267
+ 'ID' => 'aseq',
268
+ 'NAME' => 'daap.songeqpreset',
269
+ 'TYPE' => 9
270
+ },
271
+ 'asfm' => {
272
+ 'ID' => 'asfm',
273
+ 'NAME' => 'daap.songformat',
274
+ 'TYPE' => 9
275
+ },
276
+ 'asgn' => {
277
+ 'ID' => 'asgn',
278
+ 'NAME' => 'daap.songgenre',
279
+ 'TYPE' => 9
280
+ },
281
+ 'asrv' => {
282
+ 'ID' => 'asrv',
283
+ 'NAME' => 'daap.songrelativevolume',
284
+ 'TYPE' => 1
285
+ },
286
+ 'assp' => {
287
+ 'ID' => 'assp',
288
+ 'NAME' => 'daap.songstoptime',
289
+ 'TYPE' => 5
290
+ },
291
+ 'assr' => {
292
+ 'ID' => 'assr',
293
+ 'NAME' => 'daap.songsamplerate',
294
+ 'TYPE' => 5
295
+ },
296
+ 'asst' => {
297
+ 'ID' => 'asst',
298
+ 'NAME' => 'daap.songstarttime',
299
+ 'TYPE' => 5
300
+ },
301
+ 'assz' => {
302
+ 'ID' => 'assz',
303
+ 'NAME' => 'daap.songsize',
304
+ 'TYPE' => 5
305
+ },
306
+ 'astc' => {
307
+ 'ID' => 'astc',
308
+ 'NAME' => 'daap.songtrackcount',
309
+ 'TYPE' => 3
310
+ },
311
+ 'astm' => {
312
+ 'ID' => 'astm',
313
+ 'NAME' => 'daap.songtime',
314
+ 'TYPE' => 5
315
+ },
316
+ 'astn' => {
317
+ 'ID' => 'astn',
318
+ 'NAME' => 'daap.songtracknumber',
319
+ 'TYPE' => 3
320
+ },
321
+ 'asul' => {
322
+ 'ID' => 'asul',
323
+ 'NAME' => 'daap.songdataurl',
324
+ 'TYPE' => 9
325
+ },
326
+ 'asur' => {
327
+ 'ID' => 'asur',
328
+ 'NAME' => 'daap.songuserrating',
329
+ 'TYPE' => 1
330
+ },
331
+ 'asyr' => {
332
+ 'ID' => 'asyr',
333
+ 'NAME' => 'daap.songyear',
334
+ 'TYPE' => 3
335
+ },
336
+ 'avdb' => {
337
+ 'ID' => 'avdb',
338
+ 'NAME' => 'daap.serverdatabases',
339
+ 'TYPE' => 12
340
+ },
341
+ 'mbcl' => {
342
+ 'ID' => 'mbcl',
343
+ 'NAME' => 'dmap.bag',
344
+ 'TYPE' => 12
345
+ },
346
+ 'mccr' => {
347
+ 'ID' => 'mccr',
348
+ 'NAME' => 'dmap.contentcodesresponse',
349
+ 'TYPE' => 12
350
+ },
351
+ 'mcna' => {
352
+ 'ID' => 'mcna',
353
+ 'NAME' => 'dmap.contentcodesname',
354
+ 'TYPE' => 9
355
+ },
356
+ 'mcnm' => {
357
+ 'ID' => 'mcnm',
358
+ 'NAME' => 'dmap.contentcodesnumber',
359
+ 'TYPE' => 9
360
+ },
361
+ 'mcon' => {
362
+ 'ID' => 'mcon',
363
+ 'NAME' => 'dmap.container',
364
+ 'TYPE' => 12
365
+ },
366
+ 'mctc' => {
367
+ 'ID' => 'mctc',
368
+ 'NAME' => 'dmap.containercount',
369
+ 'TYPE' => 5
370
+ },
371
+ 'mcti' => {
372
+ 'ID' => 'mcti',
373
+ 'NAME' => 'dmap.containeritemid',
374
+ 'TYPE' => 5
375
+ },
376
+ 'mcty' => {
377
+ 'ID' => 'mcty',
378
+ 'NAME' => 'dmap.contentcodestype',
379
+ 'TYPE' => 3
380
+ },
381
+ 'mdcl' => {
382
+ 'ID' => 'mdcl',
383
+ 'NAME' => 'dmap.dictionary',
384
+ 'TYPE' => 12
385
+ },
386
+ 'miid' => {
387
+ 'ID' => 'miid',
388
+ 'NAME' => 'dmap.itemid',
389
+ 'TYPE' => 5
390
+ },
391
+ 'mikd' => {
392
+ 'ID' => 'mikd',
393
+ 'NAME' => 'dmap.itemkind',
394
+ 'TYPE' => 1
395
+ },
396
+ 'mimc' => {
397
+ 'ID' => 'mimc',
398
+ 'NAME' => 'dmap.itemcount',
399
+ 'TYPE' => 5
400
+ },
401
+ 'minm' => {
402
+ 'ID' => 'minm',
403
+ 'NAME' => 'dmap.itemname',
404
+ 'TYPE' => 9
405
+ },
406
+ 'mlcl' => {
407
+ 'ID' => 'mlcl',
408
+ 'NAME' => 'dmap.listing',
409
+ 'TYPE' => 12
410
+ },
411
+ 'mlid' => {
412
+ 'ID' => 'mlid',
413
+ 'NAME' => 'dmap.sessionid',
414
+ 'TYPE' => 5
415
+ },
416
+ 'mlit' => {
417
+ 'ID' => 'mlit',
418
+ 'NAME' => 'dmap.listingitem',
419
+ 'TYPE' => 12
420
+ },
421
+ 'mlog' => {
422
+ 'ID' => 'mlog',
423
+ 'NAME' => 'dmap.loginresponse',
424
+ 'TYPE' => 12
425
+ },
426
+ 'mpco' => {
427
+ 'ID' => 'mpco',
428
+ 'NAME' => 'dmap.parentcontainerid',
429
+ 'TYPE' => 5
430
+ },
431
+ 'mper' => {
432
+ 'ID' => 'mper',
433
+ 'NAME' => 'dmap.persistentid',
434
+ 'TYPE' => 7
435
+ },
436
+ 'mpro' => {
437
+ 'ID' => 'mpro',
438
+ 'NAME' => 'dmap.protocolversion',
439
+ 'TYPE' => 11
440
+ },
441
+ 'mrco' => {
442
+ 'ID' => 'mrco',
443
+ 'NAME' => 'dmap.returnedcount',
444
+ 'TYPE' => 5
445
+ },
446
+ 'msal' => {
447
+ 'ID' => 'msal',
448
+ 'NAME' => 'dmap.supportsautologout',
449
+ 'TYPE' => 1
450
+ },
451
+ 'msau' => {
452
+ 'ID' => 'msau',
453
+ 'NAME' => 'dmap.authenticationmethod',
454
+ 'TYPE' => 1
455
+ },
456
+ 'msbr' => {
457
+ 'ID' => 'msbr',
458
+ 'NAME' => 'dmap.supportsbrowse',
459
+ 'TYPE' => 1
460
+ },
461
+ 'msdc' => {
462
+ 'ID' => 'msdc',
463
+ 'NAME' => 'dmap.databasescount',
464
+ 'TYPE' => 5
465
+ },
466
+ 'msex' => {
467
+ 'ID' => 'msex',
468
+ 'NAME' => 'dmap.supportsextensions',
469
+ 'TYPE' => 1
470
+ },
471
+ 'msix' => {
472
+ 'ID' => 'msix',
473
+ 'NAME' => 'dmap.supportsindex',
474
+ 'TYPE' => 1
475
+ },
476
+ 'mslr' => {
477
+ 'ID' => 'mslr',
478
+ 'NAME' => 'dmap.loginrequired',
479
+ 'TYPE' => 1
480
+ },
481
+ 'mspi' => {
482
+ 'ID' => 'mspi',
483
+ 'NAME' => 'dmap.supportspersistentids',
484
+ 'TYPE' => 1
485
+ },
486
+ 'msqy' => {
487
+ 'ID' => 'msqy',
488
+ 'NAME' => 'dmap.supportsquery',
489
+ 'TYPE' => 1
490
+ },
491
+ 'msrs' => {
492
+ 'ID' => 'msrs',
493
+ 'NAME' => 'dmap.supportsresolve',
494
+ 'TYPE' => 1
495
+ },
496
+ 'msrv' => {
497
+ 'ID' => 'msrv',
498
+ 'NAME' => 'dmap.serverinforesponse',
499
+ 'TYPE' => 12
500
+ },
501
+ 'mstm' => {
502
+ 'ID' => 'mstm',
503
+ 'NAME' => 'dmap.timeoutinterval',
504
+ 'TYPE' => 5
505
+ },
506
+ 'msts' => {
507
+ 'ID' => 'msts',
508
+ 'NAME' => 'dmap.statusstring',
509
+ 'TYPE' => 9
510
+ },
511
+ 'mstt' => {
512
+ 'ID' => 'mstt',
513
+ 'NAME' => 'dmap.status',
514
+ 'TYPE' => 5
515
+ },
516
+ 'msup' => {
517
+ 'ID' => 'msup',
518
+ 'NAME' => 'dmap.supportsupdate',
519
+ 'TYPE' => 1
520
+ },
521
+ 'mtco' => {
522
+ 'ID' => 'mtco',
523
+ 'NAME' => 'dmap.specifiedtotalcount',
524
+ 'TYPE' => 5
525
+ },
526
+ 'mudl' => {
527
+ 'ID' => 'mudl',
528
+ 'NAME' => 'dmap.deletedidlisting',
529
+ 'TYPE' => 12
530
+ },
531
+ 'mupd' => {
532
+ 'ID' => 'mupd',
533
+ 'NAME' => 'dmap.updateresponse',
534
+ 'TYPE' => 12
535
+ },
536
+ 'musr' => {
537
+ 'ID' => 'musr',
538
+ 'NAME' => 'dmap.serverrevision',
539
+ 'TYPE' => 5
540
+ },
541
+ 'muty' => {
542
+ 'ID' => 'muty',
543
+ 'NAME' => 'dmap.updatetype',
544
+ 'TYPE' => 1
545
+ },
546
+ 'pasp' => {
547
+ 'ID' => 'pasp',
548
+ 'NAME' => 'dpap.aspectratio',
549
+ 'TYPE' => 9
550
+ },
551
+ 'pfdt' => {
552
+ 'ID' => 'pfdt',
553
+ 'NAME' => 'dpap.picturedata',
554
+ 'TYPE' => 42
555
+ },
556
+ 'picd' => {
557
+ 'ID' => 'picd',
558
+ 'NAME' => 'dpap.creationdate',
559
+ 'TYPE' => 5
560
+ },
561
+ 'pimf' => {
562
+ 'ID' => 'pimf',
563
+ 'NAME' => 'dpap.imagefilename',
564
+ 'TYPE' => 9
565
+ },
566
+ 'ppro' => {
567
+ 'ID' => 'ppro',
568
+ 'NAME' => 'dpap.protocolversion',
569
+ 'TYPE' => 11
570
+ }
571
+ }
572
+ end
573
+ end
574
+ end
575
+ end
@@ -0,0 +1,36 @@
1
+ module Net
2
+ module DAAP
3
+ # This class contains information about playlists returned from the iTunes
4
+ # server.
5
+ class Playlist
6
+ attr_reader :itemcount, :persistentid, :name, :id
7
+
8
+ def initialize(args)
9
+ info = args[:pl_info]
10
+ @itemcount = info['dmap.itemcount']
11
+ @persistentid = info['dmap.persistentid']
12
+ @name = info['dmap.itemname']
13
+ @id = info['dmap.itemid']
14
+ @daap = args[:daap]
15
+ @db = args[:db]
16
+ end
17
+
18
+ # Returns a list of songs associated with this playlist.
19
+ def songs
20
+ path = "databases/#{@db.id}/containers/#{@id}/items?type=music&meta=dmap.itemkind,dmap.itemid,dmap.containeritemid"
21
+ result = @daap.do_get(path)
22
+ listings = @daap.dmap.find(result,
23
+ "daap.playlistsongs/dmap.listing")
24
+ songs = []
25
+ @daap.unpack_listing(listings) do |value|
26
+ if block_given?
27
+ yield @db.songs.find { |s| s.id == value['dmap.itemid'] }
28
+ else
29
+ songs << @db.songs.find { |s| s.id == value['dmap.itemid'] }
30
+ end
31
+ end
32
+ songs
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module Net
2
+ module DAAP
3
+ # This class contains song information returned from the DAAP server.
4
+ class Song
5
+ attr_reader :size, :album, :name, :artist, :format, :persistentid, :id
6
+
7
+ def initialize(args)
8
+ info = args[:song_info]
9
+ @size = info['daap.songsize']
10
+ @album = info['daap.songalbum']
11
+ @name = info['dmap.itemname']
12
+ @artist = info['daap.songartist']
13
+ @format = info['daap.songformat']
14
+ @persistentid = info['dmap.persistentid']
15
+ @id = info['dmap.itemid']
16
+ @daap = args[:daap]
17
+ @db = args[:db]
18
+ end
19
+
20
+ # Fetches the song data from the DAAP server and returns it.
21
+ def get
22
+ filename = "#{@id}.#{@format}"
23
+ return @daap.get_song("databases/#{@db.id}/items/#{filename}")
24
+ end
25
+ end
26
+ end
27
+ end