source: products/PloneSMSCommunicator/trunk/PloneSMSCommunicator.py

Last change on this file was 1, checked in by myroslav, 19 years ago

Building directory structure

File size: 7.5 KB
Line 
1# Author: Melnychuk Taras
2# Contact: fenix@quintagroup.com
3# Date: $Date: 2005-11-23 11:05:50 +0200 (Thu, 23 Nov 2005) $
4# Copyright: quintagroup.com
5
6"""
7This tool talks to XIAM gateway at cellphone operator
8via XIAM-XML protocol. You'd have to set XIAM gateway properties
9in the tool' configlet before you are able to send SMSes.
10This module defines the following classes:
11
12    - `PloneSMSCommunicator`, this is the tool that carries responsibility for
13                              connection with server (message center) and sending via XIAM-XML protocol
14                              requests(short message) to server and get responses from it
15
16            Methods:
17
18              - `PloneSMSCommunicator.setProperties`: set PloneSMSCommunicator properties
19              - `PloneSMSCommunicator.getProperties`: return all properties if ids == None, else return properties that in ids list
20              - `PloneSMSCommunicator.LOG`: write all needed data to log file
21              - `PloneSMSCommunicator.write_sms`: write sms 'in' and sms 'out' files to sms directory
22              - `PloneSMSCommunicator.send_Request`: this function will send message to destination
23              - `PloneSMSCommunicator.Response`: write all data from response to xiam.log file
24              - `PloneSMSCommunicator.getAvailableSMSPolicies`: return sms policies
25              - `PloneSMSCommunicator.getServerInfo`: return dictionary that contains host name and ip address
26              - `PloneSMSCommunicator.getLogs`: return records from log file
27
28
29Exception classes:
30
31    - `SendMessageError`
32
33"""
34__docformat__ = 'restructuredtext'
35
36from Products.PloneSMSCommunicator.Utils import getHostName
37from urllib2 import urlopen, Request, HTTPError, URLError
38from Products.Archetypes.public import *
39from xml.dom.minidom import *
40from StringIO import StringIO
41from DateTime import DateTime
42from time import strftime
43import socket
44import os
45
46from config import *
47from pyXIAM import *
48
49
50class SendMessageError(IOError):
51
52    def __init__(self, reason):
53        self.reason = reason
54
55    def __str__(self):
56        return '<Can\'t send message because %s>' % self.reason
57
58class PloneSMSCommunicator(BaseFolder):
59
60    _properties = (
61      { 'id': 'server_url', 'type':'string', 'mode':'w' },
62      { 'id': 'policy', 'type':'selection', 'mode':'w', 'select_variable':'getAvailableSMSPolicies'},
63      { 'id': 'mtMessageOriginator', 'type':'string', 'mode':'w' },
64      { 'id': 'provider_id', 'type':'string', 'mode':'w' },
65      { 'id': 'log_flag', 'type':'boolean', 'mode':'w' },
66    )
67
68    archetype_name="PloneSMSCommunicator"
69    id=COMMUNICATORID
70
71    def __init__(self):
72        BaseFolder.__init__(self, self.id)
73        self.server_url = SERVER_URL
74        self.policy = 'free'
75        self.mtMessageOriginator = ORIGINATOR
76        self.log_flag = True
77        self.provider_id = PROVIDER
78
79    def setProperties(self, **properties):
80        """
81        set PloneSMSCommunicator properties
82         Parameters:
83
84          -**properties: this is the dictionary that contains pair(property_name: value)
85        """
86        for property in properties.keys():
87            setattr(self, property, properties[property])
88
89    def getProperties(self, ids = []):
90        """
91        return all properties if ids == None, else return properties that in ids list
92        """
93        props = {}
94        if ids:
95            for i in ids:
96                props[i] = getattr(self, i)
97        else:
98            for p in self._properties:
99                property = p['id']
100                props[property] = getattr(self, property, None)
101
102        return props
103
104    def LOG(self, INFO, data):
105        """
106        write all needed data to log file
107         Parameters:
108
109          - INFO: this is the parameter that defines priority of log data
110          - data: all needed data to write
111        """
112        if self.log_flag:
113            log_time = DateTime().strftime("%Y/%m/%d %H:%M:%S")
114            xiam_log = file(XIAM_LOG, 'a')
115            xiam_log.write(log_time)
116            xiam_log.write(data)
117
118    def write_sms(self, sms_id, request = None, response = None):
119        """
120        write sms 'in' and sms 'out' files to sms directory
121         Parameters:
122
123          - sms_id: id of your short message
124          - request: this is the data that was sent
125          - response: this is the data that was received from server
126        """
127        if self.log_flag:
128            #create sms directory
129            if  not 'sms' in os.listdir(CLIENT_HOME):
130                 os.mkdir(CLIENT_HOME+'/sms')
131
132            if request:
133                sms_request = file(SMS_LOG+sms_id+'out.xml', 'w')
134                sms_request.write(request)
135                sms_request.close()
136
137            if response:
138                sms_response = file(SMS_LOG+sms_id+'in.xml', 'w')
139                sms_response.write(response)
140                sms_response.close()
141
142    def send_Request(self, originator, destination, body):
143        """
144        This function will send message to destination.
145         Parameters:
146
147          - originator: contains phone number of message originator
148          - destination: contains phone number of destination
149          - body: this is the text of your message
150        """
151        response = StringIO()
152        request=SMSsubmitRequest(originator, destination, body)
153        xml = str(request.toXML())
154        self.write_sms(request.id, request = xml)
155        data = Request(self.server_url, xml, headers = {'X-XIAM-Provider-ID':self.provider_id})
156        self.LOG('INFO', " > Sent %(id)s request. Originator: %(originator)s, %(noRecipients)d recipients (%(id)sout.xml)\n" % \
157            {'id': request.id,
158             'originator': originator,
159             'noRecipients': len(destination)
160            })
161        try:
162            response = urlopen(data)
163            response_status = '200 OK'
164        except HTTPError, e:
165            response_status = str(e.code)+' '+e.msg
166        except URLError, e:
167            raise SendMessageError(e)
168        str_response = response.read()
169        self.write_sms(request.id, response = str_response)
170        self.LOG('INFO', " < Received response %(response_status)s (%(id)sin.xml)\n" % \
171            {'response_status': response_status,
172             'id': request.id
173            })
174        response.close()
175
176    def Response(self, REQUEST = None):
177        """
178        write all data from response to xiam.log file
179        """
180        stream = REQUEST.stdin
181        stream.seek(0)
182        response_xml = stream.read()
183        self.LOG('INFO', response_xml)
184        return
185
186    def getAvailableSMSPolicies(self):
187        """
188        return sms policies
189        """
190        return ['free', 'enforceOriginator']
191
192    def getServerInfo(self, server_url):
193        """
194        return dictionary that contains host name and ip address
195         Parameters:
196
197          - server_url: url address of server
198        """
199        info = {}
200        info['host_name'] = getHostName(server_url)
201        info['ip_addr'] = socket.gethostbyname(info['host_name'])
202        return info
203
204    def getLogs(self, size):
205        """
206        return records from log file
207         Parameters:
208
209          - size: number of needed records
210        """
211        line = ''
212        result = []
213        xiam_log = file(XIAM_LOG, 'r')
214        logs = xiam_log.read()
215        for log in logs:
216            if log != '\n':
217                line = line+log
218            else:
219                result.append(line)
220                line = ''
221        result = result[-size:]
222        result.reverse()
223        return result
224
225registerType(PloneSMSCommunicator)
Note: See TracBrowser for help on using the repository browser.