Index: addcomment/macro.py
===================================================================
--- addcomment/macro.py	(revision 7799)
+++ addcomment/macro.py	(working copy)
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
 # vim: expandtab
 import re, time
 from StringIO import StringIO
@@ -30,6 +32,38 @@ class AddCommentMacro(WikiMacroBase):
     """
     implements(IWikiMacroProvider, IRequestFilter, IMacroPoster)
 
+
+    def cancomment(self, req, page, appendonly):
+        cancomment = False
+        if page.readonly:
+            if 'WIKI_ADMIN' in req.perm(page.resource):
+                cancomment = True
+        elif 'WIKI_MODIFY' in req.perm(page.resource):
+            cancomment = True
+        elif appendonly and 'WIKI_VIEW' in req.perm(page.resource):
+            cancomment = True
+        else:
+            raise TracError('Error: Insufficient privileges to AddComment')
+        return cancomment
+
+    def get_postdata(self, req):
+        # Get the data from the POST
+        result = {}
+        result['comment'] = req.args.get("addcomment", "")
+        result['preview'] = req.args.get("previewaddcomment", "")
+        result['cancel'] = req.args.get("canceladdcomment", "")
+        result['submit'] = req.args.get("submitaddcomment", "")
+        if not result['cancel'] and req.authname == 'anonymous':
+            result['authname'] = req.args.get("authoraddcomment", req.authname)
+        else:
+            result['authname'] = req.authname
+        # Ensure [[AddComment]] is not present in comment, so that infinite
+        # recursion does not occur.
+        result['comment'] = to_unicode(re.sub('(^|[^!])(\[\[AddComment)', '\\1!\\2', result['comment']))
+        # XXX: We should also check for {{{!#AddComment ... maybe just ensure that AddComment is always prefixed with '!'?
+
+        return result
+
     def expand_macro(self, formatter, name, content):
         
         args, kw = parse_args(content)
@@ -47,51 +81,91 @@ class AddCommentMacro(WikiMacroBase):
             raise TracError('\'AddComment\' macro can only be used in Wiki pages.')
         
         # Setup info and defaults
-        authname = req.authname
         page = WikiPage(self.env, resource)
         page_url = req.href.wiki(resource.id)
+        postdata = self.get_postdata(req)
         wikipreview = req.args.get("preview", "")
         
         # Can this user add a comment to this page?
         appendonly = ('appendonly' in args)
-        cancomment = False
-        if page.readonly:
-            if 'WIKI_ADMIN' in req.perm(resource):
-                cancomment = True
-        elif 'WIKI_MODIFY' in req.perm(resource):
-            cancomment = True
-        elif appendonly and 'WIKI_VIEW' in req.perm(resource):
-            cancomment = True
-        else:
-            raise TracError('Error: Insufficient privileges to AddComment')
-        
-        # Get the data from the POST
-        comment = req.args.get("addcomment", "")
-        preview = req.args.get("previewaddcomment", "")
-        cancel = req.args.get("canceladdcomment", "")
-        submit = req.args.get("submitaddcomment", "")
-        if not cancel and req.authname == 'anonymous':
-            authname = req.args.get("authoraddcomment", authname)
-        
-        # Ensure [[AddComment]] is not present in comment, so that infinite
-        # recursion does not occur.
-        comment = to_unicode(re.sub('(^|[^!])(\[\[AddComment)', '\\1!\\2', comment))
+        cancomment = self.cancomment(req, page, appendonly)
         
         the_preview = the_message = the_form = tag()
 
         # If we are submitting or previewing, inject comment as it should look
-        if cancomment and comment and (preview or submit):
-            heading = tag.h4("Comment by ", authname, " on ",
-                        to_unicode(time.strftime('%c', time.localtime())),
+        if cancomment and postdata['comment'] and postdata['preview']:
+            heading = tag.h4("Kommentar von ", postdata['authname'], " am ",
+                        to_unicode(time.strftime('%d.%m.%Y um %H:%M', time.localtime())),
                         id="commentpreview")
-            if preview:
-                the_preview = tag.div(heading,
-                                format_to_html(self.env, context, comment),
-                                class_="wikipage", id="preview")
+            the_preview = tag.div(heading,
+                            format_to_html(self.env, context, postdata['comment']),
+                            class_="wikipage", id="preview")
+
+        if not wikipreview:
+            # Wiki edit preview already adds this javascript file
+            add_script(req, 'common/js/wikitoolbar.js')
         
+        the_form = tag.form(
+                    tag.fieldset(
+                        tag.legend(u"Kommentar Hinzufügen"),
+                        tag.div(
+                            (wikipreview and "Page preview..." or None),
+                            tag.textarea((not postdata['cancel'] and postdata['comment'] or ""),
+                                        class_="wikitext",
+                                        id="addcomment",
+                                        name="addcomment",
+                                        cols=80, rows=5,
+                                    disabled=(not cancomment and "disabled" or None)),
+                            class_="field"
+                        ),
+                        (req.authname == 'anonymous' and tag.div(
+                            tag.label("Your email or username:",
+                                    for_="authoraddcomment"),
+                            tag.input(id="authoraddcomment", type="text",
+                                    size=30, value=postdata['authname'])
+                        ) or None),
+                        tag.input(type="hidden", name="__FORM_TOKEN",
+                                        value=req.form_token),
+                        tag.div(
+                            tag.input(value=u"Kommentar Hinzufügen", type="submit",
+                                    name="submitaddcomment", size=30,
+                                    disabled=(not cancomment and "disabled" or None)),
+                            tag.input(value="Vorschau", type="submit",
+                                    name="previewaddcomment",
+                                    disabled=(not cancomment and "disabled" or None)),
+                            tag.input(value="Abbrechen", type="submit",
+                                    name="canceladdcomment",
+                                    disabled=(not cancomment and "disabled" or None)),
+                            class_="buttons"
+                        ),
+                    ),
+                    method="post",
+                    action=page_url+"#commenting",
+                )
+
+        return tag.div(the_preview, the_message, the_form, id="commenting")
+    
+    # IMacroPoster method
+    
+    def process_macro_post(self, req):
+        self.log.debug('AddCommentMacro: Got a POST')
+
+        page = WikiPage(self.env, req.path_info[6:])
+        page_url = req.href.wiki(page.resource.id)
+        match = re.search(r'^\[\[AddComment(\(appendonly\))?\]\]', page.text, re.MULTILINE)
+        if match is None:
+            raise TracError('Did not find \'AddComment\' macro in wiki page \'%s\'.' % req.path_info[6:])
+        if match.group(1):
+            appendonly = True
+        else:
+            appendonly = False
+
+        cancomment = self.cancomment(req, page, appendonly)
+        postdata = self.get_postdata(req)
+
         # Check the form_token
         form_ok = True
-        if submit and req.args.get('__FORM_TOKEN','') != req.form_token:
+        if postdata['submit'] and req.args.get('__FORM_TOKEN','') != req.form_token:
             form_ok = False
             the_message = tag.div(tag.strong("ERROR: "),
                 "AddComment received incorrect form token. "
@@ -99,15 +173,15 @@ class AddCommentMacro(WikiMacroBase):
                 class_="system-message")
         
         # When submitting, inject comment before macro
-        if comment and submit and cancomment and form_ok:
+        if postdata['comment'] and postdata['submit'] and cancomment and form_ok:
             submitted = False
             newtext = ""
             for line in page.text.splitlines():
                 if line.find('[[AddComment') == 0:
-                    newtext += "==== Comment by %s on %s ====\n%s\n\n" % (
-                            authname,
-                            to_unicode(time.strftime('%c', time.localtime())),
-                            comment)
+                    newtext += "==== Kommentar von %s am %s ====\n%s\n\n" % (
+                            postdata['authname'],
+                            to_unicode(time.strftime('%d.%m.%Y um %H:%M', time.localtime())),
+                            postdata['comment'])
                     submitted = True
                 newtext += line+"\n"
             if submitted:
@@ -137,7 +211,7 @@ class AddCommentMacro(WikiMacroBase):
                     the_message += tag.div(tag.strong("ERROR: "), s, class_="system-message")
 
                 if valid:        
-                    page.save(authname, req.args['comment'], req.environ['REMOTE_ADDR'])
+                    page.save(postdata['authname'], req.args['comment'], req.environ['REMOTE_ADDR'])
                     # We can't redirect from macro as it will raise RequestDone
                     # which like other macro errors gets swallowed in the Formatter.
                     # We need to re-raise it in a post_process_request instead.
@@ -147,70 +221,26 @@ class AddCommentMacro(WikiMacroBase):
                         req._outheaders = []
                         req.redirect(page_url)
                     except RequestDone:
+                        self.env.log.debug(
+                            "AddComment: did set req.addcomment_raise")
                         req.addcomment_raise = True
+                        self.env.log.debug("AddComment: %i" % hasattr(req, 'addcomment_raise'))
             else:
                 the_message = tag.div(tag.strong("ERROR: "), "[[AddComment]] "
                           "macro call must be the only content on its line. "
                           "Could not add comment.",
                           class_="system-message")
 
-        the_form = tag.form(
-                    tag.fieldset(
-                        tag.legend("Add comment"),
-                        tag.div(
-                            (wikipreview and "Page preview..." or None),
-                            tag.textarea((not cancel and comment or ""),
-                                        class_="wikitext",
-                                        id="addcomment",
-                                        name="addcomment",
-                                        cols=80, rows=5,
-                                    disabled=(not cancomment and "disabled" or None)),
-                            class_="field"
-                        ),
-                        (req.authname == 'anonymous' and tag.div(
-                            tag.label("Your email or username:",
-                                    for_="authoraddcomment"),
-                            tag.input(id="authoraddcomment", type="text",
-                                    size=30, value=authname)
-                        ) or None),
-                        tag.input(type="hidden", name="__FORM_TOKEN",
-                                        value=req.form_token),
-                        tag.div(
-                            tag.input(value="Add comment", type="submit",
-                                    name="submitaddcomment", size=30,
-                                    disabled=(not cancomment and "disabled" or None)),
-                            tag.input(value="Preview comment", type="submit",
-                                    name="previewaddcomment",
-                                    disabled=(not cancomment and "disabled" or None)),
-                            tag.input(value="Cancel", type="submit",
-                                    name="canceladdcomment",
-                                    disabled=(not cancomment and "disabled" or None)),
-                            class_="buttons"
-                        ),
-                    ),
-                    method="post",
-                    action=page_url+"#commenting",
-                )
-
-        if not wikipreview:
-            # Wiki edit preview already adds this javascript file
-            add_script(req, 'common/js/wikitoolbar.js')
-        
-        return tag.div(the_preview, the_message, the_form, id="commenting")
-    
-    # IMacroPoster method
-    
-    def process_macro_post(self, req):
-        self.log.debug('AddCommentMacro: Got a POST')
-
     # IRequestFilter methods
 
     def pre_process_request(self, req, handler):
         return handler
 
     def post_process_request(self, req, template, data, content_type):
+        self.env.log.debug("AddCommentMacro: post_process_request %s, %s" % (req.path_info, content_type))
         if hasattr(req, 'addcomment_raise'):
             self.env.log.debug("AddCommentMacro: Re-raising RequestDone from redirect")
             del(req.addcomment_raise)
+            req.send_response(303)
             raise RequestDone
         return template, data, content_type
