From c9c89cdefba7a577009fd84eccf96292fd280a2b Mon Sep 17 00:00:00 2001 From: Jurriaan Pruis Date: Tue, 13 Aug 2013 16:47:41 +0200 Subject: [PATCH] Misc fixes --- .gitignore | 3 ++- lib/dacpclient/client.rb | 42 ++++++++++++++++++++++++-------- lib/dacpclient/dmapparser.rb | 2 +- lib/dacpclient/pairingserver.rb | 6 ++--- lib/dacpclient/tagdefinitions.rb | 26 ++++++++++++-------- 5 files changed, 54 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 8f8f09b..91f825d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ rdoc spec/reports test/tmp test/version_tmp -tmp \ No newline at end of file +tmp +.DS_Store diff --git a/lib/dacpclient/client.rb b/lib/dacpclient/client.rb index 66834d5..77d6fe7 100644 --- a/lib/dacpclient/client.rb +++ b/lib/dacpclient/client.rb @@ -23,9 +23,9 @@ def initialize(name, host = 'localhost', port = 3689) @mediarevision = 1 end - def pair(pin = nil) + def pair(pin) pairingserver = PairingServer.new(@name, '0.0.0.0', 1024) - pairingserver.pin = pin unless pin.nil? + pairingserver.pin = pin pairingserver.start end @@ -44,8 +44,9 @@ def login(pin = nil) @session_id = response[:mlid] response rescue DACPForbiddenError => e - puts "#{e.result.message} error: Cannot login, starting pairing process" pin = 4.times.map { Random.rand(10) } if pin.nil? + warn "#{e.result.message} error: Cannot login, starting pairing process" + warn "Pincode: #{pin}" pair(pin) retry end @@ -151,6 +152,14 @@ def playlists(db) do_action("databases/#{db}/containers", {}, true) end + def default_db + databases[:mlcl].to_a.find {|item| item.mdbk == 1} + end + + def default_playlist(db) + @client.playlists(72).mlcl.to_a.find { |item| item.abpl } + end + def artwork(database, id, width = 320, height = 320) url = "databases/#{database}/items/#{id}/extra_data/artwork" do_action(url, { mw: width, mh: height }, true) @@ -160,15 +169,28 @@ def now_playing_artwork(width = 320, height = 320) do_action(:nowplayingartwork, { mw: width, mh: height }) end - def search(db, container, search) - words = search.split + def search(db, container, search, type = nil) + search = URI.escape(search) + types = { + title: 'dmap.itemname', + artist: 'daap.songartist', + album: 'daap.songalbum', + genre: 'daap.songgenre', + composer: 'daap.songcomposer' + } queries = [] - queries.push(words.map { |v| "\'dmap.itemname:*#{v}*\'" }.join('+')) + type = types.keys if type.nil? + Array(type).each do |t| + queries << "'#{types[t]}:#{search}'" + end + # @http.get("/databases/1/containers/1/items?query='daap.songartist:#{escaped_pattern}','daap.songalbum:#{escaped_pattern}','dmap.itemname:#{escaped_pattern}','daap.songgenre:#{escaped_pattern}','daap.songcomposer:#{escaped_pattern}'").body + #queries.push(words.map { |v| "\'dmap.itemname:*#{v}*\'" }.join('+')) # queries.push(words.map{|v| "\'daap.songartist:*#{v}*\'"}.join('+')) - q = '(' + queries.map { |query| "(#{query})" }.join(',') + ')' - meta = 'dmap.itemid,dmap.itemname,daap.songartist,daap.songalbum' + q = queries.join(',') + meta = 'dmap.itemname,dmap.itemid,daap.songartist,daap.songalbumartist,daap.songalbum,com.apple.itunes.cloud-id,dmap.containeritemid,com.apple.itunes.has-video,com.apple.itunes.itms-songid,com.apple.itunes.extended-media-kind,dmap.downloadstatus,daap.songdisabled' + url = "databases/#{db}/containers/#{container}/items" - do_action(url, { type: 'music', sort: 'album', query: q, meta: meta }, + do_action(url, { type: 'music', sort: 'album', query: q, meta: meta}, true) end @@ -180,7 +202,7 @@ def do_action(action, params = {}, cleanurl = false) params['session-id'] = @session_id action = '/ctrl-int/1' + action unless cleanurl end - params = URI.encode_www_form(params) + params = params.map { |k,v| "#{k}=#{v}" }.join('&') uri = URI::HTTP.build({ host: @host, port: @port, path: action, query: params }) req = Net::HTTP::Get.new(uri.request_uri) diff --git a/lib/dacpclient/dmapparser.rb b/lib/dacpclient/dmapparser.rb index 51ee9ac..517b4ef 100644 --- a/lib/dacpclient/dmapparser.rb +++ b/lib/dacpclient/dmapparser.rb @@ -54,7 +54,7 @@ def self.parse_container(response) when :version Tag.new tag, DMAPConverter.bin_to_version(data) else - puts "Unknown type #{tag.type}" + warn "Unknown type #{tag.type}" Tag.new(tag, parseunknown(data)) end else diff --git a/lib/dacpclient/pairingserver.rb b/lib/dacpclient/pairingserver.rb index fd965de..4540baa 100644 --- a/lib/dacpclient/pairingserver.rb +++ b/lib/dacpclient/pairingserver.rb @@ -15,7 +15,7 @@ def initialize(name, host, port = 1024) end def start - puts "Pairing started (pincode=#{@pin.join})" + # puts "Pairing started (pincode=#{@pin.join})" pairing_string = generate_pairing_string(@pair, @name, @device_type) @@ -32,12 +32,12 @@ def start client.print "HTTP/1.1 200 OK\r\n" client.print "Content-Length: #{pairing_string.length}\r\n\r\n" client.print pairing_string - puts 'Pairing succeeded :)' + # puts 'Pairing succeeded :)' client.close @service.stop break else - puts 'Wrong pincode entered' + # puts 'Wrong pincode entered' client.print "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n" end client.close diff --git a/lib/dacpclient/tagdefinitions.rb b/lib/dacpclient/tagdefinitions.rb index 99c4496..410f2a5 100644 --- a/lib/dacpclient/tagdefinitions.rb +++ b/lib/dacpclient/tagdefinitions.rb @@ -1,5 +1,3 @@ -# encoding: UTF-8 - module DACPClient module DMAPParser @@ -32,7 +30,7 @@ def to_dmap when :version DMAPConverter.version_to_bin value.to_i else - puts "Unknown type #{tag.type}" + warn "Unknown type #{tag.type}" # Tag.new tag, parseunknown(data) value end @@ -42,7 +40,6 @@ def to_dmap # The TagContainer class is a Tag which contains other Tags class TagContainer < Tag - def initialize(type = nil, value = []) super type, value end @@ -54,12 +51,16 @@ def inspect(level = 0) end def get_value(key) + if key.is_a? Fixnum + return value[key] + end key = key.to_s val = value.find { |e| e.type.tag == key } val = value.find { |e| e.type.name == key } if val.nil? + if val.type.type == :container val - else + elsif !val.nil? val.value end end @@ -74,10 +75,11 @@ def has?(key) end def method_missing(method, *arguments, &block) - value.each do |dmap| - return dmap.value if dmap.type.tag.to_s == method.to_s - end - super + get_value(method.to_s) + end + + def to_a + value end end @@ -252,7 +254,11 @@ def to_s TagDefinition.new('msml', :container, 'msml'), TagDefinition.new('aeGs', :bool, 'com.apple.itunes.can-be-genius-seed'), TagDefinition.new('aprm', :short, 'daap.playlistrepeatmode'), - TagDefinition.new('apsm', :short, 'daap.playlistshufflemode') + TagDefinition.new('apsm', :short, 'daap.playlistshufflemode'), + TagDefinition.new('cmpr', :version, 'dmcp.protocolversion'), + TagDefinition.new('capr', :version, 'dacp.protocolversion'), + TagDefinition.new('ppro', :version, 'unknown.version'), + ].freeze end end \ No newline at end of file