iro/offer/smstrade.py
author Sandro Knauß <knauss@netzguerilla.net>
Thu, 23 Feb 2012 16:57:57 +0100
branchdevel
changeset 183 07ee5543751b
parent 180 55ab949cf0f8
child 186 b381eaa774ab
permissions -rw-r--r--
offer.provider now handles the options dict and loadConfig is only in Provider class

# -*- coding: utf-8 -*-
#Copyright (C) 2009  Georg Bischoff

#This program is free software; you can redistribute it and/or modify it under the terms
#of the GNU General Public License as published by the Free Software Foundation;
#either version 3 of the License, or any later version.
#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#See the GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program; if not, see <http://www.gnu.org/licenses/>.


import urllib
import copy
from functools import partial

from ..config import Option
from ..model.status import Status
from .provider import Provider, providers

import logging
logger=logging.getLogger("smstrade")

class UnknownStatusCode(Exception):
    def __init__(self,code):
        self.code=code

    def __str__(self):
        return "StatusCode %i is unknown"%self.code


class StatusCode:
     statusCodes = {10 : "Empfaengernummer nicht korrekt",
            20 : "Absenderkennung nicht korrekt",
            30 : "Nachrichtentext nicht korrekt",
            31 : "Messagetyp nicht korrekt",
            40 : "SMS Route nicht korrekt",
            50 : "Identifikation fehlgeschlagen",
            60 : "nicht genuegend Guthaben",
            70 : "Netz wird von Route nicht abgedeckt",
            71 : "Feature nicht ueber diese Route moeglich",
            80 : "Uebergabe an SMS-C fehlgeschlagen",
            90 : "Versand nicht moeglich",
            100 : "SMS wurde versendet",
            }

     def __init__(self,code, mID=None, cost=None, count=None):
        if code in self.statusCodes.keys():
            self.code=code
        else:
            raise UnknownStatusCode(code)
        self.mID=mID
        self.cost = cost
        self.count = count
     
     def __str__(self):
        try:
            return self.statusCodes[self.code]
        except IndexError:
            raise UnknownStatusCode(self.code)

     def __int__(self):
        if not self.code in self.statusCodes.keys():
            raise UnknownStatusCode(self.code)
        return self.code




class Smstrade(Provider):
    """
    s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf
    """
    params= {"debug":("boolean",False),
            "concat_sms":('boolean',False),
            "message_id":('boolean',False),
            "count":('boolean',False),
            "cost":('boolean',False),
           }
    def __init__(self, name, config):       
        self.url = "https://gateway.smstrade.de"
        Provider.__init__(self,name,config,{"sms":["basic","economy","gold","direct"]})
        self.options.update({
            "key":Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True)
            })
        self.loadConfig()

    def send(self, route, sms, recipient):
        """send SMS with $sms to $recipients"""
        logger.debug('smstrade.sendSMS(%s,%s)'%(sms,  recipient))
        route = unicode(route)

        if recipient.land != '49' and route == "basic":
            return Exception()
        
        to ='00'+recipient.land+recipient.number
        try:
            smsSendStatus = self.__send(route, to, sms)	
            logger.info('smstrade._send(...)=%i(%s)'%(int(smsSendStatus),str(smsSendStatus)))
            if int(smsSendStatus) in (100,):
                return Status(self,route)
            else:
                raise Exception()
        except UnknownStatusCode:
            raise Exception()

    def __send(self, route, to, sms):
        """ This function is the main part of the request to the sms service.    
        The function has to return a unicode formated string that will represent the answer of the sms service
        to the request."""
        logger.debug('smstrade._send(%s,%s,%s)'%( route, to, sms))
        parameters= {"key": self.key,
                "route": route,
                "to": to,
                "message": sms.content.encode("utf-8"),
                "charset":"utf-8", 
                "debug": self.testmode,
                "message_id":True,
                "count":True,
                "cost":True,
                }
        
        doubleChar="€[]{}|\\^~"    #these charactar need two GSM Chars

        if sms.from_ is not None:
            parameters["from"] = sms.from_
       
        length=len(sms.content)
        for s in doubleChar:
            length += sms.content.count(s)
        parameters["concat_sms"] = True if length > 160 else False

        ps={}
        for p in parameters:
            if p in self.params.keys():
                if self.params[p][0] == "boolean":
                    if parameters[p] != self.params[p][1]:
                        ps[p]=int(not self.params[p][1])
            else:
                ps[p] = parameters[p]

        params = urllib.urlencode(ps)
        dp=copy.deepcopy(ps)
        dp["key"]="<KEY>"
        logger.debug('smstrade._send-parameters:%s\n\t->%s'%(str(dp), urllib.urlencode(dp)) )
        
        response = urllib.urlopen(self.url, params)
        data = response.readlines()
        if len(data) == 1:
            return StatusCode(int(data[0]))
        return StatusCode(int(data[0]),mID=data[1],cost=data[2],count=data[3])

    def getSendFunc(self, typ, route):
        Provider.getSendFunc(self, typ, route)
        return partial(self.send,route)

providers["smstrade"]=Smstrade