source: addcommentmacro/0.10/addcomment/macro.py

Last change on this file was 3204, checked in by osimons, 16 years ago

AddCommentMacro: Unicode page name fix.

Should close #2547

File size: 5.1 KB
Line 
1# vim: expandtab
2from trac.core import *
3from trac.wiki.macros import WikiMacroBase
4
5import trac.perm
6from StringIO import StringIO
7from trac.wiki.formatter import wiki_to_html
8from trac.wiki.model import WikiPage
9from trac.util import Markup
10from trac.util import TracError
11from trac.web.chrome import add_link
12from trac.util.text import to_unicode
13
14import re, time
15
16class AddCommentMacro(WikiMacroBase):
17    """A macro to add comments to a page."""
18   
19    def render_macro(self, req, name, content):
20        return execute(req.hdf, content, self.env)
21
22    def _render_macro(self, req, name, content):
23        pass # Fill in a deuglified version here
24
25    def process_macro_post(self, req):
26        self.log.debug('AddCommentMacro: Got a POST')
27       
28def execute(hdf, args, env):
29    # prevents from multiple inclusions
30    if hdf.has_key('addcommentmacro'):
31       raise TracError('\'AddComment\' macro cannot be included twice')
32    hdf['addcommentmacro'] = True
33
34    authname = to_unicode(hdf.getValue("trac.authname", "anonymous"))
35    db = env.get_db_cnx()
36    perm = trac.perm.PermissionCache(env, authname)
37    pagename = to_unicode(hdf.getValue("wiki.page_name", "WikiStart"))
38    page = WikiPage(env, pagename, None, db)
39    wikipreview = hdf.getValue("wiki.preview", "")
40    appendonly = (args == 'appendonly')
41    readonlypage = int(hdf.getValue("wiki.readonly", "0"))
42    # Can this user add a comment to this page?
43    cancomment = not readonlypage
44    # Is this an "append-only" comment or are we an administrator?
45    if perm.has_permission('WIKI_ADMIN') or appendonly:
46        cancomment = True
47
48    if not cancomment:
49        raise TracError('Error: Insufficient privileges to AddComment')
50
51    disabled = ''
52
53    comment = Markup(to_unicode(hdf.getValue("args.addcomment", ""))).unescape()
54    preview = hdf.getValue("args.previewaddcomment", "")
55    cancel = hdf.getValue("args.canceladdcomment", "")
56    submit = hdf.getValue("args.submitaddcomment", "")
57    if not cancel:
58        authname = to_unicode(hdf.getValue("args.authoraddcomment", authname))
59
60    # Ensure [[AddComment]] is not present in comment, so that infinite
61    # recursion does not occur.
62    comment = re.sub('(^|[^!])(\[\[AddComment)', '\\1!\\2', comment)
63
64    out = StringIO()
65    if wikipreview or not (perm.has_permission('WIKI_MODIFY') or appendonly):
66        disabled = ' disabled="disabled"'
67
68    # If we are submitting or previewing, inject comment as it should look
69    if cancomment and comment and (preview or submit):
70        if preview:
71            out.write("<div class='wikipage' id='preview'>\n")
72        out.write("<h4 id='commentpreview'>Comment by %s on %s</h4>\n<p>\n%s\n</p>\n" % (
73                    authname, to_unicode(time.strftime('%c', time.localtime())),
74                    wiki_to_html(comment, env, None)))
75        if preview:
76            out.write("</div>\n")
77
78    # When submitting, inject comment before macro
79    if comment and submit:
80        submitted = False
81        newtext = StringIO()
82        for line in page.text.splitlines():
83            if line.find('[[AddComment') == 0:
84                newtext.write("==== Comment by %s on %s ====\n%s\n\n" % (
85                        authname, to_unicode(time.strftime('%c', time.localtime())),
86                        comment))
87                submitted = True
88            newtext.write(line + "\n")
89        if submitted:
90            # XXX Is this the dodgiest hack ever? This is needed in
91            # "appendonly" mode when the page is readonly. XXX
92#            if appendonly:
93#                perm.expand_meta_permission('WIKI_ADMIN');
94            # TODO: How do we get remote_addr from a macro?
95            page.text = newtext.getvalue()
96            page.save(authname, 'Comment added', None)
97            comment = ""
98        else:
99            out.write("<div class='system-message'><strong>ERROR: [[AddComment]] macro call must be the only content on its line. Could not add comment.</strong></div>\n")
100
101    out.write("<form action='%s#commentpreview' method='post'>\n" % env.href.wiki(pagename))
102    out.write("<fieldset>\n<legend>Add comment</legend>\n")
103    out.write("<div class='field'>\n<textarea class='wikitext' id='addcomment' name='addcomment' cols='80' rows='5'%s>" % disabled)
104    if wikipreview:
105        out.write("Page preview...")
106    elif not cancel:
107        out.write(comment)
108    out.write("</textarea>\n")
109    out.write("</div>\n")
110    out.write('<div class="field">\n<label for="authoraddcomment">Your email or username:</label>\n<br/><input id="authoraddcomment" type="text" name="authoraddcomment" size="30" value="%s" />\n</div>' % authname)
111    out.write("<div class='field'>\n<input size='30' type='submit' name='submitaddcomment' value='Add comment'%s/>\n" % disabled)
112    out.write("<input type='submit' name='previewaddcomment' value='Preview comment'%s/>\n" % disabled)
113    out.write("<input type='submit' name='canceladdcomment' value='Cancel'%s/>\n</div>\n" % disabled)
114    out.write('<script type="text/javascript" src="%sjs/wikitoolbar.js"></script>' % hdf['htdocs_location'])
115    out.write("</fieldset>\n</form>\n")
116
117    return out.getvalue()# + "<pre>" + hdf.dump() + "</pre>"
118
Note: See TracBrowser for help on using the repository browser.