#!/usr/local/bin/python """ SMS Mailer. This module allows sending SMS messages using one of the available free SMS mailer web-sites. Copyright (c) 2000, Marc-Andre Lemburg (mal@lemburg.com). All Rights Reserved. *** For Private Use Only ! *** Permission to use, copy, modify, and distribute this software and its documentation for any private, non-commercial purpose and without fee or royalty is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation or portions thereof, including modifications, that you make. Before sending SMS messages using this module, you must make sure that you are in accord and accept the usage conditions and limitations set forth by the SMS message service of your choice. Some message services disallow usage of techniques applied in this module. If this is the case, you are not allowed to use the module for sending SMS messages via these services. Usage of this software is at your own risk. THE AUTHOR MARC-ANDRE LEMBURG DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! """#" import urllib, string # Version number __version__ = '0.1' ### Changelog # # 0.1 - initial release # # Enable debugging output ? __debug__ = 0 class SMSMailer: """ Base class for SMS Mailers. The base class does not provide a usable SMS Mailer. You have to subclass this class in order to specify the different options. """ # URL which provides the service url = '' # FORM ACTION method to use ('post' or get') method = 'post' # Static cookie to send cookie = '' # If set, .cookie will be set by first querying a cookie from the # following URL cookieurl = '' # Max. size of a single message maxsize = 120 # User agent string to send agent = 'Mozilla/4.7 [en] (Win98; U)' def format_params(self, params, quote=urllib.quote,join=string.join, strip=string.strip): l = [] for k,v in params.items(): k = strip(str(k)) v = str(v) l.append('%s=%s' % (quote(k), quote(v))) return join(l, '&') def get_cookie(self): if not self.cookieurl: return self.cookie wget = urllib.FancyURLopener() f = wget.open(self.cookieurl) try: cookie = f.headers.dict['set-cookie'] except KeyError: cookie = self.cookie else: cookie = string.split(cookie, ';', 1)[0] f.close() return cookie def encode(self, message, network, phone, idd): params = {} params['idd'] = idd params['network'] = network params['phone'] = phone params['message'] = message return params def format_message(self, message, join=string.join): l = [] while message: l.append(message[:16]) message = message[16:] if not l: raise ValueError, 'empty message' if len(l[-1]) < 16: l[-1] = l[-1] + '.'*(16 - len(l[-1])) l.append('-' * 16) text = join(l, '') if len(text) > self.maxsize: raise ValueError, \ 'message too long: max length = %i' % \ self.maxsize return text def send(self, message, network, phone, idd='49'): # Check parameters message = str(message) phone = str(phone) network = str(network) idd = str(idd) if not phone: raise ValueError, 'missing phone number' if not network: raise ValueError, 'missing network number' if not message: raise ValueError, 'empty message' # Format message message = self.format_message(message) # Get cookie cookie = self.get_cookie() if __debug__: print 'Using cookie',cookie # Format and send data params = self.encode(message, network, phone, idd) data = self.format_params(params) wget = urllib.FancyURLopener() #wget = urllib.URLopener() wget.addheaders = [('User-Agent', self.agent)] wget.addheaders.append(('Cookie', cookie)) if self.method == 'post': connection = wget.open(self.url, data) else: connection = wget.open(self.url + '?' + data) reply = connection.read() connection.close() # Check reply return self.check_reply(reply) def check_reply(self, reply): return 1 ### Subclasses for different Free Mailers # # Example for a SMSMailer subclass. # # You will have to adapt this class to the free SMS message provider # you intend to use. Please read the provider's usage conditions # carefully -- not all services will allow these techniques to be # used. # class MySMSMailer(SMSMailer): """ http://www..com/ Tested. Fast and reliable. Limitation: Max. 5 SMS / day to one phone from one IP address. """ # URL which provides the service url = 'http://www..com/sms/send.php3' # Where to get the cookie from... cookieurl = ('http://www..com/sms/send.php3?' 'action=accept') def encode(self, message, network, phone, idd): params = {} params['action'] = 'send' params['othernetwork'] = 'yes' params['networkkey'] = '' while network[0] == '0': network = network[1:] while idd[0] == '+': idd = idd[1:] params['number'] = '+%s %s %s' % (idd, network, phone) params['message'] = message params['send'] = 'Send message!' return params def check_reply(self, reply): if string.find(reply, 'successful') >= 0: return 1 if __debug__: print 'FAILED TO SEND MESSAGE:' print reply return 0 ### Testing if __name__ == '__main__': # Create SMSMailer instance sms = MySMSMailer() # Get data print 'Send an SMS to' idd = raw_input( ' Access Code [+49]: ') or '+49' network = raw_input(' Network Number : ') phone = raw_input( ' Phone Number : ') print print 'Message (one line only):' message = raw_input() print # Send message if sms.send(message, network, phone, idd): print 'Message sent.' else: print 'Failed to send message.'