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
data/lib/net/daap.rb ADDED
@@ -0,0 +1,234 @@
1
+ require 'net/http'
2
+ require 'digest/m4p'
3
+ require 'digest/md5'
4
+ require 'net/daap/dmap'
5
+ require 'net/daap/song'
6
+ require 'net/daap/playlist'
7
+ require 'net/daap/database'
8
+
9
+
10
+ module Net
11
+ # = Synopsis
12
+ # The DAAP library is used for browsing an iTunes share.
13
+ # Make sure that Digest::M4P is installed before using this library.
14
+ #
15
+ # == Example
16
+ # require 'rubygems'
17
+ # require 'net/daap'
18
+ #
19
+ # daap = Net::DAAP::Client.new('localhost')
20
+ # daap.connect do |dsn|
21
+ #
22
+ # daap.databases do |db|
23
+ # puts "All songs in the database"
24
+ # db.songs do |song|
25
+ # puts "#{song.artist} - #{song.name}"
26
+ # end
27
+ #
28
+ # puts "Songs for each playlist"
29
+ # db.playlists do |pl|
30
+ # puts "Playlist name: #{pl.name}"
31
+ # pl.songs do |song|
32
+ # puts "#{song.artist} - #{song.name}"
33
+ # File::open("dl/#{song.artist} - #{song.name}.#{song.format}", "w") do |f|
34
+ # f << song.get
35
+ # end
36
+ # end
37
+ # end
38
+ # end
39
+ # end
40
+ #
41
+ module DAAP
42
+
43
+ # = Synopsis
44
+ # The Client class interacts with the iTunes server to fetch lists of songs,
45
+ # databases, and playlists. Each Client class can have many Database,
46
+ # and each Database can have many Playlist, and many Song. See DAAP for a
47
+ # code example.
48
+ class Client
49
+ attr_reader :dmap
50
+
51
+ # Create a new Client and pass in the host where the client will connect.
52
+ def initialize(server_host)
53
+ @server_host = server_host
54
+ @server_port = 3689
55
+ @debug = 0
56
+ end
57
+
58
+ # Connects to the iTunes server. This method should be called right after
59
+ # construction. See DAAP for an example.
60
+ def connect(&connection)
61
+ @http_client = Net::HTTP.start(@server_host, @server_port)
62
+ find_validator
63
+ @dmap = Net::DAAP::DMAP.new(:daap => self)
64
+ load_server_info
65
+ @connected = 1
66
+ yield @dsn
67
+ disconnect
68
+ @connected = 0
69
+ end
70
+
71
+ # Returns the databases found on the iTunes server.
72
+ def databases
73
+ return error("Not connected, can't fetch databases") unless @connected
74
+
75
+ listings = @dmap.find(do_get("databases"),
76
+ "daap.serverdatabases/dmap.listing")
77
+ # FIXME check the value of listing
78
+ @databases = []
79
+ unpack_listing(listings) do |value|
80
+ if block_given?
81
+ yield Database.new( :db_info => value,
82
+ :daap => self )
83
+ else
84
+ @databases << Database.new( :db_info => value,
85
+ :daap => self )
86
+ end
87
+ end
88
+ @databases
89
+ end
90
+
91
+ def do_get(request)
92
+ debug("do_get")
93
+ url = String.new('/' + request)
94
+ if @session_id
95
+ url += url =~ /\?/ ? "&" : "?"
96
+ url += "session-id=#{@session_id}"
97
+ end
98
+
99
+ if @revision && request != "logout"
100
+ url += "&revision-number=#{@revision}"
101
+ end
102
+ debug(url)
103
+
104
+ res = @http_client.get(url, request_headers(url))
105
+
106
+ content_type = res.header['content-type']
107
+ if request !~ /(?:\/items\/\d+\.|logout)/ && content_type !~ /dmap/
108
+ raise "Broken response"
109
+ end
110
+
111
+ res.body
112
+ end
113
+
114
+ def get_song(request)
115
+ @request_id = 1 unless @request_id
116
+ @request_id += 1 if @request_id
117
+ do_get(request)
118
+ end
119
+
120
+ def unpack_listing(listing, &func)
121
+ listing.each do |item|
122
+ record = Hash.new
123
+ item[1].each do |pair_ref|
124
+ record[pair_ref[0]] = pair_ref[1]
125
+ end
126
+ yield record
127
+ end
128
+ end
129
+
130
+ private
131
+ def disconnect
132
+ do_get("logout")
133
+ end
134
+ def load_server_info
135
+ flat_list = @dmap.flat_list(do_get("server-info"))
136
+ @dsn = flat_list['/dmap.serverinforesponse/dmap.itemname']
137
+
138
+ debug("Connected to share '#{@dsn}'")
139
+ @session_id = @dmap.find(do_get("login"),
140
+ "dmap.loginresponse/dmap.sessionid")
141
+ debug("My id is #{@session_id}")
142
+ @dsn
143
+ end
144
+
145
+ def request_headers(url)
146
+ headers = Hash.new
147
+ headers['Client-DAAP-Version'] = "3.0"
148
+ headers['Client-DAAP-Access-Index'] = "2"
149
+ headers['Client-DAAP-Request-ID'] = @request_id.to_s if @request_id
150
+ headers['Client-DAAP-Validation'] =
151
+ @validator.validate(url, 2, @request_id) if @validator
152
+
153
+ headers
154
+ end
155
+
156
+ def find_validator
157
+ res = @http_client.get('/server-info')
158
+ server = res.header['daap-server']
159
+
160
+ if server =~ /^iTunes\/4.2/
161
+ @validator = DAAPv2.new
162
+ end
163
+
164
+ if server =~ /^iTunes/
165
+ @validator = DAAPv3.new
166
+ end
167
+ end
168
+
169
+ def debug(message)
170
+ if @debug == 1
171
+ print "DEBUG: "
172
+ p message
173
+ end
174
+ end
175
+ end
176
+
177
+ # This class is used for generating a Client-DAAP-Validation header for iTunes
178
+ # version 4.2 servers.
179
+ class DAAPv2
180
+ def initialize
181
+ @seeds = []
182
+ (0..255).each do |i|
183
+ string = String.new
184
+ string += (i & 0x80) != 0 ? "Accept-Language" : "user-agent"
185
+ string += (i & 0x40) != 0 ? "max-age" : "Authorization"
186
+ string += (i & 0x20) != 0 ? "Client-DAAP-Version" : "Accept-Encoding"
187
+ string += (i & 0x10) != 0 ? "daap.protocolversion": "daap.songartist"
188
+ string += (i & 0x08) != 0 ? "daap.songcomposer" : "daap.songdatemodified"
189
+ string += (i & 0x04) != 0 ? "daap.songdiscnumber" : "daap.songdisabled"
190
+ string += (i & 0x02) != 0 ? "playlist-item-spec" : "revision-number"
191
+ string += (i & 0x01) != 0 ? "session-id" : "content-codes"
192
+ @seeds << Digest::MD5.new(string).to_s.upcase
193
+ end
194
+ end
195
+ # Returns a validation header based on MD5
196
+ def validate(path, select = 2, req_id = nil)
197
+ string = path.dup
198
+ string += "Copyright 2003 Apple Computer, Inc."
199
+ string += @seeds[select]
200
+ return Digest::MD5.new(string).to_s.upcase
201
+ end
202
+ end
203
+
204
+ # This class is used for generating a Client-DAAP-Validation header for iTunes
205
+ # servers newer than 4.2, or something.
206
+ class DAAPv3
207
+ attr_reader :seeds
208
+ def initialize
209
+ @seeds = []
210
+ (0..255).each do |i|
211
+ string = String.new
212
+ string += (i & 0x40) != 0 ? "eqwsdxcqwesdc" : "op[;lm,piojkmn"
213
+ string += (i & 0x20) != 0 ? "876trfvb 34rtgbvc" : "=-0ol.,m3ewrdfv"
214
+ string += (i & 0x10) != 0 ? "87654323e4rgbv " : "1535753690868867974342659792"
215
+ string += (i & 0x08) != 0 ? "Song Name" : "DAAP-CLIENT-ID:"
216
+ string += (i & 0x04) != 0 ? "111222333444555" : "4089961010"
217
+ string += (i & 0x02) != 0 ? "playlist-item-spec" : "revision-number"
218
+ string += (i & 0x01) != 0 ? "session-id" : "content-codes"
219
+ string += (i & 0x80) != 0 ? "IUYHGFDCXWEDFGHN" : "iuytgfdxwerfghjm"
220
+ @seeds << Digest::M4P.new(string).to_s.upcase
221
+ end
222
+ end
223
+ # Returns a validation header using a custom MD5 called Digest::M4P
224
+ def validate(path, select = 2, req_id = nil)
225
+ string = String.new
226
+ string += path
227
+ string += "Copyright 2003 Apple Computer, Inc."
228
+ string += @seeds[select]
229
+ string += req_id.to_s if req_id != nil
230
+ Digest::M4P.new(string).to_s.upcase
231
+ end
232
+ end
233
+ end
234
+ end
data/test/CVS/Entries ADDED
@@ -0,0 +1,4 @@
1
+ /tc_client.rb/1.1.1.1/Wed Dec 7 23:25:52 2005//
2
+ /tc_protocol.rb/1.1.1.1/Wed Dec 7 23:25:52 2005//
3
+ /ts_daap.rb/1.1.1.1/Wed Dec 7 23:25:52 2005//
4
+ D/data////
@@ -0,0 +1 @@
1
+ daap/test
data/test/CVS/Root ADDED
@@ -0,0 +1 @@
1
+ :ext:aaronp@rubyforge.org:/var/cvs/daapclient
@@ -0,0 +1 @@
1
+ D/mt-daapd////
@@ -0,0 +1 @@
1
+ daap/test/data
@@ -0,0 +1 @@
1
+ :ext:aaronp@rubyforge.org:/var/cvs/daapclient
@@ -0,0 +1,11 @@
1
+ /079aca35773150da9fd98db10c7fd0c0.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
2
+ /2972f65088b42a06b5d3ca089d71791d.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
3
+ /440c2217e6207c54c317c296f71f9769.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
4
+ /4d1ce9f941cbd823ed06f1f1baa5a3b9.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
5
+ /7bded8b540fd082f102d25e181b47bc4.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
6
+ /b3e894b87111bdba88e4765967f4b45a.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
7
+ /d56b699830e77ba53855679cb1d252da.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
8
+ /e61ce3062cb76770658896b778ad06cd.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
9
+ /e9a8e709c2116651157182f130207048.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
10
+ /f9073959a0afacebfab7e3bf19c2714a.txt/1.1.1.1/Wed Dec 7 23:25:52 2005//
11
+ D
@@ -0,0 +1 @@
1
+ daap/test/data/mt-daapd
@@ -0,0 +1 @@
1
+ :ext:aaronp@rubyforge.org:/var/cvs/daapclient
data/test/tc_client.rb ADDED
@@ -0,0 +1,148 @@
1
+ require 'test/unit'
2
+ require 'net/daap'
3
+ require 'digest/md5'
4
+
5
+ class MyTest < Net::DAAP::Client
6
+ def connect
7
+ @dmap = Net::DAAP::DMAP.new(:daap => self)
8
+ load_server_info
9
+ @connected = 1
10
+ @dsn
11
+ end
12
+
13
+ def find_validator
14
+ end
15
+
16
+ def do_get(request)
17
+ contents = nil
18
+ md5 = Digest::MD5.new(request)
19
+ File::open("data/mt-daapd/" + md5.to_s + ".txt", "r") do |file|
20
+ contents = file.read
21
+ end
22
+ contents
23
+ end
24
+ end
25
+
26
+ class DAAPClient_Test < Test::Unit::TestCase
27
+ def setup
28
+ @daap = MyTest.new('localhost')
29
+ @daap.connect
30
+ end
31
+
32
+ def test_connect
33
+ daap = MyTest.new('localhost')
34
+ dsn = daap.connect
35
+ assert_equal("apatterson", dsn)
36
+ end
37
+
38
+ def test_songs
39
+ songs = @daap.databases[0].songs
40
+ songs_hash = Hash.new
41
+ songs.each do |song|
42
+ songs_hash[song.id] = { :size => song.size, :album => song.album,
43
+ :name => song.name, :artist => song.artist, :format => song.format,
44
+ :persistentid => song.persistentid, :itemid => song.id }
45
+ end
46
+
47
+ hash =
48
+ {2327300=>{:itemid=>2327300, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4654199, :name=>"Myxomatosis (Judge, Jury & Executioner)", :persistentid=>2327300},
49
+ 2327243=>{:itemid=>2327243, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>3723264, :name=>"Myxomatosis", :persistentid=>2327243},
50
+ 2327281=>{:itemid=>2327281, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>5950405, :name=>"A Punch Up At A Wedding (No No No No No No No No)", :persistentid=>2327281},
51
+ 2327234=>{:itemid=>2327234, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>4759552, :name=>"A Punch-Up At The Wedding", :persistentid=>2327234},
52
+ 2327272=>{:itemid=>2327272, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>7673398, :name=>"Paranoid Android", :persistentid=>2327272},
53
+ 2327253=>{:itemid=>2327253, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>3284376, :name=>"I will (Los Angeles version)", :persistentid=>2327253},
54
+ 2327225=>{:itemid=>2327225, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>3190784, :name=>"2+2=5", :persistentid=>2327225},
55
+ 2327301=>{:itemid=>2327301, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>6455593, :name=>"Backdrifts (Honeymoon Is Over)", :persistentid=>2327301},
56
+ 2327282=>{:itemid=>2327282, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4037702, :name=>"Scatterbrain (As Dead As Leaves)", :persistentid=>2327282},
57
+ 2327273=>{:itemid=>2327273, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>5236170, :name=>"Karma Police", :persistentid=>2327273},
58
+ 2327311=>{:itemid=>2327311, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4030394, :name=>"A Wolf At The Door (It Girl. Rag Doll)", :persistentid=>2327311},
59
+ 2327254=>{:itemid=>2327254, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>6443033, :name=>"Skttrbrain (Four Tet remix)", :persistentid=>2327254},
60
+ 2327302=>{:itemid=>2327302, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>2393022, :name=>"I Will (No Man's Land)", :persistentid=>2327302},
61
+ 2327245=>{:itemid=>2327245, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>5212004, :name=>"Gagging Order", :persistentid=>2327245},
62
+ 2327283=>{:itemid=>2327283, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4833826, :name=>"A Wolf At The Door", :persistentid=>2327283},
63
+ 2327226=>{:itemid=>2327226, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>4134912, :name=>"Sail To The Moon", :persistentid=>2327226},
64
+ 2327264=>{:itemid=>2327264, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>2350164, :name=>"Fitter Happier", :persistentid=>2327264},
65
+ 2327312=>{:itemid=>2327312, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>2868372, :name=>"I Will", :persistentid=>2327312},
66
+ 2327246=>{:itemid=>2327246, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>5130084, :name=>"I am Citizen Insane", :persistentid=>2327246},
67
+ 2327284=>{:itemid=>2327284, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4785551, :name=>"2 + 2 = 5", :persistentid=>2327284},
68
+ 2327322=>{:itemid=>2327322, :album=>"I Might Be Wrong: Live Recordings", :format=>"mp3", :artist=>"Radiohead", :size=>5953983, :name=>"The National Anthem", :persistentid=>2327322},
69
+ 2327227=>{:itemid=>2327227, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>3223552, :name=>"A Wolf At The Door", :persistentid=>2327227},
70
+ 2327265=>{:itemid=>2327265, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>4616547, :name=>"Electioneering", :persistentid=>2327265},
71
+ 2327303=>{:itemid=>2327303, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>6475455, :name=>"There There (The Boney King Of Nowhere)", :persistentid=>2327303},
72
+ 2327294=>{:itemid=>2327294, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>7122152, :name=>"We Suck Young Blood", :persistentid=>2327294},
73
+ 2327237=>{:itemid=>2327237, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>3229696, :name=>"Scatterbrain", :persistentid=>2327237},
74
+ 2327247=>{:itemid=>2327247, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>3349578, :name=>"Fog. (Again) - Live", :persistentid=>2327247},
75
+ 2327285=>{:itemid=>2327285, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>5170908, :name=>"Sail To The Moon (Brush The Cobwebs Of The Sky)", :persistentid=>2327285},
76
+ 2327323=>{:itemid=>2327323, :album=>"I Might Be Wrong: Live Recordings", :format=>"mp3", :artist=>"Radiohead", :size=>6263793, :name=>"Dollars And Cents", :persistentid=>2327323},
77
+ 2327228=>{:itemid=>2327228, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>3225600, :name=>"Go To Sleep", :persistentid=>2327228},
78
+ 2327266=>{:itemid=>2327266, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>5691739, :name=>"Airbag", :persistentid=>2327266},
79
+ 2327295=>{:itemid=>2327295, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>6240049, :name=>"Sit Down. Stand Up", :persistentid=>2327295},
80
+ 2327314=>{:itemid=>2327314, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>6463866, :name=>"Where I End And You Begin", :persistentid=>2327314},
81
+ 2327324=>{:itemid=>2327324, :album=>"I Might Be Wrong: Live Recordings", :format=>"mp3", :artist=>"Radiohead", :size=>5300405, :name=>"Idioteque", :persistentid=>2327324},
82
+ 2327229=>{:itemid=>2327229, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>5179392, :name=>"There There", :persistentid=>2327229},
83
+ 2327267=>{:itemid=>2327267, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>5707428, :name=>"Climbing Up The Walls", :persistentid=>2327267},
84
+ 2327305=>{:itemid=>2327305, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4840722, :name=>"Scatterbrain", :persistentid=>2327305},
85
+ 2327248=>{:itemid=>2327248, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>4547728, :name=>"I Am A Wicked Child", :persistentid=>2327248},
86
+ 2327286=>{:itemid=>2327286, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>4836960, :name=>"Go To Sleep", :persistentid=>2327286},
87
+ 2327258=>{:itemid=>2327258, :album=>"2+2=5 CD's", :format=>"mp3", :artist=>"Radiohead", :size=>4930333, :name=>"Remyxomatosis", :persistentid=>2327258},
88
+ 2327315=>{:itemid=>2327315, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>3990668, :name=>"2+2=5 (The Lukewarm)", :persistentid=>2327315},
89
+ 2327230=>{:itemid=>2327230, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>5163008, :name=>"Backdrifts", :persistentid=>2327230},
90
+ 2327268=>{:itemid=>2327268, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>5299397, :name=>"Exit Music (For A Film)", :persistentid=>2327268},
91
+ 2327249=>{:itemid=>2327249, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>7450123, :name=>"Remyxomatosis (Cristian Vogel RMX)", :persistentid=>2327249},
92
+ 2327287=>{:itemid=>2327287, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>7767272, :name=>"There There", :persistentid=>2327287},
93
+ 2327325=>{:itemid=>2327325, :album=>"I Might Be Wrong: Live Recordings", :format=>"mp3", :artist=>"Radiohead", :size=>4552253, :name=>"Like Spinning Plates", :persistentid=>2327325},
94
+ 2327240=>{:itemid=>2327240, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>1912832, :name=>"I Will", :persistentid=>2327240},
95
+ 2327316=>{:itemid=>2327316, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>5581763, :name=>"Myxomatosis", :persistentid=>2327316},
96
+ 2327221=>{:itemid=>2327221, :album=>"There there", :format=>"mp3", :artist=>"Radiohead", :size=>5777028, :name=>"Where bluebirds fly.", :persistentid=>2327221},
97
+ 2327259=>{:itemid=>2327259, :album=>"2+2=5 CD's", :format=>"mp3", :artist=>"Radiohead", :size=>7425967, :name=>"There There (demo)", :persistentid=>2327259},
98
+ 2327297=>{:itemid=>2327297, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>5389293, :name=>"Where I End And You Begin (The Sky Is Falling In)", :persistentid=>2327297},
99
+ 2327269=>{:itemid=>2327269, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>5195935, :name=>"Lucky", :persistentid=>2327269},
100
+ 2327307=>{:itemid=>2327307, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>7137199, :name=>"A Punchup At A Wedding", :persistentid=>2327307},
101
+ 2327250=>{:itemid=>2327250, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>11222064, :name=>"There there (First demo)", :persistentid=>2327250},
102
+ 2327231=>{:itemid=>2327231, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>4749312, :name=>"We Suck Young Blood", :persistentid=>2327231},
103
+ 2327260=>{:itemid=>2327260, :album=>"2+2=5 CD's", :format=>"mp3", :artist=>"Radiohead", :size=>4263688, :name=>"Skttrbrain (Four Tet RMX)", :persistentid=>2327260},
104
+ 2327298=>{:itemid=>2327298, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>5937853, :name=>"We Suck Young Blood (Your Time Is Up)", :persistentid=>2327298},
105
+ 2327251=>{:itemid=>2327251, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>5786001, :name=>"Paperbag Writer", :persistentid=>2327251},
106
+ 2327232=>{:itemid=>2327232, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>3393536, :name=>"The Gloaming", :persistentid=>2327232},
107
+ 2327270=>{:itemid=>2327270, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>6494227, :name=>"The Tourist", :persistentid=>2327270},
108
+ 2327280=>{:itemid=>2327280, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>6201806, :name=>"Sail To The Moon", :persistentid=>2327280},
109
+ 2327261=>{:itemid=>2327261, :album=>"2+2=5 CD's", :format=>"mp3", :artist=>"Radiohead", :size=>2158009, :name=>"I will (LA version)", :persistentid=>2327261},
110
+ 2327299=>{:itemid=>2327299, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>5089617, :name=>"The Gloaming", :persistentid=>2327299},
111
+ 2327242=>{:itemid=>2327242, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>4311040, :name=>"Where I End And You Begin", :persistentid=>2327242},
112
+ 2327271=>{:itemid=>2327271, :album=>"OK Computer", :format=>"mp3", :artist=>"Radiohead", :size=>5989015, :name=>"Let Down", :persistentid=>2327271},
113
+ 2327233=>{:itemid=>2327233, :album=>"Hail To The Theif", :format=>"mp3", :artist=>"Radiohead", :size=>4161536, :name=>"Sit Down, Stand Up", :persistentid=>2327233},
114
+ 2327252=>{:itemid=>2327252, :album=>"Radiohead - HTTT Era B-Sides", :format=>"m4a", :artist=>"Radiohead", :size=>6588253, :name=>"Where Bluebirds Fly", :persistentid=>2327252},
115
+ 2327290=>{:itemid=>2327290, :album=>"Hail To The Thief", :format=>"mp3", :artist=>"Radiohead", :size=>7743448, :name=>"Backdrifts", :persistentid=>2327290}}
116
+ assert_equal(hash, songs_hash)
117
+ end
118
+
119
+ def test_databases
120
+ # There should be only one database
121
+ assert(true, @daap.databases.length == 1)
122
+ db = @daap.databases[0]
123
+ assert_equal(1, db.persistentid)
124
+ assert_equal('apatterson', db.name)
125
+ assert_equal(4, db.containercount)
126
+ assert_equal(1, db.id)
127
+ assert_equal(68, db.itemcount)
128
+ assert_equal(68, db.songs.length)
129
+ assert(true, db.songs.length == db.itemcount)
130
+ assert_equal(4, db.playlists.length)
131
+ assert(true, db.playlists.length == db.containercount)
132
+
133
+ #@daap.databases.each do |db|
134
+ # puts "All songs in the database"
135
+ # db.songs.each do |song|
136
+ # #puts "#{song.artist} - #{song.name}"
137
+ # end
138
+ #
139
+ # puts "Songs for each playlist"
140
+ # db.playlists.each do |pl|
141
+ # puts "Playlist name: #{pl.name}"
142
+ # pl.songs.each do |song|
143
+ # #puts "#{song.artist} - #{song.name}"
144
+ # end
145
+ # end
146
+ #end
147
+ end
148
+ end
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+ require 'net/daap'
3
+ require 'digest/md5'
4
+
5
+ class DAAPProtocol_Test < Test::Unit::TestCase
6
+ def test_v3
7
+ proto = Net::DAAP::DAAPv3.new
8
+ assert_equal("434EED05046099EA7938EDEE2805E3E8",
9
+ proto.validate("/content-codes", 2))
10
+ assert_equal("77BE0B44D0D6ED1268381859B133B4B9",
11
+ proto.validate("/server-info", 2))
12
+ assert_equal("E3B047FF11C1F845093E898495A585E2",
13
+ proto.validate("/login", 2))
14
+ assert_equal("34370BBBDFC2980C568862AD40DD1F40",
15
+ proto.validate("/databases?session-id=10", 2))
16
+ assert_equal("24BF5D60319039401EE2D8B9FEA571FD",
17
+ proto.validate("/databases/1/items?type=music&meta=dmap.itemid,dmap.itemname,dmap.persistentid,daap.songalbum,daap.songartist,daap.songformat,daap.songsize&session-id=10", 2))
18
+ assert_equal("1A01D5DE1936B3E0B1A1D30D1FE6556C",
19
+ proto.validate("/databases/1/containers?meta=dmap.itemid,dmap.itemname,dmap.persistentid,com.apple.itunes.smart-playlist&session-id=10", 2))
20
+ assert_equal("3B9A624D4CF25AE764F8F241C3BCE362",
21
+ proto.validate("/logout?session-id=10", 2))
22
+ assert_equal("2530C0BC46579EE229338099E0A36CDD",
23
+ proto.validate("/databases/1/items/2327251.m4a?session-id=11", 2, 1))
24
+ assert_equal("B287AD7370CE0F06325F477A591CE488",
25
+ proto.validate("/databases/1/items/2327271.mp3?session-id=11", 2, 2))
26
+ end
27
+
28
+ def test_v2
29
+ proto = Net::DAAP::DAAPv2.new
30
+ assert_equal("4FDEE34A22CDA1490A7577750AAF367C",
31
+ proto.validate("/content-codes", 2))
32
+ assert_equal("91DE0B5A5A0C0ACF43228778CC974397",
33
+ proto.validate("/server-info", 2))
34
+ assert_equal("84EF8C938B20B66F5D32FE560E7968ED",
35
+ proto.validate("/login", 2))
36
+ assert_equal("7ECA31ED40E5D4D481156CB6A324A2B7",
37
+ proto.validate("/databases?session-id=15", 2))
38
+ assert_equal("D64E9194DF3242B283944AEC337A4FB1",
39
+ proto.validate("/databases/1/items?type=music&meta=dmap.itemid,dmap.itemname,dmap.persistentid,daap.songalbum,daap.songartist,daap.songformat,daap.songsize&session-id=15", 2))
40
+ assert_equal("44D944FFF6045A1A89FAF91CDB894230",
41
+ proto.validate("/databases/1/containers?meta=dmap.itemid,dmap.itemname,dmap.persistentid,com.apple.itunes.smart-playlist&session-id=15", 2))
42
+ assert_equal("52CD3E871A06BBE4B9BC28B07A7D8F97",
43
+ proto.validate("/databases/1/items/2327251.m4a?session-id=15", 2))
44
+ assert_equal("D4973EACAD71DE9183EE431D74C8436A",
45
+ proto.validate("/databases/1/items/2327271.mp3?session-id=15", 2))
46
+ assert_equal("6DB9B14FAB5A7198B485349B40BB188A",
47
+ proto.validate("/logout?session-id=15", 2))
48
+ end
49
+ end
data/test/ts_daap.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ require 'test/unit'
4
+ require 'tc_client'
5
+ require 'tc_protocol'
6
+