1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - ReadMessage Action 4 5 @copyright: 2012, 2013 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from MoinMoin.action import ActionBase 10 from MoinSupport import * 11 from email.parser import Parser 12 13 try: 14 from cStringIO import StringIO 15 except ImportError: 16 from StringIO import StringIO 17 18 Dependencies = [] 19 20 class ReadMessage(ActionBase, ActionSupport): 21 22 "An action that can read a stored message component." 23 24 def __init__(self, pagename, request): 25 26 """ 27 On the page with the given 'pagename', use the given 'request' to access 28 message components. 29 """ 30 31 ActionBase.__init__(self, pagename, request) 32 self.store = ItemStore(self.page, "messages", "message-locks") 33 34 def get_form_html(self, buttons_html): 35 36 "Present an interface for accessing a message component." 37 38 _ = self._ 39 request = self.request 40 form = self.get_form() 41 42 message = form.get("message", [""])[0] 43 part = form.get("part", [""])[0] 44 45 # Fill in the fields and labels. 46 47 d = { 48 "buttons_html" : buttons_html, 49 "message_label" : _("Message number"), 50 "message_default" : escattr(message), 51 "part_label" : _("Part identifier"), 52 "part_default" : escattr(part), 53 } 54 55 # Prepare the output HTML. 56 57 html = ''' 58 <table> 59 <tr> 60 <td class="label"><label>%(message_label)s</label></td> 61 <td> 62 <input name="message" type="text" value="%(message_default)s" /> 63 </td> 64 </tr> 65 <tr> 66 <td class="label"><label>%(part_label)s</label></td> 67 <td> 68 <input name="part" type="text" value="%(part_default)s" /> 69 </td> 70 </tr> 71 <tr> 72 <td></td> 73 <td class="buttons"> 74 %(buttons_html)s 75 </td> 76 </tr> 77 </table>''' % d 78 79 return html 80 81 def do_action(self): 82 83 "Attempt to send the message." 84 85 _ = self._ 86 request = self.request 87 form = self.get_form() 88 89 message_number = form.get("message", [None])[0] 90 part_identifier = form.get("part", [None])[0] 91 92 if not message_number: 93 return 0, _("A message number must be given.") 94 95 if not part_identifier: 96 return 0, _("A part identifier must be given.") 97 98 # Obtain the message. 99 100 try: 101 message_text = self.store[int(message_number)] 102 except (IndexError, ValueError): 103 return 0, _("No such message is stored on this page.") 104 105 # Visit the message parts, looking for the indicated component. 106 107 message = Parser().parse(StringIO(message_text)) 108 109 if message.is_multipart(): 110 for part in message.get_payload(): 111 112 # For the selected component, return the content as a response 113 # to the current request. 114 115 if part.get("Content-ID") == part_identifier: 116 charset = part.get_content_charset() 117 headers = [ 118 "Content-Type: %s%s" % ( 119 part.get_content_type(), 120 charset and ("; charset=%s" % charset) or "" 121 ) 122 ] 123 get_send_headers(request)(headers) 124 request.write(part.get_payload(decode=True)) 125 return 1, None 126 127 return 0, _("No such component in the indicated message.") 128 129 def render_success(self, msg, msgtype=None): 130 131 """ 132 Render neither 'msg' nor 'msgtype' since a resource has already been 133 produced. 134 NOTE: msgtype is optional because MoinMoin 1.5.x does not support it. 135 """ 136 137 pass 138 139 # Action function. 140 141 def execute(pagename, request): 142 ReadMessage(pagename, request).render() 143 144 # vim: tabstop=4 expandtab shiftwidth=4