# HG changeset patch # User Paul Boddie # Date 1383486737 -3600 # Node ID f1b03998cf9196a9e06172b1637418fb91767c6f # Parent 448c4f65b040843383202d0c9ec9dd9fe44e5dfc Moved the subpage comments functionality to a separate project. diff -r 448c4f65b040 -r f1b03998cf91 README.txt --- a/README.txt Sun Nov 03 01:03:35 2013 +0100 +++ b/README.txt Sun Nov 03 14:52:17 2013 +0100 @@ -66,6 +66,12 @@ Here, CCDIR is the path to the top level of this source distribution where this README.txt file is found. +When importing users, MoinMoin may be unable to handle user information +containing non-ASCII characters. Another patch to solve such problems can be +applied to MoinMoin as follows: + +patch -p1 $CCDIR/patches/patch-moin-1.9-MoinMoin-user.diff + Wiki Content Prerequisites -------------------------- @@ -73,18 +79,12 @@ required: http://moinmo.in/ParserMarket/ImprovedTableParser -http://hgweb.boddie.org.uk/MoinSupport +http://moinmo.in/ActionMarket/SubpageComments http://moinmo.in/MacroMarket/Color2 -In addition, extensions are provided in this distribution to support various -Confluence features, notably comments on pages. These extensions are installed -as follows: +A common dependency of various extensions is provided by MoinSupport: -python moinsetup.py -m install_actions $CCDIR/actions -python moinsetup.py -m install_macros $CCDIR/macros -python moinsetup.py -m install_theme_resources $CCDIR -python moinsetup.py -m edit_theme_stylesheet screen.css includecomments.css -python moinsetup.py -m edit_theme_stylesheet print.css includecomments.css +http://hgweb.boddie.org.uk/MoinSupport Additional Software ------------------- diff -r 448c4f65b040 -r f1b03998cf91 actions/PostComment.py --- a/actions/PostComment.py Sun Nov 03 01:03:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -# -*- coding: iso-8859-1 -*- -""" - MoinMoin - PostComment action - - @copyright: 2013 by Paul Boddie - @license: GNU GPL (v2 or later), see COPYING.txt for details. -""" - -from MoinMoin.action import ActionBase -from MoinMoin.PageEditor import PageEditor -from MoinMoin.security import Permissions -from MoinMoin.wikiutil import escape -from MoinSupport import getPagesForSearch, getPagesFromResults, ActionSupport - -Dependencies = ['pages'] - -class SpecialPermissions(Permissions): - - "Permit saving of ACL-enabled comment pages." - - def __init__(self, user, pagename): - Permissions.__init__(self, user) - self.pagename = pagename - - def admin(self, pagename): - return pagename == self.pagename - -class PostComment(ActionBase, ActionSupport): - - "Post a comment to the wiki." - - def get_form_html(self, buttons_html): - - "Return the action's form incorporating the 'buttons_html'." - - _ = self._ - request = self.request - form = self.get_form() - - comment = form.get("comment", [""])[0] - - d = { - "comment_label" : escape(comment and _("Please review your comment.") or _("Write a comment in the box.")), - "comment_default" : escape(comment), - "buttons_html" : buttons_html, - } - - return u"""\ -

%(comment_label)s

- -

%(buttons_html)s

-""" % d - - def do_action(self): - - "Attempt to post a comment." - - _ = self._ - request = self.request - form = self.get_form() - - comment = form.get("comment", [""])[0] - - if not comment.strip(): - return 0, _("A comment should have some content.") - - if not request.user.valid or not request.user.may.write(self.pagename): - return 0, _("You are not allowed to comment on this page.") - - # Determine the last comment. - - comments = get_comment_numbers(self.pagename, request) - last_comment_pagename = comments and comments[-1] or -1 - - # Write the new page. - - comment_pagename = "%s/%04d" % (self.pagename, last_comment_pagename + 1) - new_page = PageEditor(request, comment_pagename) - username = request.user.name - - try: - # To add a page with an ACL, a special policy is required. - - may = request.user.may - request.user.may = SpecialPermissions(request.user, comment_pagename) - - # Save the page, labelling it with the actual username. - - try: - new_page.saveText(comment_template % (username, username, comment), 0) - - # Restore the superusers. - - finally: - request.user.may = may - - return 1, _("Comment added.") - except new_page.SaveError, exc: - return 0, unicode(exc) - -comment_template = """\ -#acl %s:read,write,delete,revert All:read -#pragma comment-owner %s -%s""" - -def get_comment_numbers(pagename, request): - - """ - Return a list of comment numbers associated with the given 'pagename', using - the 'request' provided. - """ - - pagenames = [] - - for page in getPagesForSearch("title:regex:^%s/" % pagename, request): - basename, number = page.page_name.rsplit("/", 1) - if basename == pagename and number.isdigit(): - pagenames.append(int(number)) - - pagenames.sort() - return pagenames - -# Action invocation function. - -def execute(pagename, request): - PostComment(pagename, request).render() - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r 448c4f65b040 -r f1b03998cf91 css/includecomments.css --- a/css/includecomments.css Sun Nov 03 01:03:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* includecomments.css - some additional styles for the IncludeComments macro - which can be included in screen.css and print.css - using... - - @import "includecomments.css"; - - ...before any rules. - -Copyright (c) 2013 by Paul Boddie -Licensed under the GNU GPL (v2 or later), see COPYING.txt for details. -*/ - -.included-comment { - margin: 1em; - border: 2px solid #ddd; - padding: 1em; -} - -.included-comment-owner { - float: left; - clear: left; - margin-right: 1em; - padding: 0.5em; - background-color: #ddd; - color: #000; - font-weight: bold; - font-size: larger; -} - -/* Hide the link to the comment form when showing the form. */ - -#includecomments-anchor:target > a { - display: none; -} - -/* Hide the comment form unless the link has been followed. */ - -#includecomments-anchor:not(:target) .includecomments-form { - display: none; -} - -/* vim: tabstop=4 expandtab shiftwidth=4 - */ diff -r 448c4f65b040 -r f1b03998cf91 macros/IncludeComments.py --- a/macros/IncludeComments.py Sun Nov 03 01:03:35 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -# -*- coding: iso-8859-1 -*- -""" - MoinMoin - IncludeComments Macro - - @copyright: 2013 by Paul Boddie - @license: GNU GPL (v2 or later), see COPYING.txt for details. - - Code from the Include macro: - - @copyright: 2000-2004 Juergen Hermann , - 2000-2001 Richard Jones - @license: GNU GPL (v2 or later), see COPYING.txt for details. -""" - -from MoinMoin.Page import Page -from MoinMoin.macro import Include -from MoinMoin.user import User -from MoinMoin.wikiutil import escape -import re -import codecs - -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - -Dependencies = ['pages'] - -# Macro functions. - -def execute(macro, text): - request = macro.request - fmt = request.formatter - page = request.page - pagename = page.page_name - _ = request.getText - - output = [] - append = output.append - - # Add a heading. - - append(fmt.heading(on=1, depth=1)) - append(fmt.text(_("Comments"))) - append(fmt.heading(on=0, depth=1)) - - # Provide a form for adding new comments. - - if request.user.valid and request.user.may.write(pagename): - - d = { - "show_form" : escape(_("Add a comment to this page.")), - "comment_label" : escape(_("Write a comment in the box.")), - "comment_default" : "", - "submit" : escape(_("Submit this comment")), - } - - append("""\ -
-%(show_form)s -
-

%(comment_label)s

- -

-
-
-""" % d) - - # NOTE: Much of the code below originates from the Include macro, but it - # NOTE: excludes various options of that macro and adds comment-related - # NOTE: output. - - # Add included comments. - - filterfn = re.compile(ur"^%s/" % re.escape(pagename), re.U).match - pages = request.rootpage.getPageList(filter=filterfn) - pages.sort() - - ownerfn = re.compile("^#pragma comment-owner (.*?)$", re.MULTILINE | re.UNICODE).search - - # Track included pages. - - if not hasattr(page, '_macroInclude_pagelist'): - page._macroInclude_pagelist = {} - - # Visit each comment page. - - for inc_name in pages: - - # Skip unreadable or already included pages. - - if not request.user.may.read(inc_name): - continue - if inc_name in page._macroInclude_pagelist: - continue - - # Obtain a separate formatter for the included page. - - inc_fmt = macro.formatter.__class__(request, is_included=True) - inc_fmt._base_depth = macro.formatter._base_depth - - # Obtain the included page. - - inc_page = Page(request, inc_name, formatter=inc_fmt) - if not inc_page.exists(): - continue - inc_page._macroInclude_pagelist = page._macroInclude_pagelist - - if not hasattr(request, "_Include_backto"): - request._Include_backto = pagename - - # Output a container for the included page. - - append(fmt.div(1, id=inc_name, css_class="included-comment")) - - # Add a label indicating a comment. - - match = ownerfn(inc_page.get_raw_body()) - if match: - user = User(request, auth_username=match.group(1)) - if user.exists(): - append(fmt.div(1, css_class="included-comment-owner")) - append(fmt.text(user.aliasname or user.name)) - append(fmt.div(0)) - - # Set or increment include marker. - - page._macroInclude_pagelist[inc_name] = \ - page._macroInclude_pagelist.get(inc_name, 0) + 1 - - # Output the included page. - - strfile = codecs.getwriter("utf-8")(StringIO()) - request.redirect(strfile) - try: - inc_page.send_page(content_only=True, - omit_footnotes=True, - count_hit=False) - append(unicode(strfile.getvalue(), "utf-8")) - finally: - request.redirect() - - # Decrement or remove include marker. - - if page._macroInclude_pagelist[inc_name] > 1: - page._macroInclude_pagelist[inc_name] = \ - page._macroInclude_pagelist[inc_name] - 1 - else: - del page._macroInclude_pagelist[inc_name] - - # Close the container for the included page. - - append(fmt.div(0)) - - return u"".join(output) - -# vim: tabstop=4 expandtab shiftwidth=4