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