| 19 | | def render_macro(self, req, name, content): |
|---|
| 20 | | return execute(req.hdf, content, self.env) |
|---|
| | 29 | def expand_macro(self, formatter, name, content): |
|---|
| | 30 | |
|---|
| | 31 | args, kw = parse_args(content) |
|---|
| | 32 | req = formatter.req |
|---|
| | 33 | context = formatter.context |
|---|
| | 34 | |
|---|
| | 35 | # Prevent multiple inclusions - store a temp in req |
|---|
| | 36 | if hasattr(req, 'addcommentmacro'): |
|---|
| | 37 | raise TracError('\'AddComment\' macro cannot be included twice.') |
|---|
| | 38 | req.addcommentmacro = True |
|---|
| | 39 | |
|---|
| | 40 | # Prevent it being used outside of wiki page context |
|---|
| | 41 | resource = context.resource |
|---|
| | 42 | if not resource.realm == 'wiki': |
|---|
| | 43 | raise TracError('\'AddComment\' macro can only be used in Wiki pages.') |
|---|
| | 44 | |
|---|
| | 45 | # Setup info and defaults |
|---|
| | 46 | authname = req.authname |
|---|
| | 47 | page = WikiPage(self.env, resource) |
|---|
| | 48 | page_url = req.href.wiki(resource.id) |
|---|
| | 49 | wikipreview = req.args.get("preview", "") |
|---|
| | 50 | appendonly = ('appendonly' in args) |
|---|
| | 51 | # Can this user add a comment to this page? |
|---|
| | 52 | cancomment = not page.readonly |
|---|
| | 53 | # Is this an "append-only" comment or are we an administrator? |
|---|
| | 54 | if 'WIKI_ADMIN' in req.perm(resource) or appendonly: |
|---|
| | 55 | cancomment = True |
|---|
| | 56 | if not cancomment: |
|---|
| | 57 | raise TracError('Error: Insufficient privileges to AddComment') |
|---|
| | 58 | disabled = False |
|---|
| | 59 | |
|---|
| | 60 | # Get the data from the POST |
|---|
| | 61 | comment = req.args.get("addcomment", "") |
|---|
| | 62 | preview = req.args.get("previewaddcomment", "") |
|---|
| | 63 | cancel = req.args.get("canceladdcomment", "") |
|---|
| | 64 | submit = req.args.get("submitaddcomment", "") |
|---|
| | 65 | if not cancel and req.authname == 'anonymous': |
|---|
| | 66 | authname = req.args.get("authoraddcomment", authname) |
|---|
| | 67 | |
|---|
| | 68 | # Ensure [[AddComment]] is not present in comment, so that infinite |
|---|
| | 69 | # recursion does not occur. |
|---|
| | 70 | comment = to_unicode(re.sub('(^|[^!])(\[\[AddComment)', '\\1!\\2', comment)) |
|---|
| | 71 | |
|---|
| | 72 | the_preview = the_message = the_form = tag() |
|---|
| | 73 | |
|---|
| | 74 | if wikipreview or not ('WIKI_MODIFY' in req.perm(resource) or appendonly): |
|---|
| | 75 | disabled = True |
|---|
| | 76 | |
|---|
| | 77 | # If we are submitting or previewing, inject comment as it should look |
|---|
| | 78 | if cancomment and comment and (preview or submit): |
|---|
| | 79 | heading = tag.h4("Comment by ", authname, " on ", |
|---|
| | 80 | to_unicode(time.strftime('%c', time.localtime())), |
|---|
| | 81 | id="commentpreview") |
|---|
| | 82 | if preview: |
|---|
| | 83 | the_preview = tag.div(heading, |
|---|
| | 84 | format_to_html(self.env, context, comment), |
|---|
| | 85 | class_="wikipage", id="preview") |
|---|
| | 86 | |
|---|
| | 87 | # When submitting, inject comment before macro |
|---|
| | 88 | if comment and submit: |
|---|
| | 89 | submitted = False |
|---|
| | 90 | newtext = "" |
|---|
| | 91 | for line in page.text.splitlines(): |
|---|
| | 92 | if line.find('[[AddComment') == 0: |
|---|
| | 93 | newtext += "==== Comment by %s on %s ====\n%s\n\n" % ( |
|---|
| | 94 | authname, |
|---|
| | 95 | to_unicode(time.strftime('%c', time.localtime())), |
|---|
| | 96 | comment) |
|---|
| | 97 | submitted = True |
|---|
| | 98 | newtext += line+"\n" |
|---|
| | 99 | if submitted: |
|---|
| | 100 | page.text = newtext |
|---|
| | 101 | page.save(authname, 'Comment added', req.environ['REMOTE_ADDR']) |
|---|
| | 102 | req.warning("Comment saved.") |
|---|
| | 103 | req.redirect(page_url) |
|---|
| | 104 | else: |
|---|
| | 105 | the_message = tag.div(tag.strong("ERROR: "), "[[AddComment]] " |
|---|
| | 106 | "macro call must be the only content on its line. " |
|---|
| | 107 | "Could not add comment.", |
|---|
| | 108 | class_="system-message") |
|---|
| 22 | | def _render_macro(self, req, name, content): |
|---|
| 23 | | pass # Fill in a deuglified version here |
|---|
| | 110 | the_form = tag.form( |
|---|
| | 111 | tag.fieldset( |
|---|
| | 112 | tag.legend("Add comment"), |
|---|
| | 113 | tag.div( |
|---|
| | 114 | (wikipreview and "Page preview..." or None), |
|---|
| | 115 | tag.textarea((not cancel and comment or ""), |
|---|
| | 116 | class_="wikitext", |
|---|
| | 117 | id="addcomment", |
|---|
| | 118 | name="addcomment", |
|---|
| | 119 | cols=80, rows=5, |
|---|
| | 120 | disabled=(disabled and "disabled" or None)), |
|---|
| | 121 | class_="field" |
|---|
| | 122 | ), |
|---|
| | 123 | (req.authname == 'anonymous' and tag.div( |
|---|
| | 124 | tag.label("Your email or username:", |
|---|
| | 125 | for_="authoraddcomment"), |
|---|
| | 126 | tag.input(id="authoraddcomment", type="text", |
|---|
| | 127 | size=30, value=authname) |
|---|
| | 128 | ) or None), |
|---|
| | 129 | tag.div( |
|---|
| | 130 | tag.input(value="Add comment", type="submit", |
|---|
| | 131 | name="submitaddcomment", size=30, |
|---|
| | 132 | disabled=(disabled and "disabled" or None)), |
|---|
| | 133 | tag.input(value="Preview comment", type="submit", |
|---|
| | 134 | name="previewaddcomment", |
|---|
| | 135 | disabled=(disabled and "disabled" or None)), |
|---|
| | 136 | tag.input(value="Cancel", type="submit", |
|---|
| | 137 | name="canceladdcomment", |
|---|
| | 138 | disabled=(disabled and "disabled" or None)), |
|---|
| | 139 | class_="buttons" |
|---|
| | 140 | ), |
|---|
| | 141 | ), |
|---|
| | 142 | method="post", |
|---|
| | 143 | action=page_url+"#commenting", |
|---|
| | 144 | ) |
|---|
| | 145 | |
|---|
| | 146 | add_script(req, 'common/js/wikitoolbar.js') |
|---|
| 34 | | authname = hdf.getValue("trac.authname", "anonymous") |
|---|
| 35 | | db = env.get_db_cnx() |
|---|
| 36 | | perm = trac.perm.PermissionCache(env, authname) |
|---|
| 37 | | pagename = 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 = 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" % (authname, time.strftime('%c', time.localtime()), wiki_to_html(comment, env, None))) |
|---|
| 73 | | if preview: |
|---|
| 74 | | out.write("</div>\n") |
|---|
| 75 | | |
|---|
| 76 | | # When submitting, inject comment before macro |
|---|
| 77 | | if comment and submit: |
|---|
| 78 | | submitted = False |
|---|
| 79 | | newtext = StringIO() |
|---|
| 80 | | for line in page.text.splitlines(): |
|---|
| 81 | | if line.find('[[AddComment') == 0: |
|---|
| 82 | | newtext.write("==== Comment by %s on %s ====\n%s\n\n" % (authname, time.strftime('%c', time.localtime()), comment)) |
|---|
| 83 | | submitted = True |
|---|
| 84 | | newtext.write(line + "\n") |
|---|
| 85 | | if submitted: |
|---|
| 86 | | # XXX Is this the dodgiest hack ever? This is needed in |
|---|
| 87 | | # "appendonly" mode when the page is readonly. XXX |
|---|
| 88 | | # if appendonly: |
|---|
| 89 | | # perm.expand_meta_permission('WIKI_ADMIN'); |
|---|
| 90 | | # TODO: How do we get remote_addr from a macro? |
|---|
| 91 | | page.text = newtext.getvalue() |
|---|
| 92 | | page.save(authname, 'Comment added', None) |
|---|
| 93 | | comment = "" |
|---|
| 94 | | else: |
|---|
| 95 | | 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") |
|---|
| 96 | | |
|---|
| 97 | | out.write("<form action='%s#commentpreview' method='post'>\n" % env.href.wiki(pagename)) |
|---|
| 98 | | out.write("<fieldset>\n<legend>Add comment</legend>\n") |
|---|
| 99 | | out.write("<div class='field'>\n<textarea class='wikitext' id='addcomment' name='addcomment' cols='80' rows='5'%s>" % disabled) |
|---|
| 100 | | if wikipreview: |
|---|
| 101 | | out.write("Page preview...") |
|---|
| 102 | | elif not cancel: |
|---|
| 103 | | out.write(comment) |
|---|
| 104 | | out.write("</textarea>\n") |
|---|
| 105 | | out.write("</div>\n") |
|---|
| 106 | | 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) |
|---|
| 107 | | out.write("<div class='field'>\n<input size='30' type='submit' name='submitaddcomment' value='Add comment'%s/>\n" % disabled) |
|---|
| 108 | | out.write("<input type='submit' name='previewaddcomment' value='Preview comment'%s/>\n" % disabled) |
|---|
| 109 | | out.write("<input type='submit' name='canceladdcomment' value='Cancel'%s/>\n</div>\n" % disabled) |
|---|
| 110 | | out.write('<script type="text/javascript" src="%sjs/wikitoolbar.js"></script>' % hdf['htdocs_location']) |
|---|
| 111 | | out.write("</fieldset>\n</form>\n") |
|---|
| 112 | | |
|---|
| 113 | | return out.getvalue()# + "<pre>" + hdf.dump() + "</pre>" |
|---|
| 114 | | |
|---|