| [1267] | 1 | # vim: expandtab |
|---|
| 2 | from trac.core import * |
|---|
| 3 | from trac.wiki.macros import WikiMacroBase |
|---|
| 4 | |
|---|
| 5 | import trac.perm |
|---|
| 6 | from StringIO import StringIO |
|---|
| 7 | from trac.wiki.formatter import wiki_to_html |
|---|
| 8 | from trac.wiki.model import WikiPage |
|---|
| 9 | from trac.util import Markup |
|---|
| 10 | from trac.util import TracError |
|---|
| 11 | from trac.web.chrome import add_link |
|---|
| [2097] | 12 | from trac.util.text import to_unicode |
|---|
| [1267] | 13 | |
|---|
| 14 | import re, time |
|---|
| 15 | |
|---|
| 16 | class 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 | |
|---|
| 28 | def 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 | |
|---|
| [2817] | 34 | authname = to_unicode(hdf.getValue("trac.authname", "anonymous")) |
|---|
| [1267] | 35 | db = env.get_db_cnx() |
|---|
| 36 | perm = trac.perm.PermissionCache(env, authname) |
|---|
| [3204] | 37 | pagename = to_unicode(hdf.getValue("wiki.page_name", "WikiStart")) |
|---|
| [1267] | 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 | |
|---|
| [2097] | 53 | comment = Markup(to_unicode(hdf.getValue("args.addcomment", ""))).unescape() |
|---|
| [1267] | 54 | preview = hdf.getValue("args.previewaddcomment", "") |
|---|
| 55 | cancel = hdf.getValue("args.canceladdcomment", "") |
|---|
| 56 | submit = hdf.getValue("args.submitaddcomment", "") |
|---|
| 57 | if not cancel: |
|---|
| [2817] | 58 | authname = to_unicode(hdf.getValue("args.authoraddcomment", authname)) |
|---|
| [1267] | 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") |
|---|
| [2817] | 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))) |
|---|
| [1267] | 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: |
|---|
| [2817] | 84 | newtext.write("==== Comment by %s on %s ====\n%s\n\n" % ( |
|---|
| 85 | authname, to_unicode(time.strftime('%c', time.localtime())), |
|---|
| 86 | comment)) |
|---|
| [1267] | 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 | |
|---|
| [2097] | 101 | out.write("<form action='%s#commentpreview' method='post'>\n" % env.href.wiki(pagename)) |
|---|
| [1267] | 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 | |
|---|