From 3b1670422732a4500878affb005435deff9d59e0 Mon Sep 17 00:00:00 2001 From: Skia Date: Fri, 24 Feb 2017 01:50:05 +0100 Subject: [PATCH] Add basic moderation to forum --- forum/migrations/0007_forummessagemeta.py | 27 +++++++++++++++++++++++ forum/models.py | 21 ++++++++++++++++++ forum/templates/forum/topic.jinja | 14 ++++++++++++ forum/urls.py | 2 ++ forum/views.py | 27 ++++++++++++++++++++++- 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 forum/migrations/0007_forummessagemeta.py diff --git a/forum/migrations/0007_forummessagemeta.py b/forum/migrations/0007_forummessagemeta.py new file mode 100644 index 00000000..38e0ff25 --- /dev/null +++ b/forum/migrations/0007_forummessagemeta.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('forum', '0006_auto_20170128_2243'), + ] + + operations = [ + migrations.CreateModel( + name='ForumMessageMeta', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)), + ('date', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date')), + ('action', models.CharField(max_length=16, choices=[('EDIT', 'Edit'), ('DELETE', 'Delete'), ('UNDELETE', 'Undelete')], verbose_name='action')), + ('message', models.ForeignKey(related_name='metas', to='forum.ForumMessage')), + ('user', models.ForeignKey(related_name='forum_message_metas', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/forum/models.py b/forum/models.py index 4c2a15d9..0483fb40 100644 --- a/forum/models.py +++ b/forum/models.py @@ -156,12 +156,33 @@ class ForumMessage(models.Model): def can_be_viewed_by(self, user): return user.can_view(self.topic) + def can_be_moderated_by(self, user): + return user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID) + def get_absolute_url(self): return self.topic.get_absolute_url() + "#first_unread" def mark_as_read(self, user): self.readers.add(user) + def is_deleted(self): + meta = self.metas.exclude(action="EDIT").order_by('-date').first() + if meta: + return meta.action == "DELETE" + return False + +MESSAGE_META_ACTIONS = [ + ('EDIT', _("Message edited by")), + ('DELETE', _("Message deleted by")), + ('UNDELETE', _("Message undeleted by")), + ] + +class ForumMessageMeta(models.Model): + user = models.ForeignKey(User, related_name="forum_message_metas") + message = models.ForeignKey(ForumMessage, related_name="metas") + date = models.DateTimeField(_('date'), default=timezone.now) + action = models.CharField(_("action"), choices=MESSAGE_META_ACTIONS, max_length=16) + class ForumUserInfo(models.Model): user = models.OneToOneField(User, related_name="_forum_infos") last_read_date = models.DateTimeField(_('last read date'), default=datetime(year=settings.SITH_SCHOOL_START_YEAR, diff --git a/forum/templates/forum/topic.jinja b/forum/templates/forum/topic.jinja index 9915f7fe..41ceb1c4 100644 --- a/forum/templates/forum/topic.jinja +++ b/forum/templates/forum/topic.jinja @@ -67,6 +67,13 @@ {% if user.can_edit(m) %} {% trans %}Edit{% endtrans %} {% endif %} + {% if m.can_be_moderated_by(user) %} + {% if m.is_deleted() %} + {% trans %}Undelete{% endtrans %} + {% else %} + {% trans %}Delete{% endtrans %} + {% endif %} + {% endif %}
{{ m.date|date(DATETIME_FORMAT) }} {{ m.date|time(DATETIME_FORMAT) }} @@ -74,6 +81,13 @@
{{ m.message|markdown }}
+ {{ m.mark_as_read(user) or "" }} diff --git a/forum/urls.py b/forum/urls.py index 46027a9e..2cdfd298 100644 --- a/forum/urls.py +++ b/forum/urls.py @@ -15,5 +15,7 @@ urlpatterns = [ url(r'^topic/(?P[0-9]+)/edit$', ForumTopicEditView.as_view(), name='edit_topic'), url(r'^topic/(?P[0-9]+)/new_message$', ForumMessageCreateView.as_view(), name='new_message'), url(r'^message/(?P[0-9]+)/edit$', ForumMessageEditView.as_view(), name='edit_message'), + url(r'^message/(?P[0-9]+)/delete$', ForumMessageDeleteView.as_view(), name='delete_message'), + url(r'^message/(?P[0-9]+)/undelete$', ForumMessageUndeleteView.as_view(), name='undelete_message'), ] diff --git a/forum/views.py b/forum/views.py index ead1ad65..e021e771 100644 --- a/forum/views.py +++ b/forum/views.py @@ -1,6 +1,7 @@ from django.shortcuts import render, get_object_or_404 from django.views.generic import ListView, DetailView, RedirectView from django.views.generic.edit import UpdateView, CreateView, DeleteView +from django.views.generic.detail import SingleObjectMixin from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse, reverse_lazy from django.utils import timezone @@ -10,7 +11,7 @@ from django.db import models from django.core.exceptions import PermissionDenied from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin -from forum.models import Forum, ForumMessage, ForumTopic +from forum.models import Forum, ForumMessage, ForumTopic, ForumMessageMeta class ForumMainView(ListView): queryset = Forum.objects.filter(parent=None) @@ -133,6 +134,30 @@ class ForumMessageEditView(CanEditMixin, UpdateView): template_name = "core/edit.jinja" pk_url_kwarg = "message_id" + def form_valid(self, form): + ForumMessageMeta(message=self.object, user=self.request.user, action="EDIT").save() + return super(ForumMessageEditView, self).form_valid(form) + +class ForumMessageDeleteView(SingleObjectMixin, RedirectView): + model = ForumMessage + pk_url_kwarg = "message_id" + permanent = False + + def get_redirect_url(self, *args, **kwargs): + if self.object.can_be_moderated_by(self.request.user): + ForumMessageMeta(message=self.object, user=self.request.user, action="DELETE").save() + return self.object.get_absolute_url() + +class ForumMessageUndeleteView(SingleObjectMixin, RedirectView): + model = ForumMessage + pk_url_kwarg = "message_id" + permanent = False + + def get_redirect_url(self, *args, **kwargs): + if self.object.can_be_moderated_by(self.request.user): + ForumMessageMeta(message=self.object, user=self.request.user, action="UNDELETE").save() + return self.object.get_absolute_url() + class ForumMessageCreateView(CanCreateMixin, CreateView): model = ForumMessage fields = ['title', 'message']