1 # -*- coding: utf-8 -*- |
|
2 #Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de> |
|
3 |
|
4 #This program is free software; you can redistribute it and/or modify it under the terms |
|
5 #of the GNU General Public License as published by the Free Software Foundation; |
|
6 #either version 3 of the License, or any later version. |
|
7 #This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|
8 #without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
9 #See the GNU General Public License for more details. |
|
10 |
|
11 #You should have received a copy of the GNU General Public License |
|
12 #along with this program; if not, see <http://www.gnu.org/licenses/>. |
|
13 |
|
14 |
|
15 from anbieter import anbieter |
|
16 from telnumber import telnumber, NotATelNumber |
|
17 import ConfigParser |
|
18 import xmlrpclib |
|
19 import logging |
|
20 logger=logging.getLogger("sipgate") |
|
21 |
|
22 class NoValidStatusCode(Exception): |
|
23 def __init__(self, value): |
|
24 self.value = value |
|
25 |
|
26 def __str__(self): |
|
27 return repr(self.value) |
|
28 |
|
29 class sipgate(anbieter): |
|
30 """ |
|
31 s. auch http://www.tuxad.com/sipgate.html |
|
32 und http://lists.sipgate.net/pipermail/sipgate-developers/2007-September/000016.html |
|
33 """ |
|
34 section="sipgate" |
|
35 url="https://%s:%s@samurai.sipgate.net/RPC2" |
|
36 def __init__(self,user="",password=""): |
|
37 self.user=user |
|
38 self.password=password |
|
39 |
|
40 def read_basic_config(self,filenames): |
|
41 """Read basic options from the config file""" |
|
42 cp = ConfigParser.ConfigParser() |
|
43 cp.read(filenames) |
|
44 self.user=cp.get(self.section, 'user') |
|
45 self.password=cp.get(self.section, 'password') |
|
46 |
|
47 def sendSMS(self,sms,recipients): |
|
48 """send SMS with $sms to $recipients""" |
|
49 logger.debug('sipgate.sendSMS(%s,%s)'%(sms.getContent(), str(recipients))) |
|
50 args={ |
|
51 "TOS" : "text", |
|
52 "Content" : sms.getContent() |
|
53 } |
|
54 self.__send(args,recipients) |
|
55 |
|
56 def sendFAX(self,fax,recipients): |
|
57 """send the PDF file $fax to $recipients""" |
|
58 logger.debug('sipgate.sendFAX(%s,%s)'%(fax, str(recipients))) |
|
59 args={ |
|
60 "TOS" : "fax", |
|
61 "Content" : xmlrpclib.Binary(fax.getAttachment(0)), |
|
62 } |
|
63 self.__send(args,recipients) |
|
64 |
|
65 def __connect(self): |
|
66 """connect to sipgate XMLRPC Server""" |
|
67 logger.debug("sipgate.__connect()-"+self.url%(self.user,"XXXXXXXX")) |
|
68 |
|
69 self.serv=xmlrpclib.ServerProxy(self.url%(self.user,self.password)) |
|
70 self.samurai=self.serv.samurai |
|
71 |
|
72 args_identify = { |
|
73 "ClientName" : "anbieter.py", |
|
74 "ClientVersion" : "V1.0", |
|
75 "ClientVendor" : "Sandro Knauss" |
|
76 } |
|
77 self.__send_method(self.samurai.ClientIdentify, args_identify) |
|
78 return self.serv |
|
79 |
|
80 def __send_method(self, func, args=None): |
|
81 """execute $func and test weather if the func ran successfully or not""" |
|
82 logger.debug("sipgate.__send_method(func,%s)"%( args)) |
|
83 |
|
84 if args==None: |
|
85 xmlrpc_result = func() |
|
86 else: |
|
87 xmlrpc_result = func(args) |
|
88 if xmlrpc_result['StatusCode'] != 200: |
|
89 raise NoValidStatusCode("There was an error during identification to the server! %d %s"% (xmlrpc_result['StatusCode'], xmlrpc_result['StatusString'])) |
|
90 logger.debug("sipgate.__send_method(..):ok"); |
|
91 return xmlrpc_result |
|
92 |
|
93 def __send(self,args,recipients): |
|
94 """main sending method - sending the args to $recipients""" |
|
95 sended=[] |
|
96 |
|
97 serv=self.__connect() |
|
98 logger.debug('sipgate.__send(%s,%s)'%(args, recipients)) |
|
99 for recipient in recipients: |
|
100 try: |
|
101 tel = telnumber(recipient) |
|
102 |
|
103 if tel in sended: #only send message once per recipient |
|
104 continue |
|
105 sended.append(tel) |
|
106 |
|
107 args["RemoteUri"]="sip:%s%s@sipgate.net"%(tel.land,tel.number) |
|
108 self.__send_method(serv.samurai.SessionInitiate, args) |
|
109 self.updateStatus(arranged=recipient) |
|
110 |
|
111 except (NotATelNumber, NoValidStatusCode): |
|
112 self.updateStatus(failed=recipient) |
|
113 |
|
114 self.__disconnect() |
|
115 |
|
116 def updateStatus(self, arranged=None, failed=None): |
|
117 """is a function that is called, if a new SMS/FAX was send |
|
118 -arranged is non None, if SMS/FAX was sended successfully |
|
119 -failed is non None, if SMS/FAX sending failed |
|
120 the content will be the recipent""" |
|
121 pass |
|
122 |
|
123 def BalanceGet(self): |
|
124 """get the balance of sipgate""" |
|
125 self.__connect() |
|
126 ret = self.__send_method(self.samurai.BalanceGet ) |
|
127 self.__disconnect() |
|
128 return ret['CurrentBalance'] |
|
129 |
|
130 def getNewMessages(self): |
|
131 """get new messages from inbox""" |
|
132 self.__connect() |
|
133 tmp = self.__send_method(self.samurai.UmSummaryGet) |
|
134 self.__disconnect() |
|
135 tmp=tmp['UmSummary'] |
|
136 ret={} |
|
137 for entry in tmp: |
|
138 ret[entry['TOS']]={'read':entry["Read"],'unread':entry["Unread"]} |
|
139 return ret |
|
140 |
|
141 def getRecommendedInterval(self,methods): |
|
142 """how often you can call one $methods""" |
|
143 self.__connect() |
|
144 args = {"MethodList" : methods } |
|
145 tmp = self.__send_method(self.samurai.RecommendedIntervalGet, args) |
|
146 self. __disconnect() |
|
147 ret={} |
|
148 for entry in tmp['IntervalList']: |
|
149 ret[entry['MethodName']]=entry['RecommendedInterval'] |
|
150 return ret |
|
151 |
|
152 def __disconnect(self): |
|
153 """disconnect xmlrpc client""" |
|
154 logger.debug('sipgate.__disconnect()') |
|
155 self.samurai=None |
|
156 self.serv=None |
|
157 self.xmlrpc=None |
|