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> \\ 51 [ --to <recipient address> ] \\ 52 [ --forward <signing keyid> ] \\ 53 <URL> \\ 54 <update type> <action> <update or part>... 55 56 The update type is typically "collection" for a number of separate updates, 57 or any other value for a single multipart update consisting of several parts. 58 59 The action may be "update", "replace" or "store", with subsequent updates 60 being text strings containing text for individual updates (or parts of a single 61 update). If action is "file", however, subsequent updates must refer to files 62 and communicated updates will be given a "store" update action. 63 """ % sys.argv[0] 64 sys.exit(1) 65 66 message = Message() 67 parts = [] 68 69 # A collection of updates involves adding each update directly to the 70 # message. A single update involves collecting the given parts, combining 71 # them and putting the combined update in the message. 72 73 for arg in args: 74 75 # Read files and assign filenames to them, or read argument strings, and 76 # adopt them as parts. 77 78 if action == "file": 79 part = readfile(arg) 80 part["Content-Disposition"] = split(arg)[-1] 81 else: 82 part = MIMEText(arg, "moin", sys.stdin.encoding) 83 84 if type == "collection": 85 add_update(message, action, part) 86 else: 87 parts.append(part) 88 89 # Obtain the alternative representations as an update and add it to the 90 # message. 91 92 if type != "collection": 93 multipart = message.get_update(parts) 94 add_update(message, action, multipart) 95 96 email_message = message.get_payload() 97 gpg = GPG() 98 99 try: 100 signed_message = gpg.signMessage(email_message, signer) 101 message_to_send = gpg.encryptMessage(signed_message, recipient) 102 103 # Forwarded messages should be timestamped and must be directed to a 104 # message store. 105 106 if forwarder: 107 timestamp(message_to_send) 108 message_to_send["Update-Action"] = "store" 109 message_to_send = gpg.signMessage(message_to_send, forwarder) 110 111 # An explicit recipient can also be added. 112 113 if to: 114 message_to_send["To"] = to 115 116 resp = sendMessage(message_to_send, url) 117 print resp 118 119 except MoinMessageTransferError, exc: 120 print >>sys.stderr, exc 121 print >>sys.stderr, exc.body 122 123 except MoinMessageError, exc: 124 print >>sys.stderr, exc 125 126 # vim: tabstop=4 expandtab shiftwidth=4