summaryrefslogtreecommitdiff
path: root/src/meetingtools
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2012-01-17 10:52:47 +0100
committerLeif Johansson <leifj@sunet.se>2012-01-17 10:52:47 +0100
commit4b0e1df7a77b74cbd7cb88b79de11de860abd4a2 (patch)
tree35829a3e52acaa188dcefa4101a0fc07ad576499 /src/meetingtools
parent156b905ef6c63647f9ce163a3b0f2c5b9e00ea41 (diff)
basic user and domain statistics
Diffstat (limited to 'src/meetingtools')
-rw-r--r--src/meetingtools/apps/stats/__init__.py0
-rw-r--r--src/meetingtools/apps/stats/forms.py11
-rw-r--r--src/meetingtools/apps/stats/views.py176
-rw-r--r--src/meetingtools/urls.py5
4 files changed, 191 insertions, 1 deletions
diff --git a/src/meetingtools/apps/stats/__init__.py b/src/meetingtools/apps/stats/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/meetingtools/apps/stats/__init__.py
diff --git a/src/meetingtools/apps/stats/forms.py b/src/meetingtools/apps/stats/forms.py
new file mode 100644
index 0000000..d9cf555
--- /dev/null
+++ b/src/meetingtools/apps/stats/forms.py
@@ -0,0 +1,11 @@
+'''
+Created on Jan 16, 2012
+
+@author: leifj
+'''
+from django.forms.forms import Form
+from django.forms.fields import DateTimeField
+
+class StatCaledarForm(Form):
+ begin = DateTimeField(required=False)
+ end = DateTimeField(required=False) \ No newline at end of file
diff --git a/src/meetingtools/apps/stats/views.py b/src/meetingtools/apps/stats/views.py
new file mode 100644
index 0000000..5090c1f
--- /dev/null
+++ b/src/meetingtools/apps/stats/views.py
@@ -0,0 +1,176 @@
+'''
+Created on Jan 16, 2012
+
+@author: leifj
+'''
+from django.contrib.auth.decorators import login_required
+from django.http import HttpResponseForbidden, HttpResponseBadRequest
+from meetingtools.ac import ac_api_client
+from iso8601 import iso8601
+from time import mktime
+from meetingtools.multiresponse import json_response, respond_to
+from meetingtools.apps.stats.forms import StatCaledarForm
+
+def _iso2datesimple(iso):
+ (date,rest) = iso.split("T")
+ return date
+
+def _iso2ts(iso):
+ return mktime(iso8601.parse_date(iso).timetuple())*1000
+
+def _date_ts(date):
+ (y,m,d) = date.split("-")
+ return int(mktime((int(y),int(m),int(d),12,0,0,0,0,-1)))*1000 # high noon
+
+@login_required
+def user(request):
+ (local,domain) = request.user.username.split('@')
+ return respond_to(request,{'text/html': 'apps/stats/user.html'},{'domain': domain})
+
+@login_required
+def domain(request,domain):
+ (l,d) = request.user.username.split('@')
+ if d != domain:
+ return HttpResponseForbidden("You can only look at stats for your own domain!")
+
+ return respond_to(request,{'text/html': 'apps/stats/domain.html'},{'domain': domain})
+
+@login_required
+def user_minutes_api(request,username=None):
+ if username and username != request.user.username:
+ return HttpResponseForbidden("You can't spy on others!")
+
+ if username == None:
+ username = request.user.username
+
+ api = ac_api_client(request)
+ p = {'sort1-type': 'asc','sort2-type': 'asc','sort1': 'date-created','sort2': 'date-closed','filter-type': 'meeting','filter-login':username}
+
+ form = StatCaledarForm(request.GET)
+ if not form.is_valid():
+ return HttpResponseBadRequest()
+
+ begin = form.cleaned_data['begin']
+ end = form.cleaned_data['end']
+
+ if begin != None:
+ p['filter-gte-date-created'] = begin
+ if end != None:
+ p['filter-lt-date-created'] = end
+ r = api.request('report-bulk-consolidated-transactions',p)
+
+ series = []
+ d_created = None
+ d_closed = None
+ ms = 0
+ curdate = None
+ t_ms = 0
+ rc = {}
+ for row in r.et.xpath("//row"):
+ rc[row.get('sco-id')] = True
+ date_created_str = row.findtext("date-created")
+ ts_created = _iso2ts(date_created_str)
+ date_closed_str = row.findtext("date-closed")
+ ts_closed = _iso2ts(date_closed_str)
+
+ d1 = _iso2datesimple(date_created_str)
+ if d_created == None:
+ d_created = d1
+
+ d2 = _iso2datesimple(date_closed_str)
+ if d_closed == None:
+ d_closed = d2
+
+ if curdate == None:
+ curdate = d1
+
+ if curdate != d1:
+ series.append([_date_ts(curdate),int(ms/60000)])
+ ms = 0
+ curdate = d1
+
+ if d1 == d2: #same date
+ diff = (ts_closed - ts_created)
+ ms = ms + diff
+ t_ms = t_ms + diff
+ else: # meeting spanned midnight
+ ts_date_ts = _date_ts(d2)
+ ms = ms + (ts_date_ts - ts_created)
+ series.append([_date_ts(d1),int(ms/60000)])
+ t_ms = t_ms + ms
+ curdate = d2
+ ms = (ts_closed - ts_date_ts)
+
+ if curdate != None and ms > 0:
+ series.append([_date_ts(curdate),int(ms/60000)])
+
+ return json_response({'data': sorted(series,key=lambda x: x[0]), 'rooms': len(rc.keys()), 'minutes': int(t_ms/60000)},request)
+
+@login_required
+def domain_minutes_api(request,domain):
+ api = ac_api_client(request)
+ p = {'sort': 'asc','sort1': 'date-created','filter-type': 'meeting'}
+
+ form = StatCaledarForm(request.GET)
+ if not form.is_valid():
+ return HttpResponseBadRequest()
+
+ begin = form.cleaned_data['begin']
+ end = form.cleaned_data['end']
+
+ if begin != None:
+ p['filter-gte-date-created'] = begin
+ if end != None:
+ p['filter-lt-date-created'] = end
+ r = api.request('report-bulk-consolidated-transactions',p)
+
+ series = []
+ d_created = None
+ d_closed = None
+ ms = 0
+ curdate = None
+ t_ms = 0
+ rc = {}
+ for row in r.et.xpath("//row"):
+ login = row.findtext("login")
+ if not login.endswith("@%s" % domain):
+ continue
+
+ rc[row.get('sco-id')] = True
+ date_created_str = row.findtext("date-created")
+ ts_created = _iso2ts(date_created_str)
+ date_closed_str = row.findtext("date-closed")
+ ts_closed = _iso2ts(date_closed_str)
+
+ d1 = _iso2datesimple(date_created_str)
+ if d_created == None:
+ d_created = d1
+
+ d2 = _iso2datesimple(date_closed_str)
+ if d_closed == None:
+ d_closed = d2
+
+ if curdate == None:
+ curdate = d1
+
+ if curdate != d1:
+ series.append([_date_ts(curdate),int(ms/60000)])
+ ms = 0
+ curdate = d1
+
+ if d1 == d2: #same date
+ diff = (ts_closed - ts_created)
+ ms = ms + diff
+ t_ms = t_ms + diff
+ else: # meeting spanned midnight
+ ts_date_ts = _date_ts(d2)
+ ms = ms + (ts_date_ts - ts_created)
+ series.append([_date_ts(d1),int(ms/60000)])
+ t_ms = t_ms + ms
+ curdate = d2
+ ms = (ts_closed - ts_date_ts)
+
+ if curdate != None and ms > 0:
+ series.append([_date_ts(curdate),int(ms/60000)])
+
+ return json_response({'data': sorted(series,key=lambda x: x[0]), 'rooms': len(rc.keys()), 'minutes': int(t_ms/60000)},request) \ No newline at end of file
diff --git a/src/meetingtools/urls.py b/src/meetingtools/urls.py
index 4dd8bcb..13382d8 100644
--- a/src/meetingtools/urls.py
+++ b/src/meetingtools/urls.py
@@ -41,7 +41,10 @@ urlpatterns = patterns('',
(r'^widget/?\+?(.*)$','meetingtools.apps.room.views.widget'),
# Uncomment the admin/doc line below to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
-
+ (r'^api/stats/user/(.*)$','meetingtools.apps.stats.views.user_minutes_api'),
+ (r'^api/stats/domain/(.*)$','meetingtools.apps.stats.views.domain_minutes_api'),
+ (r'^stats$','meetingtools.apps.stats.views.user'),
+ (r'^stats/(.+)$','meetingtools.apps.stats.views.domain'),
# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls))
)