1.1 --- a/actions/FetchMessages.py Sun Jan 12 18:10:13 2014 +0100
1.2 +++ b/actions/FetchMessages.py Sun Jan 12 18:12:22 2014 +0100
1.3 @@ -2,18 +2,15 @@
1.4 """
1.5 MoinMoin - FetchMessages Action
1.6
1.7 - @copyright: 2012, 2013 by Paul Boddie <paul@boddie.org.uk>
1.8 + @copyright: 2012, 2013, 2014 by Paul Boddie <paul@boddie.org.uk>
1.9 @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.10 """
1.11
1.12 from MoinSupport import getMetadata, writeHeaders, parseDictEntry
1.13 -from MoinMessage import Message, GPG
1.14 +from MoinMessage import GPG, MessageInterface
1.15 from MoinMessageSupport import MoinMessageAction, \
1.16 get_signing_users, get_recipient_details, \
1.17 MoinMessageRecipientError
1.18 -from email.mime.text import MIMEText
1.19 -from email.parser import Parser
1.20 -from itertools import islice
1.21
1.22 Dependencies = ['pages']
1.23
1.24 @@ -27,9 +24,9 @@
1.25
1.26 request = self.request
1.27
1.28 - # NOTE: Could employ a more accurate content type.
1.29 + # Employing an unstandardised content type.
1.30
1.31 - if not content.get_content_type() == "text/plain":
1.32 + if not content.get_content_type() == "text/x-moinmessage-fetch":
1.33 writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
1.34 request.write("The content does not appear to be a request for messages.")
1.35 return
1.36 @@ -62,91 +59,11 @@
1.37 request.write(exc.message)
1.38 return
1.39
1.40 - # Obtain commands from the payload, returning a collection of messages.
1.41 + # Obtain commands from the payload, returning a collection of messages
1.42 + # and command results.
1.43
1.44 commands = content.get_payload(decode=True)
1.45 -
1.46 - # Build a container for the responses.
1.47 -
1.48 - message = Message()
1.49 -
1.50 - # Process each command, using RFC 1939 (POP3) as inspiration.
1.51 -
1.52 - for command in commands.split("\n"):
1.53 - command = command.strip()
1.54 -
1.55 - # Get the command and arguments.
1.56 -
1.57 - command_parts = command.split(None, 1)
1.58 - cmd = command_parts[0]
1.59 -
1.60 - # A request to count the messages is returned in a part.
1.61 -
1.62 - if cmd == "STAT":
1.63 - result = str(len(self.store))
1.64 - part = MIMEText(result, "plain")
1.65 - part["Request-Type"] = "STAT"
1.66 - part["Request-Status"] = "OK"
1.67 - message.add_update(part)
1.68 -
1.69 - # A request for specific messages returns each message in its own
1.70 - # part.
1.71 -
1.72 - elif cmd in ("RETR", "DELE"):
1.73 -
1.74 - try:
1.75 - # Either select all.
1.76 -
1.77 - if len(command_parts) == 1:
1.78 - count = None
1.79 -
1.80 - # Or select a particular number.
1.81 -
1.82 - else:
1.83 - count = int(parameters[1])
1.84 -
1.85 - except ValueError:
1.86 - part = MIMEText(command, "plain")
1.87 - part["Request-Type"] = cmd
1.88 - part["Request-Status"] = "ERR"
1.89 - message.add_update(part)
1.90 -
1.91 - else:
1.92 - # A request for specific messages returns each message
1.93 - # in its own part within a collection part.
1.94 -
1.95 - if cmd == "RETR":
1.96 - container = Message()
1.97 -
1.98 - for message_text in islice(iter(self.store), count):
1.99 - message_item = Parser().parsestr(message_text)
1.100 - container.add_update(message_item)
1.101 -
1.102 - # Convert the container to a proper multipart section.
1.103 -
1.104 - message.add_update(container.get_payload())
1.105 -
1.106 - # A request to delete messages is performed immediately.
1.107 -
1.108 - elif cmd == "DELE":
1.109 - keys = self.store.keys()[:count]
1.110 - keys.sort()
1.111 -
1.112 - for key in keys:
1.113 - del self.store[key]
1.114 -
1.115 - part = MIMEText(result, "plain")
1.116 - part["Request-Type"] = cmd
1.117 - part["Request-Status"] = "OK"
1.118 - message.add_update(part)
1.119 -
1.120 - # Handle invalid commands.
1.121 -
1.122 - elif cmd:
1.123 - part = MIMEText(result, "plain")
1.124 - part["Request-Type"] = cmd
1.125 - part["Request-Status"] = "ERR"
1.126 - message.add_update(part)
1.127 + message = MessageInterface(self.store).execute(commands)
1.128
1.129 # Sign and encrypt the message.
1.130
1.131 @@ -159,7 +76,7 @@
1.132
1.133 # Write the response.
1.134
1.135 - writeHeaders(request, "text/plain", getMetadata(self.page))
1.136 + writeHeaders(request, "text/x-moinmessage-fetch-response", getMetadata(self.page))
1.137 request.write(message.as_string())
1.138
1.139 # Action function.