Notifications
This commit is contained in:
1 parent
288aa8c0a1
commit
85fc1c01ee
67 files changed
+3270
-400
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,29 @@
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.helpers.request import jsonified
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.environment import Env
|
||||
|
||||
class Notification(Plugin):
|
||||
|
||||
default_title = 'CouchPotato'
|
||||
test_message = 'ZOMG Lazors Pewpewpew!'
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
pass
|
||||
|
||||
def conf(self, attr):
|
||||
return Env.setting(attr, self.__class__.__name__.lower())
|
||||
|
||||
def isDisabled(self):
|
||||
return not self.isEnabled()
|
||||
|
||||
def isEnabled(self):
|
||||
return self.conf('enabled', True)
|
||||
|
||||
def test(self):
|
||||
success = self.notify(message = self.test_message)
|
||||
|
||||
return jsonified({'success': success})
|
||||
@@ -0,0 +1,33 @@
|
||||
from .main import Growl
|
||||
|
||||
def start():
|
||||
return Growl()
|
||||
|
||||
config = [{
|
||||
'name': 'growl',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'notifications',
|
||||
'name': 'growl',
|
||||
'options': [
|
||||
{
|
||||
'name': 'enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'host',
|
||||
'default': 'localhost',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'password',
|
||||
'default': '',
|
||||
'type': 'password',
|
||||
'description': '',
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,111 @@
|
||||
# Based on netprowl by the following authors.
|
||||
|
||||
# Altered 1st October 2010 - Tim Child.
|
||||
# Have added the ability for the command line arguments to take a password.
|
||||
|
||||
# Altered 1-17-2010 - Tanner Stokes - www.tannr.com
|
||||
# Added support for command line arguments
|
||||
|
||||
# ORIGINAL CREDITS
|
||||
# """Growl 0.6 Network Protocol Client for Python"""
|
||||
# __version__ = "0.6.3"
|
||||
# __author__ = "Rui Carmo (http://the.taoofmac.com)"
|
||||
# __copyright__ = "(C) 2004 Rui Carmo. Code under BSD License."
|
||||
# __contributors__ = "Ingmar J Stein (Growl Team), John Morrissey (hashlib patch)"
|
||||
|
||||
import struct
|
||||
|
||||
try:
|
||||
import hashlib
|
||||
md5_constructor = hashlib.md5
|
||||
except ImportError:
|
||||
import md5
|
||||
md5_constructor = md5.new
|
||||
|
||||
GROWL_UDP_PORT = 9887
|
||||
GROWL_PROTOCOL_VERSION = 1
|
||||
GROWL_TYPE_REGISTRATION = 0
|
||||
GROWL_TYPE_NOTIFICATION = 1
|
||||
|
||||
|
||||
class GrowlRegistrationPacket:
|
||||
"""Builds a Growl Network Registration packet.
|
||||
Defaults to emulating the command-line growlnotify utility."""
|
||||
|
||||
def __init__(self, application = "CouchPotato", password = None):
|
||||
self.notifications = []
|
||||
self.defaults = [] # array of indexes into notifications
|
||||
self.application = application.encode("utf-8")
|
||||
self.password = password
|
||||
|
||||
def addNotification(self, notification = "General Notification", enabled = True):
|
||||
"""Adds a notification type and sets whether it is enabled on the GUI"""
|
||||
|
||||
self.notifications.append(notification)
|
||||
if enabled:
|
||||
self.defaults.append(len(self.notifications) - 1)
|
||||
|
||||
def payload(self):
|
||||
"""Returns the packet payload."""
|
||||
self.data = struct.pack("!BBH",
|
||||
GROWL_PROTOCOL_VERSION,
|
||||
GROWL_TYPE_REGISTRATION,
|
||||
len(self.application)
|
||||
)
|
||||
self.data += struct.pack("BB",
|
||||
len(self.notifications),
|
||||
len(self.defaults)
|
||||
)
|
||||
self.data += self.application
|
||||
for notification in self.notifications:
|
||||
encoded = notification.encode("utf-8")
|
||||
self.data += struct.pack("!H", len(encoded))
|
||||
self.data += encoded
|
||||
for default in self.defaults:
|
||||
self.data += struct.pack("B", default)
|
||||
self.checksum = md5()
|
||||
self.checksum.update(self.data)
|
||||
if self.password:
|
||||
self.checksum.update(self.password)
|
||||
self.data += self.checksum.digest()
|
||||
return self.data
|
||||
|
||||
class GrowlNotificationPacket:
|
||||
"""Builds a Growl Network Notification packet.
|
||||
Defaults to emulating the command-line growlnotify utility."""
|
||||
|
||||
def __init__(self, application = "CouchPotato",
|
||||
notification = "General Notification", title = "Title",
|
||||
description = "Description", priority = 0, sticky = False, password = None):
|
||||
|
||||
self.application = application.encode("utf-8")
|
||||
self.notification = notification.encode("utf-8")
|
||||
self.title = title.encode("utf-8")
|
||||
self.description = description.encode("utf-8")
|
||||
flags = (priority & 0x07) * 2
|
||||
if priority < 0:
|
||||
flags |= 0x08
|
||||
if sticky:
|
||||
flags = flags | 0x0100
|
||||
self.data = struct.pack("!BBHHHHH",
|
||||
GROWL_PROTOCOL_VERSION,
|
||||
GROWL_TYPE_NOTIFICATION,
|
||||
flags,
|
||||
len(self.notification),
|
||||
len(self.title),
|
||||
len(self.description),
|
||||
len(self.application)
|
||||
)
|
||||
self.data += self.notification
|
||||
self.data += self.title
|
||||
self.data += self.description
|
||||
self.data += self.application
|
||||
self.checksum = md5_constructor()
|
||||
self.checksum.update(self.data)
|
||||
if password:
|
||||
self.checksum.update(password)
|
||||
self.data += self.checksum.digest()
|
||||
|
||||
def payload(self):
|
||||
"""Returns the packet payload."""
|
||||
return self.data
|
||||
@@ -0,0 +1,45 @@
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from couchpotato.core.notifications.growl.growl import GROWL_UDP_PORT, \
|
||||
GrowlRegistrationPacket, GrowlNotificationPacket
|
||||
from couchpotato.environment import Env
|
||||
from socket import AF_INET, SOCK_DGRAM, socket
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Growl(Notification):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
addEvent('notify.growl', self.notify)
|
||||
|
||||
addApiView('notify.growl.test', self.test)
|
||||
|
||||
def conf(self, attr):
|
||||
return Env.setting(attr, 'growl')
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
|
||||
if self.isDisabled():
|
||||
return
|
||||
|
||||
hosts = [x.strip() for x in self.conf('host').split(",")]
|
||||
password = self.conf('password')
|
||||
|
||||
for curHost in hosts:
|
||||
addr = (curHost, GROWL_UDP_PORT)
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
p = GrowlRegistrationPacket(password = password)
|
||||
p.addNotification()
|
||||
s.sendto(p.payload(), addr)
|
||||
|
||||
# send notification
|
||||
p = GrowlNotificationPacket(title = self.default_title, description = message, priority = 0, sticky = False, password = password)
|
||||
s.sendto(p.payload(), addr)
|
||||
s.close()
|
||||
|
||||
log.info('Growl notifications sent.')
|
||||
@@ -0,0 +1,37 @@
|
||||
from .main import NMJ
|
||||
|
||||
def start():
|
||||
return NMJ()
|
||||
|
||||
config = [{
|
||||
'name': 'nmj',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'notifications',
|
||||
'name': 'nmj',
|
||||
'label': 'NMJ',
|
||||
'options': [
|
||||
{
|
||||
'name': 'enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
},
|
||||
{
|
||||
'name': 'host',
|
||||
'default': 'localhost',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'database',
|
||||
'default': '',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'mount',
|
||||
'default': '',
|
||||
'description': '',
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,131 @@
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.helpers.request import getParams, jsonified
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from couchpotato.environment import Env
|
||||
import re
|
||||
import telnetlib
|
||||
import urllib
|
||||
import urllib2
|
||||
|
||||
try:
|
||||
import xml.etree.cElementTree as etree
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class NMJ(Notification):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
addEvent('notify.nmj', self.notify)
|
||||
|
||||
addApiView('notify.nmj.test', self.test)
|
||||
addApiView('notify.nmj.auto_config', self.autoConfig)
|
||||
|
||||
def conf(self, attr):
|
||||
return Env.setting(attr, 'nmj')
|
||||
|
||||
def autoConfig(self):
|
||||
|
||||
params = getParams()
|
||||
host = params.get('host', 'localhost')
|
||||
|
||||
database = ''
|
||||
mount = ''
|
||||
|
||||
try:
|
||||
terminal = telnetlib.Telnet(host)
|
||||
except Exception:
|
||||
log.error('Warning: unable to get a telnet session to %s' % (host))
|
||||
return self.failed()
|
||||
|
||||
log.debug('Connected to %s via telnet' % (host))
|
||||
terminal.read_until('sh-3.00# ')
|
||||
terminal.write('cat /tmp/source\n')
|
||||
terminal.write('cat /tmp/netshare\n')
|
||||
terminal.write('exit\n')
|
||||
tnoutput = terminal.read_all()
|
||||
|
||||
match = re.search(r'(.+\.db)\r\n?(.+)(?=sh-3.00# cat /tmp/netshare)', tnoutput)
|
||||
|
||||
if match:
|
||||
database = match.group(1)
|
||||
device = match.group(2)
|
||||
log.info('Found NMJ database %s on device %s' % (database, device))
|
||||
else:
|
||||
log.error('Could not get current NMJ database on %s, NMJ is probably not running!' % (host))
|
||||
return self.failed()
|
||||
|
||||
if device.startswith('NETWORK_SHARE/'):
|
||||
match = re.search('.*(?=\r\n?%s)' % (re.escape(device[14:])), tnoutput)
|
||||
|
||||
if match:
|
||||
mount = match.group().replace('127.0.0.1', host)
|
||||
log.info('Found mounting url on the Popcorn Hour in configuration: %s' % (mount))
|
||||
else:
|
||||
log.error('Detected a network share on the Popcorn Hour, but could not get the mounting url')
|
||||
return self.failed()
|
||||
|
||||
return jsonified({
|
||||
'success': True,
|
||||
'database': database,
|
||||
'mount': mount,
|
||||
})
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
|
||||
if self.isDisabled():
|
||||
return False
|
||||
|
||||
host = self.conf('host')
|
||||
mount = self.conf('mount')
|
||||
database = self.conf('database')
|
||||
|
||||
if self.mount:
|
||||
try:
|
||||
req = urllib2.Request(mount)
|
||||
log.debug('Try to mount network drive via url: %s' % (mount))
|
||||
handle = urllib2.urlopen(req)
|
||||
except IOError, e:
|
||||
log.error('Warning: Couldn\'t contact popcorn hour on host %s: %s' % (host, e))
|
||||
return False
|
||||
|
||||
params = {
|
||||
'arg0': 'scanner_start',
|
||||
'arg1': database,
|
||||
'arg2': 'background',
|
||||
'arg3': '',
|
||||
}
|
||||
params = urllib.urlencode(params)
|
||||
UPDATE_URL = 'http://%(host)s:8008/metadata_database?%(params)s'
|
||||
updateUrl = UPDATE_URL % {'host': host, 'params': params}
|
||||
|
||||
try:
|
||||
req = urllib2.Request(updateUrl)
|
||||
log.debug('Sending NMJ scan update command via url: %s' % (updateUrl))
|
||||
handle = urllib2.urlopen(req)
|
||||
response = handle.read()
|
||||
except IOError, e:
|
||||
log.error('Warning: Couldn\'t contact Popcorn Hour on host %s: %s' % (host, e))
|
||||
return False
|
||||
|
||||
try:
|
||||
et = etree.fromstring(response)
|
||||
result = et.findtext('returnValue')
|
||||
except SyntaxError, e:
|
||||
log.error('Unable to parse XML returned from the Popcorn Hour: %s' % (e))
|
||||
return False
|
||||
|
||||
if int(result) > 0:
|
||||
log.error('Popcorn Hour returned an errorcode: %s' % (result))
|
||||
return False
|
||||
else:
|
||||
log.info('NMJ started background scan')
|
||||
return True
|
||||
|
||||
def failed(self):
|
||||
return jsonified({'success': False})
|
||||
@@ -0,0 +1,32 @@
|
||||
from .main import Notifo
|
||||
|
||||
def start():
|
||||
return Notifo()
|
||||
|
||||
config = [{
|
||||
'name': 'notifo',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'notifications',
|
||||
'name': 'notifo',
|
||||
'description': '',
|
||||
'options': [
|
||||
{
|
||||
'name': 'enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
},
|
||||
{
|
||||
'name': 'username',
|
||||
'default': '',
|
||||
'type': 'string',
|
||||
},
|
||||
{
|
||||
'name': 'password',
|
||||
'default': '',
|
||||
'type': 'password',
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,53 @@
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from couchpotato.environment import Env
|
||||
from flask.helpers import json
|
||||
import base64
|
||||
import urllib
|
||||
import urllib2
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Notifo(Notification):
|
||||
|
||||
url = 'https://api.notifo.com/v1/send_notification'
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
addEvent('notify.notifo', self.notify)
|
||||
|
||||
addApiView('notify.notifo.test', self.test)
|
||||
|
||||
def conf(self, attr):
|
||||
return Env.setting(attr, 'notifo')
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
|
||||
if self.isDisabled():
|
||||
return False
|
||||
|
||||
try:
|
||||
data = urllib.urlencode({
|
||||
'msg': toUnicode(message),
|
||||
})
|
||||
|
||||
req = urllib2.Request(self.url)
|
||||
authHeader = "Basic %s" % base64.encodestring('%s:%s' % (self.conf('username'), self.conf('api_key')))[:-1]
|
||||
req.add_header("Authorization", authHeader)
|
||||
|
||||
handle = urllib2.urlopen(req, data)
|
||||
result = json.load(handle)
|
||||
|
||||
if result['status'] != 'success' or result['response_message'] != 'OK':
|
||||
raise Exception
|
||||
|
||||
except Exception, e:
|
||||
log.error('Notification failed: %s' % e)
|
||||
return False
|
||||
|
||||
log.info('Notifo notification successful.')
|
||||
return True
|
||||
@@ -0,0 +1,33 @@
|
||||
from .main import Plex
|
||||
|
||||
def start():
|
||||
return Plex()
|
||||
|
||||
config = [{
|
||||
'name': 'plex',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'notifications',
|
||||
'name': 'plex',
|
||||
'options': [
|
||||
{
|
||||
'name': 'enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'host',
|
||||
'default': 'localhost',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'password',
|
||||
'default': '',
|
||||
'type': 'password',
|
||||
'description': '',
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,43 @@
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from xml.dom import minidom
|
||||
import urllib
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Plex(Notification):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
addEvent('notify.plex', self.notify)
|
||||
|
||||
addApiView('notify.plex.test', self.test)
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
|
||||
if self.isDisabled():
|
||||
return
|
||||
|
||||
log.info('Sending notification to Plex')
|
||||
hosts = [x.strip() for x in self.conf('host').split(",")]
|
||||
|
||||
for host in hosts:
|
||||
|
||||
source_type = ['movie']
|
||||
base_url = 'http://%s/library/sections' % host
|
||||
refresh_url = '%s/%%s/refresh' % base_url
|
||||
|
||||
try:
|
||||
xml_sections = minidom.parse(urllib.urlopen(base_url))
|
||||
sections = xml_sections.getElementsByTagName('Directory')
|
||||
for s in sections:
|
||||
if s.getAttribute('type') in source_type:
|
||||
url = refresh_url % s.getAttribute('key')
|
||||
x = urllib.urlopen(url)
|
||||
except:
|
||||
log.error('Plex library update failed for %s.' % host)
|
||||
|
||||
return True
|
||||
@@ -0,0 +1,35 @@
|
||||
from .main import Prowl
|
||||
|
||||
def start():
|
||||
return Prowl()
|
||||
|
||||
config = [{
|
||||
'name': 'prowl',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'notifications',
|
||||
'name': 'prowl',
|
||||
'options': [
|
||||
{
|
||||
'name': 'enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'api_key',
|
||||
'default': '',
|
||||
'label': 'Api key',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'priority',
|
||||
'default': '0',
|
||||
'type': 'dropdown',
|
||||
'description': '',
|
||||
'values': [('Very Low', -2), ('Moderate', -1), ('Normal', 0), ('High', 1), ('Emergency', 2)]
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,51 @@
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
from httplib import HTTPSConnection
|
||||
from urllib import urlencode
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Prowl(Notification):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
addEvent('notify.prowl', self.notify)
|
||||
|
||||
addApiView('notify.prowl.test', self.test)
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
|
||||
if self.isDisabled():
|
||||
return
|
||||
|
||||
http_handler = HTTPSConnection('api.prowlapp.com')
|
||||
|
||||
data = {
|
||||
'apikey': self.conf('api_key'),
|
||||
'application': self.default_title,
|
||||
'event': self.default_title,
|
||||
'description': toUnicode(message),
|
||||
'priority': self.conf('priority'),
|
||||
}
|
||||
|
||||
http_handler.request('POST',
|
||||
'/publicapi/add',
|
||||
headers = {'Content-type': 'application/x-www-form-urlencoded'},
|
||||
body = urlencode(data)
|
||||
)
|
||||
response = http_handler.getresponse()
|
||||
request_status = response.status
|
||||
|
||||
if request_status == 200:
|
||||
log.info('Prowl notifications sent.')
|
||||
return True
|
||||
elif request_status == 401:
|
||||
log.error('Prowl auth failed: %s' % response.reason)
|
||||
return False
|
||||
else:
|
||||
log.error('Prowl notification failed.')
|
||||
return False
|
||||
@@ -0,0 +1,38 @@
|
||||
from .main import XBMC
|
||||
|
||||
def start():
|
||||
return XBMC()
|
||||
|
||||
config = [{
|
||||
'name': 'xbmc',
|
||||
'groups': [
|
||||
{
|
||||
'tab': 'notifications',
|
||||
'name': 'xbmc',
|
||||
'options': [
|
||||
{
|
||||
'name': 'enabled',
|
||||
'default': False,
|
||||
'type': 'enabler',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'host',
|
||||
'default': 'localhost:8080',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'username',
|
||||
'default': 'xbmc',
|
||||
'description': '',
|
||||
},
|
||||
{
|
||||
'name': 'password',
|
||||
'default': 'xbmc',
|
||||
'type': 'password',
|
||||
'description': '',
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}]
|
||||
@@ -0,0 +1,47 @@
|
||||
from couchpotato.api import addApiView
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.notifications.base import Notification
|
||||
import base64
|
||||
import urllib
|
||||
import urllib2
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class XBMC(Notification):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('notify', self.notify)
|
||||
addEvent('notify.xbmc', self.notify)
|
||||
|
||||
addApiView('notify.xbmc.test', self.test)
|
||||
|
||||
def notify(self, message = '', data = {}):
|
||||
|
||||
if self.isDisabled():
|
||||
return
|
||||
|
||||
for host in [x.strip() for x in self.conf('host').split(",")]:
|
||||
self.send({'command': 'ExecBuiltIn', 'parameter': 'Notification(CouchPotato, %s)' % message}, host)
|
||||
self.send({'command': 'ExecBuiltIn', 'parameter': 'XBMC.updatelibrary(video)'}, host)
|
||||
|
||||
return True
|
||||
|
||||
def send(self, command, host):
|
||||
|
||||
url = 'http://%s/xbmcCmds/xbmcHttp/?%s' % (host, urllib.urlencode(command))
|
||||
|
||||
try:
|
||||
req = urllib2.Request(url)
|
||||
if self.password:
|
||||
authHeader = "Basic %s" % base64.encodestring('%s:%s' % (self.conf('username'), self.conf('password')))[:-1]
|
||||
req.add_header("Authorization", authHeader)
|
||||
|
||||
urllib2.urlopen(req, timeout = 10).read()
|
||||
except Exception, e:
|
||||
log.error("Couldn't sent command to XBMC. %s" % e)
|
||||
return False
|
||||
|
||||
log.info('XBMC notification to %s successful.' % host)
|
||||
return True
|
||||
Reference in new issue
Block a user