Package pushnotify :: Module nma
[hide private]
[frames] | no frames]

Source Code for Module pushnotify.nma

  1  #!/usr/bin/env python 
  2  # vim: set fileencoding=utf-8 
  3   
  4  """Module for sending push notifications to Android devices that have 
  5  Notify My Android installed. See www.notifymyandroid.com/ for more 
  6  information. 
  7   
  8  copyright: Copyright (c) Jeffrey Goettsch and other contributors. 
  9  license: BSD, see LICENSE for details. 
 10   
 11  """ 
 12   
 13   
 14  import warnings 
 15  try: 
 16      from xml.etree import cElementTree 
 17      ElementTree = cElementTree 
 18  except ImportError: 
 19      from xml.etree import ElementTree 
 20   
 21  from pushnotify import abstract 
 22  from pushnotify import exceptions 
 23   
 24   
 25  PUBLIC_API_URL = u'https://www.notifymyandroid.com/publicapi' 
 26  VERIFY_URL = u'/'.join([PUBLIC_API_URL, 'verify']) 
 27  NOTIFY_URL = u'/'.join([PUBLIC_API_URL, 'notify']) 
 28   
 29  DESC_LIMIT = 10000 
 30   
 31   
32 -class Client(abstract.AbstractClient):
33 """Client for sending push notificiations to Android devices with 34 the Notify My Android (NMA) application installed. 35 36 Member Vars: 37 developerkey: A string containing a valid developer key for the 38 NMA application. 39 application: A string containing the name of the application on 40 behalf of whom the NMA client will be sending messages. 41 apikeys: A dictionary where the keys are strings containing 42 valid user API keys, and the values are lists of strings, 43 each containing a valid user device key. Device keys are not 44 used by this client. 45 46 """ 47
48 - def __init__(self, developerkey='', application=''):
49 """Initialize the Notify My Android client. 50 51 Args: 52 developerkey: A string containing a valid developer key for 53 the NMA application. 54 application: A string containing the name of the application 55 on behalf of whom the NMA client will be sending 56 messages. 57 58 """ 59 60 super(self.__class__, self).__init__(developerkey, application) 61 62 self._type = 'nma' 63 self._urls = {'notify': NOTIFY_URL, 'verify': VERIFY_URL}
64
65 - def _parse_response_stream(self, response_stream, verify=False):
66 67 xmlresp = response_stream.read() 68 root = ElementTree.fromstring(xmlresp) 69 70 self._last['type'] = root[0].tag.lower() 71 self._last['code'] = root[0].attrib['code'] 72 73 if self._last['type'] == 'success': 74 self._last['message'] = None 75 self._last['remaining'] = root[0].attrib['remaining'] 76 self._last['resettimer'] = root[0].attrib['resettimer'] 77 elif self._last['type'] == 'error': 78 self._last['message'] = root[0].text 79 self._last['remaining'] = None 80 self._last['resettimer'] = None 81 82 if (not verify or 83 (self._last['code'] != '400' and 84 self._last['code'] != '401')): 85 self._raise_exception() 86 else: 87 raise exceptions.UnrecognizedResponseError(xmlresp, -1) 88 89 return root
90
91 - def _raise_exception(self):
92 93 if self._last['code'] == '400': 94 raise exceptions.FormatError(self._last['message'], 95 int(self._last['code'])) 96 elif self._last['code'] == '401': 97 raise exceptions.ApiKeyError(self._last['message'], 98 int(self._last['code'])) 99 elif self._last['code'] == '402': 100 raise exceptions.RateLimitExceeded(self._last['message'], 101 int(self._last['code'])) 102 elif self._last['code'] == '500': 103 raise exceptions.ServerError(self._last['message'], 104 int(self._last['code'])) 105 else: 106 raise exceptions.UnknownError(self._last['message'], 107 int(self._last['code']))
108
109 - def notify(self, description, event, split=True, kwargs=None):
110 """Send a notification to each user's apikey in self.apikeys. 111 112 Args: 113 description: A string of up to DESC_LIMIT characters 114 containing the main notification text. 115 event: A string of up to 1000 characters containing a 116 subject or brief description of the event. 117 split: A boolean indicating whether to split long 118 descriptions among multiple notifications (True) or to 119 possibly raise an exception (False). (default True) 120 kwargs: A dictionary with any of the following strings as 121 keys: 122 priority: An integer between -2 and 2, indicating the 123 priority of the notification. -2 is the lowest, 2 is 124 the highest, and 0 is normal. 125 url: A string of up to 2000 characters containing a URL 126 to attach to the notification. 127 content_type: A string containing "text/html" (without 128 the quotes) that then allows some basic HTML to be 129 used while displaying the notification. 130 (default: None) 131 132 Raises: 133 pushnotify.exceptions.ApiKeyError 134 pushnotify.exceptions.FormatError 135 pushnotify.exceptions.RateLimitExceeded 136 pushnotify.exceptions.ServerError 137 pushnotify.exceptions.UnknownError 138 pushnotify.exceptions.UnrecognizedResponseError 139 140 """ 141 142 def send_notify(description, event, kwargs): 143 data = {'apikey': ','.join(self.apikeys), 144 'application': self.application, 145 'event': event, 146 'description': description} 147 148 if self.developerkey: 149 data['developerkey'] = self.developerkey 150 151 if kwargs: 152 data.update(kwargs) 153 154 response_stream = self._post(self._urls['notify'], data) 155 self._parse_response_stream(response_stream)
156 157 if not self.apikeys: 158 self.logger.warn('notify called with no users set') 159 return 160 161 if split: 162 while description: 163 this_desc = description[0:DESC_LIMIT] 164 description = description[DESC_LIMIT:] 165 send_notify(this_desc, event, kwargs) 166 else: 167 send_notify(description, event, kwargs)
168
169 - def verify(self, apikey):
170 """This method is deprecated. Use verify_user instead. 171 172 """ 173 174 msg = 'The verify method is deprecated. User verify_user instead.' 175 self.logger.warn(msg) 176 warnings.warn(msg, DeprecationWarning) 177 178 return self.verify_user(apikey)
179
180 - def verify_user(self, apikey):
181 """Verify a user's API key. 182 183 Args: 184 apikey: A string of 48 characters containing a user's API 185 key. 186 187 Raises: 188 pushnotify.exceptions.RateLimitExceeded 189 pushnotify.exceptions.ServerError 190 pushnotify.exceptions.UnknownError 191 pushnotify.exceptions.UnrecognizedResponseError 192 193 Returns: 194 A boolean containing True if the user's API key is valid, 195 and False if it is not. 196 197 """ 198 199 data = {'apikey': apikey} 200 201 if self.developerkey: 202 data['developerkey'] = self.developerkey 203 204 response_stream = self._get(self._urls['verify'], data) 205 self._parse_response_stream(response_stream, True) 206 207 return self._last['code'] == '200'
208 209 if __name__ == '__main__': 210 pass 211