iro/offer/provider.py
author Sandro Knauß <knauss@netzguerilla.net>
Fri, 30 Mar 2012 15:55:44 +0200
branchdevel
changeset 269 0d134b173cb1
parent 254 de301b8c58d9
child 275 88d45c846f2b
permissions -rw-r--r--
iro.config: using OrderedDict instead of Dict + List for Options.

from functools import partial
from collections 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 Functionfor 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`
   
"""