1 #!/usr/bin/env python 2 3 from MoinMessage import * 4 from email.mime.application import MIMEApplication 5 from email.mime.text import MIMEText 6 from os.path import split 7 import sys 8 9 def add_update(message, action, part): 10 if action == "file": 11 action = "store" 12 part["Update-Action"] = action 13 message.add_update(part) 14 15 def readfile(filename): 16 f = open(filename, "rb") 17 try: 18 return MIMEApplication(f.read()) 19 finally: 20 f.close() 21 22 if __name__ == "__main__": 23 try: 24 signer = sys.argv[1] 25 recipient = sys.argv[2] 26 i = 3 27 if sys.argv[i] == "--to": 28 to = sys.argv[i+1] 29 i += 2 30 else: 31 to = None 32 if sys.argv[i] == "--forward": 33 forwarder = sys.argv[i+1] 34 i += 2 35 else: 36 forwarder = None 37 url = sys.argv[i] + "?action=PostMessage" 38 type = sys.argv[i+1] 39 action = sys.argv[i+2] 40 args = sys.argv[i+3:] 41 except IndexError: 42 args = None 43 44 if not args: 45 print >>sys.stderr, """\ 46 Need a signer, recipient, URL, update type, action and some updates as arguments to this program. 47 48 Syntax: 49 50 %s <signing keyid> <recipient keyid> [ --forward <signing keyid> ] <URL> \\ 51 <update type> <action> <update or part>... 52 53 The update type is typically "collection" for a number of separate updates, 54 or any other value for a single multipart update consisting of several parts. 55 56 The action may be "update", "replace" or "store", with subsequent updates 57 being text strings containing text for individual updates (or parts of a single 58 update). If action is "file", however, subsequent updates must refer to files 59 and communicated updates will be given a "store" update action. 60 """ % sys.argv[0] 61 sys.exit(1) 62 63 message = Message() 64 parts = [] 65 66 # A collection of updates involves adding each update directly to the 67 # message. A single update involves collecting the given parts, combining 68 # them and putting the combined update in the message. 69 70 for arg in args: 71 72 # Read files and assign filenames to them, or read argument strings, and 73 # adopt them as parts. 74 75 if action == "file": 76 part = readfile(arg) 77 part["Content-Disposition"] = split(arg)[-1] 78 else: 79 part = MIMEText(arg, "moin", sys.stdin.encoding) 80 81 if type == "collection": 82 add_update(message, action, part) 83 else: 84 parts.append(part) 85 86 # Obtain the alternative representations as an update and add it to the 87 # message. 88 89 if type != "collection": 90 multipart = message.get_update(parts) 91 add_update(message, action, multipart) 92 93 email_message = message.get_payload() 94 gpg = GPG() 95 96 try: 97 signed_message = gpg.signMessage(email_message, signer) 98 message_to_send = gpg.encryptMessage(signed_message, recipient) 99 100 # Forwarded messages should be timestamped and must be directed to a 101 # message store. 102 103 if forwarder: 104 timestamp(message_to_send) 105 message_to_send["Update-Action"] = "store" 106 message_to_send = gpg.signMessage(message_to_send, forwarder) 107 108 # An explicit recipient can also be added. 109 110 if to: 111 message_to_send["To"] = to 112 113 resp = sendMessage(message_to_send, url) 114 print resp 115 116 except MoinMessageError, exc: 117 print >>sys.stderr, exc 118 119 # vim: tabstop=4 expandtab shiftwidth=4