changeset 7:bf896507faa9

Add code to send an SMS if configured to do so. Rearrange the output stage a bit to make it clearer.
author darius
date Fri, 07 Sep 2007 01:31:47 +0000
parents 9f3eb9a07966
children d17fd6f3a492
files SMSVodaAu.py scrape-vb.ini scrape-vb.py
diffstat 3 files changed, 136 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SMSVodaAu.py	Fri Sep 07 01:31:47 2007 +0000
@@ -0,0 +1,66 @@
+import mechanize, ClientForm, re, sys, logging
+
+class BadLogin(Exception):
+    pass
+
+class SMSVodaAu:
+    MSGPAGE = 'https://www.myvodafone.com.au/yrweb2txt/enter.do'
+
+    def __init__(self, user, password):
+        self.br = mechanize.Browser()
+        self.cj = mechanize.CookieJar()
+        self.br.set_cookiejar(self.cj)
+        self.user = user
+        self.password = password
+
+    def dodebug(self):
+        # logging.DEBUG covers masses of debugging information,
+        # logging.INFO just shows the output from HTTPRedirectDebugProcessor,
+        logger = logging.getLogger("mechanize")
+        logger.addHandler(logging.StreamHandler(sys.stdout))
+        logger.setLevel(logging.DEBUG)
+        
+    def sendamsg(self, recipient, msg):
+        assert(len(msg) < 160)
+
+        self.br.open(self.MSGPAGE)
+        for f in self.br.forms():
+            if (f.name == 'loginForm'):
+                #print "Need to login"
+                self.br.select_form("loginForm")
+                self.br['txtUserID'] = self.user
+                self.br['txtPassword'] = self.password
+                response = self.br.submit()
+                if (re.match('Sorry you must enter a valid username and password', response.read(), re.IGNORECASE) != None):
+                    print "Unable to login"
+                    raise BadLogin()
+
+        self.br.select_form("sendMessageForm")
+
+        self.br.form.find_control("action").readonly = False
+        self.br.form.find_control("action").value = 'send'
+
+        self.br.form.find_control("totalMsgs").readonly = False
+        self.br.form.find_control("totalMsgs").value = '1'
+        
+        self.br.form.find_control("msg_counter").readonly = False
+        self.br.form.find_control("msg_counter").value = '1'
+
+        #c = self.br.form.find_control(name = "recipients")
+        #ClientForm.Item(c, {'contents' : 'adhoc' + recipient, 'value' : recipient})
+
+        nc = ClientForm.TextControl('text', 'recipients', {})
+        nc.add_to_form(self.br.form)
+        self.br.form.find_control(name = "recipients", type = "text").value = 'adhoc' + recipient
+        
+        self.br.form.find_control("messageBody").value = msg
+        self.br.form.find_control("counter").readonly = False
+        self.br.form.find_control("counter").value = str(160 - len(msg))
+
+        #return(self.br)
+        #f = open('out.html', 'w')
+        r = self.br.submit()
+        #f.write(r.read())
+        #r.seek(0)
+        return(r)
+        
--- a/scrape-vb.ini	Wed Aug 29 07:37:59 2007 +0000
+++ b/scrape-vb.ini	Fri Sep 07 01:31:47 2007 +0000
@@ -4,9 +4,13 @@
 #mailsubj="Virgin Blue Happy Hour Deals"
 #mailsend=True
 #vburl = 'http://virginblue.com.au'
+smsuser=0403070726
+smspass=DWxVl6DdjAg
+smssend=True
 
 [darius@dons.net.au]
-city1=Sydney
+phone=0403070726
+#city1=Perth
 
 [sarah.mahoney@nehta.give.au]
 city1=Adelaide
--- a/scrape-vb.py	Wed Aug 29 07:37:59 2007 +0000
+++ b/scrape-vb.py	Fri Sep 07 01:31:47 2007 +0000
@@ -6,7 +6,7 @@
 # Prints out (and emails) when criteria match based on cost,
 # destination, etc
 #
-# $Id: scrape-vb.py,v 1.5 2007/08/29 07:37:59 darius Exp $
+# $Id: scrape-vb.py,v 1.6 2007/09/07 01:31:47 darius Exp $
 ############################################################################
 #
 # Copyright (C) 2007 Daniel O'Connor. All rights reserved.
@@ -35,14 +35,14 @@
 ############################################################################
 
 import os, re, BeautifulSoup, datetime, time, smtplib, sys, urllib
-import ConfigParser, optparse
+import ConfigParser, optparse, SMSVodaAu
 
 usage = '''%prog [options]
 Reads configuration from ./scrape-vb.ini and ~/.scrape-vb.ini'''
 
-optparse = optparse.OptionParser(usage, version="$Id: scrape-vb.py,v 1.5 2007/08/29 07:37:59 darius Exp $")
+optparse = optparse.OptionParser(usage, version="$Id: scrape-vb.py,v 1.6 2007/09/07 01:31:47 darius Exp $")
 optparse.add_option('-d', '--debug', action="store_true", default=False,
-                    help="Disable mail sending, prints mail message to stdout")
+                    help="Disable mail & SMS sending, prints message to stdout")
 optparse.add_option('-f', '--file', help="Do not fetch the page, use this file instead")
 optparse.add_option('-e', '--example', action="store_true", default=False,
                     help="Print an example configuration file to stdout and exit")
@@ -55,6 +55,9 @@
 mailfrom=user@host.com
 mailsend=True
 mailhost=mail.server.com
+smsuser=0412312312
+smspass=mys3krit
+smssend=True
 
 [user@host.com]
 # All fields are optional
@@ -62,6 +65,7 @@
 city2=Bar
 when=dd/mm/yy
 maxcost=123
+phone=0498765432
 '''
     sys.exit(0)
     
@@ -86,7 +90,22 @@
 except IOError, e:
     print  "Unable to fetch page - " + str(e)
     sys.exit(1)
-    
+
+# Test if we have been configured to send SMSs
+try:
+    smsuser = conf.get('global', 'smsuser')
+    smspass = conf.get('global', 'smspass')
+    smssend = conf.getboolean('global', 'smssend')
+except ConfigParser.NoOptionError:
+    smssend = False
+
+if (options.debug == True and smssend):
+    print "smssend overridden due to debugging"
+    smssend = False
+
+if (smssend):
+    smshndl = SMSVodaAu.SMSVodaAu(smsuser, smspass)
+
 s = BeautifulSoup.BeautifulSoup(f)
 hrr = s.find("ul", "happyhr-rows")
 if (hrr == None):
@@ -105,6 +124,12 @@
 frtime = datetime.datetime(*time.strptime(times.group(1), "%d/%m/%y")[0:3])
 totime = datetime.datetime(*time.strptime(times.group(2), "%d/%m/%y")[0:3])
 
+#
+# Go through the HTML and work out who wants to be notified of what
+#
+# Store in output, a dictionary keyed by email adddress which holds a
+# list of each matching flight (city1, city2, cost, url)
+#
 output = {}
 for i in hrlist:
     href =  i.find('a')
@@ -152,6 +177,7 @@
                 output[t['email']] = []
             output[t['email']].append([city1, city2, cost, url])
 
+# Test if we have been configured to send email
 try:
     mailsubj = conf.get('global', 'mailsubj')
     mailhost = conf.get('global', 'mailhost')
@@ -167,27 +193,41 @@
 if (mailsend):
     server = smtplib.SMTP(mailhost)
     #server.set_debuglevel(1)
-else:
-    print "Note: Mail sending disabled"
-    
-for o in output:
-    if (mailsend):
-        msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (mailfrom, o, mailsubj))
+
+#
+# Output the various notifications
+#
+ttimestr = "Note: travel period is from %s to %s" % \
+           (frtime.strftime("%A %e %B %Y"), totime.strftime("%A %e %B %Y"))
+
+# Email each person about their flights    
+if (mailsend):
+    for o in output:
+        msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (mailfrom, o, mailsubj)
         msg = msg + "Your criteria for flights have been matched\r\n\r\n"
-    else:
+        for i in output[o]:
+            msg = msg + "%s <-> %s costs $%d - %s\r\n" % (i[0], i[1], i[2], i[3])
+
+        msg = msg + "\r\n" + ttimestr + "\r\n"
+        server.sendmail(mailfrom, o, msg)
+
+else:
+    # If not emailing print to stdout
+    for o in output:
         print "Match for " + o
-    for i in output[o]:
-        if (mailsend):
-            msg = msg + "%s <-> %s costs $%d - %s\r\n" % (i[0], i[1], i[2], i[3])
-        else:
+        for i in output[o]:
             print "%s <-> %s costs $%d" % (i[0], i[1], i[2])
 
-    ttimestr = "Note: travel period is from %s to %s" % \
-               (frtime.strftime("%A %e %B %Y"), totime.strftime("%A %e %B %Y"))
-
-    if (mailsend):
-        msg = msg + "\r\n" + ttimestr + "\r\n"
-        server.sendmail(mailfrom, o, msg)
-    else:
-        print ttimestr
-        print
+# SMS each person about their flights
+if (smssend):
+    for o in output:
+        if (conf.has_option(o, 'phone')):
+            msg = ""
+            for i in output[o]:
+                msg = msg + "%s <-> %s $%d, " % (i[0], i[1], i[2])
+            # Chop off the last , & make sure the whole message is not
+            # too large.
+            msgend = min(len(msg) - 2, 160)
+            print "SMS to " + conf.get(o, 'phone')
+            print msg[0:msgend]
+            smshndl.sendamsg(conf.get(o, 'phone'), msg[0:msgend])