daapclient 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +63 -0
- data/doc/classes/Net/DAAP/Client.html +251 -0
- data/doc/classes/Net/DAAP/Client.src/M000003.html +20 -0
- data/doc/classes/Net/DAAP/Client.src/M000004.html +25 -0
- data/doc/classes/Net/DAAP/Client.src/M000005.html +33 -0
- data/doc/classes/Net/DAAP/Client.src/M000006.html +37 -0
- data/doc/classes/Net/DAAP/Client.src/M000007.html +20 -0
- data/doc/classes/Net/DAAP/Client.src/M000008.html +24 -0
- data/doc/classes/Net/DAAP/DAAPv2.html +165 -0
- data/doc/classes/Net/DAAP/DAAPv2.src/M000015.html +30 -0
- data/doc/classes/Net/DAAP/DAAPv2.src/M000016.html +21 -0
- data/doc/classes/Net/DAAP/DAAPv3.html +178 -0
- data/doc/classes/Net/DAAP/DAAPv3.src/M000017.html +30 -0
- data/doc/classes/Net/DAAP/DAAPv3.src/M000018.html +23 -0
- data/doc/classes/Net/DAAP/DMAP.html +189 -0
- data/doc/classes/Net/DAAP/DMAP.src/M000012.html +20 -0
- data/doc/classes/Net/DAAP/DMAP.src/M000013.html +18 -0
- data/doc/classes/Net/DAAP/DMAP.src/M000014.html +24 -0
- data/doc/classes/Net/DAAP/Database.html +224 -0
- data/doc/classes/Net/DAAP/Database.src/M000009.html +25 -0
- data/doc/classes/Net/DAAP/Database.src/M000010.html +21 -0
- data/doc/classes/Net/DAAP/Database.src/M000011.html +35 -0
- data/doc/classes/Net/DAAP/Playlist.html +192 -0
- data/doc/classes/Net/DAAP/Playlist.src/M000001.html +24 -0
- data/doc/classes/Net/DAAP/Playlist.src/M000002.html +30 -0
- data/doc/classes/Net/DAAP/Song.html +208 -0
- data/doc/classes/Net/DAAP/Song.src/M000019.html +27 -0
- data/doc/classes/Net/DAAP/Song.src/M000020.html +19 -0
- data/doc/classes/Net/DAAP.html +168 -0
- data/doc/classes/Net.html +127 -0
- data/doc/created.rid +1 -0
- data/doc/files/CHANGELOG.html +110 -0
- data/doc/files/LICENSE.html +531 -0
- data/doc/files/README.html +176 -0
- data/doc/files/lib/net/daap/database_rb.html +101 -0
- data/doc/files/lib/net/daap/dmap_rb.html +101 -0
- data/doc/files/lib/net/daap/playlist_rb.html +101 -0
- data/doc/files/lib/net/daap/song_rb.html +101 -0
- data/doc/files/lib/net/daap_rb.html +114 -0
- data/doc/fr_class_index.html +35 -0
- data/doc/fr_file_index.html +34 -0
- data/doc/fr_method_index.html +46 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/CVS/Entries +1 -0
- data/lib/CVS/Repository +1 -0
- data/lib/CVS/Root +1 -0
- data/lib/net/CVS/Entries +2 -0
- data/lib/net/CVS/Repository +1 -0
- data/lib/net/CVS/Root +1 -0
- data/lib/net/daap/CVS/Entries +5 -0
- data/lib/net/daap/CVS/Repository +1 -0
- data/lib/net/daap/CVS/Root +1 -0
- data/lib/net/daap/database.rb +69 -0
- data/lib/net/daap/dmap.rb +575 -0
- data/lib/net/daap/playlist.rb +36 -0
- data/lib/net/daap/song.rb +27 -0
- data/lib/net/daap.rb +234 -0
- data/test/CVS/Entries +4 -0
- data/test/CVS/Repository +1 -0
- data/test/CVS/Root +1 -0
- data/test/data/CVS/Entries +1 -0
- data/test/data/CVS/Repository +1 -0
- data/test/data/CVS/Root +1 -0
- data/test/data/mt-daapd/079aca35773150da9fd98db10c7fd0c0.txt +0 -0
- data/test/data/mt-daapd/2972f65088b42a06b5d3ca089d71791d.txt +0 -0
- data/test/data/mt-daapd/440c2217e6207c54c317c296f71f9769.txt +0 -0
- data/test/data/mt-daapd/4d1ce9f941cbd823ed06f1f1baa5a3b9.txt +0 -0
- data/test/data/mt-daapd/7bded8b540fd082f102d25e181b47bc4.txt +0 -0
- data/test/data/mt-daapd/CVS/Entries +11 -0
- data/test/data/mt-daapd/CVS/Repository +1 -0
- data/test/data/mt-daapd/CVS/Root +1 -0
- data/test/data/mt-daapd/b3e894b87111bdba88e4765967f4b45a.txt +0 -0
- data/test/data/mt-daapd/d56b699830e77ba53855679cb1d252da.txt +0 -0
- data/test/data/mt-daapd/e61ce3062cb76770658896b778ad06cd.txt +0 -0
- data/test/data/mt-daapd/e9a8e709c2116651157182f130207048.txt +0 -0
- data/test/data/mt-daapd/f9073959a0afacebfab7e3bf19c2714a.txt +0 -0
- data/test/tc_client.rb +148 -0
- data/test/tc_protocol.rb +49 -0
- data/test/ts_daap.rb +6 -0
- 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
data/test/CVS/Repository
ADDED
@@ -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
|
data/test/data/CVS/Root
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
:ext:aaronp@rubyforge.org:/var/cvs/daapclient
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -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
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
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
|
data/test/tc_protocol.rb
ADDED
@@ -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
|