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