|
@@ -1,3 +1,4 @@
|
|
|
+from django.contrib import messages
|
|
|
from django.core.urlresolvers import reverse
|
|
|
from django.shortcuts import redirect
|
|
|
from django.utils.translation import ugettext_lazy, ugettext as _
|
|
@@ -6,31 +7,83 @@ from misago.core.shortcuts import paginate
|
|
|
from misago.readtracker import threadstracker
|
|
|
|
|
|
from misago.threads.models import Label
|
|
|
+from misago.threads.moderation import ModerationError
|
|
|
from misago.threads.views.generic.base import ViewBase
|
|
|
|
|
|
|
|
|
-__all__ = ['Sorting', 'Threads', 'ThreadsView']
|
|
|
+__all__ = ['Actions', 'Sorting', 'Threads', 'ThreadsView']
|
|
|
|
|
|
|
|
|
+class Actions(object):
|
|
|
+ select_threads_message = ugettext_lazy(
|
|
|
+ "You have to select at least one thread")
|
|
|
|
|
|
-class Threads(object):
|
|
|
- def __init__(self, user):
|
|
|
- self.user = user
|
|
|
+ def __init__(self, **kwargs):
|
|
|
+ if kwargs.get('user').is_authenticated():
|
|
|
+ self.available_actions = self.get_available_actions(kwargs)
|
|
|
+ else:
|
|
|
+ self.available_actions = []
|
|
|
+ self.selected_ids = []
|
|
|
|
|
|
- def sort(self, sort_by):
|
|
|
- self.queryset = self.queryset.order_by(sort_by)
|
|
|
+ def get_available_actions(self, kwargs):
|
|
|
+ raise NotImplementedError("get_available_actions has to return list "
|
|
|
+ "of dicts with allowed actions")
|
|
|
|
|
|
- def label_threads(self, threads, labels=None):
|
|
|
- if labels:
|
|
|
- labels_dict = dict([(label.pk, label) for label in labels])
|
|
|
+ def resolve_action(self, request):
|
|
|
+ action_name = request.get_list('thread')
|
|
|
+ if ':' in action_name:
|
|
|
+ action_name, action_arg = action_name.split(':')
|
|
|
else:
|
|
|
- labels_dict = Label.objects.get_cached_labels_dict()
|
|
|
+ action_arg = None
|
|
|
|
|
|
- for thread in threads:
|
|
|
- thread.label = labels_dict.get(thread.label_id)
|
|
|
+ for action in self.available_actions:
|
|
|
+ if action['action'] == action_name:
|
|
|
+ action_callable = 'action_%s' % action_name
|
|
|
+ return getattr(self, action_callable)
|
|
|
+ else:
|
|
|
+ raise ModerationError(_("Requested action is invalid."))
|
|
|
+
|
|
|
+ def clean_selection(self, data):
|
|
|
+ filtered_data = []
|
|
|
+ for pk in data[:50]: # a tiny fail-safe to avoid too big workloads
|
|
|
+ try:
|
|
|
+ filtered_data.append(int(pk))
|
|
|
+ except ValueError:
|
|
|
+ pass
|
|
|
+
|
|
|
+ if not filtered_data:
|
|
|
+ raise ModerationError(self.select_threads_message)
|
|
|
+
|
|
|
+ return filtered_data
|
|
|
+
|
|
|
+ def handle_post(self, request, queryset):
|
|
|
+ try:
|
|
|
+ action, action_arg = self.resolve_action(request)
|
|
|
+ self.selected_ids = self.clean_selection(
|
|
|
+ request.POST.get_list('thread'))
|
|
|
+
|
|
|
+ filtered_queryset = queryset.filter(pk__in=self.selected_ids)
|
|
|
+ if filtered_queryset.exists():
|
|
|
+ if action_arg:
|
|
|
+ response = action(request, filtered_queryset, action_arg)
|
|
|
+ else:
|
|
|
+ response = action(request, filtered_queryset)
|
|
|
+ if response:
|
|
|
+ return response
|
|
|
+ else:
|
|
|
+ # prepare default response: page reload
|
|
|
+ return redirect(request.path)
|
|
|
+ else:
|
|
|
+ raise ModerationError(self.select_threads_message)
|
|
|
+ except ModerationError as e:
|
|
|
+ messages.error(request, e.message)
|
|
|
+ return False
|
|
|
|
|
|
- def make_threads_read_aware(self, threads):
|
|
|
- threadstracker.make_read_aware(self.user, threads)
|
|
|
+ def get_list(self):
|
|
|
+ return self.available_actions
|
|
|
+
|
|
|
+ def get_selected_ids(self):
|
|
|
+ return self.selected_ids
|
|
|
|
|
|
|
|
|
class Sorting(object):
|
|
@@ -121,6 +174,26 @@ class Sorting(object):
|
|
|
threads.sort(self.sorting['order_by'])
|
|
|
|
|
|
|
|
|
+class Threads(object):
|
|
|
+ def __init__(self, user):
|
|
|
+ self.user = user
|
|
|
+
|
|
|
+ def sort(self, sort_by):
|
|
|
+ self.queryset = self.queryset.order_by(sort_by)
|
|
|
+
|
|
|
+ def label_threads(self, threads, labels=None):
|
|
|
+ if labels:
|
|
|
+ labels_dict = dict([(label.pk, label) for label in labels])
|
|
|
+ else:
|
|
|
+ labels_dict = Label.objects.get_cached_labels_dict()
|
|
|
+
|
|
|
+ for thread in threads:
|
|
|
+ thread.label = labels_dict.get(thread.label_id)
|
|
|
+
|
|
|
+ def make_threads_read_aware(self, threads):
|
|
|
+ threadstracker.make_read_aware(self.user, threads)
|
|
|
+
|
|
|
+
|
|
|
class ThreadsView(ViewBase):
|
|
|
def get_threads(self, request, kwargs):
|
|
|
queryset = self.get_threads_queryset(request, forum)
|