Browse Source

Superbasic data downloads admin interface

Rafał Pitoń 7 years ago
parent
commit
440c916002

+ 95 - 0
misago/templates/misago/admin/datadownloads/list.html

@@ -0,0 +1,95 @@
+{% extends "misago/admin/generic/list.html" %}
+{% load i18n misago_avatars misago_forms %}
+
+
+{% block table-header %}
+<th style="width: 1%;">&nbsp;</th>
+<th>{% trans "User" %}</th>
+<th>{% trans "Status" %}</th>
+<th>{% trans "Requested on" %}</th>
+<th style="width: 1%;">&nbsp;</th>
+<th>{% trans "Requested by" %}</th>
+{% for action in extra_actions %}
+<th style="width: 1%;">&nbsp;</th>
+{% endfor %}
+<th style="width: 1%;">&nbsp;</th>
+{% endblock table-header %}
+
+
+{% block table-row %}
+<td>
+  <a href="{{ item.user.get_absolute_url }}">
+    <img src="{{ item.user|avatar:24 }}" alt="{% trans "Avatar" %}" width="24" height="24">
+  </a>
+</td>
+<td class="item-name">
+  <a href="{{ item.user.get_absolute_url }}">
+    {{ item.user }}
+  </a>
+</td>
+<td>
+  {{ item.get_status_display }}
+</td>
+<td>
+  <abbr class="moment" data-iso="{{ item.requested_on.isoformat }}" data-format="LL"></abbr>
+</td>
+<td>
+  <a href="{{ item.requester.get_absolute_url }}">
+    <img src="{{ item.requester|avatar:24 }}" alt="{% trans "Avatar" %}" width="24" height="24">
+  </a>
+</td>
+<td class="item-name">
+  <a href="{{ item.requester.get_absolute_url }}">
+    {{ item.requester_name }}
+  </a>
+</td>
+{% for action in extra_actions %}
+<td class="row-action">
+  <a href="{% url action.link pk=item.pk %}" class="btn btn-{% if action.style %}{{ action.style }}{% else %}default{% endif %} tooltip-top" title="{{ action.name }}">
+    <span class="{{ action.icon }}"></span>
+  </a>
+</td>
+{% endfor %}
+<td class="row-action">
+  {% if item.file %}
+    <a href="{{ item.file.url }}" class="btn btn-primary tooltip-top" title="{% trans "Download data" %}">
+      <span class="fa fa-download"></span>
+    </a>
+  {% endif %}
+</td>
+{% endblock table-row %}
+
+
+{% block emptylist %}
+<td colspan="{{ 7|add:extra_actions_len }}">
+  {% if active_filters %}
+    <p>{% trans "No data downloads matching search criteria have been found." %}</p>
+  {% else %}
+    <p>{% trans "No data downloads exist at the moment." %}</p>
+  {% endif %}
+</td>
+{% endblock emptylist %}
+
+
+{% block modal-title %}
+{% trans "Search data downloads" %}
+{% endblock modal-title %}
+
+
+{% block modal-body %}
+<div class="row">
+  <div class="col-md-12">
+    {% form_row search_form.status %}
+  </div>
+</div>
+<div class="row">
+  <div class="col-md-12">
+    {% form_row search_form.user %}
+  </div>
+</div>
+<div class="row">
+  <div class="col-md-12">
+    {% form_row search_form.requested_by %}
+  </div>
+</div>
+{% endblock modal-body %}

+ 18 - 0
misago/users/admin.py

@@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
 
 from .djangoadmin import UserAdminModel
 from .views.admin.bans import BansList, DeleteBan, EditBan, NewBan
+from .views.admin.datadownloads import DataDownloadsList
 from .views.admin.ranks import (
     DefaultRank, DeleteRank, EditRank, MoveDownRank, MoveUpRank, NewRank, RanksList, RankUsers)
 from .views.admin.users import (
@@ -65,6 +66,14 @@ class MisagoAdminExtension(object):
             url(r'^delete/(?P<pk>\d+)/$', DeleteBan.as_view(), name='delete'),
         )
 
+        # Data Downloads
+        urlpatterns.namespace(r'^data-downloads/', 'data-downloads', 'users')
+        urlpatterns.patterns(
+            'users:data-downloads',
+            url(r'^$', DataDownloadsList.as_view(), name='index'),
+            url(r'^(?P<page>\d+)/$', DataDownloadsList.as_view(), name='index'),
+        )
+        
     def register_navigation_nodes(self, site):
         site.add_node(
             name=_("Users"),
@@ -100,3 +109,12 @@ class MisagoAdminExtension(object):
             namespace='misago:admin:users:bans',
             link='misago:admin:users:bans:index',
         )
+
+        site.add_node(
+            name=_("Data downloads"),
+            icon='fa fa-download',
+            parent='misago:admin:users',
+            after='misago:admin:users:bans:index',
+            namespace='misago:admin:users:data-downloads',
+            link='misago:admin:users:data-downloads:index',
+        )

+ 30 - 1
misago/users/forms/admin.py

@@ -9,7 +9,7 @@ from misago.conf import settings
 from misago.core import threadstore
 from misago.core.forms import IsoDateTimeField, YesNoSwitch
 from misago.core.validators import validate_sluggable
-from misago.users.models import Ban, Rank
+from misago.users.models import Ban, DataDownload, Rank
 from misago.users.profilefields import profilefields
 from misago.users.validators import validate_email, validate_username
 
@@ -640,3 +640,32 @@ class SearchBansForm(forms.Form):
             queryset = queryset.filter(registration_only=False)
 
         return queryset
+
+
+class SearchDataDownloadsForm(forms.Form):
+    status = forms.ChoiceField(
+        label=_("Status"),
+        required=False,
+        choices=DataDownload.STATUS_CHOICES,
+    )
+    user = forms.CharField(
+        label=_("User"),
+        required=False,
+    )
+    requested_by = forms.CharField(
+        label=_("Requested by"),
+        required=False,
+    )
+
+    def filter_queryset(self, search_criteria, queryset):
+        criteria = search_criteria
+        if criteria.get('status') is not None:
+            queryset = queryset.filter(status=criteria['status'])
+
+        if criteria.get('user'):
+            queryset = queryset.filter(user__slug__istartswith=criteria['user'])
+
+        if criteria.get('requested_by'):
+            queryset = queryset.filter(requester__slug__istartswith=criteria['requested_by'])
+
+        return queryset

+ 26 - 0
misago/users/views/admin/datadownloads.py

@@ -0,0 +1,26 @@
+from django.utils.translation import ugettext_lazy as _
+
+from misago.admin.views import generic
+from misago.users.forms.admin import SearchDataDownloadsForm
+from misago.users.models import DataDownload
+
+
+class DataDownloadAdmin(generic.AdminBaseMixin):
+    root_link = 'misago:admin:users:data-downloads:index'
+    templates_dir = 'misago/admin/datadownloads'
+    model = DataDownload
+
+
+class DataDownloadsList(DataDownloadAdmin, generic.ListView):
+    items_per_page = 30
+    ordering = [
+        ('-id', _("From newest")),
+        ('id', _("From oldest")),
+    ]
+
+    def get_queryset(self):
+        qs = super(DataDownloadsList, self).get_queryset()
+        return qs.select_related('user', 'requester')
+        
+    def get_search_form(self, request):
+        return SearchDataDownloadsForm