iro/offer/provider.py
author Sandro Knauß <knauss@netzguerilla.net>
Fri, 24 Aug 2012 01:05:06 +0200
branchdevel
changeset 294 0e75bd39767d
parent 282 50cc13814bfb
permissions -rw-r--r--
adding LICENSE to all files

# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net>
# 
# This file is part of Iro.
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# #Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from functools import partial
try:
    from collections import OrderedDict
except ImportError:
    from ordereddict import OrderedDict

from ..error import NoRoute, NoTyp, ValidateException, NoProvider
from ..config import Option, Config

class Provider(Config):
    """Base class for Providerbackends."""

    testmode = False
    """- **True** -- no message to external provider should be send.
    - **False** (default) -- message are send to external provider."""
    def __init__(self, name, typs={}, options=[]):
        """Constructor for Provider class.
        
        :param string name: Name of the Provider.
        :param dict typs: A Dictonary with typs and routes.
        :param items options: [("name",Option(...)),...]

        >>> p = Provider("myProvider",{"sms":["route1","route2"]})
        """

        Config.__init__(self, name, OrderedDict([
                    ("typ",Option(vProvider, long="One available provider typ.", must=True, default=name))
                    ]+options)
                )
        self.typs=typs
        self.testmode = False

    def send(self, typ, route, recipient, message):
        """Main send function, that is called, for every single message.

        .. note::
            This function is not used directly. Normally :func:`~iro.offer.provider.Provider.getSendFunc` return this function with typ and route bound."""
        pass

    def getSendFunc(self, typ, route):
        """Returns the actually send function for a given typ and route.
        
        Normally it returns the send function with typ and route bound.

        :raises: :exc:`~iro.error.NoRoute`, :exc:`~iro.error.NoTyp`
        """

        try:
            if route not in self.typs[typ]:
                raise NoRoute(route)
        except KeyError:
            raise NoTyp(route)
        return partial(self.send, typ, route)

def getProvider(name, typ, config):
    '''creates a provider object and init this with config.
   
    :param dict config: The Configuration dict. Normally you use ``configParser.items("section")``.
    :param string typ: A valid typ
    :raises: :exc:`~iro.error.NoProvider`
    '''
    try:
        p = providers[typ](name)
        p.load(config)
        return p
    except KeyError:
        raise NoProvider(typ)

def vProvider(typ, field):
    '''validator to test the existence of the typ.

    :param string typ: A typ
    :param string field: A field name used for the Exception.
    :return:
        - valid -- returns typ
        - invalid -- raises :class:`~iro.error.ValidateException`

    :raises: :exc:`~iro.error.ValidateException`
    '''
    if typ not in providers.keys():
        raise ValidateException(field=field)
    return typ

providers={}
"""Avalable Providers.
    - **key** -- typ of provider (see configuration typ field).
    - **value** -- class to handle specific Providertyp.

To extend provider typs, just add this new typ to this dict.
see :doc:`provider`
   
"""