]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/views/admin.py
OSQA-720, changing the WMD markdown editor, applying patches that resolve issues...
[osqa.git] / forum / views / admin.py
index b131d8fea11cd92c808a34375613b1559c56e7ee..6dffa5120a9add77f5f1dc97d651da2512a14c08 100644 (file)
@@ -10,9 +10,10 @@ from django.utils.translation import ugettext as _
 from django.utils import simplejson
 from django.db import models
 from forum.settings.base import Setting
 from django.utils import simplejson
 from django.db import models
 from forum.settings.base import Setting
-from forum.forms import MaintenanceModeForm, PageForm, NodeManFilterForm, CreateUserForm
+from forum.forms import MaintenanceModeForm, PageForm, CreateUserForm
 from forum.settings.forms import SettingsSetForm
 from forum.utils import pagination, html
 from forum.settings.forms import SettingsSetForm
 from forum.utils import pagination, html
+from forum.utils.mail import send_template_email
 
 from forum.models import Question, Answer, User, Node, Action, Page, NodeState, Tag
 from forum.models.node import NodeMetaClass
 
 from forum.models import Question, Answer, User, Node, Action, Page, NodeState, Tag
 from forum.models.node import NodeMetaClass
@@ -30,28 +31,47 @@ def super_user_required(fn):
 
     return wrapper
 
 
     return wrapper
 
-def admin_page(fn):
-    @super_user_required
+def staff_user_required(fn):
     def wrapper(request, *args, **kwargs):
     def wrapper(request, *args, **kwargs):
-        res = fn(request, *args, **kwargs)
-        if isinstance(res, HttpResponse):
-            return res
+        if request.user.is_authenticated() and (request.user.is_staff or request.user.is_superuser):
+            return fn(request, *args, **kwargs)
+        else:
+            return HttpResponseUnauthorized(request)
 
 
-        template, context = res
-        context['basetemplate'] = settings.DJSTYLE_ADMIN_INTERFACE and "osqaadmin/djstyle_base.html" or "osqaadmin/base.html"
-        context['allsets'] = Setting.sets
-        context['othersets'] = sorted(
-                [s for s in Setting.sets.values() if not s.name in
-                ('basic', 'users', 'email', 'paths', 'extkeys', 'repgain', 'minrep', 'voting', 'accept', 'badges', 'about', 'faq', 'sidebar',
-                'form', 'moderation', 'css', 'headandfoot', 'head', 'view', 'urls')]
-                , lambda s1, s2: s1.weight - s2.weight)
+    return wrapper
+
+def admin_page_wrapper(fn, request, *args, **kwargs):
+    res = fn(request, *args, **kwargs)
+    if isinstance(res, HttpResponse):
+        return res
+
+    template, context = res
+    context['basetemplate'] = settings.DJSTYLE_ADMIN_INTERFACE and "osqaadmin/djstyle_base.html" or "osqaadmin/base.html"
+    context['allsets'] = Setting.sets
+    context['othersets'] = sorted(
+            [s for s in Setting.sets.values() if not s.name in
+            ('basic', 'users', 'email', 'paths', 'extkeys', 'repgain', 'minrep', 'voting', 'accept', 'badges', 'about', 'faq', 'sidebar',
+            'form', 'moderation', 'css', 'headandfoot', 'head', 'view', 'urls')]
+            , lambda s1, s2: s1.weight - s2.weight)
 
 
-        context['tools'] = TOOLS
+    context['tools'] = [(name, fn.label) for name, fn in TOOLS.items()]
 
 
-        unsaved = request.session.get('previewing_settings', {})
-        context['unsaved'] = set([getattr(settings, s).set.name for s in unsaved.keys() if hasattr(settings, s)])
+    unsaved = request.session.get('previewing_settings', {})
+    context['unsaved'] = set([getattr(settings, s).set.name for s in unsaved.keys() if hasattr(settings, s)])
 
 
-        return render_to_response(template, context, context_instance=RequestContext(request))
+    return render_to_response(template, context, context_instance=RequestContext(request))
+
+def admin_page(fn):
+    @super_user_required
+    def wrapper(request, *args, **kwargs):
+        return admin_page_wrapper(fn, request, *args, **kwargs)
+
+    return wrapper
+
+def moderation_page(fn):
+    @staff_user_required
+    def wrapper(request, *args, **kwargs):
+        return admin_page_wrapper(fn, request, *args, **kwargs)
 
     return wrapper
 
 
     return wrapper
 
@@ -327,7 +347,7 @@ def maintenance(request):
                                            })
 
 
                                            })
 
 
-@admin_page
+@moderation_page
 def flagged_posts(request):
     return ('osqaadmin/flagged_posts.html', {
     'flagged_posts': get_flagged_posts(),
 def flagged_posts(request):
     return ('osqaadmin/flagged_posts.html', {
     'flagged_posts': get_flagged_posts(),
@@ -381,6 +401,12 @@ def edit_page(request, id=None):
     'published': published
     })
 
     'published': published
     })
 
+@admin_page
+def delete_page(request, id=None):
+    page = get_object_or_404(Page, id=id)
+    page.delete()
+    return HttpResponseRedirect(reverse('admin_static_pages'))
+
 @admin_tools_page(_('createuser'), _("Create new user"))
 def create_user(request):
     if request.POST:
 @admin_tools_page(_('createuser'), _("Create new user"))
 def create_user(request):
     if request.POST:
@@ -410,112 +436,152 @@ def create_user(request):
 class NodeManagementPaginatorContext(pagination.PaginatorContext):
     def __init__(self, id='QUESTIONS_LIST', prefix='', default_pagesize=100):
         super (NodeManagementPaginatorContext, self).__init__(id, sort_methods=(
 class NodeManagementPaginatorContext(pagination.PaginatorContext):
     def __init__(self, id='QUESTIONS_LIST', prefix='', default_pagesize=100):
         super (NodeManagementPaginatorContext, self).__init__(id, sort_methods=(
-            (_('title'), pagination.SimpleSort(_('title'), '-title', "")),
             (_('added_at'), pagination.SimpleSort(_('added_at'), '-added_at', "")),
             (_('added_at'), pagination.SimpleSort(_('added_at'), '-added_at', "")),
+            (_('added_at_asc'), pagination.SimpleSort(_('added_at_asc'), 'added_at', "")),
+            (_('author'), pagination.SimpleSort(_('author'), '-author__username', "")),
+            (_('author_asc'), pagination.SimpleSort(_('author_asc'), 'author__username', "")),
             (_('score'), pagination.SimpleSort(_('score'), '-score', "")),
             (_('score'), pagination.SimpleSort(_('score'), '-score', "")),
+            (_('score_asc'), pagination.SimpleSort(_('score_asc'), 'score', "")),
             (_('act_at'), pagination.SimpleSort(_('act_at'), '-last_activity_at', "")),
             (_('act_at'), pagination.SimpleSort(_('act_at'), '-last_activity_at', "")),
-        ), pagesizes=(default_pagesize,), default_pagesize=default_pagesize, prefix=prefix)
+            (_('act_at_asc'), pagination.SimpleSort(_('act_at_asc'), 'last_activity_at', "")),
+            (_('act_by'), pagination.SimpleSort(_('act_by'), '-last_activity_by__username', "")),
+            (_('act_by_asc'), pagination.SimpleSort(_('act_by_asc'), 'last_activity_by__username', "")),
+        ), pagesizes=(default_pagesize,), force_sort='added_at', default_pagesize=default_pagesize, prefix=prefix)
 
 
-@admin_tools_page(_("nodeman"), _("Node management"))
+@admin_tools_page(_("nodeman"), _("Bulk management"))
 def node_management(request):
     if request.POST:
 def node_management(request):
     if request.POST:
-        selected_nodes = request.POST.getlist('_selected_node')
+        params = pagination.generate_uri(request.GET, ('page',))
 
 
-        if selected_nodes and request.POST.get('action', None):
-            action = request.POST['action']
-            selected_nodes = Node.objects.filter(id__in=selected_nodes)
+        if "save_filter" in request.POST:
+            filter_name = request.POST.get('filter_name', _('filter'))
+            params = pagination.generate_uri(request.GET, ('page',))
+            current_filters = settings.NODE_MAN_FILTERS.value
+            current_filters.append((filter_name, params))
+            settings.NODE_MAN_FILTERS.set_value(current_filters)
 
 
-            message = _("No action performed")
+        elif r"execute" in request.POST:
+            selected_nodes = request.POST.getlist('_selected_node')
 
 
-            if action == 'delete_selected':
-                for node in selected_nodes:
-                    if node.node_type in ('question', 'answer', 'comment') and (not node.nis.deleted):
-                        DeleteAction(user=request.user, node=node, ip=request.META['REMOTE_ADDR']).save()
-                        
-                message = _("All selected nodes marked as deleted")
+            if selected_nodes and request.POST.get('action', None):
+                action = request.POST['action']
+                selected_nodes = Node.objects.filter(id__in=selected_nodes)
 
 
-            if action == "close_selected":
-                for node in selected_nodes:
-                    if node.node_type == "question" and (not node.nis.closed):
-                        CloseAction(node=node.leaf, user=request.user, extra=_("bulk close"), ip=request.META['REMOTE_ADDR']).save()
+                message = _("No action performed")
 
 
-                message = _("Selected questions were closed")
+                if action == 'delete_selected':
+                    for node in selected_nodes:
+                        if node.node_type in ('question', 'answer', 'comment') and (not node.nis.deleted):
+                            DeleteAction(user=request.user, node=node, ip=request.META['REMOTE_ADDR']).save()
 
 
-            if action == "hard_delete_selected":
-                ids = [n.id for n in selected_nodes]
+                    message = _("All selected nodes marked as deleted")
 
 
-                for id in ids:
-                    try:
-                        node = Node.objects.get(id=id)
-                        node.delete()
-                    except:
-                        pass                        
+                if action == 'undelete_selected':
+                    for node in selected_nodes:
+                        if node.node_type in ('question', 'answer', 'comment') and (node.nis.deleted):
+                            node.nstate.deleted.cancel(ip=request.META['REMOTE_ADDR'])
 
 
-                message = _("All selected nodes deleted")
+                    message = _("All selected nodes undeleted")
 
 
-            request.user.message_set.create(message=message)
-            return HttpResponseRedirect(reverse("admin_tools", kwargs={'name': 'nodeman'}))
+                if action == "close_selected":
+                    for node in selected_nodes:
+                        if node.node_type == "question" and (not node.nis.closed):
+                            CloseAction(node=node.leaf, user=request.user, extra=_("bulk close"), ip=request.META['REMOTE_ADDR']).save()
+
+                    message = _("Selected questions were closed")
+
+                if action == "hard_delete_selected":
+                    ids = [n.id for n in selected_nodes]
+
+                    for id in ids:
+                        try:
+                            node = Node.objects.get(id=id)
+                            node.delete()
+                        except:
+                            pass
+
+                    message = _("All selected nodes deleted")
+
+                request.user.message_set.create(message=message)
+
+                params = pagination.generate_uri(request.GET, ('page',))
+                
+            return HttpResponseRedirect(reverse("admin_tools", kwargs={'name': 'nodeman'}) + "?" + params)
 
 
     nodes = Node.objects.all()
 
 
 
     nodes = Node.objects.all()
 
-    if (request.GET):
-        filter_form = NodeManFilterForm(request.GET)
-    else:
-        filter_form = NodeManFilterForm({'node_type': 'all', 'state_type': 'any'})
+    text = request.GET.get('text', '')
+    text_in = request.GET.get('text_in', 'body')
 
     authors = request.GET.getlist('authors')
     tags = request.GET.getlist('tags')
 
 
     authors = request.GET.getlist('authors')
     tags = request.GET.getlist('tags')
 
-    if filter_form.is_valid():
-        data = filter_form.cleaned_data
+    type_filter = request.GET.getlist('node_type')
+    state_filter = request.GET.getlist('state_type')
+    state_filter_type = request.GET.get('state_filter_type', 'any')
 
 
-        if data['node_type'] != 'all':
-            nodes = nodes.filter(node_type=data['node_type'])
+    if type_filter:
+        nodes = nodes.filter(node_type__in=type_filter)
 
 
-        if (data['state_type'] != 'any'):
-            nodes = nodes.filter_state(**{str(data['state_type']): True})
+    state_types = NodeState.objects.filter(node__in=nodes).values_list('state_type', flat=True).distinct('state_type')
+    state_filter = [s for s in state_filter if s in state_types]
 
 
-        if (authors):
-            nodes = nodes.filter(author__id__in=authors)
-            authors = User.objects.filter(id__in=authors)
+    if state_filter:
+        if state_filter_type == 'all':
+            nodes = nodes.all_states(*state_filter)
+        else:
+            nodes = nodes.any_state(*state_filter)
 
 
-        if (tags):
-            nodes = nodes.filter(tags__id__in=tags)
-            tags = Tag.objects.filter(id__in=tags)
+    if (authors):
+        nodes = nodes.filter(author__id__in=authors)
+        authors = User.objects.filter(id__in=authors)
 
 
-        if data['text']:
-            filter = None
+    if (tags):
+        nodes = nodes.filter(tags__id__in=tags)
+        tags = Tag.objects.filter(id__in=tags)
 
 
-            if data['text_in'] == 'title' or data['text_in'] == 'both':
-                filter = models.Q(title__icontains=data['text'])
+    if text:
+        text_in = request.GET.get('text_in', 'body')
+        filter = None
 
 
-            if data['text_in'] == 'body' or data['text_in'] == 'both':
-                sec_filter = models.Q(body__icontains=data['text'])
-                if filter:
-                    filter = filter | sec_filter
-                else:
-                    filter = sec_filter
+        if text_in == 'title' or text_in == 'both':
+            filter = models.Q(title__icontains=text)
 
 
+        if text_in == 'body' or text_in == 'both':
+            sec_filter = models.Q(body__icontains=text)
             if filter:
             if filter:
-                nodes = nodes.filter(filter)
+                filter = filter | sec_filter
+            else:
+                filter = sec_filter
 
 
-    node_types = [('all', _("all"))] + [(k, n.friendly_name) for k, n in NodeMetaClass.types.items()]
-    state_types = NodeState.objects.filter(node__in=nodes).values_list('state_type', flat=True).distinct('state_type')
+        if filter:
+            nodes = nodes.filter(filter)
+
+    node_types = [(k, n.friendly_name) for k, n in NodeMetaClass.types.items()]
 
     return ('osqaadmin/nodeman.html', pagination.paginated(request, ("nodes", NodeManagementPaginatorContext()), {
     'nodes': nodes,
 
     return ('osqaadmin/nodeman.html', pagination.paginated(request, ("nodes", NodeManagementPaginatorContext()), {
     'nodes': nodes,
+    'text': text,
+    'text_in': text_in,
+    'type_filter': type_filter,
+    'state_filter': state_filter,
+    'state_filter_type': state_filter_type,
     'node_types': node_types,
     'state_types': state_types,
     'node_types': node_types,
     'state_types': state_types,
-    'filter_form': filter_form,
     'authors': authors,
     'tags': tags,
     'hide_menu': True
     }))
 
     'authors': authors,
     'tags': tags,
     'hide_menu': True
     }))
 
+@super_user_required
+def test_email_settings(request):
+    user = request.user
 
 
+    send_template_email([user,], 'osqaadmin/mail_test.html', { 'user' : user })
 
 
-
-
-
-
+    return render_to_response(
+        'osqaadmin/test_email_settings.html',
+        { 'user': user, },
+        RequestContext(request)
+    )
\ No newline at end of file