Import re instead of sre.
[ottawa-travel-planner.git] / mailPlanner.py
blob5e40ced5774e02216b0857cb84aec16bbee68382
1 #!/usr/bin/python
2 # vi: set softtabstop=4 shiftwidth=4 tabstop=8 expandtab:
4 import email.FeedParser
5 from email.MIMEText import MIMEText
6 from email.Utils import parseaddr
7 import smtplib
8 import sys
9 import traceback
10 import syslog
12 import Planner
13 import PlanTime
14 import time
15 import CommandParser
16 import ShortFormatter
18 FROM_ADDRESS = "tp@hurts.ca"
19 SMTP_SERVER = "127.0.0.1"
21 def logIt(string):
22 syslog.syslog(syslog.LOG_INFO, string)
24 def sendMessage(msg, to):
25 msg['From'] = FROM_ADDRESS
26 msg['To'] = to
28 s = smtplib.SMTP(SMTP_SERVER)
29 s.sendmail(parseaddr(FROM_ADDRESS)[1], [parseaddr(msg['To'])[1]],
30 msg.as_string())
31 s.close()
33 def sendError(e, replyto):
34 sendMessage(MIMEText(e.args[0]), replyto)
36 def handleMessage(msg, replyto):
37 try:
38 if msg.is_multipart():
39 raise Exception("Sorry, fancy multipart messages aren't supported.")
41 for line in msg.get_payload().splitlines():
42 s = line.strip()
43 if len(s) != 0:
44 logIt(s)
45 cmd = CommandParser.CommandParser(s).cmd
46 break
47 else:
48 # No command.
49 logIt("Empty command from %s" % replyto)
50 return 0
52 # Leave in 3 minutes if time is unspecified.
53 if cmd.time is None:
54 cmd.time = PlanTime.PlanTime(time.time() + 180,
55 PlanTime.MUST_LEAVE_AFTER)
57 itin = Planner.plan(cmd.start, cmd.end, cmd.time)
58 sf = ShortFormatter.ShortFormatter(itin.entries)
60 text = "\n".join(sf.lines)
61 if itin.anyUnparsed():
62 text += "\nWarning: This itinerary display may be incomplete!"
64 logIt("%s: success, %d entries" % (s, len(itin.entries)))
65 sendMessage(MIMEText(text), replyto)
66 except Exception, e:
67 logIt("Exception: %s" % e)
68 logIt(traceback.format_exc())
69 sendError(e, replyto)
71 # Always return success. Otherwise Postfix will send a bounce message.
72 return 0
74 def main():
75 fp = email.FeedParser.FeedParser()
76 for line in sys.stdin:
77 fp.feed(line)
78 msg = fp.close()
80 # if these headers are here, we can reply semi-intelligently with errors
81 replyto = msg["reply-to"] or msg["from"]
82 return handleMessage(msg, replyto)
84 if __name__ == '__main__':
85 syslog.openlog(sys.argv[0], syslog.LOG_DAEMON)
86 sys.exit(main())