1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - PostMessage 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.Page import Page 10 from MoinMoin.PageEditor import PageEditor 11 from MoinMoin import wikiutil 12 from MoinSupport import getMetadata, writeHeaders 13 from MoinMessage import Message, is_collection, to_replace, to_store 14 from MoinMessageSupport import MoinMessageAction 15 import time 16 17 Dependencies = ['pages'] 18 19 class PostMessage(MoinMessageAction): 20 21 "A posted message handler." 22 23 def handle_message_content(self, content): 24 25 "Handle the given message 'content'." 26 27 request = self.request 28 29 # Interpret the content as one or more updates. 30 31 message = Message() 32 message.handle_message(content) 33 34 # Test any date against the page or message store. 35 36 if message.date: 37 store_date = time.gmtime(self.store.mtime()) 38 page_date = time.gmtime(wikiutil.version2timestamp(self.page.mtime_usecs())) 39 last_date = max(store_date, page_date) 40 41 # Reject messages older than the page date. 42 43 if message.date < last_date: 44 writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden") 45 request.write("The message is too old: %s versus %s." % (message.date, last_date)) 46 return 47 48 # Reject messages without dates if so configured. 49 50 elif getattr(request.cfg, "moinmessage_reject_messages_without_dates", True): 51 writeHeaders(request, "text/plain", getMetadata(self.page), "403 Forbidden") 52 request.write("The message has no date information.") 53 return 54 55 # Handle each update. 56 57 for update in message.updates: 58 59 # Handle a single part. 60 61 if not is_collection(update): 62 self.handle_message_parts([update], update) 63 64 # Or a collection of alternative representations for a single 65 # update. 66 67 else: 68 self.handle_message_parts(update.get_payload(), update) 69 70 # Default output. 71 72 writeHeaders(request, "text/plain", getMetadata(self.page), "204 No Content") 73 74 def handle_message_parts(self, parts, update): 75 76 """ 77 Handle the given message 'parts', using the original 'update' to 78 determine whether the content is to replace or update page content, or 79 whether it will be placed in a message store. 80 """ 81 82 # Handle the different update actions. 83 # Update a message store for the page. 84 85 if to_store(update): 86 self.store.append(update.as_string()) 87 88 # Update the page. 89 90 else: 91 # NOTE: Should either choose preferred content types or somehow retain them 92 # NOTE: all but present one at a time. 93 94 body = [] 95 replace = to_replace(update) 96 97 for part in parts: 98 mimetype = part.get_content_type() 99 encoding = part.get_content_charset() 100 if mimetype == "text/moin": 101 body.append(part.get_payload()) 102 if replace: 103 break 104 105 if not replace: 106 body.append(self.page.get_raw_body()) 107 108 page_editor = PageEditor(self.request, self.pagename) 109 page_editor.saveText("\n\n".join(body), 0) 110 111 # Refresh the page. 112 113 self.page = Page(self.request, self.pagename) 114 115 # Action function. 116 117 def execute(pagename, request): 118 PostMessage(pagename, request).do_action() # instead of render 119 120 # vim: tabstop=4 expandtab shiftwidth=4