daapclient 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +36 -0
- data/EXAMPLES +79 -0
- data/LICENSE +340 -0
- data/NOTES +33 -0
- data/README +7 -31
- data/lib/net/daap.rb +34 -20
- data/lib/net/daap/album.rb +16 -0
- data/lib/net/daap/artist.rb +16 -0
- data/lib/net/daap/daap_version.rb +7 -0
- data/lib/net/daap/database.rb +54 -27
- data/lib/net/daap/dmap.rb +13 -24
- data/lib/net/daap/playlist.rb +4 -5
- data/lib/net/daap/song.rb +10 -8
- data/test/data/mt-daapd/02dd88de4b3a69c74bcc56c1acca9ae5.txt +0 -0
- data/test/data/mt-daapd/0de583b288d8ae30f89acb26d4c8535b.txt +0 -0
- data/test/data/mt-daapd/4146ec82a0f0a638db9293a0c2039e6b.txt +0 -0
- data/test/data/mt-daapd/51a2a6f2a53743bec7e79fe0d074dd28.txt +0 -0
- data/test/data/mt-daapd/6069971903eef3c8c71ec2c7b395bfeb.txt +0 -0
- data/test/data/mt-daapd/{e9a8e709c2116651157182f130207048.txt → 7102a16e834342b8264f1fb5226690e5.txt} +0 -0
- data/test/data/mt-daapd/9d29fb31969da7757fa2f4baa3a52fe9.txt +0 -0
- data/test/data/mt-daapd/a52dd33cc99471cc156528c06b22e709.txt +0 -0
- data/test/data/mt-daapd/a600829e59b3d719b32f25323a2719b0.txt +0 -0
- data/test/data/mt-daapd/e2552df8d742fe31d6cc6e1e41e496b3.txt +0 -0
- data/test/data/mt-daapd/fc631aa54b83344df9ccf1fbaa7684b0.txt +0 -0
- data/test/data/song_data.txt +0 -0
- data/test/data/song_structure.txt +209 -0
- data/test/mock_server.rb +56 -0
- data/test/server_saver.rb +31 -0
- data/test/tc_artists.rb +33 -0
- data/test/tc_client.rb +47 -116
- data/test/tc_download.rb +29 -0
- data/test/tc_playlist.rb +37 -0
- data/test/tc_protocol.rb +3 -0
- data/test/test_daap.rb +23 -0
- data/test/ts_daap.rb +7 -0
- metadata +41 -97
- data/doc/classes/Net.html +0 -127
- data/doc/classes/Net/DAAP.html +0 -168
- data/doc/classes/Net/DAAP/Client.html +0 -269
- data/doc/classes/Net/DAAP/Client.src/M000003.html +0 -20
- data/doc/classes/Net/DAAP/Client.src/M000004.html +0 -28
- data/doc/classes/Net/DAAP/Client.src/M000005.html +0 -33
- data/doc/classes/Net/DAAP/Client.src/M000006.html +0 -37
- data/doc/classes/Net/DAAP/Client.src/M000007.html +0 -20
- data/doc/classes/Net/DAAP/Client.src/M000008.html +0 -24
- data/doc/classes/Net/DAAP/Client.src/M000009.html +0 -18
- data/doc/classes/Net/DAAP/DAAPv2.html +0 -165
- data/doc/classes/Net/DAAP/DAAPv2.src/M000016.html +0 -30
- data/doc/classes/Net/DAAP/DAAPv2.src/M000017.html +0 -21
- data/doc/classes/Net/DAAP/DAAPv3.html +0 -178
- data/doc/classes/Net/DAAP/DAAPv3.src/M000018.html +0 -30
- data/doc/classes/Net/DAAP/DAAPv3.src/M000019.html +0 -23
- data/doc/classes/Net/DAAP/DMAP.html +0 -176
- data/doc/classes/Net/DAAP/DMAP.src/M000013.html +0 -20
- data/doc/classes/Net/DAAP/DMAP.src/M000014.html +0 -18
- data/doc/classes/Net/DAAP/DMAP.src/M000015.html +0 -24
- data/doc/classes/Net/DAAP/Database.html +0 -224
- data/doc/classes/Net/DAAP/Database.src/M000010.html +0 -25
- data/doc/classes/Net/DAAP/Database.src/M000011.html +0 -21
- data/doc/classes/Net/DAAP/Database.src/M000012.html +0 -35
- data/doc/classes/Net/DAAP/Playlist.html +0 -192
- data/doc/classes/Net/DAAP/Playlist.src/M000001.html +0 -24
- data/doc/classes/Net/DAAP/Playlist.src/M000002.html +0 -30
- data/doc/classes/Net/DAAP/Song.html +0 -208
- data/doc/classes/Net/DAAP/Song.src/M000020.html +0 -27
- data/doc/classes/Net/DAAP/Song.src/M000021.html +0 -19
- data/doc/created.rid +0 -1
- data/doc/files/CHANGELOG.html +0 -134
- data/doc/files/LICENSE.html +0 -531
- data/doc/files/README.html +0 -182
- data/doc/files/lib/net/daap/database_rb.html +0 -101
- data/doc/files/lib/net/daap/dmap_rb.html +0 -101
- data/doc/files/lib/net/daap/playlist_rb.html +0 -101
- data/doc/files/lib/net/daap/song_rb.html +0 -101
- data/doc/files/lib/net/daap_rb.html +0 -114
- data/doc/fr_class_index.html +0 -35
- data/doc/fr_file_index.html +0 -34
- data/doc/fr_method_index.html +0 -47
- data/doc/index.html +0 -24
- data/doc/rdoc-style.css +0 -208
- data/lib/CVS/Entries +0 -1
- data/lib/CVS/Repository +0 -1
- data/lib/CVS/Root +0 -1
- data/lib/net/CVS/Entries +0 -2
- data/lib/net/CVS/Repository +0 -1
- data/lib/net/CVS/Root +0 -1
- data/lib/net/daap/CVS/Entries +0 -5
- data/lib/net/daap/CVS/Repository +0 -1
- data/lib/net/daap/CVS/Root +0 -1
- data/test/CVS/Entries +0 -4
- data/test/CVS/Repository +0 -1
- data/test/CVS/Root +0 -1
- data/test/data/CVS/Entries +0 -1
- data/test/data/CVS/Repository +0 -1
- data/test/data/CVS/Root +0 -1
- 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 +0 -11
- data/test/data/mt-daapd/CVS/Repository +0 -1
- data/test/data/mt-daapd/CVS/Root +0 -1
- 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/f9073959a0afacebfab7e3bf19c2714a.txt +0 -0
data/NOTES
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= Net::DAAP::Client Release Notes
|
2
|
+
|
3
|
+
== 0.2.0
|
4
|
+
|
5
|
+
Net::DAAP::Client has a newer, extended interface. In addition to the song
|
6
|
+
list that the database already contained, there is now a list of artists and
|
7
|
+
a list of albums that you can access from the database. The artists contain
|
8
|
+
all of the albums associated with that artists, and each album has all the songs
|
9
|
+
for that album. Each artist contains all songs by that artist as well.
|
10
|
+
|
11
|
+
For example, to access all songs by one artist, one could do this:
|
12
|
+
|
13
|
+
db.artists.find { |a| a.name == 'Radiohead' '}.songs.each { |s|
|
14
|
+
puts s.name
|
15
|
+
}
|
16
|
+
|
17
|
+
Or, to access all of Radiohead's albums, one could do this:
|
18
|
+
|
19
|
+
db.artists.find { |a| a.name == 'Radiohead' '}.albums.each { |a|
|
20
|
+
puts a.name
|
21
|
+
}
|
22
|
+
|
23
|
+
An exhaustive example can be seen in the EXAMPLES file.
|
24
|
+
|
25
|
+
This version of Net::DAAP::Client relies on digest-m4p which can be obtained
|
26
|
+
from the project page here[http://rubyforge.org/frs/?group_id=1155].
|
27
|
+
Unfortunately I can't get digest-m4p to build on Windows (I don't have a
|
28
|
+
windows machine), so for now digest-m4p only works on Linux and OS X.
|
29
|
+
Hopefully someone can send me a patch (hint hint).
|
30
|
+
|
31
|
+
Also, because of a bug in RubyGems, digest-m4p cannot be released as a gem
|
32
|
+
until I find a workaround, or the new version of RubyGems gets released.
|
33
|
+
|
data/README
CHANGED
@@ -3,18 +3,14 @@
|
|
3
3
|
This library is used for browsing iTunes DAAP servers.
|
4
4
|
|
5
5
|
Most of this is based off the work in the perl version by Richard Clamp which
|
6
|
-
can be found here
|
7
|
-
|
8
|
-
http://search.cpan.org/~rclamp/
|
6
|
+
can be found here[http://search.cpan.org/~rclamp/].
|
9
7
|
|
10
8
|
Ruby version is by Aaron Patterson <aaronp@rubyforge.org>
|
11
9
|
|
12
10
|
== Installation
|
13
11
|
|
14
12
|
Make sure that Digest::M4P is installed before using this package. Digest::M4P
|
15
|
-
is available on the daap client ruby forge site
|
16
|
-
|
17
|
-
http://rubyforge.org/frs/?group_id=1155
|
13
|
+
is available on the daap client ruby forge site here[http://rubyforge.org/frs/?group_id=1155].
|
18
14
|
|
19
15
|
Digest::M4P has not been turned in to a Ruby gem as of this writing.
|
20
16
|
|
@@ -22,33 +18,13 @@ After that, just install the gem:
|
|
22
18
|
|
23
19
|
sudo gem install daapclient
|
24
20
|
|
25
|
-
Also, check out the project page
|
26
|
-
|
27
|
-
http://rubyforge.org/projects/daapclient
|
21
|
+
Also, check out the project page here[http://rubyforge.org/projects/daapclient].
|
28
22
|
|
29
23
|
== Example Usage
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
daap = Net::DAAP::Client.new('localhost')
|
35
|
-
|
36
|
-
daap.connect do |dsn|
|
37
|
-
daap.databases do |db|
|
38
|
-
puts "All songs in the database"
|
39
|
-
db.songs do |song|
|
40
|
-
filename = "#{song.artist} - #{song.name}.#{song.format}"
|
41
|
-
directory = "db/#{song.album}"
|
42
|
-
FileUtils::mkdir_p(directory)
|
43
|
-
|
44
|
-
File.open("#{directory}/#{filename}", "w") do |f|
|
45
|
-
song.get { |str| f.write str }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
== Acknowledgements
|
25
|
+
See the EXAMPLES[link://files/EXAMPLES.html] file
|
26
|
+
|
27
|
+
== Acknowledgments
|
52
28
|
|
53
29
|
The library is mostly a port of the Perl library, and owes most of its
|
54
30
|
communication logic to the original Perl version by Richard Clamp.
|
@@ -62,5 +38,5 @@ favorite language! ;-)
|
|
62
38
|
|
63
39
|
== License
|
64
40
|
|
65
|
-
This library is distributed under the GPL. Please see the LICENSE file.
|
41
|
+
This library is distributed under the GPL. Please see the LICENSE[link://files/LICENSE.html] file.
|
66
42
|
|
data/lib/net/daap.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'digest/m4p'
|
3
3
|
require 'digest/md5'
|
4
|
+
require 'logger'
|
4
5
|
require 'net/daap/dmap'
|
6
|
+
require 'net/daap/artist'
|
7
|
+
require 'net/daap/album'
|
5
8
|
require 'net/daap/song'
|
6
9
|
require 'net/daap/playlist'
|
7
10
|
require 'net/daap/database'
|
11
|
+
require 'net/daap/daap_version'
|
8
12
|
|
9
13
|
|
10
14
|
module Net
|
@@ -46,22 +50,29 @@ module Net
|
|
46
50
|
# and each Database can have many Playlist, and many Song. See DAAP for a
|
47
51
|
# code example.
|
48
52
|
class Client
|
53
|
+
attr_accessor :log
|
49
54
|
attr_reader :dmap
|
50
55
|
|
51
56
|
# Create a new Client and pass in the host where the client will connect.
|
52
57
|
def initialize(server_host)
|
53
58
|
@server_host = server_host
|
54
59
|
@server_port = 3689
|
55
|
-
@
|
60
|
+
@validator = nil
|
61
|
+
@log = Logger.new(nil)
|
62
|
+
@session_id = nil
|
63
|
+
@request_id = nil
|
64
|
+
yield self if block_given?
|
56
65
|
end
|
57
66
|
|
58
67
|
# Connects to the iTunes server. This method should be called right after
|
59
68
|
# construction. See DAAP for an example.
|
60
69
|
def connect
|
70
|
+
@log.info("Connecting to #{@server_host}:#{@server_port}")
|
61
71
|
@http_client = Net::HTTP.start(@server_host, @server_port)
|
62
72
|
find_validator
|
63
73
|
@dmap = Net::DAAP::DMAP.new(:daap => self)
|
64
74
|
load_server_info
|
75
|
+
@log.info("Now connected")
|
65
76
|
@connected = 1
|
66
77
|
if block_given?
|
67
78
|
yield @dsn
|
@@ -73,15 +84,18 @@ module Net
|
|
73
84
|
|
74
85
|
# Returns the databases found on the iTunes server.
|
75
86
|
def databases
|
76
|
-
|
87
|
+
unless @connected
|
88
|
+
errstr = "Not connected, can't fetch databases"
|
89
|
+
@log.error(errstr)
|
90
|
+
raise errstr
|
91
|
+
end
|
77
92
|
|
78
93
|
listings = @dmap.find(do_get("databases"),
|
79
94
|
"daap.serverdatabases/dmap.listing")
|
80
95
|
# FIXME check the value of listing
|
81
96
|
@databases = []
|
82
97
|
unpack_listing(listings) do |value|
|
83
|
-
db = Database.new(
|
84
|
-
:daap => self )
|
98
|
+
db = Database.new( value.merge(:daap => self) )
|
85
99
|
if block_given?
|
86
100
|
yield db
|
87
101
|
else
|
@@ -92,19 +106,20 @@ module Net
|
|
92
106
|
end
|
93
107
|
|
94
108
|
def do_get(request, &block)
|
95
|
-
debug("do_get")
|
109
|
+
@log.debug("do_get called")
|
96
110
|
url = String.new('/' + request)
|
97
111
|
if @session_id
|
98
112
|
url += url =~ /\?/ ? "&" : "?"
|
99
113
|
url += "session-id=#{@session_id}"
|
100
114
|
end
|
101
115
|
|
102
|
-
if @revision && request != "logout"
|
103
|
-
|
104
|
-
end
|
105
|
-
debug(url)
|
116
|
+
#if @revision && request != "logout"
|
117
|
+
# url += "&revision-number=#{@revision}"
|
118
|
+
#end
|
119
|
+
@log.debug("Fetching url: #{url}")
|
106
120
|
|
107
121
|
res = @http_client.get(url, request_headers(url), nil, &block)
|
122
|
+
@log.debug("Done Fetching url: #{url}")
|
108
123
|
|
109
124
|
content_type = res.header['content-type']
|
110
125
|
if request !~ /(?:\/items\/\d+\.|logout)/ && content_type !~ /dmap/
|
@@ -115,8 +130,8 @@ module Net
|
|
115
130
|
end
|
116
131
|
|
117
132
|
def get_song(request, &block)
|
118
|
-
@
|
119
|
-
@request_id
|
133
|
+
@log.debug("Downloading a song")
|
134
|
+
@request_id = @request_id.nil? ? 2 : @request_id + 1
|
120
135
|
do_get(request, &block)
|
121
136
|
end
|
122
137
|
|
@@ -132,17 +147,19 @@ module Net
|
|
132
147
|
|
133
148
|
# Disconnects from the DAAP server
|
134
149
|
def disconnect
|
150
|
+
@log.info("Disconnecting")
|
135
151
|
do_get("logout")
|
136
152
|
end
|
153
|
+
|
137
154
|
private
|
138
155
|
def load_server_info
|
139
156
|
flat_list = @dmap.flat_list(do_get("server-info"))
|
140
157
|
@dsn = flat_list['/dmap.serverinforesponse/dmap.itemname']
|
141
158
|
|
142
|
-
debug("Connected to share '#{@dsn}'")
|
159
|
+
@log.debug("Connected to share '#{@dsn}'")
|
143
160
|
@session_id = @dmap.find(do_get("login"),
|
144
161
|
"dmap.loginresponse/dmap.sessionid")
|
145
|
-
debug("My id is #{@session_id}")
|
162
|
+
@log.debug("My id is #{@session_id}")
|
146
163
|
@dsn
|
147
164
|
end
|
148
165
|
|
@@ -157,23 +174,20 @@ module Net
|
|
157
174
|
headers
|
158
175
|
end
|
159
176
|
|
177
|
+
# Figure out what protocol version to use
|
160
178
|
def find_validator
|
179
|
+
@log.info("Determining DAAP version")
|
161
180
|
res = @http_client.get('/server-info')
|
162
181
|
server = res.header['daap-server']
|
163
182
|
|
164
183
|
if server =~ /^iTunes\/4.2/
|
165
184
|
@validator = DAAPv2.new
|
185
|
+
@log.info("Found DAAPv2")
|
166
186
|
end
|
167
187
|
|
168
188
|
if server =~ /^iTunes/
|
169
189
|
@validator = DAAPv3.new
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
def debug(message)
|
174
|
-
if @debug == 1
|
175
|
-
print "DEBUG: "
|
176
|
-
p message
|
190
|
+
@log.info("Found DAAPv3")
|
177
191
|
end
|
178
192
|
end
|
179
193
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Net
|
2
|
+
module DAAP
|
3
|
+
# This class contains album information returned from the DAAP server.
|
4
|
+
class Album
|
5
|
+
attr_reader :name, :artist, :songs
|
6
|
+
|
7
|
+
alias :to_s :name
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@name = args[:name] || args['daap.songalbum']
|
11
|
+
@artist = args[:artist]
|
12
|
+
@songs = []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Net
|
2
|
+
module DAAP
|
3
|
+
# This class contains artist information returned from the DAAP server.
|
4
|
+
class Artist
|
5
|
+
attr_reader :name, :albums, :songs
|
6
|
+
|
7
|
+
alias :to_s :name
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@name = args[:name] || args['daap.songartist']
|
11
|
+
@albums = []
|
12
|
+
@songs = []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/net/daap/database.rb
CHANGED
@@ -1,30 +1,39 @@
|
|
1
|
+
class Module
|
2
|
+
def attr_blockreader(*syms)
|
3
|
+
syms.each do |sym|
|
4
|
+
class_eval %{ def #{sym.to_s}
|
5
|
+
if block_given?
|
6
|
+
@#{sym.to_s}.each \{ |s| yield s \}
|
7
|
+
end
|
8
|
+
@#{sym.to_s}
|
9
|
+
end
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
1
15
|
module Net
|
2
16
|
module DAAP
|
3
17
|
# This class contains a database found on an iTunes server.
|
4
18
|
class Database
|
5
19
|
attr_reader :persistentid, :name, :containercount, :id, :itemcount
|
6
|
-
|
20
|
+
attr_blockreader :songs, :artists, :albums
|
21
|
+
|
7
22
|
@@SONG_ATTRIBUTES = %w{ dmap.itemid dmap.itemname dmap.persistentid
|
8
23
|
daap.songalbum daap.songartist daap.songformat
|
9
24
|
daap.songsize }
|
10
25
|
|
11
26
|
def initialize(args)
|
12
|
-
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@itemcount = info['dmap.itemcount']
|
27
|
+
@persistentid = args['dmap.persistentid']
|
28
|
+
@name = args['dmap.itemname']
|
29
|
+
@containercount = args['dmap.containercount']
|
30
|
+
@id = args['dmap.itemid']
|
31
|
+
@itemcount = args['dmap.itemcount']
|
18
32
|
@daap = args[:daap]
|
19
|
-
@songs =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def songs
|
24
|
-
if block_given?
|
25
|
-
@songs.each { |s| yield s }
|
26
|
-
end
|
27
|
-
@songs
|
33
|
+
@songs = []
|
34
|
+
@artists = []
|
35
|
+
@albums = []
|
36
|
+
load_songs
|
28
37
|
end
|
29
38
|
|
30
39
|
# Returns the playlists associated with this database
|
@@ -36,14 +45,13 @@ module Net
|
|
36
45
|
|
37
46
|
playlists = []
|
38
47
|
@daap.unpack_listing(listings) do |value|
|
48
|
+
playlist = Playlist.new( value.merge(
|
49
|
+
:daap => @daap,
|
50
|
+
:db => self ))
|
39
51
|
if block_given?
|
40
|
-
yield
|
41
|
-
:daap => @daap,
|
42
|
-
:db => self )
|
52
|
+
yield playlist
|
43
53
|
else
|
44
|
-
playlists <<
|
45
|
-
:daap => @daap,
|
46
|
-
:db => self )
|
54
|
+
playlists << playlist
|
47
55
|
end
|
48
56
|
end
|
49
57
|
playlists
|
@@ -56,13 +64,32 @@ module Net
|
|
56
64
|
|
57
65
|
listings = @daap.dmap.find(@daap.do_get(path),
|
58
66
|
"daap.databasesongs/dmap.listing")
|
59
|
-
|
67
|
+
artist_hash = {}
|
68
|
+
album_hash = {}
|
60
69
|
@daap.unpack_listing(listings) do |value|
|
61
|
-
|
62
|
-
|
63
|
-
|
70
|
+
artist = artist_hash[value['daap.songartist']] ||= Artist.new(value)
|
71
|
+
album = album_hash[value['daap.songalbum']] ||= Album.new(
|
72
|
+
:name => value['daap.songalbum'],
|
73
|
+
:artist => artist )
|
74
|
+
|
75
|
+
song = Song.new( value.merge(
|
76
|
+
:daap => @daap,
|
77
|
+
:db => self,
|
78
|
+
:artist => artist,
|
79
|
+
:album => album))
|
80
|
+
|
81
|
+
album.songs << song
|
82
|
+
artist.songs << song
|
83
|
+
@songs << song
|
64
84
|
end
|
65
|
-
|
85
|
+
|
86
|
+
# Add each album to its artist
|
87
|
+
album_hash.each_value do |value|
|
88
|
+
value.artist.albums << value
|
89
|
+
@albums << value
|
90
|
+
end
|
91
|
+
|
92
|
+
artist_hash.each_value { |v| @artists << v }
|
66
93
|
end
|
67
94
|
end
|
68
95
|
end
|
data/lib/net/daap/dmap.rb
CHANGED
@@ -4,8 +4,9 @@ module Net
|
|
4
4
|
# structures.
|
5
5
|
class DMAP
|
6
6
|
def initialize(args)
|
7
|
-
@daap
|
8
|
-
|
7
|
+
@daap = args[:daap]
|
8
|
+
@big_endian = "Ruby".unpack("i")[0] != 2036495698 ? true : false
|
9
|
+
@type_to_unpack = find_type
|
9
10
|
update_content_codes
|
10
11
|
end
|
11
12
|
|
@@ -24,9 +25,9 @@ module Net
|
|
24
25
|
end
|
25
26
|
|
26
27
|
private
|
27
|
-
def
|
28
|
+
def find_type
|
28
29
|
types = nil
|
29
|
-
if big_endian
|
30
|
+
if @big_endian
|
30
31
|
types = {
|
31
32
|
1 => 'c',
|
32
33
|
3 => 'S',
|
@@ -52,11 +53,6 @@ module Net
|
|
52
53
|
types
|
53
54
|
end
|
54
55
|
|
55
|
-
def big_endian?
|
56
|
-
return @big_endian if @big_endian
|
57
|
-
@big_endian = "Ruby".unpack("i")[0] != 2036495698 ? true : false
|
58
|
-
end
|
59
|
-
|
60
56
|
def update_content_codes
|
61
57
|
content_codes = unpack(@daap.do_get("content-codes"))
|
62
58
|
mccr = seek(content_codes, "dmap.contentcodesresponse")
|
@@ -70,10 +66,8 @@ module Net
|
|
70
66
|
end
|
71
67
|
type = 9 if id == 'mcnm'
|
72
68
|
type = 42 if id == 'pfdt'
|
73
|
-
|
69
|
+
@@types[id] = { 'NAME' => name, 'ID' => id, 'TYPE' => type }
|
74
70
|
end
|
75
|
-
#@types = short
|
76
|
-
@types
|
77
71
|
end
|
78
72
|
|
79
73
|
def flat_list_traverse(struct, list = [], prefix = '')
|
@@ -94,12 +88,10 @@ module Net
|
|
94
88
|
def unpack(buffer = nil)
|
95
89
|
tags = []
|
96
90
|
|
97
|
-
buffer = @code unless buffer
|
98
|
-
|
99
91
|
while(buffer.length > 0)
|
100
92
|
tag, len = nil, nil
|
101
93
|
|
102
|
-
if big_endian
|
94
|
+
if @big_endian
|
103
95
|
tag, len = buffer.unpack("a4L")
|
104
96
|
else
|
105
97
|
tag, len = buffer.unpack("a4N")
|
@@ -109,22 +101,22 @@ module Net
|
|
109
101
|
|
110
102
|
buffer[0...8+len] = ''
|
111
103
|
|
112
|
-
type =
|
104
|
+
type = @@types[tag]['TYPE']
|
113
105
|
|
114
106
|
if type == 12
|
115
107
|
data = unpack(data)
|
116
108
|
elsif type == 7
|
117
|
-
n1, n2 = big_endian
|
109
|
+
n1, n2 = @big_endian ? data.unpack("L2") : data.unpack("N2")
|
118
110
|
data = n1 << 32
|
119
111
|
data += n2
|
120
112
|
else
|
121
|
-
data = data.unpack(type_to_unpack
|
113
|
+
data = data.unpack(@type_to_unpack[type])
|
122
114
|
end
|
123
115
|
|
124
116
|
if data.class == Array && data.length == 1 && data[0].class != Array || type == 11
|
125
|
-
tmp = [
|
117
|
+
tmp = [ @@types[tag]['NAME'], data[0]]
|
126
118
|
else
|
127
|
-
tmp = [
|
119
|
+
tmp = [ @@types[tag]['NAME'], data]
|
128
120
|
end
|
129
121
|
|
130
122
|
tags << tmp
|
@@ -148,9 +140,7 @@ module Net
|
|
148
140
|
return struct
|
149
141
|
end
|
150
142
|
|
151
|
-
|
152
|
-
def load_types
|
153
|
-
@types =
|
143
|
+
@@types =
|
154
144
|
{
|
155
145
|
'abal' => {
|
156
146
|
'ID' => 'abal',
|
@@ -598,7 +588,6 @@ module Net
|
|
598
588
|
'TYPE' => 11
|
599
589
|
}
|
600
590
|
}
|
601
|
-
end
|
602
591
|
end
|
603
592
|
end
|
604
593
|
end
|