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 recipient from the original message. 89 90 if self.message.has_key("To") and not update.has_key("To"): 91 update["To"] = self.message["To"] 92 93 # Add any authenticated user. 94 # Note that where messages are signed by the real author, encrypted, 95 # and then signed for sending, the authenticated user here is not 96 # the real author. 97 98 update["Moin-User"] = request.user and request.user.valid and request.user.name or None 99 100 # Propagate time information using the unintuitive time functions. 101 102 if message.date: 103 update["Date"] = message.date.as_RFC2822_datetime_string() 104 105 self.store.append(as_string(update)) 106 107 # Update the page. 108 109 else: 110 # NOTE: Should either choose preferred content types or somehow retain them 111 # NOTE: all but present one at a time. 112 113 body = [] 114 replace = to_replace(update) 115 116 for part in parts: 117 mimetype = part.get_content_type() 118 encoding = part.get_content_charset() 119 if mimetype == "text/moin": 120 payload = part.get_payload(decode=True) 121 body.append(encoding and unicode(payload, encoding) or payload) 122 if replace: 123 break 124 125 if not replace: 126 body.append(self.page.get_raw_body()) 127 128 page_editor = PageEditor(request, self.pagename) 129 page_editor.saveText("\n\n".join(body), 0) 130 131 # Refresh the page. 132 133 self.page = Page(request, self.pagename) 134 135 return True 136 137 # Action function. 138 139 def execute(pagename, request): 140 PostMessage(pagename, request).do_action() # instead of render 141 142 # vim: tabstop=4 expandtab shiftwidth=4