/library/pynma/pynma.py

https://github.com/CybeTech/CouchPotato · Python · 137 lines · 95 code · 22 blank · 20 comment · 30 complexity · cf622b41266d4200e467745d3536a23b MD5 · raw file

  1. #!/usr/bin/python
  2. from xml.dom.minidom import parseString
  3. from httplib import HTTPSConnection
  4. from urllib import urlencode
  5. __version__ = "0.1"
  6. API_SERVER = 'nma.usk.bz'
  7. ADD_PATH = '/publicapi/notify'
  8. USER_AGENT="PyNMA/v%s"%__version__
  9. def uniq_preserve(seq): # Dave Kirby
  10. # Order preserving
  11. seen = set()
  12. return [x for x in seq if x not in seen and not seen.add(x)]
  13. def uniq(seq):
  14. # Not order preserving
  15. return {}.fromkeys(seq).keys()
  16. class PyNMA(object):
  17. """PyNMA(apikey=[], developerkey=None)
  18. takes 2 optional arguments:
  19. - (opt) apykey: might me a string containing 1 key or an array of keys
  20. - (opt) developerkey: where you can store your developer key
  21. """
  22. def __init__(self, apikey=[], developerkey=None):
  23. self._developerkey = None
  24. self.developerkey(developerkey)
  25. if apikey:
  26. if type(apikey) == str:
  27. apikey = [apikey]
  28. self._apikey = uniq(apikey)
  29. def addkey(self, key):
  30. "Add a key (register ?)"
  31. if type(key) == str:
  32. if not key in self._apikey:
  33. self._apikey.append(key)
  34. elif type(key) == list:
  35. for k in key:
  36. if not k in self._apikey:
  37. self._apikey.append(k)
  38. def delkey(self, key):
  39. "Removes a key (unregister ?)"
  40. if type(key) == str:
  41. if key in self._apikey:
  42. self._apikey.remove(key)
  43. elif type(key) == list:
  44. for k in key:
  45. if key in self._apikey:
  46. self._apikey.remove(k)
  47. def developerkey(self, developerkey):
  48. "Sets the developer key (and check it has the good length)"
  49. if type(developerkey) == str and len(developerkey) == 48:
  50. self._developerkey = developerkey
  51. def push(self, application="", event="", description="", url="", priority=0, batch_mode=False):
  52. """Pushes a message on the registered API keys.
  53. takes 5 arguments:
  54. - (req) application: application name [256]
  55. - (req) event: event name [1000]
  56. - (req) description: description [10000]
  57. - (opt) url: url [512]
  58. - (opt) priority: from -2 (lowest) to 2 (highest) (def:0)
  59. - (opt) batch_mode: call API 5 by 5 (def:False)
  60. Warning: using batch_mode will return error only if all API keys are bad
  61. cf: http://nma.usk.bz/api.php
  62. """
  63. datas = {
  64. 'application': application[:256].encode('utf8'),
  65. 'event': event[:1024].encode('utf8'),
  66. 'description': description[:10000].encode('utf8'),
  67. 'priority': priority
  68. }
  69. if url:
  70. datas['url'] = url[:512]
  71. if self._developerkey:
  72. datas['developerkey'] = self._developerkey
  73. results = {}
  74. if not batch_mode:
  75. for key in self._apikey:
  76. datas['apikey'] = key
  77. res = self.callapi('POST', ADD_PATH, datas)
  78. results[key] = res
  79. else:
  80. for i in range(0, len(self._apikey), 5):
  81. datas['apikey'] = ",".join(self._apikey[i:i+5])
  82. res = self.callapi('POST', ADD_PATH, datas)
  83. results[datas['apikey']] = res
  84. return results
  85. def callapi(self, method, path, args):
  86. headers = { 'User-Agent': USER_AGENT }
  87. if method == "POST":
  88. headers['Content-type'] = "application/x-www-form-urlencoded"
  89. http_handler = HTTPSConnection(API_SERVER)
  90. http_handler.request(method, path, urlencode(args), headers)
  91. resp = http_handler.getresponse()
  92. try:
  93. res = self._parse_reponse(resp.read())
  94. except Exception, e:
  95. res = {'type': "pynmaerror",
  96. 'code': 600,
  97. 'message': str(e)
  98. }
  99. pass
  100. return res
  101. def _parse_reponse(self, response):
  102. root = parseString(response).firstChild
  103. for elem in root.childNodes:
  104. if elem.nodeType == elem.TEXT_NODE: continue
  105. if elem.tagName == 'success':
  106. res = dict(elem.attributes.items())
  107. res['message'] = ""
  108. res['type'] = elem.tagName
  109. return res
  110. if elem.tagName == 'error':
  111. res = dict(elem.attributes.items())
  112. res['message'] = elem.firstChild.nodeValue
  113. res['type'] = elem.tagName
  114. return res