David Chambers avatar David Chambers committed d03afdc

Refactored `post` view so that it can operate when Disqus is offline.

Comments (0)

Files changed (1)

 # -*- coding: utf-8 -*-
 
 import hashlib
-import re
-import urllib
+
+import disqus
 
 from django import http
 from django.core.mail import EmailMultiAlternatives, send_mail
 
             try:
                 recipients = [primary_author_email()]
-            except EmptySettingError as e:
-                return http.HttpResponseServerError(e.html())
+            except EmptySettingError as error:
+                logger.error(error.message)
+                return http.HttpResponseServerError(error.html())
 
             if form.cleaned_data['cc_sender']:
                 recipients.append(sender)
     if view_source:
         return http.HttpResponse(document.body, content_type=PLAIN)
 
-    form = CommentForm()
-    thread = None
-    comment = request.session.get('comment')
-    if comment:
-        del request.session['comment']
+    comment = request.session.pop('comment', None)
+    if comment is not None:
         comment = loader.render_to_string('comment.dhtml', {'comment': comment})
 
-    comments = []
-    if FORUM:
-        # This call is only here for legacy and migration support, it will never return a value on Mango made threads
+    try:
+        # accommodate old threads (Mango-made threads must be accessed by identifier)
         thread = DISQUS.get_thread_by_url(FORUM, document.urls['canon']['abs'])
         if not thread:
             thread = DISQUS.thread_by_identifier(FORUM, document.title, document.urls['canon']['rel'])['thread']
+    except disqus.APIError as error:
+        logger.warning('Disqus API error: %s' % error)
+        thread = None
 
-        if request.method == 'POST':
-            form = CommentForm(request.POST, request=request)
-            if form.is_valid():
-                author_name = form.cleaned_data['author_name']
-                author_email = form.cleaned_data['author_email']
-                author_url = form.cleaned_data['author_url']
-                message = form.cleaned_data['message']
-                subscribe = form.cleaned_data['subscribe']
+    while True: # avoids excessive indentation
+        form = CommentForm()
+        if request.method != 'POST': break
 
-                if subscribe and SUBSCRIPTIONS: # don't assume that SUBSCRIPTIONS is True
-                    subscriptions = Subscription.objects.filter(
-                            subscriber_email=author_email, url=document.urls['canon']['abs'])
-                    if not subscriptions:
-                        subscription = Subscription(subscriber_name=author_name,
-                                subscriber_email=author_email, url=document.urls['canon']['abs'])
-                        subscription.save()
-                    logger.debug('%s is %s subscribed to comments on %s' % (author_name,
-                            'already' if subscriptions else 'now', thread.title))
+        form = CommentForm(request.POST, request=request)
+        if not form.is_valid(): break
 
-                # send request to Disqus
-                comment = DISQUS.create_post(FORUM, thread,
-                        message=message,
-                        author_name=author_name,
-                        author_email=author_email,
-                        author_url=author_url,
-                        ip_address=request.META['REMOTE_ADDR'])
+        author_name = form.cleaned_data['author_name']
+        author_email = form.cleaned_data['author_email']
+        author_url = form.cleaned_data['author_url']
+        message = form.cleaned_data['message']
+        subscribe = form.cleaned_data['subscribe']
 
-                # store comment so that it can be displayed to the author even if withheld for moderation
-                request.session['comment'] = comment
+        if subscribe and SUBSCRIPTIONS: # don't assume that SUBSCRIPTIONS is True
+            subscriptions = Subscription.objects.filter(
+                    subscriber_email=author_email, url=document.urls['canon']['abs'])
+            if not subscriptions:
+                subscription = Subscription(subscriber_name=author_name,
+                        subscriber_email=author_email, url=document.urls['canon']['abs'])
+                subscription.save()
+            logger.debug('%s is %s subscribed to comments on %s' % (author_name,
+                    'already' if subscriptions else 'now', document.title))
 
-                # send e-mail notification
-                author = u'%s <%s>' % (author_name, author_email)
-                subject = u'[%s] Comment: "%s"' % (SITE_TITLE, document.title)
-                context = {
-                    'commenter': author,
-                    'comment': message,
-                    'base_url': BASE_URL,
-                    'path': path,
-                    'api_key': hashlib.sha1(DISQUS_API_KEY).hexdigest(),
-                    'post_id': comment.id,
-                    'thread_id': thread.id,
-                }
-                try:
-                    recipient = primary_author_email()
-                except EmptySettingError as e:
-                    return http.HttpResponseServerError(e.html())
+        if not FORUM or not thread: break
 
-                msg = EmailMultiAlternatives(subject, loader.render_to_string('email/moderator.dtext', context),
-                        to=[recipient], headers={'Reply-To': author})
-                msg.attach_alternative(loader.render_to_string('email/moderator.dhtml', context), 'text/html')
-                msg.send(fail_silently=False)
+        try:
+            # send request to Disqus
+            comment = DISQUS.create_post(FORUM, thread,
+                    message=message,
+                    author_name=author_name,
+                    author_email=author_email,
+                    author_url=author_url,
+                    ip_address=request.META['REMOTE_ADDR'])
+        except disqus.APIError as error:
+            logger.warning('Disqus API error: %s' % error)
+            break
 
-                return http.HttpResponseRedirect('redirect/')
+        # store comment so that it can be displayed to
+        # its author even if withheld for moderation
+        request.session['comment'] = comment
 
-        for c in DISQUS.get_thread_posts(FORUM, thread, limit=9999, exclude='killed'):
-            if c.has_been_moderated or not COMMENTS_REQUIRE_APPROVAL:
-                comments.append(c)
-        comments.sort(key=lambda comment: comment.created_at)
+        # send e-mail notification
+        author = u'%s <%s>' % (author_name, author_email)
+        subject = u'[%s] Comment: "%s"' % (SITE_TITLE, document.title)
+        context = {
+            'commenter': author,
+            'comment': message,
+            'base_url': BASE_URL,
+            'path': path,
+            'api_key': hashlib.sha1(DISQUS_API_KEY).hexdigest(),
+            'post_id': comment.id,
+            'thread_id': thread.id,
+        }
+        try:
+            recipient = primary_author_email()
+        except EmptySettingError as error:
+            logger.error(error.message)
+            return http.HttpResponseServerError(error.html())
+
+        msg = EmailMultiAlternatives(subject, loader.render_to_string('email/moderator.dtext', context),
+                to=[recipient], headers={'Reply-To': author})
+        msg.attach_alternative(loader.render_to_string('email/moderator.dhtml', context), 'text/html')
+        msg.send(fail_silently=False)
+
+        return http.HttpResponseRedirect('redirect/')
+
+    if thread: # get comments
+        try:
+            thread_posts = DISQUS.get_thread_posts(FORUM, thread, limit=9999, exclude='killed')
+        except disqus.APIError as error:
+            logger.warning('Disqus API error: %s' % error)
+            comments = []
+        else:
+            comments = [c for c in thread_posts if c.has_been_moderated or not COMMENTS_REQUIRE_APPROVAL]
+            comments.sort(key=lambda comment: comment.created_at)
 
     context = _defaults(request, context={
         'comments': comments,
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.