Browse Source

Warning levels admin. #37

Rafał Pitoń 11 years ago
parent
commit
defd471a96

+ 30 - 1
misago/apps/admin/sections/users.py

@@ -1,7 +1,7 @@
 from django.conf.urls import patterns, include, url
 from django.utils.translation import ugettext_lazy as _
 from misago.admin import AdminAction
-from misago.models import Ban, Newsletter, PruningPolicy, Rank, User
+from misago.models import Ban, Newsletter, PruningPolicy, Rank, User, WarnLevel
 
 ADMIN_ACTIONS = (
     AdminAction(
@@ -66,6 +66,35 @@ ADMIN_ACTIONS = (
                 ),
     AdminAction(
                 section='users',
+                id='warning_levels',
+                name=_("Warning Levels"),
+                help=_("Define penalties for different warning levels."),
+                icon='exclamation-sign',
+                model=WarnLevel,
+                actions=[
+                         {
+                          'id': 'list',
+                          'name': _("Browse Warning Levels"),
+                          'help': _("Browse all existing warning levels"),
+                          'link': 'admin_warning_levels'
+                          },
+                         {
+                          'id': 'new',
+                          'name': _("Set New Warning Level"),
+                          'help': None,
+                          'link': 'admin_warning_levels_new'
+                          },
+                         ],
+                link='admin_warning_levels',
+                urlpatterns=patterns('misago.apps.admin.warninglevels.views',
+                         url(r'^$', 'List', name='admin_warning_levels'),
+                         url(r'^new/$', 'New', name='admin_warning_levels_new'),
+                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_warning_levels_edit'),
+                         url(r'^delete/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Delete', name='admin_warning_levels_delete'),
+                     ),
+                ),
+    AdminAction(
+                section='users',
                 id='bans',
                 name=_("Bans"),
                 help=_("Ban or unban users from forums."),

+ 0 - 0
misago/apps/admin/warninglevels/__init__.py


+ 32 - 0
misago/apps/admin/warninglevels/forms.py

@@ -0,0 +1,32 @@
+from django.utils.translation import ugettext_lazy as _
+import floppyforms as forms
+from misago.forms import Form, YesNoSwitch
+from misago.models import WarnLevel
+from misago.validators import validate_sluggable
+
+class WarnLevelForm(Form):
+    name = forms.CharField(label=_("Warning Level Name"),
+                           max_length=255, validators=[validate_sluggable(
+                                                                          _("Warning level name must contain alphanumeric characters."),
+                                                                          _("Warning level name is too long.")
+                                                                          )])
+    description = forms.CharField(label=_("Warning Level Description"),
+                                  help_text=_("Optional message displayed to members with this warning level."),
+                                  widget=forms.Textarea, required=False)
+    expires_after_minutes = forms.IntegerField(label=_("Warning Level Expiration"),
+                                               help_text=_("Enter number of minutes since this warning level was imposed on member until it's reduced and lower level is imposed, or 0 to make this warning level permanent."),
+                                               initial=0, min_value=0)
+    inhibit_posting_replies = forms.TypedChoiceField(label=_("Restrict Replies Posting"),
+                                                     choices=(
+                                                        (0, _("No restrictions")),
+                                                        (1, _("Review by moderator")),
+                                                        (2, _("Disallowed")),
+                                                     ),
+                                                     coerce=int, initial=0)
+    inhibit_posting_threads = forms.TypedChoiceField(label=_("Restrict Threads Posting"),
+                                                     choices=(
+                                                        (0, _("No restrictions")),
+                                                        (1, _("Review by moderator")),
+                                                        (2, _("Disallowed")),
+                                                     ),
+                                                     coerce=int, initial=0)

+ 165 - 0
misago/apps/admin/warninglevels/views.py

@@ -0,0 +1,165 @@
+from django.core.urlresolvers import reverse as django_reverse
+from django.utils.translation import ugettext as _
+import floppyforms as forms
+from misago import messages
+from misago.admin import site
+from misago.apps.admin.widgets import *
+from misago.forms import Form
+from misago.models import WarnLevel
+from misago.utils.strings import slugify
+from misago.apps.admin.warninglevels.forms import WarnLevelForm
+
+def reverse(route, target=None):
+    if target:
+        return django_reverse(route, kwargs={'target': target.pk, 'slug': slugify(target.name)})
+    return django_reverse(route)
+
+
+"""
+Views
+"""
+class List(ListWidget):
+    admin = site.get_action('warning_levels')
+    id = 'list'
+    columns = (
+               ('name', _("Level Name")),
+               )
+    table_form_button = _('Change Warning Levels')
+    nothing_checked_message = _('You have to check at least one warning level.')
+    actions = (
+               ('delete', _("Delete selected levels"), _("Are you sure you want to delete selected warning levels?")),
+               )
+
+    def get_table_form(self, page_items):
+        order_form = {}
+
+        # Build choices list
+        choices = []
+        for i in range(0, len(page_items)):
+           choices.append([str(i), i + 1])
+
+        # Build selectors list
+        position = 0
+        for item in page_items:
+            order_form['pos_' + str(item.pk)] = forms.ChoiceField(choices=choices, initial=str(position))
+            position += 1
+
+        # Turn dict into object
+        return type('OrderWarningLevelsForm', (Form,), order_form)
+
+    def table_action(self, page_items, cleaned_data):
+        for item in page_items:
+            item.warning_level = cleaned_data['pos_' + str(item.pk)]
+            item.save(force_update=True)
+        return Message(_('Warning levels have been changed'), messages.SUCCESS), reverse('admin_warning_levels')
+
+    def sort_items(self, page_items, sorting_method):
+        return page_items.order_by('warning_level')
+
+    def get_item_actions(self, item):
+        return (
+                self.action('pencil', _("Edit Level"), reverse('admin_warning_levels_edit', item)),
+                self.action('remove', _("Delete Level"), reverse('admin_warning_levels_delete', item), post=True, prompt=_("Are you sure you want to delete this warning level?")),
+                )
+
+    def action_delete(self, items, checked):
+        WarnLevel.objects.filter(id__in=checked).delete()
+
+        levels_counter = 1
+        for level in WarnLevel.objects.order_by('warning_level').iterator():
+            if level.warning_level != levels_counter:
+                level.warning_level = levels_counter
+                level.save(force_update=True)
+            levels_counter += 1
+
+        return Message(_('Selected warning levels have been deleted successfully.'), messages.SUCCESS), reverse('admin_warning_levels')
+
+
+class New(FormWidget):
+    admin = site.get_action('warning_levels')
+    id = 'new'
+    fallback = 'admin_warning_levels'
+    form = WarnLevelForm
+    submit_button = _("Save Warning Level")
+
+    def get_new_link(self, model):
+        return reverse('admin_warning_levels_new')
+
+    def get_edit_link(self, model):
+        return reverse('admin_warning_levels_edit', model)
+
+    def submit_form(self, form, target):
+        top_level = WarnLevel.objects.order_by('-warning_level')[:1]
+        if top_level:
+            new_warning_level = top_level[0].warning_level + 1
+        else:
+            new_warning_level = 1
+
+        new_level = WarnLevel(
+                              name=form.cleaned_data['name'],
+                              slug=slugify(form.cleaned_data['name']),
+                              description=form.cleaned_data['description'],
+                              warning_level=new_warning_level,
+                              expires_after_minutes=form.cleaned_data['expires_after_minutes'],
+                              inhibit_posting_replies=form.cleaned_data['inhibit_posting_replies'],
+                              inhibit_posting_threads=form.cleaned_data['inhibit_posting_threads']
+                              )
+        new_level.save(force_insert=True)
+        return new_level, Message(_('New warning level has been defined.'), messages.SUCCESS)
+
+
+class Edit(FormWidget):
+    admin = site.get_action('warning_levels')
+    id = 'edit'
+    name = _("Edit Warning Level")
+    fallback = 'admin_warning_levels'
+    form = WarnLevelForm
+    target_name = 'name'
+    notfound_message = _('Requested warning level could not be found.')
+    translate_target_name = False
+    submit_fallback = True
+
+    def get_link(self, model):
+        return reverse('admin_warning_levels_edit', model)
+
+    def get_edit_link(self, model):
+        return self.get_link(model)
+
+    def get_initial_data(self, model):
+        return {
+                'name': model.name,
+                'description': model.description,
+                'expires_after_minutes': model.expires_after_minutes,
+                'inhibit_posting_replies': model.inhibit_posting_replies,
+                'inhibit_posting_threads': model.inhibit_posting_threads,
+                }
+
+    def submit_form(self, form, target):
+        target.name = form.cleaned_data['name']
+        target.slug = slugify(form.cleaned_data['name'])
+        target.description = form.cleaned_data['description']
+        target.expires_after_minutes = form.cleaned_data['expires_after_minutes']
+        target.inhibit_posting_replies = form.cleaned_data['inhibit_posting_replies']
+        target.inhibit_posting_threads = form.cleaned_data['inhibit_posting_threads']
+        target.save(force_update=True)
+
+        return target, Message(_('Changes in warning level "%(name)s" have been saved.') % {'name': self.original_name}, messages.SUCCESS)
+
+
+class Delete(ButtonWidget):
+    admin = site.get_action('warning_levels')
+    id = 'delete'
+    fallback = 'admin_warning_levels'
+    notfound_message = _('Requested warning level could not be found.')
+
+    def action(self, target):
+        target.delete()
+
+        levels_counter = 1
+        for level in WarnLevel.objects.order_by('warning_level').iterator():
+            if level.warning_level != levels_counter:
+                level.warning_level = levels_counter
+                level.save(force_update=True)
+            levels_counter += 1
+
+        return Message(_('Warning level "%(name)s" has been deleted.') % {'name': _(target.name)}, messages.SUCCESS), False

+ 1 - 1
misago/models/warnlevelmodel.py

@@ -6,8 +6,8 @@ class WarnLevel(models.Model):
     description = models.TextField(null=True, blank=True)
     warning_level = models.PositiveIntegerField(default=1, db_index=True)
     expires_after_minutes = models.PositiveIntegerField(default=0)
-    inhibit_posting_threads = models.PositiveIntegerField(default=0)
     inhibit_posting_replies = models.PositiveIntegerField(default=0)
+    inhibit_posting_threads = models.PositiveIntegerField(default=0)
 
     class Meta:
         app_label = 'misago'

+ 16 - 0
templates/admin/warning_levels/form.html

@@ -0,0 +1,16 @@
+{% extends "admin/admin/form.html" %}
+{% import "forms.html" as form_theme with context %}
+
+{% block form %}
+<fieldset>
+  <legend>{% trans %}Basic Warning Level Options{% endtrans %}</legend>
+  {{ form_theme.row(form.name, attrs={'class': 'span12'}) }}
+  {{ form_theme.row(form.description, attrs={'class': 'span12', 'rows': 3}) }}
+  {{ form_theme.row(form.expires_after_minutes, attrs={'class': 'span12'}) }}
+</fieldset>
+<fieldset>
+  <legend>{% trans %}Restrictions{% endtrans %}</legend>
+  {{ form_theme.row(form.inhibit_posting_replies, attrs={'class': 'span12'}) }}
+  {{ form_theme.row(form.inhibit_posting_threads, attrs={'class': 'span12'}) }}
+</fieldset>
+{% endblock %}

+ 17 - 0
templates/admin/warning_levels/list.html

@@ -0,0 +1,17 @@
+{% extends "admin/admin/list.html" %}
+{% import "forms.html" as form_theme with context %}
+
+{% block table_head scoped %}
+  {{ super() }}
+  <th>{% trans %}Warning Level{% endtrans %}</th>
+{% endblock %}
+
+{% block table_row scoped %}
+  <td>
+    <strong>{{ item.name }}</strong>
+    {% if item.description %}<div class="muted">{{ item.description }}</div>{% endif %}
+  </td>
+  <td class="span2">
+    {{ form_theme.field(table_form['pos_' + item.pk|string], attrs={'form': 'table_form', 'class': 'span2'}) }}
+  </td>
+{% endblock%}