# HG changeset patch # User Paul Boddie # Date 1318187829 -7200 # Node ID 079d9a82b77bbfed1c0807604b7c8796a2d1cf39 # Parent 5f6c0f465dec0e1d2c01f8194c0e4bd31a3ad465 Added a test to make sure that the action is only performed on queued pages. Added the option to purge other queue entries when approving changes. Introduced a common library for the action and handler. diff -r 5f6c0f465dec -r 079d9a82b77b ApproveChangesSupport.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ApproveChangesSupport.py Sun Oct 09 21:17:09 2011 +0200 @@ -0,0 +1,92 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - ApproveChanges library + + @copyright: 2011 by Paul Boddie + @license: GNU GPL (v2 or later), see COPYING.txt for details. +""" + +import re + +__version__ = "0.1" + +def get_queued_changes_area(request): + return getattr(request.cfg, "queued_changes_area", "ApprovalQueue") + +def get_approved_editors_group(request): + return getattr(request.cfg, "approved_editors_group", "ApprovedGroup") + +def match_queue_pages(pagename, queued_changes_area): + + "Return a filter function which matches subpages of 'pagename'." + + return re.compile(ur"^%s/%s/.*$" % (re.escape(pagename), re.escape(queued_changes_area)), re.UNICODE).match + +def get_queue_pages(request, pagename, queued_changes_area): + + """ + Return the queued pages given the 'request', 'pagename' and subpage folder + specified by 'queued_changes_area'. + """ + + return request.rootpage.getPageList(exists=1, filter=match_queue_pages(pagename, queued_changes_area)) + +def is_queued_page(pagename, queued_changes_area): + + """ + Return whether 'pagename' is a queued page by testing for the presence of + the 'queued_changes_area' component in its page path. + """ + + parts = pagename.split("/") + return len(parts) > 2 and parts[-2] == queued_changes_area + +def get_target_page_name(pagename): + + "Return the target page name for the given queued 'pagename'." + + return "/".join(pagename.split("/")[:-2]) + +# Utility classes and associated functions. +# NOTE: These are a subset of EventAggregatorSupport. + +class Form: + + """ + A wrapper preserving MoinMoin 1.8.x (and earlier) behaviour in a 1.9.x + environment. + """ + + def __init__(self, form): + self.form = form + + def get(self, name, default=None): + values = self.form.getlist(name) + if not values: + return default + else: + return values + + def __getitem__(self, name): + return self.form.getlist(name) + +class ActionSupport: + + """ + Work around disruptive MoinMoin changes in 1.9, and also provide useful + convenience methods. + """ + + def get_form(self): + return get_form(self.request) + +def get_form(request): + + "Work around disruptive MoinMoin changes in 1.9." + + if hasattr(request, "values"): + return Form(request.values) + else: + return request.form + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 5f6c0f465dec -r 079d9a82b77b actions/ApproveChanges.py --- a/actions/ApproveChanges.py Sun Oct 09 20:37:21 2011 +0200 +++ b/actions/ApproveChanges.py Sun Oct 09 21:17:09 2011 +0200 @@ -15,6 +15,8 @@ from MoinMoin.action import ActionBase from MoinMoin.PageEditor import PageEditor +from MoinMoin.wikiutil import escape +from ApproveChangesSupport import * # Action class and supporting functions. @@ -32,9 +34,35 @@ _ = self._ request = self.request fmt = request.formatter - prompt = _("Approve the displayed page version?") - return fmt.paragraph(1) + fmt.text(prompt) + fmt.paragraph(0) + \ - fmt.paragraph(1) + fmt.rawHTML(buttons_html) + fmt.paragraph(0) + + d = { + "buttons_html" : buttons_html, + "prompt" : escape(_("Approve the displayed page version?")), + "purge_label" : escape(_("Purge all other queued versions")) + } + + # Prepare the output HTML. + + html = ''' + + + + + + + + + + + + +
%(prompt)s
+ +
+ %(buttons_html)s +
''' % d + + return html def do_action(self): @@ -45,6 +73,7 @@ # Make sure that only suitably privileged users can perform this action. + queued_changes_area = get_queued_changes_area(request) reviewers_group = getattr(request.cfg, "reviewers_group", "PageReviewersGroup") if not request.user.valid or ( @@ -54,10 +83,12 @@ return 0, _("Only page reviewers can perform this action.") # Edit the target page, using this page's content. - # The current page should have a name of the form... - # ".../TargetPage/ApprovalQueue/n" + # The current page must be a queued page version. - target_page_name = "/".join(self.pagename.split("/")[:-2]) + if not is_queued_page(self.pagename, queued_changes_area): + return 0, _("This page is not queued for approval.") + + target_page_name = get_target_page_name(self.pagename) target_page = PageEditor(request, target_page_name) # Save the target page. @@ -72,6 +103,15 @@ current_page = PageEditor(request, self.pagename) current_page.deletePage(_("Changes to page approved.")) + # Delete the rest of the queue if requested. + + form = get_form(request) + + if form.get("purge"): + for name in get_queue_pages(request, target_page_name, queued_changes_area): + queue_page = PageEditor(request, name) + queue_page.deletePage(_("Changes to page rejected.")) + # Redirect to the target page. request.http_redirect(target_page.url(request)) diff -r 5f6c0f465dec -r 079d9a82b77b events/queue_for_review.py --- a/events/queue_for_review.py Sun Oct 09 20:37:21 2011 +0200 +++ b/events/queue_for_review.py Sun Oct 09 21:17:09 2011 +0200 @@ -11,28 +11,21 @@ from MoinMoin.PageEditor import PageEditor from MoinMoin.events import PagePreSaveEvent, Abort -import re - -def match_queue_pages(pagename, queued_changes_area): - - "Return a filter function which matches subpages of 'pagename'." - - return re.compile(ur"^%s/%s/.*$" % (re.escape(pagename), re.escape(queued_changes_area)), re.UNICODE).match +from ApproveChangesSupport import * def handle_presave(event): request = event.request _ = request.getText - approved_editors_group = getattr(request.cfg, "approved_editors_group", "ApprovedGroup") - queued_changes_area = getattr(request.cfg, "queued_changes_area", "ApprovalQueue") + approved_editors_group = get_approved_editors_group(request) + queued_changes_area = get_queued_changes_area(request) pagename = event.page_editor.page_name - parts = pagename.split("/") # Saving into queues has to be permitted or the mechanism will keep trying # to save into a queue of the specified page. - if len(parts) > 2 and parts[-2] == queued_changes_area: + if is_queued_page(pagename, queued_changes_area): return None # For normal pages, the user has to be approved. Otherwise, the page will be @@ -47,7 +40,7 @@ queue_number = -1 - for name in request.rootpage.getPageList(exists=1, filter=match_queue_pages(pagename, queued_changes_area)): + for name in get_queue_pages(request, pagename, queued_changes_area): number = name.split("/")[-1] if number.isdigit(): queue_number = max(queue_number, int(number)) diff -r 5f6c0f465dec -r 079d9a82b77b setup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/setup.py Sun Oct 09 21:17:09 2011 +0200 @@ -0,0 +1,13 @@ +#! /usr/bin/env python + +from distutils.core import setup + +setup( + name = "ApproveChanges", + description = "Queue changes to Wiki pages for subsequent approval", + author = "Paul Boddie", + author_email = "paul@boddie.org.uk", + url = "http://moinmo.in/ActionMarket/ApproveChanges", + version = "0.1", + py_modules = ["ApproveChangesSupport"] + )