1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - PostComment action 4 5 @copyright: 2013, 2018 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from MoinMoin.action import ActionBase 10 from MoinMoin.PageEditor import PageEditor 11 from MoinMoin.security import Permissions 12 from MoinMoin.wikiutil import escape 13 from MoinMoin.util import lock 14 from MoinSupport import ActionSupport 15 from SubpageComments import get_comment_numbers 16 17 __version__ = "0.1" 18 19 Dependencies = ['pages'] 20 21 class SpecialPermissions(Permissions): 22 23 "Permit saving of ACL-enabled comment pages." 24 25 def __init__(self, user, pagename): 26 Permissions.__init__(self, user) 27 self.pagename = pagename 28 29 def admin(self, pagename): 30 return pagename == self.pagename 31 32 class PostComment(ActionBase, ActionSupport): 33 34 "Post a comment to the wiki." 35 36 def get_form_html(self, buttons_html): 37 38 "Return the action's form incorporating the 'buttons_html'." 39 40 _ = self._ 41 request = self.request 42 form = self.get_form() 43 44 comment = form.get("comment", [""])[0] 45 46 d = { 47 "comment_label" : escape(comment and _("Please review your comment.") or _("Write a comment in the box.")), 48 "comment_default" : escape(comment), 49 "buttons_html" : buttons_html, 50 } 51 52 return u"""\ 53 <p>%(comment_label)s</p> 54 <textarea name="comment" cols="60" rows="10">%(comment_default)s</textarea> 55 <p>%(buttons_html)s</p> 56 """ % d 57 58 def do_action(self): 59 60 "Attempt to post a comment." 61 62 _ = self._ 63 request = self.request 64 form = self.get_form() 65 66 comment = form.get("comment", [""])[0] 67 68 if not comment.strip(): 69 return 0, _("A comment should have some content.") 70 71 if not request.user.valid or not request.user.may.write(self.pagename): 72 return 0, _("You are not allowed to comment on this page.") 73 74 # Obtain a lock to prevent contention over comment numbers. 75 76 writelock = lock.WriteLock(self.page.getPagePath("comment-lock")) 77 writelock.acquire() 78 79 try: 80 # Determine the last comment. 81 82 comments = get_comment_numbers(self.pagename, request) 83 if comments: 84 last_comment_pagename = comments[-1] 85 else: 86 last_comment_pagename = -1 87 88 # Write the new page. 89 90 comment_pagename = "%s/%04d" % (self.pagename, last_comment_pagename + 1) 91 new_page = PageEditor(request, comment_pagename) 92 username = request.user.name 93 94 try: 95 # To add a page with an ACL, a special policy is required. 96 97 may = request.user.may 98 request.user.may = SpecialPermissions(request.user, comment_pagename) 99 100 # Save the page, labelling it with the actual username. 101 102 try: 103 new_page.saveText(comment_template % (username, username, comment), 0) 104 105 # Restore the original policy. 106 107 finally: 108 request.user.may = may 109 110 return 1, _("Comment added.") 111 except new_page.SaveError, exc: 112 return 0, unicode(exc) 113 114 # Release the lock and let others post comments now. 115 116 finally: 117 writelock.release() 118 119 comment_template = """\ 120 #acl %s:read,write,delete,revert All:read 121 #pragma comment-owner %s 122 %s""" 123 124 # Action invocation function. 125 126 def execute(pagename, request): 127 PostComment(pagename, request).render() 128 129 # vim: tabstop=4 expandtab shiftwidth=4