# HG changeset patch # User darius # Date 1189128707 0 # Node ID bf896507faa9d34105d94990b6a8b7da6650f6c9 # Parent 9f3eb9a079664a9a069971d71632e9db0ef4c98b Add code to send an SMS if configured to do so. Rearrange the output stage a bit to make it clearer. diff -r 9f3eb9a07966 -r bf896507faa9 SMSVodaAu.py --- /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) + diff -r 9f3eb9a07966 -r bf896507faa9 scrape-vb.ini --- 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 diff -r 9f3eb9a07966 -r bf896507faa9 scrape-vb.py --- 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])