diff options
author | luxagraf <sng@luxagraf.net> | 2015-09-07 17:22:24 +0000 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2015-09-07 17:22:24 +0000 |
commit | 6cf2f5b09f3753351abc291cc70c6ae7e1126078 (patch) | |
tree | ebd14d3fd9b425eb8d8a88a0cae4034dddf28061 /app/lib/django_comments/views | |
parent | 6ff5d738b9442c92fa6cc36477a3e099eb516f7d (diff) |
added comments to my apps, fixed uwsgi config, fixed bug in photo template jquery url, added piwik stats code
Diffstat (limited to 'app/lib/django_comments/views')
-rw-r--r-- | app/lib/django_comments/views/__init__.py | 0 | ||||
-rw-r--r-- | app/lib/django_comments/views/comments.py | 136 | ||||
-rw-r--r-- | app/lib/django_comments/views/moderation.py | 165 | ||||
-rw-r--r-- | app/lib/django_comments/views/utils.py | 71 |
4 files changed, 372 insertions, 0 deletions
diff --git a/app/lib/django_comments/views/__init__.py b/app/lib/django_comments/views/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/lib/django_comments/views/__init__.py diff --git a/app/lib/django_comments/views/comments.py b/app/lib/django_comments/views/comments.py new file mode 100644 index 0000000..92084b6 --- /dev/null +++ b/app/lib/django_comments/views/comments.py @@ -0,0 +1,136 @@ +from __future__ import absolute_import + +from django import http +from django.conf import settings +from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.db import models +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.template.loader import render_to_string +from django.utils.html import escape +from django.views.decorators.csrf import csrf_protect +from django.views.decorators.http import require_POST + +import django_comments +from django_comments import signals +from django_comments.views.utils import next_redirect, confirmation_view + +class CommentPostBadRequest(http.HttpResponseBadRequest): + """ + Response returned when a comment post is invalid. If ``DEBUG`` is on a + nice-ish error message will be displayed (for debugging purposes), but in + production mode a simple opaque 400 page will be displayed. + """ + def __init__(self, why): + super(CommentPostBadRequest, self).__init__() + if settings.DEBUG: + self.content = render_to_string("comments/400-debug.html", {"why": why}) + + +@require_POST +def post_comment(request, next=None, using=None): + """ + Post a comment. + + HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are + errors a preview template, ``comments/preview.html``, will be rendered. + """ + # Fill out some initial data fields from an authenticated user, if present + data = request.POST.copy() + if request.user.is_authenticated(): + if not data.get('name', ''): + data["name"] = request.user.get_full_name() or request.user.get_username() + if not data.get('email', ''): + data["email"] = request.user.email + + # Look up the object we're trying to comment about + ctype = data.get("content_type") + object_pk = data.get("object_pk") + if ctype is None or object_pk is None: + return CommentPostBadRequest("Missing content_type or object_pk field.") + try: + model = models.get_model(*ctype.split(".", 1)) + target = model._default_manager.using(using).get(pk=object_pk) + except TypeError: + return CommentPostBadRequest( + "Invalid content_type value: %r" % escape(ctype)) + except AttributeError: + return CommentPostBadRequest( + "The given content-type %r does not resolve to a valid model." % \ + escape(ctype)) + except ObjectDoesNotExist: + return CommentPostBadRequest( + "No object matching content-type %r and object PK %r exists." % \ + (escape(ctype), escape(object_pk))) + except (ValueError, ValidationError) as e: + return CommentPostBadRequest( + "Attempting go get content-type %r and object PK %r exists raised %s" % \ + (escape(ctype), escape(object_pk), e.__class__.__name__)) + + # Do we want to preview the comment? + preview = "preview" in data + + # Construct the comment form + form = django_comments.get_form()(target, data=data) + + # Check security information + if form.security_errors(): + return CommentPostBadRequest( + "The comment form failed security verification: %s" % \ + escape(str(form.security_errors()))) + + # If there are errors or if we requested a preview show the comment + if form.errors or preview: + template_list = [ + # These first two exist for purely historical reasons. + # Django v1.0 and v1.1 allowed the underscore format for + # preview templates, so we have to preserve that format. + "comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.model_name), + "comments/%s_preview.html" % model._meta.app_label, + # Now the usual directory based template hierarchy. + "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.model_name), + "comments/%s/preview.html" % model._meta.app_label, + "comments/preview.html", + ] + return render_to_response( + template_list, { + "comment": form.data.get("comment", ""), + "form": form, + "next": data.get("next", next), + }, + RequestContext(request, {}) + ) + + # Otherwise create the comment + comment = form.get_comment_object() + comment.ip_address = request.META.get("REMOTE_ADDR", None) + if request.user.is_authenticated(): + comment.user = request.user + + # Signal that the comment is about to be saved + responses = signals.comment_will_be_posted.send( + sender=comment.__class__, + comment=comment, + request=request + ) + + for (receiver, response) in responses: + if response == False: + return CommentPostBadRequest( + "comment_will_be_posted receiver %r killed the comment" % receiver.__name__) + + # Save the comment and signal that it was saved + comment.save() + signals.comment_was_posted.send( + sender=comment.__class__, + comment=comment, + request=request + ) + + return next_redirect(request, fallback=next or 'comments-comment-done', + c=comment._get_pk_val()) + +comment_done = confirmation_view( + template="comments/posted.html", + doc="""Display a "comment was posted" success page.""" +) diff --git a/app/lib/django_comments/views/moderation.py b/app/lib/django_comments/views/moderation.py new file mode 100644 index 0000000..b35626a --- /dev/null +++ b/app/lib/django_comments/views/moderation.py @@ -0,0 +1,165 @@ +from __future__ import absolute_import + +from django import template +from django.conf import settings +from django.contrib.auth.decorators import login_required, permission_required +from django.shortcuts import get_object_or_404, render_to_response +from django.views.decorators.csrf import csrf_protect + +import django_comments +from django_comments import signals +from django_comments.views.utils import next_redirect, confirmation_view + +@csrf_protect +@login_required +def flag(request, comment_id, next=None): + """ + Flags a comment. Confirmation on GET, action on POST. + + Templates: :template:`comments/flag.html`, + Context: + comment + the flagged `comments.comment` object + """ + comment = get_object_or_404(django_comments.get_model(), pk=comment_id, site__pk=settings.SITE_ID) + + # Flag on POST + if request.method == 'POST': + perform_flag(request, comment) + return next_redirect(request, fallback=next or 'comments-flag-done', + c=comment.pk) + + # Render a form on GET + else: + return render_to_response('comments/flag.html', + {'comment': comment, "next": next}, + template.RequestContext(request) + ) + +@csrf_protect +@permission_required("django_comments.can_moderate") +def delete(request, comment_id, next=None): + """ + Deletes a comment. Confirmation on GET, action on POST. Requires the "can + moderate comments" permission. + + Templates: :template:`comments/delete.html`, + Context: + comment + the flagged `comments.comment` object + """ + comment = get_object_or_404(django_comments.get_model(), pk=comment_id, site__pk=settings.SITE_ID) + + # Delete on POST + if request.method == 'POST': + # Flag the comment as deleted instead of actually deleting it. + perform_delete(request, comment) + return next_redirect(request, fallback=next or 'comments-delete-done', + c=comment.pk) + + # Render a form on GET + else: + return render_to_response('comments/delete.html', + {'comment': comment, "next": next}, + template.RequestContext(request) + ) + +@csrf_protect +@permission_required("django_comments.can_moderate") +def approve(request, comment_id, next=None): + """ + Approve a comment (that is, mark it as public and non-removed). Confirmation + on GET, action on POST. Requires the "can moderate comments" permission. + + Templates: :template:`comments/approve.html`, + Context: + comment + the `comments.comment` object for approval + """ + comment = get_object_or_404(django_comments.get_model(), pk=comment_id, site__pk=settings.SITE_ID) + + # Delete on POST + if request.method == 'POST': + # Flag the comment as approved. + perform_approve(request, comment) + return next_redirect(request, fallback=next or 'comments-approve-done', + c=comment.pk) + + # Render a form on GET + else: + return render_to_response('comments/approve.html', + {'comment': comment, "next": next}, + template.RequestContext(request) + ) + +# The following functions actually perform the various flag/aprove/delete +# actions. They've been broken out into separate functions to that they +# may be called from admin actions. + +def perform_flag(request, comment): + """ + Actually perform the flagging of a comment from a request. + """ + flag, created = django_comments.models.CommentFlag.objects.get_or_create( + comment = comment, + user = request.user, + flag = django_comments.models.CommentFlag.SUGGEST_REMOVAL + ) + signals.comment_was_flagged.send( + sender = comment.__class__, + comment = comment, + flag = flag, + created = created, + request = request, + ) + +def perform_delete(request, comment): + flag, created = django_comments.models.CommentFlag.objects.get_or_create( + comment = comment, + user = request.user, + flag = django_comments.models.CommentFlag.MODERATOR_DELETION + ) + comment.is_removed = True + comment.save() + signals.comment_was_flagged.send( + sender = comment.__class__, + comment = comment, + flag = flag, + created = created, + request = request, + ) + + +def perform_approve(request, comment): + flag, created = django_comments.models.CommentFlag.objects.get_or_create( + comment = comment, + user = request.user, + flag = django_comments.models.CommentFlag.MODERATOR_APPROVAL, + ) + + comment.is_removed = False + comment.is_public = True + comment.save() + + signals.comment_was_flagged.send( + sender = comment.__class__, + comment = comment, + flag = flag, + created = created, + request = request, + ) + +# Confirmation views. + +flag_done = confirmation_view( + template = "comments/flagged.html", + doc = 'Displays a "comment was flagged" success page.' +) +delete_done = confirmation_view( + template = "comments/deleted.html", + doc = 'Displays a "comment was deleted" success page.' +) +approve_done = confirmation_view( + template = "comments/approved.html", + doc = 'Displays a "comment was approved" success page.' +) diff --git a/app/lib/django_comments/views/utils.py b/app/lib/django_comments/views/utils.py new file mode 100644 index 0000000..314ab8c --- /dev/null +++ b/app/lib/django_comments/views/utils.py @@ -0,0 +1,71 @@ +""" +A few bits of helper functions for comment views. +""" + +import textwrap +try: + from urllib.parse import urlencode +except ImportError: # Python 2 + from urllib import urlencode + +from django.http import HttpResponseRedirect +from django.shortcuts import render_to_response, resolve_url +from django.template import RequestContext +from django.core.exceptions import ObjectDoesNotExist +from django.utils.http import is_safe_url + +import django_comments + +def next_redirect(request, fallback, **get_kwargs): + """ + Handle the "where should I go next?" part of comment views. + + The next value could be a + ``?next=...`` GET arg or the URL of a given view (``fallback``). See + the view modules for examples. + + Returns an ``HttpResponseRedirect``. + """ + next = request.POST.get('next') + if not is_safe_url(url=next, host=request.get_host()): + next = resolve_url(fallback) + + if get_kwargs: + if '#' in next: + tmp = next.rsplit('#', 1) + next = tmp[0] + anchor = '#' + tmp[1] + else: + anchor = '' + + joiner = ('?' in next) and '&' or '?' + next += joiner + urlencode(get_kwargs) + anchor + return HttpResponseRedirect(next) + +def confirmation_view(template, doc="Display a confirmation view."): + """ + Confirmation view generator for the "comment was + posted/flagged/deleted/approved" views. + """ + def confirmed(request): + comment = None + if 'c' in request.GET: + try: + comment = django_comments.get_model().objects.get(pk=request.GET['c']) + except (ObjectDoesNotExist, ValueError): + pass + return render_to_response(template, + {'comment': comment}, + context_instance=RequestContext(request) + ) + + confirmed.__doc__ = textwrap.dedent("""\ + %s + + Templates: :template:`%s`` + Context: + comment + The posted comment + """ % (doc, template) + ) + return confirmed |