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

Source Code for Module pushnotify.nma

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