diff --git a/headphones/notifiers.py b/headphones/notifiers.py index 3df88485..ecdd10a7 100644 --- a/headphones/notifiers.py +++ b/headphones/notifiers.py @@ -23,6 +23,7 @@ from httplib import HTTPSConnection from urllib import urlencode import os.path import subprocess +import lib.simplejson as simplejson class PROWL: @@ -86,67 +87,102 @@ class XBMC: self.hosts = headphones.XBMC_HOST self.username = headphones.XBMC_USERNAME self.password = headphones.XBMC_PASSWORD - - def _send(self, command): - - hosts = [x.strip() for x in self.hosts.split(',')] + + def _sendhttp(self, host, command): + username = self.username password = self.password url_command = urllib.urlencode(command) - for host in hosts: - - url = host + '/xbmcCmds/xbmcHttp/?' + url_command + url = host + '/xbmcCmds/xbmcHttp/?' + url_command - req = urllib2.Request(url) + req = urllib2.Request(url) - if password: - base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') - req.add_header("Authorization", "Basic %s" % base64string) + if password: + base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') + req.add_header("Authorization", "Basic %s" % base64string) - logger.info('XBMC url: %s' % url) + logger.info('XBMC url: %s' % url) - try: - handle = urllib2.urlopen(req) - except Exception, e: - logger.warn('Error opening XBMC url: ' % e) - return + try: + handle = urllib2.urlopen(req) + except Exception, e: + logger.warn('Error opening XBMC url: %s' % e) + return - response = handle.read().decode(headphones.SYS_ENCODING) + response = handle.read().decode(headphones.SYS_ENCODING) - return response + return response + def _sendjson(self, host, method, params={}): + data = [{'id': 0, 'jsonrpc': '2.0', 'method': method, 'params': params}] + data = simplejson.JSONEncoder().encode(data) + + content = {'Content-Type': 'application/json', 'Content-Length': len(data)} + + req = urllib2.Request(host+'/jsonrpc', data, content) + + if self.username and self.password: + base64string = base64.encodestring('%s:%s' % (self.username, self.password)).replace('\n', '') + req.add_header("Authorization", "Basic %s" % base64string) + + try: + handle = urllib2.urlopen(req) + except Exception, e: + logger.warn('Error opening XBMC url: %s' % e) + return + + response = simplejson.JSONDecoder().decode(handle.read()) + + try: + return response[0]['result'] + except: + logger.warn('XBMC returned error: %s' % response[0]['error']) + return + def update(self): # From what I read you can't update the music library on a per directory or per path basis # so need to update the whole thing - - updatecommand = {'command': 'ExecBuiltIn', 'parameter': 'XBMC.updatelibrary(music)'} - - logger.info('Sending library update command to XBMC') - request = self._send(updatecommand) - - if not request: - logger.warn('Error sending update request to XBMC') + + hosts = [x.strip() for x in self.hosts.split(',')] + + for host in hosts: + logger.info('Sending library update command to XBMC @ '+host) + request = self._sendjson(host, 'AudioLibrary.Scan') + + if not request: + logger.warn('Error sending update request to XBMC') def notify(self, artist, album, albumartpath): - + + hosts = [x.strip() for x in self.hosts.split(',')] + header = "Headphones" message = "%s - %s added to your library" % (artist, album) time = "3000" # in ms - - - notification = header + "," + message + "," + time + "," + albumartpath - - notifycommand = {'command': 'ExecBuiltIn', 'parameter': 'Notification(' + notification + ')' } - - logger.info('Sending notification command to XMBC') - request = self._send(notifycommand) - - if not request: - logger.warn('Error sending notification request to XBMC') - + + for host in hosts: + logger.info('Sending notification command to XMBC @ '+host) + try: + version = self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})['version']['major'] + + if version < 12: #Eden + notification = header + "," + message + "," + time + "," + albumartpath + notifycommand = {'command': 'ExecBuiltIn', 'parameter': 'Notification('+notification+')'} + request = self._sendhttp(host, notifycommand) + + else: #Frodo + params = {'title':header, 'message': message, 'displaytime': int(time), 'image': albumartpath} + request = self._sendjson(host, 'GUI.ShowNotification', params) + + if not request: + raise Exception + + except: + logger.warn('Error sending notification request to XBMC') + class NMA: def __init__(self):