Mercurial > public > sg101
changeset 13:777451a98f9d
Shoutbox work: shouts now have absolute URLs. Shouts can now be flagged as abuse. Minor tweak to breadcrumbs css. Added flag date to comments admin.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 16 Apr 2009 02:00:17 +0000 |
parents | f408971657b9 |
children | 7b6540b185d9 |
files | gpp/comments/admin.py gpp/shoutbox/admin.py gpp/shoutbox/models.py gpp/shoutbox/urls.py gpp/shoutbox/views.py gpp/templates/shoutbox/missing_shout.html gpp/templates/shoutbox/shout_detail.html gpp/templates/shoutbox/shoutbox.html gpp/templates/shoutbox/view.html gpp/templates/shoutbox/view_shout.html media/css/base.css media/js/shoutbox_app.js |
diffstat | 12 files changed, 160 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/gpp/comments/admin.py Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/comments/admin.py Thu Apr 16 02:00:17 2009 +0000 @@ -25,7 +25,7 @@ raw_id_fields = ('user', 'content_type') class CommentFlagAdmin(admin.ModelAdmin): - list_display = ('__unicode__', 'get_comment_url') + list_display = ('__unicode__', 'flag_date', 'get_comment_url') admin.site.register(Comment, CommentAdmin) admin.site.register(CommentFlag, CommentFlagAdmin)
--- a/gpp/shoutbox/admin.py Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/shoutbox/admin.py Thu Apr 16 02:00:17 2009 +0000 @@ -3,9 +3,17 @@ """ from django.contrib import admin from shoutbox.models import Shout +from shoutbox.models import ShoutFlag class ShoutAdmin(admin.ModelAdmin): - list_display = ('shout_date', '__unicode__') - raw_id_fields = ('user', ) + list_display = ('shout_date', '__unicode__') + raw_id_fields = ('user', ) + +class ShoutFlagAdmin(admin.ModelAdmin): + list_display = ('__unicode__', 'flag_date', 'get_shout_url') + admin.site.register(Shout, ShoutAdmin) +admin.site.register(ShoutFlag, ShoutFlagAdmin) + +# vim: ts=4 sw=4
--- a/gpp/shoutbox/models.py Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/shoutbox/models.py Thu Apr 16 02:00:17 2009 +0000 @@ -4,14 +4,38 @@ from django.db import models from django.contrib.auth.models import User + class Shout(models.Model): - user = models.ForeignKey(User) - shout_date = models.DateTimeField(auto_now_add=True) - shout = models.TextField() + user = models.ForeignKey(User) + shout_date = models.DateTimeField(auto_now_add=True) + shout = models.TextField() - def __unicode__(self): - shout = self.shout[:60] - return u'Shout from %s: %s' % (self.user.username, shout) + @models.permalink + def get_absolute_url(self): + return ('shoutbox-view', [str(self.id)]) - class Meta: - ordering = ('-shout_date', ) + def __unicode__(self): + shout = self.shout[:60] + return u'Shout from %s: %s' % (self.user.username, shout) + + class Meta: + ordering = ('-shout_date', ) + + +class ShoutFlag(models.Model): + """This model represents a user flagging a shout as inappropriate.""" + user = models.ForeignKey(User) + shout = models.ForeignKey(Shout) + flag_date = models.DateTimeField(auto_now_add=True) + + def __unicode__(self): + return u'Shout ID %s flagged by %s' % (self.shout_id, self.user.username) + + class Meta: + ordering = ('flag_date', ) + + def get_shout_url(self): + return '<a href="/admin/shoutbox/shout/%s">Shout</a>' % self.shout.id + get_shout_url.allow_tags = True + +# vim: ts=4 sw=4
--- a/gpp/shoutbox/urls.py Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/shoutbox/urls.py Thu Apr 16 02:00:17 2009 +0000 @@ -7,7 +7,11 @@ urlpatterns = patterns('shoutbox.views', url(r'^delete/$', 'delete', name='shoutbox-delete'), url(r'^edit/$', 'edit', name='shoutbox-edit'), + url(r'^flag/$', 'flag', name='shoutbox-flag'), url(r'^shout/$', 'shout', name='shoutbox-shout'), url(r'^text/$', 'text', name='shoutbox-text'), - url(r'^view/(?P<page>\d+)/$', 'view', name='shoutbox-view'), + url(r'^view/(\d+)/$', 'view_shout', name='shoutbox-view'), + url(r'^view/history/(?P<page>\d+)/$', 'view_history', name='shoutbox-history'), ) + +# vim: ts=4 sw=4
--- a/gpp/shoutbox/views.py Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/shoutbox/views.py Thu Apr 16 02:00:17 2009 +0000 @@ -13,8 +13,10 @@ from django.views.decorators.http import require_POST from core.paginator import DiggPaginator +from core.functions import email_admins from shoutbox.forms import ShoutBoxForm from shoutbox.models import Shout +from shoutbox.models import ShoutFlag SHOUTS_PER_PAGE = 10 @@ -33,7 +35,21 @@ context_instance = RequestContext(request)) -def view(request, page=1): +def view_shout(request, id): + """This view is for viewing an individual shout.""" + try: + shout = Shout.objects.get(pk=id) + except Shout.DoesNotExist: + return render_to_response('shoutbox/missing_shout.html', {}, + context_instance = RequestContext(request)) + + return render_to_response('shoutbox/view_shout.html', { + 'shout': shout, + }, + context_instance = RequestContext(request)) + + +def view_history(request, page=1): """This view allows one to view the shoutbox history.""" paginator = DiggPaginator(Shout.objects.all(), SHOUTS_PER_PAGE, body=5, tail=3, margin=3, padding=2) try: @@ -107,4 +123,32 @@ return HttpResponseForbidden() + +@require_POST +def flag(request): + """ + This function handles the flagging of shouts by users. This function should + be the target of an AJAX post. + """ + if not request.user.is_authenticated(): + return HttpResponse('Please login or register to flag a shout.') + + id = request.POST.get('id', None) + if id is None: + return HttpResponseBadRequest('No id') + + try: + shout = Shout.objects.get(pk=id) + except Shout.DoesNotExist: + return HttpResponseBadRequest('No shout with id %s' % id) + + flag = ShoutFlag(user=request.user, shout=shout) + flag.save() + email_admins('A Shout Has Been Flagged', """Hello, + +A user has flagged a shout for review. +""") + return HttpResponse('The shout was flagged. A moderator will review the shout shortly. ' \ + 'Thanks for helping to improve the quality of this site.') + # vim: ts=4 sw=4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/templates/shoutbox/missing_shout.html Thu Apr 16 02:00:17 2009 +0000 @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +{% block title %}Shout Not Found{% endblock %} +{% block content %} +<div class="breadcrumbs"><a href="{% url shoutbox-history page=1 %}">Shoutbox History</a> » Shout Not Found</div> +<h2>Shout Not Found</h2> +<p>We're sorry, it looks like that shout no longer exists.</p> +{% endblock %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/templates/shoutbox/shout_detail.html Thu Apr 16 02:00:17 2009 +0000 @@ -0,0 +1,21 @@ +{% load avatar_tags %} +{% load smiley_tags %} +<tr> +<th> +<a href="{% url bio-view_profile username=shout.user.username %}">{% avatar shout.user %}</a> +<a href="{% url bio-view_profile username=shout.user.username %}">{{ shout.user.username }}</a> +</th> +<td> +<div {% ifequal user shout.user %}class="edit" id="shout-{{ shout.id }}"{% endifequal %}>{{ shout.shout|smilify|urlize }}</div> +</div> +<br /> +<span class="date">{{ shout.shout_date|date:"D M d Y H:i:s" }}</span><br /> +<a href="{% url shoutbox-view shout.id %}"><img src="{{ MEDIA_URL }}icons/link.png" alt="Permalink" title="Permalink" /></a> +<a href="#" class="shout-flag" id="shout-flag-{{ shout.id }}"><img src="{{ MEDIA_URL }}icons/flag_red.png" alt="Flag" + title="Flag this shout as offensive" /></a> +{% ifequal user shout.user %} +<a href="#" class="shout-del" id="shout-del-{{ shout.id }}"><img src="{{ MEDIA_URL }}icons/cross.png" alt="Delete" + title="Delete this shout" /></a> +{% endifequal %} +</td> +</tr>
--- a/gpp/templates/shoutbox/shoutbox.html Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/templates/shoutbox/shoutbox.html Thu Apr 16 02:00:17 2009 +0000 @@ -11,7 +11,7 @@ </p> {% endfor %} </div> -<center><a href="{% url shoutbox-view page=1 %}">Shout History</a></center> +<center><a href="{% url shoutbox-history page=1 %}">Shout History</a></center> {% if user.is_authenticated %} <center> <form action="{% url shoutbox-shout %}" method="post">
--- a/gpp/templates/shoutbox/view.html Wed Apr 15 01:13:17 2009 +0000 +++ b/gpp/templates/shoutbox/view.html Thu Apr 16 02:00:17 2009 +0000 @@ -19,21 +19,7 @@ <div class="shoutbox-history"> <table> {% for shout in page.object_list %} - <tr> - <th> - <a href="{% url bio-view_profile username=shout.user.username %}">{% avatar shout.user %}</a> - <a href="{% url bio-view_profile username=shout.user.username %}">{{ shout.user.username }}</a> - </th> - <td> -<div {% ifequal user shout.user %}class="edit" id="shout-{{ shout.id }}"{% endifequal %}>{{ shout.shout|smilify|urlize }}</div> - </div> - <br /> - <span class="date">{{ shout.shout_date|date:"D M d Y H:i:s" }}</span> - {% ifequal user shout.user %} - | <a href="#" class="shout-del" id="shout-del-{{ shout.id }}">Delete</a> - {% endifequal %} - </td> - </tr> +{% include "shoutbox/shout_detail.html" %} {% endfor %} </table> </div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/templates/shoutbox/view_shout.html Thu Apr 16 02:00:17 2009 +0000 @@ -0,0 +1,19 @@ +{% extends 'base.html' %} +{% load script_tags %} +{% block custom_css %} +<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/shoutbox_app.css" /> +{% endblock %} +{% block custom_js %} +{% script_tags "jquery-jeditable" %} +<script type="text/javascript" src="{{ MEDIA_URL }}js/shoutbox_app.js"></script> +{% endblock %} +{% block title %}Shout #{{ shout.id }}{% endblock %} +{% block content %} +<div class="breadcrumbs"><a href="{% url shoutbox-history page=1 %}">Shoutbox History</a> » Shout #{{ shout.id }}</div> +<h2>Shout #{{ shout.id }}</h2> +<div class="shoutbox-history"> +<table> +{% include "shoutbox/shout_detail.html" %} +</table> +</div> +{% endblock %}
--- a/media/css/base.css Wed Apr 15 01:13:17 2009 +0000 +++ b/media/css/base.css Thu Apr 16 02:00:17 2009 +0000 @@ -97,6 +97,7 @@ } .breadcrumbs { font-size: x-small; + padding-bottom: 0.5em; } table { width: auto;
--- a/media/js/shoutbox_app.js Wed Apr 15 01:13:17 2009 +0000 +++ b/media/js/shoutbox_app.js Thu Apr 16 02:00:17 2009 +0000 @@ -7,10 +7,10 @@ submit : 'OK', cancel : 'Cancel' }); - $('.shout-del').click(function () { + $('a.shout-del').click(function () { if (confirm('Really delete this shout?')) { var id = this.id; - if (id.match(/shout-del-(\d+)/)) { + if (id.match(/^shout-del-(\d+)/)) { $.post('/shout/delete/', { id : RegExp.$1 }, function (id) { var id = '#shout-del-' + id; $(id).parents('tr').fadeOut(1500, function () { @@ -22,4 +22,19 @@ } return false; }); + $('.shout-flag').click(function () { + var id = this.id; + if (id.match(/^shout-flag-(\d+)/)) { + id = RegExp.$1; + if (confirm('Only flag a shout if you feel it is spam, abuse, violates site rules, ' + + 'or is not appropriate. ' + + 'A moderator will be notified and will review the shout. ' + + 'Are you sure you want to flag this shout?')) { + $.post('/shout/flag/', { id : id }, function(response) { + alert(response); + }, 'text'); + } + } + return false; + }); });