Browse Source

NotifyMyAndroid support

pull/51/merge
Ruud 14 years ago
parent
commit
1d61433fb1
  1. 36
      couchpotato/core/notifications/notifymyandroid/__init__.py
  2. 26
      couchpotato/core/notifications/notifymyandroid/main.py
  3. 4
      libs/pynma/__init__.py
  4. 137
      libs/pynma/pynma.py

36
couchpotato/core/notifications/notifymyandroid/__init__.py

@ -0,0 +1,36 @@
from .main import NotifyMyAndroid
def start():
return NotifyMyAndroid()
config = [{
'name': 'notifymyandroid',
'groups': [
{
'tab': 'notifications',
'name': 'notifymyandroid',
'label': 'Notify My Android',
'options': [
{
'name': 'enabled',
'default': 0,
'type': 'enabler',
},
{
'name': 'api_key',
'description': 'Multiple keys seperated by a comma. Maximum of 5.'
},
{
'name': 'dev_key',
'advanced': True,
},
{
'name': 'priority',
'default': 0,
'type': 'dropdown',
'values': [('Very Low', -2), ('Moderate', -1), ('Normal', 0), ('High', 1), ('Emergency', 2)],
},
],
}
],
}]

26
couchpotato/core/notifications/notifymyandroid/main.py

@ -0,0 +1,26 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.notifications.base import Notification
from libs import pynma
log = CPLog(__name__)
class NotifyMyAndroid(Notification):
listen_to = ['movie.downloaded', 'movie.snatched']
def notify(self, message = '', data = {}, type = None):
if self.dontNotify(type): return
nma = pynma.PyNMA()
keys = self.conf('api_key').split(',')
nma.addkey(keys)
nma.developerkey(self.conf('dev_key'))
response = nma.push(self.app_name, 'CouchPotato', message, priority = self.priority, batch_mode = len(keys) > 1)
for key in keys:
if not response[str(key)]['code'] == u'200':
log.error('Could not send notification to NotifyMyAndroid (%s). %s' % (key, response[key]['message']))
return response

4
libs/pynma/__init__.py

@ -0,0 +1,4 @@
#!/usr/bin/python
from pynma import PyNMA

137
libs/pynma/pynma.py

@ -0,0 +1,137 @@
#!/usr/bin/python
from xml.dom.minidom import parseString
from httplib import HTTPSConnection
from urllib import urlencode
__version__ = "0.1"
API_SERVER = 'nma.usk.bz'
ADD_PATH = '/publicapi/notify'
USER_AGENT="PyNMA/v%s"%__version__
def uniq_preserve(seq): # Dave Kirby
# Order preserving
seen = set()
return [x for x in seq if x not in seen and not seen.add(x)]
def uniq(seq):
# Not order preserving
return {}.fromkeys(seq).keys()
class PyNMA(object):
"""PyNMA(apikey=[], developerkey=None)
takes 2 optional arguments:
- (opt) apykey: might me a string containing 1 key or an array of keys
- (opt) developerkey: where you can store your developer key
"""
def __init__(self, apikey=[], developerkey=None):
self._developerkey = None
self.developerkey(developerkey)
if apikey:
if type(apikey) == str:
apikey = [apikey]
self._apikey = uniq(apikey)
def addkey(self, key):
"Add a key (register ?)"
if type(key) == str:
if not key in self._apikey:
self._apikey.append(key)
elif type(key) == list:
for k in key:
if not k in self._apikey:
self._apikey.append(k)
def delkey(self, key):
"Removes a key (unregister ?)"
if type(key) == str:
if key in self._apikey:
self._apikey.remove(key)
elif type(key) == list:
for k in key:
if key in self._apikey:
self._apikey.remove(k)
def developerkey(self, developerkey):
"Sets the developer key (and check it has the good length)"
if type(developerkey) == str and len(developerkey) == 48:
self._developerkey = developerkey
def push(self, application="", event="", description="", url="", priority=0, batch_mode=False):
"""Pushes a message on the registered API keys.
takes 5 arguments:
- (req) application: application name [256]
- (req) event: event name [1000]
- (req) description: description [10000]
- (opt) url: url [512]
- (opt) priority: from -2 (lowest) to 2 (highest) (def:0)
- (opt) batch_mode: call API 5 by 5 (def:False)
Warning: using batch_mode will return error only if all API keys are bad
cf: http://nma.usk.bz/api.php
"""
datas = {
'application': application[:256].encode('utf8'),
'event': event[:1024].encode('utf8'),
'description': description[:10000].encode('utf8'),
'priority': priority
}
if url:
datas['url'] = url[:512]
if self._developerkey:
datas['developerkey'] = self._developerkey
results = {}
if not batch_mode:
for key in self._apikey:
datas['apikey'] = key
res = self.callapi('POST', ADD_PATH, datas)
results[key] = res
else:
for i in range(0, len(self._apikey), 5):
datas['apikey'] = ",".join(self._apikey[i:i+5])
res = self.callapi('POST', ADD_PATH, datas)
results[datas['apikey']] = res
return results
def callapi(self, method, path, args):
headers = { 'User-Agent': USER_AGENT }
if method == "POST":
headers['Content-type'] = "application/x-www-form-urlencoded"
http_handler = HTTPSConnection(API_SERVER)
http_handler.request(method, path, urlencode(args), headers)
resp = http_handler.getresponse()
try:
res = self._parse_reponse(resp.read())
except Exception, e:
res = {'type': "pynmaerror",
'code': 600,
'message': str(e)
}
pass
return res
def _parse_reponse(self, response):
root = parseString(response).firstChild
for elem in root.childNodes:
if elem.nodeType == elem.TEXT_NODE: continue
if elem.tagName == 'success':
res = dict(elem.attributes.items())
res['message'] = ""
res['type'] = elem.tagName
return res
if elem.tagName == 'error':
res = dict(elem.attributes.items())
res['message'] = elem.firstChild.nodeValue
res['type'] = elem.tagName
return res
Loading…
Cancel
Save