dacpclient 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -1
- data/Gemfile +0 -9
- data/README.md +24 -0
- data/Rakefile +1 -1
- data/bin/dacpclient +61 -6
- data/dacpclient.gemspec +6 -1
- data/lib/dacpclient/bonjour.rb +43 -0
- data/lib/dacpclient/client.rb +112 -53
- data/lib/dacpclient/dmapbuilder.rb +20 -18
- data/lib/dacpclient/dmapconverter.rb +60 -7
- data/lib/dacpclient/dmapparser.rb +29 -75
- data/lib/dacpclient/pairingserver.rb +33 -34
- data/lib/dacpclient/tag.rb +21 -0
- data/lib/dacpclient/tag_container.rb +49 -0
- data/lib/dacpclient/tag_definition.rb +29 -0
- data/lib/dacpclient/tag_definitions.rb +167 -0
- data/lib/dacpclient/version.rb +2 -2
- data/lib/dacpclient.rb +1 -1
- metadata +79 -5
- data/lib/dacpclient/tagdefinitions.rb +0 -264
@@ -1,264 +0,0 @@
|
|
1
|
-
module DACPClient
|
2
|
-
module DMAPParser
|
3
|
-
|
4
|
-
Tag = Struct.new(:type, :value) do
|
5
|
-
def inspect(level = 0)
|
6
|
-
"#{' ' * level}#{type}: #{value}"
|
7
|
-
end
|
8
|
-
|
9
|
-
def to_dmap
|
10
|
-
value = self.value
|
11
|
-
value = case type.type
|
12
|
-
when :container
|
13
|
-
value.reduce('') { |a, e| a += e.to_dmap }
|
14
|
-
when :byte
|
15
|
-
DMAPConverter.byte_to_bin value
|
16
|
-
when :uint16, :short
|
17
|
-
DMAPConverter.short_to_bin value
|
18
|
-
when :uint32
|
19
|
-
DMAPConverter.int_to_bin value
|
20
|
-
when :uint64
|
21
|
-
DMAPConverter.long_to_bin value
|
22
|
-
when :bool
|
23
|
-
DMAPConverter.bool_to_bin value
|
24
|
-
when :hex
|
25
|
-
DMAPConverter.hex_to_bin value
|
26
|
-
when :string
|
27
|
-
value
|
28
|
-
when :date
|
29
|
-
DMAPConverter.int_to_bin value.to_i
|
30
|
-
when :version
|
31
|
-
DMAPConverter.version_to_bin value.to_i
|
32
|
-
else
|
33
|
-
warn "Unknown type #{tag.type}"
|
34
|
-
# Tag.new tag, parseunknown(data)
|
35
|
-
value
|
36
|
-
end
|
37
|
-
type.tag.to_s + [value.length].pack('N') + value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# The TagContainer class is a Tag which contains other Tags
|
42
|
-
class TagContainer < Tag
|
43
|
-
def initialize(type = nil, value = [])
|
44
|
-
super type, value
|
45
|
-
end
|
46
|
-
|
47
|
-
def inspect(level = 0)
|
48
|
-
"#{' ' * level}#{type}:\n" + value.reduce('') do |a, e|
|
49
|
-
a + e.inspect(level + 1).chomp + "\n"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def get_value(key)
|
54
|
-
if key.is_a? Fixnum
|
55
|
-
return value[key]
|
56
|
-
end
|
57
|
-
key = key.to_s
|
58
|
-
val = value.find { |e| e.type.tag == key }
|
59
|
-
val = value.find { |e| e.type.name == key } if val.nil?
|
60
|
-
|
61
|
-
if val.type.type == :container
|
62
|
-
val
|
63
|
-
elsif !val.nil?
|
64
|
-
val.value
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
alias_method :[], :get_value
|
69
|
-
|
70
|
-
def has?(key)
|
71
|
-
key = key.to_s
|
72
|
-
val = value.find { |e| e.type.tag == key }
|
73
|
-
val = value.find { |e| e.type.name == key } if val.nil?
|
74
|
-
!val.nil?
|
75
|
-
end
|
76
|
-
|
77
|
-
def method_missing(method, *arguments, &block)
|
78
|
-
get_value(method.to_s)
|
79
|
-
end
|
80
|
-
|
81
|
-
def to_a
|
82
|
-
value
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
TagDefinition = Struct.new(:tag, :type, :name) do
|
87
|
-
def inspect
|
88
|
-
"#{tag} (#{name}: #{type})"
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_s
|
92
|
-
"#{tag} (#{name}: #{type})"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Sources:
|
97
|
-
# https://github.com/chendo/dmap-ng/blob/master/lib/dmap/tag_definitions.rb
|
98
|
-
# https://code.google.com/p/ytrack/wiki/DMAP
|
99
|
-
# https://code.google.com/p/tunesremote-se/wiki/ContentCodes
|
100
|
-
# https://raw.github.com/mattstevens/dmap-parser/master/dmap_parser.c
|
101
|
-
# /content-codes
|
102
|
-
Types = [
|
103
|
-
TagDefinition.new('mcon', :container, 'dmap.container'),
|
104
|
-
TagDefinition.new('msrv', :container, 'dmap.serverinforesponse'),
|
105
|
-
TagDefinition.new('msml', :container, 'dmap.msml'),
|
106
|
-
TagDefinition.new('mccr', :container, 'dmap.contentcodesresponse'),
|
107
|
-
TagDefinition.new('mdcl', :container, 'dmap.dictionary'),
|
108
|
-
TagDefinition.new('mlog', :container, 'dmap.loginresponse'),
|
109
|
-
TagDefinition.new('mupd', :container, 'dmap.updateresponse'),
|
110
|
-
TagDefinition.new('avdb', :container, 'daap.serverdatabases'),
|
111
|
-
TagDefinition.new('mlcl', :container, 'dmap.listing'),
|
112
|
-
TagDefinition.new('mlit', :container, 'dmap.listingitem'),
|
113
|
-
TagDefinition.new('mbcl', :container, 'dmap.bag'),
|
114
|
-
TagDefinition.new('adbs', :container, 'daap.returndatabasesongs'),
|
115
|
-
TagDefinition.new('aply', :container, 'daap.databaseplaylists'),
|
116
|
-
TagDefinition.new('apso', :container, 'daap.playlistsongs'),
|
117
|
-
TagDefinition.new('mudl', :container, 'dmap.deletedidlisting'),
|
118
|
-
TagDefinition.new('abro', :container, 'daap.databasebrowse'),
|
119
|
-
TagDefinition.new('abal', :container, 'daap.browsealbumlisting'),
|
120
|
-
TagDefinition.new('abar', :container, 'daap.browseartistlisting'),
|
121
|
-
TagDefinition.new('abcp', :container, 'daap.browsecomposerlisting'),
|
122
|
-
TagDefinition.new('abgn', :container, 'daap.browsegenrelisting'),
|
123
|
-
TagDefinition.new('prsv', :container, 'daap.resolve'),
|
124
|
-
TagDefinition.new('arif', :container, 'daap.resolveinfo'),
|
125
|
-
TagDefinition.new('casp', :container, 'dacp.speakers'),
|
126
|
-
TagDefinition.new('caci', :container, 'dacp.controlint'),
|
127
|
-
TagDefinition.new('cmpa', :container, 'dacp.pairinganswer'),
|
128
|
-
TagDefinition.new('cacr', :container, 'dacp.cacr'),
|
129
|
-
TagDefinition.new('cmcp', :container, 'dmcp.controlprompt'),
|
130
|
-
TagDefinition.new('cmgt', :container, 'dmcp.getpropertyresponse'),
|
131
|
-
TagDefinition.new('cmst', :container, 'dmcp.status'),
|
132
|
-
TagDefinition.new('agal', :container, 'daap.albumgrouping'),
|
133
|
-
TagDefinition.new('minm', :string, 'dmap.itemname'),
|
134
|
-
TagDefinition.new('msts', :string, 'dmap.statusstring'),
|
135
|
-
TagDefinition.new('mcna', :string, 'dmap.contentcodesname'),
|
136
|
-
TagDefinition.new('asal', :string, 'daap.songalbum'),
|
137
|
-
TagDefinition.new('asaa', :string, 'daap.songalbumartist'),
|
138
|
-
TagDefinition.new('asar', :string, 'daap.songartist'),
|
139
|
-
TagDefinition.new('ascm', :string, 'daap.songcomment'),
|
140
|
-
TagDefinition.new('asfm', :string, 'daap.songformat'),
|
141
|
-
TagDefinition.new('aseq', :string, 'daap.songeqpreset'),
|
142
|
-
TagDefinition.new('asgn', :string, 'daap.songgenre'),
|
143
|
-
TagDefinition.new('asdt', :string, 'daap.songdescription'),
|
144
|
-
TagDefinition.new('asul', :string, 'daap.songdataurl'),
|
145
|
-
TagDefinition.new('ceWM', :string, 'com.apple.itunes.welcome-message'),
|
146
|
-
TagDefinition.new('ascp', :string, 'daap.songcomposer'),
|
147
|
-
TagDefinition.new('assu', :string, 'daap.sortartist'),
|
148
|
-
TagDefinition.new('assa', :string, 'daap.sortalbum'),
|
149
|
-
TagDefinition.new('agrp', :string, 'daap.songgrouping'),
|
150
|
-
TagDefinition.new('cann', :string, 'daap.nowplayingtrack'),
|
151
|
-
TagDefinition.new('cana', :string, 'daap.nowplayingartist'),
|
152
|
-
TagDefinition.new('canl', :string, 'daap.nowplayingalbum'),
|
153
|
-
TagDefinition.new('cang', :string, 'daap.nowplayinggenre'),
|
154
|
-
TagDefinition.new('cmnm', :string, 'dacp.devicename'),
|
155
|
-
TagDefinition.new('cmty', :string, 'dacp.devicetype'),
|
156
|
-
TagDefinition.new('cmpg', :hex, 'dacp.pairingguid'), # hex string
|
157
|
-
TagDefinition.new('mper', :uint64, 'dmap.persistentid'),
|
158
|
-
TagDefinition.new('canp', :uint64, 'dacp.nowplaying'),
|
159
|
-
TagDefinition.new('cmpy', :uint64, 'dacp.passguid'),
|
160
|
-
TagDefinition.new('mstt', :uint32, 'dmap.status'), # http status??
|
161
|
-
TagDefinition.new('mcnm', :uint32, 'dmap.contentcodesnumber'),
|
162
|
-
TagDefinition.new('miid', :uint32, 'dmap.itemid'),
|
163
|
-
TagDefinition.new('mcti', :uint32, 'dmap.containeritemid'),
|
164
|
-
TagDefinition.new('mpco', :uint32, 'dmap.parentcontainerid'),
|
165
|
-
TagDefinition.new('mimc', :uint32, 'dmap.itemcount'),
|
166
|
-
TagDefinition.new('mrco', :uint32, 'dmap.returnedcount'),
|
167
|
-
TagDefinition.new('mtco', :uint32, 'dmap.containercount'),
|
168
|
-
TagDefinition.new('mstm', :uint32, 'dmap.timeoutinterval'),
|
169
|
-
TagDefinition.new('msdc', :uint32, 'dmap.databasescount'),
|
170
|
-
TagDefinition.new('msma', :uint32, 'dmap.speakermachineaddress'),
|
171
|
-
TagDefinition.new('mlid', :uint32, 'dmap.sessionid'),
|
172
|
-
TagDefinition.new('assr', :uint32, 'daap.songsamplerate'),
|
173
|
-
TagDefinition.new('assz', :uint32, 'daap.songsize'),
|
174
|
-
TagDefinition.new('asst', :uint32, 'daap.songstarttime'),
|
175
|
-
TagDefinition.new('assp', :uint32, 'daap.songstoptime'),
|
176
|
-
TagDefinition.new('astm', :uint32, 'daap.songtime'),
|
177
|
-
TagDefinition.new('msto', :uint32, 'dmap.utcoffset'),
|
178
|
-
TagDefinition.new('cmsr', :uint32, 'dmcp.mediarevision'),
|
179
|
-
TagDefinition.new('caas', :uint32, 'dacp.albumshuffle'),
|
180
|
-
TagDefinition.new('caar', :uint32, 'dacp.albumrepeat'),
|
181
|
-
TagDefinition.new('cant', :uint32, 'dacp.remainingtime'),
|
182
|
-
TagDefinition.new('cmmk', :uint32, 'dmcp.mediakind'),
|
183
|
-
TagDefinition.new('cast', :uint32, 'dacp.tracklength'),
|
184
|
-
TagDefinition.new('asai', :uint32, 'daap.songalbumid'),
|
185
|
-
TagDefinition.new('aeNV', :uint32, 'com.apple.itunes.norm-volume'),
|
186
|
-
TagDefinition.new('cmvo', :uint32, 'dmcp.volume'),
|
187
|
-
TagDefinition.new('mcty', :uint16, 'dmap.contentcodestype'),
|
188
|
-
TagDefinition.new('asbt', :uint16, 'daap.songsbeatsperminute'),
|
189
|
-
TagDefinition.new('asbr', :uint16, 'daap.songbitrate'),
|
190
|
-
TagDefinition.new('asdc', :uint16, 'daap.songdisccount'),
|
191
|
-
TagDefinition.new('asdn', :uint16, 'daap.songdiscnumber'),
|
192
|
-
TagDefinition.new('astc', :uint16, 'daap.songtrackcount'),
|
193
|
-
TagDefinition.new('astn', :uint16, 'daap.songtracknumber'),
|
194
|
-
TagDefinition.new('asyr', :uint16, 'daap.songyear'),
|
195
|
-
TagDefinition.new('ated', :uint16, 'daap.supportsextradata'),
|
196
|
-
TagDefinition.new('asgr', :uint16, 'daap.supportsgroups'),
|
197
|
-
TagDefinition.new('mikd', :byte, 'dmap.itemkind'),
|
198
|
-
TagDefinition.new('casu', :byte, 'dacp.su'),
|
199
|
-
TagDefinition.new('msau', :byte, 'dmap.authenticationmethod'),
|
200
|
-
TagDefinition.new('mstu', :byte, 'dmap.updatetype'),
|
201
|
-
TagDefinition.new('asrv', :byte, 'daap.songrelativevolume'),
|
202
|
-
TagDefinition.new('asur', :byte, 'daap.songuserrating'),
|
203
|
-
TagDefinition.new('asdk', :byte, 'daap.songdatakind'),
|
204
|
-
TagDefinition.new('caps', :byte, 'dacp.playstatus'),
|
205
|
-
TagDefinition.new('cash', :byte, 'dacp.shufflestate'),
|
206
|
-
TagDefinition.new('carp', :byte, 'dacp.repeatstate'),
|
207
|
-
TagDefinition.new('muty', :byte, 'dmap.updatetype'),
|
208
|
-
TagDefinition.new("f\215ch", :byte, 'dmap.haschildcontainers'),
|
209
|
-
TagDefinition.new('msas', :byte, 'dmap.authenticationschemes'),
|
210
|
-
TagDefinition.new('cavs', :bool, 'dacp.visualizer'),
|
211
|
-
TagDefinition.new('cafs', :bool, 'dacp.fullscreen'),
|
212
|
-
TagDefinition.new('ceGS', :bool, 'com.apple.itunes.genius-selectable'),
|
213
|
-
TagDefinition.new('mslr', :bool, 'dmap.loginrequired'),
|
214
|
-
TagDefinition.new('msal', :bool, 'dmap.supportsautologout'),
|
215
|
-
TagDefinition.new('msup', :bool, 'dmap.supportsupdate'),
|
216
|
-
TagDefinition.new('mspi', :bool, 'dmap.supportspersistenids'),
|
217
|
-
TagDefinition.new('msex', :bool, 'dmap.supportsextensions'),
|
218
|
-
TagDefinition.new('msbr', :bool, 'dmap.supportsbrowse'),
|
219
|
-
TagDefinition.new('msqy', :bool, 'dmap.supportsquery'),
|
220
|
-
TagDefinition.new('msix', :bool, 'dmap.supportsindex'),
|
221
|
-
TagDefinition.new('msrs', :bool, 'dmap.supportsresolve'),
|
222
|
-
TagDefinition.new('asco', :bool, 'daap.songcompliation'),
|
223
|
-
TagDefinition.new('asdb', :bool, 'daap.songdisabled'),
|
224
|
-
TagDefinition.new('abpl', :bool, 'daap.baseplaylist'),
|
225
|
-
TagDefinition.new('aeSP', :bool, 'com.apple.itunes.smart-playlist'),
|
226
|
-
TagDefinition.new('aePP', :bool, 'com.apple.itunes.is-podcast-playlist'),
|
227
|
-
TagDefinition.new('aePS', :bool, 'com.apple.itunes.special-playlist'),
|
228
|
-
TagDefinition.new('aeSG', :bool, 'com.apple.itunes.saved-genius'),
|
229
|
-
TagDefinition.new('aeFP', :bool, 'com.apple.itunes.req-fplay'),
|
230
|
-
TagDefinition.new('aeHV', :bool, 'com.apple.itunes.has-video'),
|
231
|
-
TagDefinition.new('caia', :bool, 'dacp.isavailiable'),
|
232
|
-
TagDefinition.new('ceVO', :bool, 'com.apple.itunes.voting-enabled'),
|
233
|
-
TagDefinition.new('aeSV', :version,
|
234
|
-
'com.apple.itunes.music-sharing-version'),
|
235
|
-
TagDefinition.new('mpro', :version, 'dmap.protocolversion'),
|
236
|
-
TagDefinition.new('apro', :version, 'daap.protocolversion'),
|
237
|
-
TagDefinition.new('musr', :version, 'dmap.serverrevision'),
|
238
|
-
TagDefinition.new('mstc', :date, 'dmap.utc-time'),
|
239
|
-
TagDefinition.new('asda', :date, 'daap.songdateadded'),
|
240
|
-
TagDefinition.new('asdm', :date, 'daap.songdatemodified'),
|
241
|
-
TagDefinition.new('ceJC', :bool, 'com.apple.itunes.jukebox-client-vote'),
|
242
|
-
TagDefinition.new('ceJI', :bool, 'com.apple.itunes.jukebox-current'),
|
243
|
-
TagDefinition.new('ceJS', :uint16, 'com.apple.itunes.jukebox-score'),
|
244
|
-
TagDefinition.new('ceJV', :bool, 'com.apple.itunes.jukebox-vote'),
|
245
|
-
TagDefinition.new('ceQR', :container,
|
246
|
-
'com.apple.itunes.playqueue-contents-response'),
|
247
|
-
TagDefinition.new('ceQS', :container,
|
248
|
-
'com.apple.itunes.playqueue-contents-???'),
|
249
|
-
TagDefinition.new('ceQs', :uint64, 'com.apple.itunes.playqueue-id'),
|
250
|
-
TagDefinition.new('ceQa', :string, 'com.apple.itunes.playqueue-album'),
|
251
|
-
TagDefinition.new('ceQg', :string, 'com.apple.itunes.playqueue-genre'),
|
252
|
-
TagDefinition.new('ceQn', :string, 'com.apple.itunes.playqueue-name'),
|
253
|
-
TagDefinition.new('ceQr', :string, 'com.apple.itunes.playqueue-artist'),
|
254
|
-
TagDefinition.new('msml', :container, 'msml'),
|
255
|
-
TagDefinition.new('aeGs', :bool, 'com.apple.itunes.can-be-genius-seed'),
|
256
|
-
TagDefinition.new('aprm', :short, 'daap.playlistrepeatmode'),
|
257
|
-
TagDefinition.new('apsm', :short, 'daap.playlistshufflemode'),
|
258
|
-
TagDefinition.new('cmpr', :version, 'dmcp.protocolversion'),
|
259
|
-
TagDefinition.new('capr', :version, 'dacp.protocolversion'),
|
260
|
-
TagDefinition.new('ppro', :version, 'unknown.version'),
|
261
|
-
|
262
|
-
].freeze
|
263
|
-
end
|
264
|
-
end
|