1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - PostMessage Action 4 5 @copyright: 2012, 2013, 2014 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from MoinMoin.Page import Page 10 from MoinMoin.PageEditor import PageEditor 11 from MoinSupport import getMetadata, writeHeaders 12 from MoinMessage import is_collection, to_replace, to_store, get_update_action, \ 13 as_string 14 from MoinMessageSupport import MoinMessageAction 15 16 Dependencies = ['pages'] 17 18 class PostMessage(MoinMessageAction): 19 20 "A posted message handler." 21 22 def handle_message_object(self, message): 23 self.do_as_user(self.new_user, self._handle_message_object, [message]) 24 25 def _handle_message_object(self, message): 26 27 "Handle the given 'message' object." 28 29 request = self.request 30 31 # Handle each update. 32 33 all_successful = True 34 any_successful = False 35 36 for update in message.updates: 37 38 # Handle a single part. 39 40 if not is_collection(update): 41 success = self.handle_message_parts(message, [update], update) 42 43 # Or a collection of alternative representations for a single 44 # update. 45 46 else: 47 success = self.handle_message_parts(message, update.get_payload(), update) 48 49 all_successful = all_successful and success 50 any_successful = any_successful or success 51 52 # Default output. 53 54 if any_successful: 55 writeHeaders(request, "text/plain", getMetadata(self.page), "200 OK") 56 else: 57 writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden") 58 59 if all_successful: 60 request.write("All updates were successful.") 61 elif any_successful: 62 request.write("Some updates were unsuccessful.") 63 else: 64 request.write("No updates were successful.") 65 66 def handle_message_parts(self, message, parts, update): 67 68 """ 69 From the given 'message', handle the given 'parts', using the original 70 'update' to determine whether the content is to replace or update page 71 content, or whether it will be placed in a message store. 72 """ 73 74 request = self.request 75 76 # Test for privileges to change the page or message store. 77 78 update_action = get_update_action(update) 79 80 if not self.can_perform_action(update_action): 81 return False 82 83 # Handle the different update actions. 84 # Update a message store for the page. 85 86 if to_store(update): 87 88 # Add any authenticated user. 89 # Note that where messages are signed by the real author, encrypted, 90 # and then signed for sending, the authenticated user here is not 91 # the real author. 92 93 update["Moin-User"] = request.user and request.user.valid and request.user.name or None 94 95 # Propagate time information using the unintuitive time functions. 96 97 if message.date: 98 update["Date"] = message.date.as_RFC2822_datetime_string() 99 100 self.store.append(as_string(update)) 101 102 # Update the page. 103 104 else: 105 # NOTE: Should either choose preferred content types or somehow retain them 106 # NOTE: all but present one at a time. 107 108 body = [] 109 replace = to_replace(update) 110 111 for part in parts: 112 mimetype = part.get_content_type() 113 encoding = part.get_content_charset() 114 if mimetype == "text/moin": 115 payload = part.get_payload(decode=True) 116 body.append(encoding and unicode(payload, encoding) or payload) 117 if replace: 118 break 119 120 if not replace: 121 body.append(self.page.get_raw_body()) 122 123 page_editor = PageEditor(request, self.pagename) 124 page_editor.saveText("\n\n".join(body), 0) 125 126 # Refresh the page. 127 128 self.page = Page(request, self.pagename) 129 130 return True 131 132 # Action function. 133 134 def execute(pagename, request): 135 PostMessage(pagename, request).do_action() # instead of render 136 137 # vim: tabstop=4 expandtab shiftwidth=4