admin tab invitations with export capability
authorSofia Papagiannaki <papagian@gmail.com>
Tue, 22 Nov 2011 11:43:55 +0000 (13:43 +0200)
committerSofia Papagiannaki <papagian@gmail.com>
Tue, 22 Nov 2011 11:43:55 +0000 (13:43 +0200)
Refs: #1666

pithos/im/templates/base.html
pithos/im/templates/invitations_list.html [new file with mode: 0644]
pithos/im/urls.py
pithos/im/views.py

index 46e6bec..40fef24 100644 (file)
@@ -22,6 +22,9 @@
       <li{% ifequal tab "users" %} class="active"{% endifequal %}>
         <a href="{% url pithos.im.views.users_list %}">Users</a>
       </li>
+      <li{% ifequal tab "invitations" %} class="active"{% endifequal %}>
+        <a href="{% url pithos.im.views.invitations_list %}">Invitations</a>
+      </li>
     </ul>
 
     {% block body %}{% endblock %}
diff --git a/pithos/im/templates/invitations_list.html b/pithos/im/templates/invitations_list.html
new file mode 100644 (file)
index 0000000..797485f
--- /dev/null
@@ -0,0 +1,75 @@
+{% extends "base.html" %}
+
+{% load formatters %}
+
+{% block body %}
+
+<div class="row">
+  <div class="offset10 span3">
+    <form method="get">
+      <div class="input">
+        <input class="span3" name="filter" type="search" placeholder="search" value="{{ filter }}">
+      </div>
+    </form>
+  </div>
+</div>
+
+<table class="zebra-striped id-sorted">
+  <thead>
+    <tr>
+      <th>ID</th>
+      <th>Uniq</th>
+      <th>Real Name</th>
+      <th>Code</th>
+      <th>Inviter Uniq</th>
+      <th>Inviter Real Name</th>
+      <th>Is_accepted</th>
+      <th>Created</th>
+      <th>Accepted</th>
+    </tr>
+  </thead>
+  <tbody>
+    {% for inv in invitations %}
+    <tr>
+      <td>{{ inv.id }}</td>
+      <td>{{ inv.uniq }}</td>
+      <td>{{ inv.realname }}</td>
+      <td>{{ inv.code }}</td>
+      <td>{{ inv.inviter.uniq }}</td>
+      <td>{{ inv.inviter.realname }}</td>
+      <td>{{ inv.is_accepted }}</td>
+      <td>{{ inv.created }}</td>
+      <td>{{ inv.accepted }}</td>
+    </tr>
+    {% endfor %}
+  </tbody>
+</table>
+
+{% if pages|length > 1 %}
+<div class="pagination">
+  <ul>
+    {% if prev %}
+      <li class="prev"><a href="?page={{ prev }}{% if filter %}&filter={{ filter }}{% endif %}">&larr; Previous</a></li>
+    {% else %}
+      <li class="prev disabled"><a href="#">&larr; Previous</a></li>
+    {% endif %}
+
+    {% for p in pages %}
+      <li{% if page == p %} class="active"{% endif %}><a href="?page={{ p }}{% if filter %}&filter={{ filter }}{% endif %}">{{ p }}</a></li>
+    {% endfor %}
+
+    {% if next %}
+      <li class="next"><a href="?page={{ next }}{% if filter %}&filter={{ filter }}{% endif %}">&rarr; Next</a></li>
+    {% else %}
+      <li class="next disabled"><a href="#">&rarr; Next</a></li>
+    {% endif %}
+  </ul>
+</div>
+{% endif %}
+
+<form action="{% url pithos.im.views.invitations_export %}" method="post">
+<button  type="submit" class="btn primary">Export</button>
+</form>
+
+<br /><br />
+{% endblock body %}
index 62299dd..6ea46c7 100644 (file)
@@ -45,7 +45,10 @@ urlpatterns = patterns('pithos.im.views',
     (r'^admin/users/(\d+)/?$', 'users_info'),
     (r'^admin/users/create$', 'users_create'),
     (r'^admin/users/(\d+)/modify/?$', 'users_modify'),
-    (r'^admin/users/(\d+)/delete/?$', 'users_delete')
+    (r'^admin/users/(\d+)/delete/?$', 'users_delete'),
+    
+    (r'^admin/invitations/?$', 'invitations_list'),
+    (r'^admin/invitations/export/?$', 'invitations_export'),
 )
 
 urlpatterns += patterns('pithos.im.target',
index 72b82db..38f503e 100644 (file)
@@ -34,6 +34,7 @@
 import json
 import logging
 import socket
+import csv
 
 from datetime import datetime
 from functools import wraps
@@ -138,21 +139,6 @@ def users_list(request):
                             page=page,
                             prev=prev,
                             next=next)
-    
-@requires_admin
-def users_create(request):
-    if request.method == 'GET':
-        return render_response('users_create.html')
-    if request.method == 'POST':
-        user = User()
-        user.uniq = request.POST.get('uniq')
-        user.realname = request.POST.get('realname')
-        user.is_admin = True if request.POST.get('admin') else False
-        user.affiliation = request.POST.get('affiliation')
-        user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3)  # In GiB
-        user.renew_token()
-        user.save()
-        return redirect(users_info, user.id)
 
 @requires_admin
 def users_info(request, user_id):
@@ -366,3 +352,78 @@ def reclaim_password(request):
                 'status': status,
                 'message': message})
         return HttpResponse(html)
+
+@requires_admin
+def invitations_list(request):
+    invitations = Invitation.objects.order_by('id')
+    
+    filter = request.GET.get('filter', '')
+    if filter:
+        if filter.startswith('-'):
+            invitations = invitations.exclude(uniq__icontains=filter[1:])
+        else:
+            invitations = invitations.filter(uniq__icontains=filter)
+    
+    try:
+        page = int(request.GET.get('page', 1))
+    except ValueError:
+        page = 1
+    offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
+    limit = offset + settings.ADMIN_PAGE_LIMIT
+    
+    npages = int(ceil(1.0 * invitations.count() / settings.ADMIN_PAGE_LIMIT))
+    prev = page - 1 if page > 1 else None
+    next = page + 1 if page < npages else None
+    return render_response('invitations_list.html',
+                            invitations=invitations[offset:limit],
+                            filter=filter,
+                            pages=range(1, npages + 1),
+                            page=page,
+                            prev=prev,
+                            next=next)
+
+@requires_admin
+def invitations_export(request):
+    # Create the HttpResponse object with the appropriate CSV header.
+    response = HttpResponse(mimetype='text/csv')
+    response['Content-Disposition'] = 'attachment; filename=invitations.csv'
+
+    writer = csv.writer(response)
+    writer.writerow(['ID',
+      'Uniq',
+      'Real Name',
+      'Code',
+      'Inviter Uniq',
+      'Inviter Real Name',
+      'Is_accepted',
+      'Created',
+      'Accepted',])
+    invitations = Invitation.objects.order_by('id')
+    for inv in invitations:
+        writer.writerow([inv.id,
+      inv.uniq,
+      inv.realname.encode("utf-8"),
+      inv.code,
+      inv.inviter.uniq,
+      inv.inviter.realname.encode("utf-8"),
+      inv.is_accepted,
+      inv.created,
+      inv.accepted,
+      ])
+
+    return response
+
+@requires_admin
+def users_create(request):
+    if request.method == 'GET':
+        return render_response('users_create.html')
+    if request.method == 'POST':
+        user = User()
+        user.uniq = request.POST.get('uniq')
+        user.realname = request.POST.get('realname')
+        user.is_admin = True if request.POST.get('admin') else False
+        user.affiliation = request.POST.get('affiliation')
+        user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3)  # In GiB
+        user.renew_token()
+        user.save()
+        return redirect(users_info, user.id)