From 231cb236dc38aeb61e522ca2ee42398f0dbba05f Mon Sep 17 00:00:00 2001 From: Skia Date: Fri, 12 May 2017 18:30:06 +0200 Subject: [PATCH] Add moderation tool to Trombi --- core/static/core/style.scss | 6 +- locale/fr/LC_MESSAGES/django.po | 155 +++++++++++++----- .../0003_trombicomment_is_moderated.py | 19 +++ trombi/models.py | 1 + .../templates/trombi/comment_moderation.jinja | 34 ++++ trombi/templates/trombi/detail.jinja | 1 + trombi/templates/trombi/user_profile.jinja | 4 +- trombi/urls.py | 2 + trombi/views.py | 58 +++++++ 9 files changed, 234 insertions(+), 46 deletions(-) create mode 100644 trombi/migrations/0003_trombicomment_is_moderated.py create mode 100644 trombi/templates/trombi/comment_moderation.jinja diff --git a/core/static/core/style.scss b/core/static/core/style.scss index 833dbe54..5db187ad 100644 --- a/core/static/core/style.scss +++ b/core/static/core/style.scss @@ -255,13 +255,17 @@ p, pre { margin-left: 0px; } -ul, ol { +ul, ol, dl { margin-top: 1em; margin-bottom: 1em; list-style-type: disc; margin-left: 25px; } +dt { + margin-top: 25px; +} + code { font-family: monospace; } diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 0258a475..93ae22ce 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-11 18:32+0200\n" +"POT-Creation-Date: 2017-05-12 16:56+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -335,14 +335,15 @@ msgstr "Compte en banque : " #: counter/templates/counter/last_ops.jinja:59 #: election/templates/election/election_detail.jinja:280 #: election/templates/election/election_detail.jinja:329 -#: forum/templates/forum/macros.jinja:20 forum/templates/forum/macros.jinja:110 +#: forum/templates/forum/macros.jinja:20 +#: forum/templates/forum/macros.jinja:110 #: launderette/templates/launderette/launderette_admin.jinja:16 #: launderette/views.py:178 sas/templates/sas/album.jinja:26 #: sas/templates/sas/moderation.jinja:18 sas/templates/sas/picture.jinja:74 -#: sas/templates/sas/picture.jinja.py:124 +#: sas/templates/sas/picture.jinja:124 #: stock/templates/stock/stock_shopping_list.jinja:43 #: stock/templates/stock/stock_shopping_list.jinja:69 -#: trombi/templates/trombi/detail.jinja:27 +#: trombi/templates/trombi/detail.jinja:28 msgid "Delete" msgstr "Supprimer" @@ -490,8 +491,8 @@ msgstr "Non" #: accounting/templates/accounting/club_account_details.jinja:56 #: com/templates/com/news_admin_list.jinja:38 -#: com/templates/com/news_admin_list.jinja:70 core/templates/core/file.jinja:36 -#: core/templates/core/page.jinja:28 +#: com/templates/com/news_admin_list.jinja:70 +#: core/templates/core/file.jinja:36 core/templates/core/page.jinja:28 msgid "View" msgstr "Voir" @@ -590,7 +591,7 @@ msgstr "Effectuées" #: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:798 #: trombi/templates/trombi/comment.jinja:4 #: trombi/templates/trombi/comment.jinja:8 -#: trombi/templates/trombi/user_tools.jinja:46 +#: trombi/templates/trombi/user_tools.jinja:52 msgid "Comment" msgstr "Commentaire" @@ -858,7 +859,8 @@ msgstr "L'utilisateur est déjà membre de ce club" msgid "past member" msgstr "Anciens membres" -#: club/templates/club/club_list.jinja:4 club/templates/club/club_list.jinja:24 +#: club/templates/club/club_list.jinja:4 +#: club/templates/club/club_list.jinja:24 msgid "Club list" msgstr "Liste des clubs" @@ -920,13 +922,14 @@ msgstr "Du" msgid "To" msgstr "Au" -#: club/templates/club/club_sellings.jinja:5 club/views.py:84 club/views.py:247 -#: counter/templates/counter/counter_main.jinja:19 +#: club/templates/club/club_sellings.jinja:5 club/views.py:84 +#: club/views.py:247 counter/templates/counter/counter_main.jinja:19 #: counter/templates/counter/last_ops.jinja:35 msgid "Sellings" msgstr "Ventes" -#: club/templates/club/club_sellings.jinja:9 club/templates/club/stats.jinja:19 +#: club/templates/club/club_sellings.jinja:9 +#: club/templates/club/stats.jinja:19 #: counter/templates/counter/cash_summary_list.jinja:15 msgid "Show" msgstr "Montrer" @@ -1116,7 +1119,7 @@ msgstr "titre" msgid "summary" msgstr "résumé" -#: com/models.py:62 com/models.py:150 trombi/models.py:111 +#: com/models.py:62 com/models.py:150 trombi/models.py:108 msgid "content" msgstr "contenu" @@ -1126,7 +1129,7 @@ msgstr "contenu" msgid "type" msgstr "type" -#: com/models.py:65 com/models.py:151 trombi/models.py:109 +#: com/models.py:65 com/models.py:151 trombi/models.py:106 msgid "author" msgstr "auteur" @@ -1183,8 +1186,9 @@ msgid "News admin" msgstr "Administration des nouvelles" #: com/templates/com/news_admin_list.jinja:9 -#: com/templates/com/news_detail.jinja:5 com/templates/com/news_detail.jinja:11 -#: com/templates/com/news_list.jinja:4 com/templates/com/news_list.jinja:28 +#: com/templates/com/news_detail.jinja:5 +#: com/templates/com/news_detail.jinja:11 com/templates/com/news_list.jinja:4 +#: com/templates/com/news_list.jinja:28 msgid "News" msgstr "Nouvelles" @@ -1343,6 +1347,7 @@ msgstr "Supprimer du Weekmail" #: core/templates/core/user_account_detail.jinja:11 #: core/templates/core/user_account_detail.jinja:104 launderette/views.py:178 #: stock/templates/stock/shopping_list_items.jinja:9 +#: trombi/templates/trombi/comment_moderation.jinja:10 msgid "Back" msgstr "Retour" @@ -1665,6 +1670,7 @@ msgstr "Un utilisateur de ce nom d'utilisateur existe déjà" #: election/templates/election/election_detail.jinja:316 #: forum/templates/forum/macros.jinja:87 forum/templates/forum/macros.jinja:89 #: forum/templates/forum/reply.jinja:36 forum/templates/forum/reply.jinja:38 +#: trombi/templates/trombi/user_tools.jinja:43 msgid "Profile" msgstr "Profil" @@ -1855,7 +1861,8 @@ msgstr "S'enregister" msgid "View more" msgstr "Voir plus" -#: core/templates/core/base.jinja:62 forum/templates/forum/last_unread.jinja:15 +#: core/templates/core/base.jinja:62 +#: forum/templates/forum/last_unread.jinja:15 msgid "Mark all as read" msgstr "Marquer tout commme lu" @@ -1887,7 +1894,7 @@ msgstr "SAS" #: core/templates/core/base.jinja:94 forum/templates/forum/forum.jinja:10 #: forum/templates/forum/last_unread.jinja:12 -#: forum/templates/forum/main.jinja:6 forum/templates/forum/main.jinja.py:11 +#: forum/templates/forum/main.jinja:6 forum/templates/forum/main.jinja:11 #: forum/templates/forum/main.jinja:13 forum/templates/forum/reply.jinja:15 #: forum/templates/forum/topic.jinja:30 msgid "Forum" @@ -2101,11 +2108,13 @@ msgstr "login" msgid "Lost password?" msgstr "Mot de passe perdu ?" -#: core/templates/core/macros.jinja:27 core/templates/core/user_detail.jinja:27 +#: core/templates/core/macros.jinja:27 +#: core/templates/core/user_detail.jinja:27 msgid "Born: " msgstr "Né le : " -#: core/templates/core/macros.jinja:31 core/templates/core/user_detail.jinja:48 +#: core/templates/core/macros.jinja:31 +#: core/templates/core/user_detail.jinja:48 msgid "Promo: " msgstr "Promo : " @@ -4322,11 +4331,11 @@ msgid "You must either choose an existing user or create a new one properly" msgstr "" "Vous devez soit choisir un utilisateur existant, soit en créer un proprement" -#: trombi/models.py:52 +#: trombi/models.py:51 msgid "subscription deadline" msgstr "fin des inscriptions" -#: trombi/models.py:53 +#: trombi/models.py:52 msgid "" "Before this date, users are allowed to subscribe to this Trombi. After this " "date, users subscribed will be allowed to comment on each other." @@ -4335,42 +4344,46 @@ msgstr "" "Après cette date, les utilisateurs inscrits peuvent se soumettre des " "commentaires entre eux." -#: trombi/models.py:56 +#: trombi/models.py:55 msgid "comments deadline" msgstr "fin des commentaires" -#: trombi/models.py:57 +#: trombi/models.py:56 msgid "After this date, users won't be able to make comments anymore." msgstr "" "Après cette date, les utilisateurs ne peuvent plus faire de commentaires." -#: trombi/models.py:59 +#: trombi/models.py:58 msgid "maximum characters" msgstr "nombre de caractères max" -#: trombi/models.py:60 +#: trombi/models.py:59 msgid "Maximum number of characters allowed in a comment." msgstr "Nombre maximum de caractères autorisés dans un commentaire." +#: trombi/models.py:60 +msgid "show users profiles to each other" +msgstr "montrer les profils aux inscrits" + #: trombi/models.py:71 msgid "" "Closing the subscriptions after the comments is definitively not a good idea." msgstr "" "Fermer les inscriptions après les commentaires est vraiment une idée pourrie." -#: trombi/models.py:94 +#: trombi/models.py:91 msgid "trombi user" msgstr "utilisateur trombi" -#: trombi/models.py:95 +#: trombi/models.py:92 msgid "trombi" msgstr "trombi" -#: trombi/models.py:96 +#: trombi/models.py:93 msgid "profile pict" msgstr "photo de profil" -#: trombi/models.py:97 +#: trombi/models.py:94 msgid "" "The profile picture you want in the trombi (warning: this picture may be " "published)" @@ -4378,11 +4391,11 @@ msgstr "" "La photo de profil que vous souhaitez voir dans le Trombi (attention: cette " "photo risque d'être publiée)" -#: trombi/models.py:98 +#: trombi/models.py:95 msgid "scrub pict" msgstr "photo de blouse" -#: trombi/models.py:99 +#: trombi/models.py:96 msgid "" "The scrub picture you want in the trombi (warning: this picture may be " "published)" @@ -4390,10 +4403,27 @@ msgstr "" "La photo de blouse que vous souhaitez voir dans le Trombi (attention: cette " "photo risque d'être publiée)" -#: trombi/models.py:110 +#: trombi/models.py:107 msgid "target" msgstr "cible" +#: trombi/models.py:109 +msgid "is the comment moderated" +msgstr "le commentaire est modéré" + +#: trombi/templates/trombi/comment_moderation.jinja:4 +#: trombi/templates/trombi/comment_moderation.jinja:8 +msgid "Moderate Trombi comments" +msgstr "Modérer les commentaires du Trombi" + +#: trombi/templates/trombi/comment_moderation.jinja:23 +msgid "Accept" +msgstr "Accepter" + +#: trombi/templates/trombi/comment_moderation.jinja:28 +msgid "Reject" +msgstr "Refuser" + #: trombi/templates/trombi/detail.jinja:4 #: trombi/templates/trombi/detail.jinja:8 #, python-format @@ -4401,13 +4431,26 @@ msgid "%(club)s's Trombi" msgstr "Trombi de %(club)s" #: trombi/templates/trombi/detail.jinja:10 +msgid "Moderate comments" +msgstr "Modérer les commentaires" + +#: trombi/templates/trombi/detail.jinja:11 msgid "Subscription deadline: " msgstr "Fin des inscriptions : " -#: trombi/templates/trombi/detail.jinja:11 +#: trombi/templates/trombi/detail.jinja:12 msgid "Comment deadline: " msgstr "Fin des commentaires : " +#: trombi/templates/trombi/user_profile.jinja:4 +#: trombi/templates/trombi/user_profile.jinja:8 +msgid "%(user_name)s's Trombi profile" +msgstr "Profil Trombi de %(user_name)s" + +#: trombi/templates/trombi/user_profile.jinja:9 +msgid "Back to tools" +msgstr "Retour aux outils" + #: trombi/templates/trombi/user_tools.jinja:4 #, python-format msgid "%(user_name)s's Trombi" @@ -4435,26 +4478,52 @@ msgid "You can not write comments at this date." msgstr "Vous ne pouvez pas commenter à cette date." #: trombi/templates/trombi/user_tools.jinja:25 +#, python-format msgid "" "Comments are only allowed between %(start)s (excluded) and %(end)s (included)" msgstr "" "Les commentaires sont autorisés entre le %(start)s (exclu) et le %(end)s " "(inclu)" -#: trombi/templates/trombi/user_tools.jinja:44 +#: trombi/templates/trombi/user_tools.jinja:50 msgid "Edit comment" msgstr "Éditer le commentaire" -#: trombi/views.py:101 +#: trombi/views.py:110 +msgid "Explain why you rejected the comment" +msgstr "Expliquez pourquoi vous refusez le commentaire" + +#: trombi/views.py:132 +msgid "Rejected comment" +msgstr "Commentaire rejeté" + +#: trombi/views.py:133 +#, python-format +msgid "" +"Your comment to %(target)s on the Trombi \"%(trombi)s\" was rejected for the " +"following reason: %(reason)s\n" +"\n" +"Your comment was:\n" +"\n" +"%(content)s" +msgstr "" +"Votre commentaire pour %(target)s sur le Trombi \"%(trombi)s\" a été rejecté pour le " +"motif suivant: %(reason)s\n" +"\n" +"Votre commentaire était:\n" +"\n" +"%(content)s" + +#: trombi/views.py:156 #, python-format msgid "%(name)s (deadline: %(date)s)" msgstr "%(name)s (date limite: %(date)s)" -#: trombi/views.py:104 +#: trombi/views.py:159 msgid "Select trombi" msgstr "Choisir un trombi" -#: trombi/views.py:105 +#: trombi/views.py:160 msgid "" "This allows you to subscribe to a Trombi. Be aware that you can subscribe " "only once, so don't play with that, or you will expose yourself to the " @@ -4464,19 +4533,19 @@ msgstr "" "pouvez vous inscrire qu'à un seul Trombi, donc ne jouez pas avec cet option " "ou vous encourerez la colère des admins!" -#: trombi/views.py:151 +#: trombi/views.py:206 msgid "Personal email (not UTBM)" msgstr "Email personnel (pas UTBM)" -#: trombi/views.py:152 +#: trombi/views.py:207 msgid "Phone" msgstr "Téléphone" -#: trombi/views.py:153 +#: trombi/views.py:208 msgid "Native town" msgstr "Ville d'origine" -#: trombi/views.py:174 +#: trombi/views.py:243 msgid "" "You can not yet write comment, you must wait for the subscription deadline " "to be passed." @@ -4484,11 +4553,11 @@ msgstr "" "Vous ne pouvez pas encore écrire de commentaires, vous devez attendre la fin " "des inscriptions" -#: trombi/views.py:177 +#: trombi/views.py:246 msgid "You can not write comment anymore, the deadline is already passed." msgstr "Vous ne pouvez plus écrire de commentaires, la date est passée." -#: trombi/views.py:184 +#: trombi/views.py:253 #, python-format msgid "Maximum characters: %(max_length)s" msgstr "Nombre de caractères max: %(max_length)s" diff --git a/trombi/migrations/0003_trombicomment_is_moderated.py b/trombi/migrations/0003_trombicomment_is_moderated.py new file mode 100644 index 00000000..9089b305 --- /dev/null +++ b/trombi/migrations/0003_trombicomment_is_moderated.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('trombi', '0002_trombi_show_profiles'), + ] + + operations = [ + migrations.AddField( + model_name='trombicomment', + name='is_moderated', + field=models.BooleanField(default=False, verbose_name='is the comment moderated'), + ), + ] diff --git a/trombi/models.py b/trombi/models.py index cb91c016..5e180502 100644 --- a/trombi/models.py +++ b/trombi/models.py @@ -106,6 +106,7 @@ class TrombiComment(models.Model): author = models.ForeignKey(TrombiUser, verbose_name=_("author"), related_name='given_comments') target = models.ForeignKey(TrombiUser, verbose_name=_("target"), related_name='received_comments') content = models.TextField(_("content"), default="") + is_moderated = models.BooleanField(_("is the comment moderated"), default=False) def can_be_viewed_by(self, user): if user.id == self.target.user.id: diff --git a/trombi/templates/trombi/comment_moderation.jinja b/trombi/templates/trombi/comment_moderation.jinja new file mode 100644 index 00000000..a7133d95 --- /dev/null +++ b/trombi/templates/trombi/comment_moderation.jinja @@ -0,0 +1,34 @@ +{% extends "core/base.jinja" %} + +{% block title %} +{% trans %}Moderate Trombi comments{% endtrans %} +{% endblock %} + +{% block content %} +

{% trans %}Moderate Trombi comments{% endtrans %}

+

{{ trombi }}

+{% trans %}Back{% endtrans %} +
+
+{% for c in comments %} +
{% trans author=c.author.user.get_display_name(), + target=c.target.user.get_display_name() %}Author: {{ author }} - Target: {{ target }}{% endtrans %}
+
+

+ {{ c.content }} +

+
+ {% csrf_token %} + +

+
+
+ {% csrf_token %} + +

+
+
+{% endfor %} +
+ +{% endblock %} diff --git a/trombi/templates/trombi/detail.jinja b/trombi/templates/trombi/detail.jinja index 5a8db4ab..c9503b0e 100644 --- a/trombi/templates/trombi/detail.jinja +++ b/trombi/templates/trombi/detail.jinja @@ -7,6 +7,7 @@ {% block content %}

{% trans club=object.club %}{{ club }}'s Trombi{% endtrans %}

{% trans %}Edit{% endtrans %} + {% trans %}Moderate comments{% endtrans %}

{% trans %}Subscription deadline: {% endtrans %}{{ object.subscription_deadline|date(DATETIME_FORMAT) }}

{% trans %}Comment deadline: {% endtrans %}{{ object.comments_deadline|date(DATETIME_FORMAT) }}

Export diff --git a/trombi/templates/trombi/user_profile.jinja b/trombi/templates/trombi/user_profile.jinja index 1afd3aba..61adb4b7 100644 --- a/trombi/templates/trombi/user_profile.jinja +++ b/trombi/templates/trombi/user_profile.jinja @@ -25,9 +25,9 @@
- {% for c in trombi_user.received_comments.all() %} + {% for c in trombi_user.received_comments.filter(is_moderated=True) %}
{{ c.author.user.get_display_name() }}
-
{{ c.content}}
+
{{ c.content }}
{% endfor %}
diff --git a/trombi/urls.py b/trombi/urls.py index 74936daa..5c87ce53 100644 --- a/trombi/urls.py +++ b/trombi/urls.py @@ -29,6 +29,8 @@ from trombi.views import * urlpatterns = [ url(r'^(?P[0-9]+)/new$', TrombiCreateView.as_view(), name='create'), url(r'^(?P[0-9]+)/edit$', TrombiEditView.as_view(), name='edit'), + url(r'^(?P[0-9]+)/moderate_comments$', TrombiModerateCommentsView.as_view(), name='moderate_comments'), + url(r'^(?P[0-9]+)/moderate$', TrombiModerateCommentView.as_view(), name='moderate_comment'), url(r'^(?P[0-9]+)/delete/(?P[0-9]+)$', TrombiDeleteUserView.as_view(), name='delete_user'), url(r'^(?P[0-9]+)$', TrombiDetailView.as_view(), name='detail'), url(r'^(?P[0-9]+)/new_comment$', TrombiCommentCreateView.as_view(), name='new_comment'), diff --git a/trombi/views.py b/trombi/views.py index a0e758c8..5ef776a1 100644 --- a/trombi/views.py +++ b/trombi/views.py @@ -29,6 +29,7 @@ from django.views.generic import ListView, DetailView, RedirectView, TemplateVie from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView, SingleObjectMixin from django.utils.translation import ugettext_lazy as _ from django import forms +from django.conf import settings from django.forms.models import modelform_factory from datetime import date @@ -95,6 +96,63 @@ class TrombiDeleteUserView(CanEditPropMixin, SingleObjectMixin, RedirectView): # See if we need to also delete the comments on the user, or if we keep them return redirect(self.object.get_absolute_url()+"?qn_success") +class TrombiModerateCommentsView(CanEditPropMixin, QuickNotifMixin, DetailView): + model = Trombi + template_name = 'trombi/comment_moderation.jinja' + pk_url_kwarg = 'trombi_id' + + def get_context_data(self, **kwargs): + kwargs = super(TrombiModerateCommentsView, self).get_context_data(**kwargs) + kwargs['comments'] = TrombiComment.objects.filter(is_moderated=False, + author__trombi__id=self.object.id).exclude(target__user__id=self.request.user.id) + return kwargs + +class TrombiModerateForm(forms.Form): + reason = forms.CharField(help_text=_("Explain why you rejected the comment")) + action = forms.CharField(initial="delete", widget=forms.widgets.HiddenInput) + +class TrombiModerateCommentView(DetailView): + model = TrombiComment + template_name = 'core/edit.jinja' + pk_url_kwarg = 'comment_id' + + def dispatch(self, request, *args, **kwargs): + self.object = self.get_object() + if not request.user.is_owner(self.object.author.trombi): + raise Http404() + return super(TrombiModerateCommentView, self).dispatch(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + if "action" in request.POST: + if request.POST['action'] == "accept": + self.object.is_moderated = True + self.object.save() + return redirect(reverse('trombi:moderate_comments', kwargs={'trombi_id': self.object.author.trombi.id})+"?qn_success") + elif request.POST['action'] == "reject": + return super(TrombiModerateCommentView, self).get(request, *args, **kwargs) + elif request.POST['action'] == "delete" and "reason" in request.POST.keys(): + self.object.author.user.email_user( + subject="[%s] %s" % (settings.SITH_NAME, _("Rejected comment")), + message=_("Your comment to %(target)s on the Trombi \"%(trombi)s\" was rejected for the following " + "reason: %(reason)s\n\n" + "Your comment was:\n\n%(content)s" + ) % { + 'target': self.object.target.user.get_display_name(), + 'trombi': self.object.author.trombi, + 'reason': request.POST["reason"], + 'content': self.object.content, + }, + ) + self.object.delete() + return redirect(reverse('trombi:moderate_comments', kwargs={'trombi_id': self.object.author.trombi.id})+"?qn_success") + raise Http404 + + + def get_context_data(self, **kwargs): + kwargs = super(TrombiModerateCommentView, self).get_context_data(**kwargs) + kwargs['form'] = TrombiModerateForm() + return kwargs + # User side class TrombiModelChoiceField(forms.ModelChoiceField): def label_from_instance(self, obj):