1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - IncludeComments Macro 4 5 @copyright: 2013 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 8 Code from the Include macro: 9 10 @copyright: 2000-2004 Juergen Hermann <jh@web.de>, 11 2000-2001 Richard Jones <richard@bizarsoftware.com.au> 12 @license: GNU GPL (v2 or later), see COPYING.txt for details. 13 """ 14 15 from MoinMoin.Page import Page 16 from MoinMoin.macro import Include 17 from MoinMoin.user import User 18 from MoinMoin.wikiutil import escape 19 from SubpageComments import get_comment_numbers 20 import re 21 import codecs 22 23 try: 24 from cStringIO import StringIO 25 except ImportError: 26 from StringIO import StringIO 27 28 __version__ = "0.1" 29 30 Dependencies = ['pages'] 31 32 # Macro functions. 33 34 def execute(macro, text): 35 request = macro.request 36 fmt = request.formatter 37 page = request.page 38 pagename = page.page_name 39 _ = request.getText 40 41 output = [] 42 append = output.append 43 44 # Add a heading. 45 46 append(fmt.heading(on=1, depth=1)) 47 append(fmt.text(_("Comments"))) 48 append(fmt.heading(on=0, depth=1)) 49 50 # Provide a form for adding new comments. 51 52 if request.user.valid and request.user.may.write(pagename): 53 54 d = { 55 "show_form" : escape(_("Add a comment to this page.")), 56 "comment_label" : escape(_("Write a comment in the box.")), 57 "comment_default" : "", 58 "submit" : escape(_("Submit this comment")), 59 } 60 61 append("""\ 62 <div id="includecomments-anchor"> 63 <a href="#includecomments-anchor">%(show_form)s</a> 64 <form action="?action=PostComment" method="post" class="includecomments-form"> 65 <p>%(comment_label)s</p> 66 <textarea name="comment" cols="60" rows="10">%(comment_default)s</textarea> 67 <p><input name="submit" type="submit" value="%(submit)s" /></p> 68 </form> 69 </div> 70 """ % d) 71 72 # Add included comments. 73 74 pages = get_comment_numbers(pagename, request) 75 76 ownerfn = re.compile("^#pragma comment-owner (.*?)$", re.MULTILINE | re.UNICODE).search 77 78 # NOTE: Much of the code below originates from the Include macro, but it 79 # NOTE: excludes various options of that macro and adds comment-related 80 # NOTE: output. 81 82 # Track included pages. 83 84 if not hasattr(page, '_macroInclude_pagelist'): 85 page._macroInclude_pagelist = {} 86 87 # Visit each comment page. 88 89 for inc_name in pages: 90 inc_name = "%s/%04d" % (pagename, inc_name) 91 92 # Skip unreadable or already included pages. 93 94 if not request.user.may.read(inc_name): 95 continue 96 if inc_name in page._macroInclude_pagelist: 97 continue 98 99 # Obtain a separate formatter for the included page. 100 101 inc_fmt = macro.formatter.__class__(request, is_included=True) 102 inc_fmt._base_depth = macro.formatter._base_depth 103 104 # Obtain the included page. 105 106 inc_page = Page(request, inc_name, formatter=inc_fmt) 107 if not inc_page.exists(): 108 continue 109 inc_page._macroInclude_pagelist = page._macroInclude_pagelist 110 111 if not hasattr(request, "_Include_backto"): 112 request._Include_backto = pagename 113 114 # Output a container for the included page. 115 116 append(fmt.div(1, id=inc_name, css_class="included-comment")) 117 118 # Add a label indicating a comment. 119 120 match = ownerfn(inc_page.get_raw_body()) 121 if match: 122 user = User(request, auth_username=match.group(1)) 123 if user.exists(): 124 append(fmt.div(1, css_class="included-comment-owner")) 125 append(fmt.text(user.aliasname or user.name)) 126 append(fmt.div(0)) 127 128 # Set or increment include marker. 129 130 page._macroInclude_pagelist[inc_name] = \ 131 page._macroInclude_pagelist.get(inc_name, 0) + 1 132 133 # Output the included page. 134 135 strfile = codecs.getwriter("utf-8")(StringIO()) 136 request.redirect(strfile) 137 try: 138 inc_page.send_page(content_only=True, 139 omit_footnotes=True, 140 count_hit=False) 141 append(unicode(strfile.getvalue(), "utf-8")) 142 finally: 143 request.redirect() 144 145 # Decrement or remove include marker. 146 147 if page._macroInclude_pagelist[inc_name] > 1: 148 page._macroInclude_pagelist[inc_name] = \ 149 page._macroInclude_pagelist[inc_name] - 1 150 else: 151 del page._macroInclude_pagelist[inc_name] 152 153 # Close the container for the included page. 154 155 append(fmt.div(0)) 156 157 return u"".join(output) 158 159 # vim: tabstop=4 expandtab shiftwidth=4