py-pushnotify / pushnotify / abstract.py

#!/usr/bin/env python
# vim: set fileencoding=utf-8

"""Module for abstract class.

copyright: Copyright (c) Jeffrey Goettsch and other contributors.
license: BSD, see LICENSE for details.

"""

import httplib2
import logging
import urllib


class AbstractClient(object):
    """Abstract client for sending push notifications. Inherit from this
    class but don't call it directly.

    Member Vars:
        developerkey: A string containing a valid developer key for the
            client's application.
        application: A string containing the name of the application on
            behalf of whom the client will be sending messages.
        apikeys: A dictionary where the keys are strings containing
            valid user API keys, and the values are lists of strings,
            each containing a valid user device key.

    """

    def __init__(self, developerkey='', application=''):
        """Initialize the client.

        Args:
            developerkey: A string containing a valid developer key for
                the client's application.
            application: A string containing the name of the application
                on behalf of whom the client will be sending messages.

        """

        self.logger = logging.getLogger('{0}.{1}'.format(
            self.__module__, self.__class__.__name__))

        if not application:
            application = 'pushnotify'

        self.developerkey = developerkey
        self.application = application
        self.apikeys = {}

        # as of 2012-10-06, the pushover server does not pass SSL validation
        # because httplib2 uses its own certificate store
        # see: http://code.google.com/p/httplib2/issues/detail?id=154

        self._browser = httplib2.Http(
            '.cache', disable_ssl_certificate_validation=True)
        self._last = {}
        self._urls = {'notify': '', 'verify': ''}

    def _get(self, url, data):

        querystring = urllib.urlencode(data)
        url = '?'.join([url, querystring])

        self.logger.debug('_get requesting url: {0}'.format(url))

        return self._browser.request(url, 'GET')

    def _post(self, url, data):

        body = urllib.urlencode(data)

        self.logger.debug('_post sending data: {0}'.format(body))
        self.logger.debug('_post sending to url: {0}'.format(url))

        return self._browser.request(
            url, 'POST', body,
            headers={'Content-Type': 'application/x-www-form-urlencoded'})

    def add_key(self, apikey, device_key=''):
        """Add the given key to self.apikeys.

        Args:
            apikey: A string containing a valid user's API key for the
                client's application.
            device_key: A string containing a valid device key to go
                along with the API key. (default: '')
        """

        if apikey not in self.apikeys:
            self.apikeys[apikey] = []

        if device_key and device_key not in self.apikeys[apikey]:
            self.apikeys[apikey].append(device_key)

    def del_key(self, apikey, device_key=''):
        """Delete the given API key or device key from self.apikeys.

        If device_key is not set, delete apikey and all of its device
        keys. Otherwise only delete the device key.

        Args:
            apikey: A string containing a valid user's API key that is
                in self.apikeys.
            device_key: A string containing a valid device key that is
                in self.apikeys[apikey]. (default: '')

        """

        if device_key:
            self.apikeys[apikey] = [value for value in self.apikeys[apikey]
                                    if value != device_key]
        else:
            del(self.apikeys[apikey])

    def notify(self, description, event, split=True, kwargs=None):
        """Send a notification to each user/device combination in
        self.apikeys.

        Args:
            description: A string containing the main notification text.
                The maximum length varies by application. See each
                client's documentation for details.
            event: A string containing a subject or brief description of
                the event. The maximum length varies by application. See
                each client's documentation for details.
            split: A boolean indicating whether to split long
                descriptions among multiple notifications (True) or to
                raise an exception if it is too long (False).
                (default True)
            kwargs: A dictionary for application specific options. See
                each client's documentation for details.
                (default: None)

        Raises:
            pushnotify.exceptions.ApiKeyError
            pushnotify.exceptions.FormatError
            pushnotify.exceptions.RateLimitExceeded
            pushnotify.exceptions.ServerError
            pushnotify.exceptions.UnknownError
            pushnotify.exceptions.UnrecognizedResponseError

        """

        raise NotImplementedError

    def retrieve_apikey(self, reg_token):

        raise NotImplementedError

    def retrieve_token(self):

        raise NotImplementedError

    def verify_device(self, apikey, device_key):
        """Verify a device identifier for the user given by apikey.

        Args:
            apikey: A string containing a user identifer.
            device_key: A string containing a device identifier.

        Raises:
            pushnotify.exceptions.ApiKeyError

        Returns:
            A boolean containing True if device_key is valid for
            apikey, and False if it is not.

        """

        raise NotImplementedError

    def verify_user(self, apikey):
        """Verify a user's API key.

        Args:
            apikey: A string containing a user's API key.

        Raises:
            pushnotify.exceptions.RateLimitExceeded
            pushnotify.exceptions.ServerError
            pushnotify.exceptions.UnknownError
            pushnotify.exceptions.UnrecognizedResponseError

        Returns:
            A boolean containing True if the user's API key is valid,
            and False if it is not.

        """

        raise NotImplementedError
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.