summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meetingtools/apps/auth/utils.py14
-rw-r--r--meetingtools/apps/content/views.py44
-rw-r--r--meetingtools/multiresponse.py64
-rw-r--r--meetingtools/urls.py5
4 files changed, 123 insertions, 4 deletions
diff --git a/meetingtools/apps/auth/utils.py b/meetingtools/apps/auth/utils.py
index 0651eba..c792b4a 100644
--- a/meetingtools/apps/auth/utils.py
+++ b/meetingtools/apps/auth/utils.py
@@ -5,6 +5,8 @@ Created on Jul 7, 2010
"""
from uuid import uuid4
+from django.conf import settings as django_settings
+
def nonce():
return uuid4().hex
@@ -19,4 +21,14 @@ def groups(request):
if request.user.is_authenticated():
groups = request.user.groups
- return groups \ No newline at end of file
+ return groups
+
+
+def report_auth(request):
+ auth_data = request.META.get('HTTP_X_REPORT_AUTH', None)
+ if auth_data and ':' in auth_data:
+ report_users = getattr(django_settings, 'REPORT_USERS')
+ requester, key = auth_data.split(':')
+ if report_users[requester]['key'] == key:
+ return report_users[requester]
+ return False \ No newline at end of file
diff --git a/meetingtools/apps/content/views.py b/meetingtools/apps/content/views.py
index bc8abb3..ceec589 100644
--- a/meetingtools/apps/content/views.py
+++ b/meetingtools/apps/content/views.py
@@ -5,12 +5,14 @@ from django.contrib.auth.decorators import login_required
from django.db.models import Sum
from django.http import HttpResponseForbidden
from django.core.cache import cache
-from meetingtools.multiresponse import respond_to
+from django.template.defaultfilters import filesizeformat
from django.shortcuts import get_object_or_404
from tagging.models import Tag
+from meetingtools.multiresponse import respond_to, dicts_to_csv_response
from meetingtools.apps.content.models import Content
from meetingtools.apps.cluster.models import ACCluster
from meetingtools.apps.content import tasks
+from meetingtools.apps.auth.utils import report_auth
@login_required
@@ -66,3 +68,43 @@ def domain(request, domain_name):
return respond_to(request, {'text/html': 'apps/content/domain.html'},
{'domain': domain_name, 'total_bytecount': total_bytecount, 'total_files': total_files,
'users': users})
+
+
+def cluster_report(request, cluster_name):
+ requester = report_auth(request)
+ if requester and cluster_name in requester['clusters']:
+ data = []
+ acc = get_object_or_404(ACCluster, name=cluster_name)
+ domains, total_bytecount = tasks.get_cluster_content(acc)
+ for item in domains:
+ value = float(item['domain_bytes'])
+ max_value = float(total_bytecount)
+ percent = (value / max_value) * 100
+ data.append({
+ 'domain': item['domain'],
+ 'number_of_files': item['number_of_files'],
+ 'storage_used': filesizeformat(item['domain_bytes']),
+ 'percent': '{:0.2g}%'.format(percent)
+ })
+ return dicts_to_csv_response(data, header=['domain', 'number_of_files', 'storage_used', 'percent'])
+ return HttpResponseForbidden()
+
+
+def domain_report(request, domain_name):
+ requester = report_auth(request)
+ if requester and (domain_name in requester['domains'] or '*' in requester['domains']):
+ data = []
+ domain_tag = get_object_or_404(Tag, name='domain:%s' % domain_name)
+ users, total_files, total_bytecount = tasks.get_domain_content(domain_tag)
+ for item in users:
+ value = float(item['bytecount'])
+ max_value = float(total_bytecount)
+ percent = (value / max_value) * 100
+ data.append({
+ 'username': item['username'],
+ 'number_of_files': item['number_of_files'],
+ 'storage_used': filesizeformat(item['bytecount']),
+ 'percent': '{:0.2g}%'.format(percent)
+ })
+ return dicts_to_csv_response(data, header=['username', 'number_of_files', 'storage_used', 'percent'])
+ return HttpResponseForbidden() \ No newline at end of file
diff --git a/meetingtools/multiresponse.py b/meetingtools/multiresponse.py
index 1510760..f4784ba 100644
--- a/meetingtools/multiresponse.py
+++ b/meetingtools/multiresponse.py
@@ -1,6 +1,9 @@
from meetingtools import context_processors
import meetingtools.mimeparse as mimeparse
import re
+import csv
+import codecs
+import cStringIO
import rfc822
from django.conf import settings
from django.shortcuts import render_to_response
@@ -15,6 +18,37 @@ default_suffix_mapping = {"\.htm(l?)$": "text/html",
"\.atom$": "application/atom+xml",
"\.torrent$": "application/x-bittorrent"}
+
+class UnicodeCSVWriter:
+ """
+ A CSV writer which will write rows to CSV file "f",
+ which is encoded in the given encoding.
+ """
+
+ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+ # Redirect output to a queue
+ self.queue = cStringIO.StringIO()
+ self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
+ self.stream = f
+ self.encoder = codecs.getincrementalencoder(encoding)()
+
+ def writerow(self, row):
+ self.writer.writerow([s.encode("utf-8") for s in row])
+ # Fetch UTF-8 output from the queue ...
+ data = self.queue.getvalue()
+ data = data.decode("utf-8")
+ # ... and reencode it into the target encoding
+ data = self.encoder.encode(data)
+ # write to the target stream
+ self.stream.write(data)
+ # empty queue
+ self.queue.truncate(0)
+
+ def writerows(self, rows):
+ for row in rows:
+ self.writerow(row)
+
+
def _accept_types(request, suffix):
for r in suffix.keys():
p = re.compile(r)
@@ -45,9 +79,37 @@ def json_response(data,request=None):
r = HttpResponse(response_data,content_type='application/json')
r['Cache-Control'] = 'no-cache, must-revalidate'
r['Pragma'] = 'no-cache'
-
return r
+
+def dicts_to_csv_response(dict_list, header=None):
+ """
+ Takes a list of dicts and returns a comma separated file with all dict keys
+ and their values.
+ """
+ # Create the HttpResponse object with the appropriate CSV header.
+ response = HttpResponse(mimetype='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=result.csv; charset=utf-8;'
+ writer = UnicodeCSVWriter(response, delimiter=',', quoting=csv.QUOTE_NONNUMERIC)
+ if not header:
+ key_set = set()
+ for item in dict_list:
+ key_set.update(item.keys())
+ key_set = sorted(key_set)
+ else:
+ key_set = header
+ writer.writerow(key_set) # Line collection with header
+ for item in dict_list:
+ line = []
+ for key in key_set:
+ try:
+ line.append('%s' % item[key])
+ except KeyError:
+ line.append('') # Node did not have that key, add a blank item.
+ writer.writerow(line)
+ return response
+
+
def render500(request):
return render_to_response("500.html",RequestContext(request,{},[context_processors.misc_urls]))
diff --git a/meetingtools/urls.py b/meetingtools/urls.py
index 925783e..d84f68f 100644
--- a/meetingtools/urls.py
+++ b/meetingtools/urls.py
@@ -63,6 +63,9 @@ urlpatterns = patterns('',
(r'^stats/room/(\d+)$','meetingtools.apps.stats.views.room'),
(r'^content$', 'meetingtools.apps.content.views.user'),
(r'^content/cluster/$', 'meetingtools.apps.content.views.cluster'),
+ (r'^content/cluster/(?P<cluster_name>[\w ]+)/report$', 'meetingtools.apps.content.views.cluster_report'),
+ (r'^content/domain/(?P<domain_name>[\w\.;]+)/report$', 'meetingtools.apps.content.views.domain_report'),
(r'^content/cluster/(?P<cluster_name>[\w ]+)$', 'meetingtools.apps.content.views.cluster'),
- (r'^content/domain/(?P<domain_name>[\w\.;]+)$', 'meetingtools.apps.content.views.domain')
+ (r'^content/domain/(?P<domain_name>[\w\.;]+)$', 'meetingtools.apps.content.views.domain'),
+
)