1 #!/usr/bin/env python 2 3 from email import message_from_file 4 from email.mime.multipart import MIMEMultipart 5 from email.mime.text import MIMEText 6 from smtplib import SMTP 7 from imiptools.content import handle_itip_part 8 import imip_resource 9 import sys 10 11 MESSAGE_SENDER = "resources+agent@example.com" 12 13 MESSAGE_SUBJECT = "Calendar system message" 14 15 MESSAGE_TEXT = """\ 16 This is a response to a calendar message sent by your calendar program. 17 """ 18 19 # Postfix exit codes. 20 21 EX_TEMPFAIL = 75 22 23 # Permitted iTIP content types. 24 25 itip_content_types = [ 26 "text/calendar", # from RFC 6047 27 "text/x-vcalendar", "application/ics", # other possibilities 28 ] 29 30 # Sending of outgoing messages. 31 32 def sendmail(sender, recipients, data): 33 smtp = SMTP("localhost") 34 smtp.sendmail(sender, recipients, data) 35 smtp.quit() 36 37 # Processing of incoming messages. 38 39 def process(f, original_recipients, recipients, this_sender): 40 41 """ 42 Process content from the stream 'f' accompanied by the given 43 'original_recipients' and 'recipients', together with details of 44 'this_sender' (the sender address on messages sent by this service). 45 """ 46 47 msg = message_from_file(f) 48 senders = msg.get_all("Reply-To") or msg.get_all("From") 49 original_recipients = original_recipients or get_all_values(msg, "To") 50 51 # Handle messages with iTIP parts. 52 53 all_parts = [] 54 55 for part in msg.walk(): 56 if part.get_content_type() in itip_content_types and \ 57 part.get_param("method"): 58 59 # NOTE: Act on behalf of resources for now. 60 61 all_parts += handle_itip_part(part, original_recipients, imip_resource.handlers) 62 63 # Pack the parts into a single message. 64 65 if all_parts: 66 text_part = MIMEText(MESSAGE_TEXT) 67 all_parts.insert(0, text_part) 68 message = MIMEMultipart("alternative", _subparts=all_parts) 69 message.preamble = MESSAGE_TEXT 70 71 message["From"] = this_sender 72 for sender in senders: 73 message["To"] = sender 74 message["Subject"] = MESSAGE_SUBJECT 75 76 if "-d" in sys.argv: 77 print message 78 else: 79 sendmail(this_sender, senders, message.as_string()) 80 81 def get_all_values(msg, key): 82 l = [] 83 for v in msg.get_all(key) or []: 84 l += [s.strip() for s in v.split(",")] 85 return l 86 87 def main(): 88 89 "Interpret program arguments and process input." 90 91 # Obtain the different kinds of recipients plus sender address. 92 93 original_recipients = [] 94 recipients = [] 95 senders = [] 96 97 l = [] 98 99 for arg in sys.argv[1:]: 100 101 # Switch to collecting recipients. 102 103 if arg == "-o": 104 l = original_recipients 105 elif arg == "-r": 106 l = recipients 107 108 # Switch to collecting senders. 109 110 elif arg == "-s": 111 l = senders 112 113 # Ignore debugging options. 114 115 elif arg == "-d": 116 pass 117 else: 118 l.append(arg) 119 120 process(sys.stdin, original_recipients, recipients, senders and senders[0] or MESSAGE_SENDER) 121 122 if __name__ == "__main__": 123 if "-d" in sys.argv[1:]: 124 main() 125 else: 126 try: 127 main() 128 except SystemExit, value: 129 sys.exit(value) 130 except Exception, exc: 131 type, value, tb = sys.exc_info() 132 print >>sys.stderr, "Exception %s at %d" % (exc, tb.tb_lineno) 133 sys.exit(EX_TEMPFAIL) 134 sys.exit(0) 135 136 # vim: tabstop=4 expandtab shiftwidth=4