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