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