summaryrefslogtreecommitdiff
path: root/src/meetingtools
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2012-02-09 00:16:16 +0100
committerLeif Johansson <leifj@sunet.se>2012-02-09 00:16:16 +0100
commitad21e8e4e5ac8f9eb38830f3024e19fd9329e288 (patch)
tree4aa7d7c3a6cd66cae59708e5bba274ce1cdb1eba /src/meetingtools
parent635d92fc5ded0faec71849554224608f0424fae2 (diff)
* refactor api
* now depends on with statement * object-pool using queues
Diffstat (limited to 'src/meetingtools')
-rw-r--r--src/meetingtools/ac/__init__.py86
-rw-r--r--src/meetingtools/ac/api.py17
-rw-r--r--src/meetingtools/apps/room/tasks.py54
-rw-r--r--src/meetingtools/apps/room/views.py211
-rw-r--r--src/meetingtools/apps/stats/views.py380
5 files changed, 383 insertions, 365 deletions
diff --git a/src/meetingtools/ac/__init__.py b/src/meetingtools/ac/__init__.py
index 2727d67..6523475 100644
--- a/src/meetingtools/ac/__init__.py
+++ b/src/meetingtools/ac/__init__.py
@@ -1,53 +1,57 @@
from meetingtools.ac.api import ACPClient
import time
from meetingtools.apps.cluster.models import acc_for_user
+from django.core.cache import cache
+from Queue import Queue
+import logging
+from django.contrib.auth.models import User
-def ac_api_client_cache(request,acc=None):
- if acc == None:
- acc = acc_for_user(request.user)
- tag = 'ac_api_client_%s' % acc.name
- if not request.session.has_key(tag):
- request.session[tag] = ACPClientWrapper(acc)
-
- return request.session[tag]
-
-def ac_api_client_nocache(request,acc=None):
- if acc == None:
- acc = acc_for_user(request.user)
- return ACPClientWrapper(acc)
-
-def ac_api_client_direct(acc):
- return ACPClientWrapper(acc)
-
-ac_api_client = ac_api_client_cache
-
-def ac_api(request,acc=None):
- return ACPClient(acc.api_url,acc.user,acc.password)
+_pools = {}
MAXCALLS = 10
MAXIDLE = 10
-class ACPClientWrapper(object):
+class ClientPool(object):
- def __init__(self,acc):
- self.acc = acc
- self._delegate = None
- self.ncalls = 0
- self.lastcall = time.time()
-
- def invalidate(self):
- self._delegate = None
-
- def client_factory(self):
+ def __init__(self,acc,maxsize=0,increment=5):
+ self._q = Queue(maxsize)
+ self._acc = acc
+ self._increment = increment
+
+ def allocate(self):
now = time.time()
- if self.ncalls > MAXCALLS or now - self.lastcall > MAXIDLE or not self._delegate:
- self._delegate = ACPClient(self.acc.api_url,self.acc.user,self.acc.password)
- self.ncalls = 0
- self.ncalls += 1
- self.lastcall = now
- return self._delegate
+ api = None
+ while not api:
+ if self._q.empty():
+ for i in range(1,self._increment):
+ logging.debug("adding instance %d" % i)
+ api = ACPClient(self._acc.api_url,self._acc.user,self._acc.password,cpool=self)
+ self._q.put_nowait(api)
+
+ api = self._q.get()
+ if api and (api.age > MAXCALLS or now - api.lastused > MAXIDLE):
+ api = None
+ return api
+
+# with ac_api_client(acc) as api
+# ...
+
+def ac_api_client(o):
+ acc = o
+ logging.debug("ac_api_client(%s)" % repr(o))
+ if hasattr(o,'user') and isinstance(getattr(o,'user'),User):
+ acc = acc_for_user(getattr(o,'user'))
+ elif hasattr(o,'acc'):
+ acc = getattr(o,'acc')
+
+ tag = 'ac_api_client_%d' % acc.id
+ pool = _pools.get(tag)
+ if pool is None:
+ pool = ClientPool(acc,maxsize=30)
+ _pools[tag] = pool
- def __getattr__(self,name):
- client = self.client_factory()
- return getattr(client,name)
+ return pool.allocate()
+
+
+
\ No newline at end of file
diff --git a/src/meetingtools/ac/api.py b/src/meetingtools/ac/api.py
index c17d500..4d5559f 100644
--- a/src/meetingtools/ac/api.py
+++ b/src/meetingtools/ac/api.py
@@ -10,6 +10,7 @@ import logging
from pprint import pformat
import os
import tempfile
+import time
from lxml import etree
from meetingtools.site_logging import logger
import lxml
@@ -67,15 +68,29 @@ def _getset(d,key,value=None):
class ACPClient():
- def __init__(self,url,username=None,password=None,cache=True):
+ def __init__(self,url,username=None,password=None,cache=True,cpool=None):
+ self._cpool = cpool
+ self.age = 0
+ self.createtime = time.time()
+ self.lastused = self.createtime
self.url = url
self.session = None
if username and password:
self.login(username,password)
if cache:
self._cache = {'login':{},'group':{}}
+
+ def __exit__(self,type,value,traceback):
+ if self._cpool:
+ self._cpool._q.put_nowait(self)
+
+ def __enter__(self):
+ return self
+
def request(self,method,p={},raise_error=False):
+ self.age += 1
+ self.lastused = time.time()
u = []
u.append("action=%s" % method)
if self.session:
diff --git a/src/meetingtools/apps/room/tasks.py b/src/meetingtools/apps/room/tasks.py
index 7bfc92a..aea6b3b 100644
--- a/src/meetingtools/apps/room/tasks.py
+++ b/src/meetingtools/apps/room/tasks.py
@@ -6,8 +6,7 @@ Created on Jan 18, 2012
from celery.task import periodic_task,task
from celery.schedules import crontab
from meetingtools.apps.cluster.models import ACCluster
-from meetingtools.ac import ac_api_client, ac_api_client_nocache,\
- ac_api_client_direct
+from meetingtools.ac import ac_api_client
from meetingtools.apps.room.models import Room
import iso8601
from django.contrib.auth.models import User
@@ -17,7 +16,6 @@ import logging
from datetime import datetime,timedelta
from lxml import etree
from django.db.models import Q
-import math
def _owner_username(api,sco):
logging.debug(sco)
@@ -87,11 +85,12 @@ def _import_one_room(acc,api,row):
lastupdated = None
if room:
lastupdated = room.lastupdated.replace(tzinfo=None) # make the compare work - very ugly
- logging.debug("last %s" % last)
- logging.debug("lastupdated %s" % lastupdated)
+
+ #logging.debug("last %s" % last)
+ #logging.debug("lastupdated %s" % lastupdated)
if not room or lastupdated < last:
(r,username) = _extended_info(api, sco_id)
- logging.debug("owner: %s" % username)
+ logging.debug("found room owned by %s time for and update" % username)
if username is None:
return
@@ -119,15 +118,14 @@ def _import_one_room(acc,api,row):
room.unlock()
def _import_acc(acc):
- api = ac_api_client_direct(acc)
- backthen = datetime.now()-timedelta(seconds=6000000)
- backthen = backthen.replace(microsecond=0)
- logging.debug(backthen.isoformat())
- r = api.request('report-bulk-objects',{'filter-type': 'meeting','filter-gt-date-modified': backthen.isoformat()})
- for row in r.et.xpath("//row"):
- _import_one_room(acc,api,row)
+ with ac_api_client(acc) as api:
+ then = datetime.now()-timedelta(seconds=3600)
+ then = then.replace(microsecond=0)
+ r = api.request('report-bulk-objects',{'filter-type': 'meeting','filter-gt-date-modified': then.isoformat()})
+ for row in r.et.xpath("//row"):
+ _import_one_room(acc,api,row)
-@periodic_task(run_every=crontab(hour="*", minute="*/1", day_of_week="*"))
+@periodic_task(run_every=crontab(hour="*", minute="*/5", day_of_week="*"))
def import_all_rooms():
for acc in ACCluster.objects.all():
_import_acc(acc)
@@ -137,22 +135,22 @@ def start_user_counts_poll(room,niter):
@task(name='meetingtools.apps.room.tasks.poll_user_counts',rate_limit="10/s")
def poll_user_counts(room,niter=0):
- logging.debug("rechecking user_counts for room %s" % room.name)
- api = ac_api_client_direct(room.acc)
- (nusers,nhosts) = api.poll_user_counts(room)
- if nusers > 0:
- logging.debug("room occupied by %d users and %d hosts, checking again in 20 ..." % (nusers,nhosts))
- poll_user_counts.apply_async(args=[room],kwargs={'niter': 0},countdown=20)
- elif niter > 0:
- logging.debug("room empty, will check again in 5 for %d more times ..." % (niter -1))
- poll_user_counts.apply_async(args=[room],kwargs={'niter': niter-1},countdown=5)
- return (nusers,nhosts)
+ logging.debug("polling user_counts for room %s" % room.name)
+ with ac_api_client(room.acc) as api:
+ (nusers,nhosts) = api.poll_user_counts(room)
+ if nusers > 0:
+ logging.debug("room occupied by %d users and %d hosts, checking again in 20 ..." % (nusers,nhosts))
+ poll_user_counts.apply_async(args=[room],kwargs={'niter': 0},countdown=20)
+ elif niter > 0:
+ logging.debug("room empty, will check again in 5 for %d more times ..." % (niter -1))
+ poll_user_counts.apply_async(args=[room],kwargs={'niter': niter-1},countdown=5)
+ return (nusers,nhosts)
# belts and suspenders - we setup polling for active rooms aswell...
@periodic_task(run_every=crontab(hour="*", minute="*/5", day_of_week="*"))
def import_recent_user_counts():
for acc in ACCluster.objects.all():
- api = ac_api_client_direct(acc)
- then = datetime.now()-timedelta(seconds=600)
- for room in Room.objects.filter((Q(lastupdated__gt=then) | Q(lastvisited__gt=then)) & Q(acc=acc)):
- api.poll_user_counts(room) \ No newline at end of file
+ with ac_api_client(acc) as api:
+ then = datetime.now()-timedelta(seconds=600)
+ for room in Room.objects.filter((Q(lastupdated__gt=then) | Q(lastvisited__gt=then)) & Q(acc=acc)):
+ api.poll_user_counts(room) \ No newline at end of file
diff --git a/src/meetingtools/apps/room/views.py b/src/meetingtools/apps/room/views.py
index 49d8481..ba949fe 100644
--- a/src/meetingtools/apps/room/views.py
+++ b/src/meetingtools/apps/room/views.py
@@ -9,7 +9,7 @@ from meetingtools.multiresponse import respond_to, redirect_to, json_response,\
from meetingtools.apps.room.forms import DeleteRoomForm,\
CreateRoomForm, ModifyRoomForm, TagRoomForm
from django.shortcuts import get_object_or_404
-from meetingtools.ac import ac_api_client, api
+from meetingtools.ac import ac_api_client
import re
from meetingtools.apps import room
from django.contrib.auth.decorators import login_required
@@ -36,54 +36,55 @@ from meetingtools.apps.room.tasks import start_user_counts_poll
def _user_meeting_folder(request,acc):
if not session(request,'my_meetings_sco_id'):
- connect_api = ac_api_client(request, acc)
- userid = request.user.username
- folders = connect_api.request('sco-search-by-field',{'filter-type': 'folder','field':'name','query':userid}).et.xpath('//sco[folder-name="User Meetings"]')
- logging.debug("user meetings folder: "+pformat(folders))
- #folder = next((f for f in folders if f.findtext('.//folder-name') == 'User Meetings'), None)
- if folders and len(folders) > 0:
- session(request,'my_meetings_sco_id',folders[0].get('sco-id'))
+ with ac_api_client(acc) as api:
+ userid = request.user.username
+ folders = api.request('sco-search-by-field',{'filter-type': 'folder','field':'name','query':userid}).et.xpath('//sco[folder-name="User Meetings"]')
+ logging.debug("user meetings folder: "+pformat(folders))
+ #folder = next((f for f in folders if f.findtext('.//folder-name') == 'User Meetings'), None)
+ if folders and len(folders) > 0:
+ session(request,'my_meetings_sco_id',folders[0].get('sco-id'))
+
return session(request,'my_meetings_sco_id')
def _shared_templates_folder(request,acc):
if not session(request,'shared_templates_sco_id'):
- connect_api = ac_api_client(request, acc)
- shared = connect_api.request('sco-shortcuts').et.xpath('.//sco[@type="shared-meeting-templates"]')
- logging.debug("shared templates folder: "+pformat(shared))
- #folder = next((f for f in folders if f.findtext('.//folder-name') == 'User Meetings'), None)
- if shared and len(shared) > 0:
- session(request,'shared_templates_sco_id',shared[0].get('sco-id'))
+ with ac_api_client(acc) as api:
+ shared = api.request('sco-shortcuts').et.xpath('.//sco[@type="shared-meeting-templates"]')
+ logging.debug("shared templates folder: "+pformat(shared))
+ #folder = next((f for f in folders if f.findtext('.//folder-name') == 'User Meetings'), None)
+ if shared and len(shared) > 0:
+ session(request,'shared_templates_sco_id',shared[0].get('sco-id'))
return session(request,'shared_templates_sco_id')
def _user_rooms(request,acc,my_meetings_sco_id):
rooms = []
if my_meetings_sco_id:
- connect_api = ac_api_client(request, acc)
- meetings = connect_api.request('sco-expanded-contents',{'sco-id': my_meetings_sco_id,'filter-type': 'meeting'})
- if meetings:
- rooms = [{'sco_id': r.get('sco-id'),
- 'name': r.findtext('name'),
- 'source_sco_id': r.get('source-sco-id'),
- 'urlpath': r.findtext('url-path'),
- 'description': r.findtext('description')} for r in meetings.et.findall('.//sco')]
+ with ac_api_client(acc) as api:
+ meetings = api.request('sco-expanded-contents',{'sco-id': my_meetings_sco_id,'filter-type': 'meeting'})
+ if meetings:
+ rooms = [{'sco_id': r.get('sco-id'),
+ 'name': r.findtext('name'),
+ 'source_sco_id': r.get('source-sco-id'),
+ 'urlpath': r.findtext('url-path'),
+ 'description': r.findtext('description')} for r in meetings.et.findall('.//sco')]
return rooms
def _user_templates(request,acc,my_meetings_sco_id):
templates = []
- connect_api = ac_api_client(request, acc)
- if my_meetings_sco_id:
- my_templates = connect_api.request('sco-contents',{'sco-id': my_meetings_sco_id,'filter-type': 'folder'}).et.xpath('.//sco[folder-name="My Templates"][0]')
- if my_templates and len(my_templates) > 0:
- my_templates_sco_id = my_templates[0].get('sco_id')
- meetings = connect_api.request('sco-contents',{'sco-id': my_templates_sco_id,'filter-type': 'meeting'})
- if meetings:
- templates = templates + [(r.get('sco-id'),r.findtext('name')) for r in meetings.et.findall('.//sco')]
-
- shared_templates_sco_id = _shared_templates_folder(request, acc)
- if shared_templates_sco_id:
- shared_templates = connect_api.request('sco-contents',{'sco-id': shared_templates_sco_id,'filter-type': 'meeting'})
- if shared_templates:
- templates = templates + [(r.get('sco-id'),r.findtext('name')) for r in shared_templates.et.findall('.//sco')]
+ with ac_api_client(acc) as api:
+ if my_meetings_sco_id:
+ my_templates = api.request('sco-contents',{'sco-id': my_meetings_sco_id,'filter-type': 'folder'}).et.xpath('.//sco[folder-name="My Templates"][0]')
+ if my_templates and len(my_templates) > 0:
+ my_templates_sco_id = my_templates[0].get('sco_id')
+ meetings = api.request('sco-contents',{'sco-id': my_templates_sco_id,'filter-type': 'meeting'})
+ if meetings:
+ templates = templates + [(r.get('sco-id'),r.findtext('name')) for r in meetings.et.findall('.//sco')]
+
+ shared_templates_sco_id = _shared_templates_folder(request, acc)
+ if shared_templates_sco_id:
+ shared_templates = api.request('sco-contents',{'sco-id': shared_templates_sco_id,'filter-type': 'meeting'})
+ if shared_templates:
+ templates = templates + [(r.get('sco-id'),r.findtext('name')) for r in shared_templates.et.findall('.//sco')]
return templates
@@ -121,7 +122,6 @@ def _init_update_form(request,form,acc,my_meetings_sco_id):
form.fields['source_sco_id'].widget.choices = [('','-- select template --')]+[r for r in _user_templates(request,acc,my_meetings_sco_id)]
def _update_room(request, room, form=None):
- api = ac_api_client(request, room.acc)
params = {'type':'meeting'}
for attr,param in (('sco_id','sco-id'),('folder_sco_id','folder-id'),('source_sco_id','source-sco-id'),('urlpath','url-path'),('name','name'),('description','description')):
@@ -141,48 +141,48 @@ def _update_room(request, room, form=None):
params[param] = repr(v)
logging.debug(pformat(params))
- r = api.request('sco-update', params, True)
-
- sco_id = r.et.find(".//sco").get('sco-id')
- if form:
- form.cleaned_data['sco_id'] = sco_id
- form.cleaned_data['source_sco_id'] = r.et.find(".//sco").get('sco-source-id')
-
- room.sco_id = sco_id
- room.save()
-
- user_principal = api.find_user(room.creator.username)
- #api.request('permissions-reset',{'acl-id': sco_id},True)
- api.request('permissions-update',{'acl-id': sco_id,'principal-id': user_principal.get('principal-id'),'permission-id':'host'},True) # owner is always host
-
- if form:
- if form.cleaned_data.has_key('access'):
- access = form.cleaned_data['access']
- if access == 'public':
- allow(room,'anyone','view-hidden')
- elif access == 'private':
- allow(room,'anyone','remove')
-
- # XXX figure out how to keep the room permissions in sync with the AC permissions
- for ace in acl(room):
- principal_id = None
- if ace.group:
- principal = api.find_group(ace.group.name)
- if principal:
- principal_id = principal.get('principal-id')
- elif ace.user:
- principal = api.find_user(ace.user.username)
- if principal:
- principal_id = principal.get('principal-id')
- else:
- principal_id = "public-access"
+ with ac_api_client(room.acc) as api:
+ r = api.request('sco-update', params, True)
+ sco_id = r.et.find(".//sco").get('sco-id')
+ if form:
+ form.cleaned_data['sco_id'] = sco_id
+ form.cleaned_data['source_sco_id'] = r.et.find(".//sco").get('sco-source-id')
- if principal_id:
- api.request('permissions-update',{'acl-id': room.sco_id, 'principal-id': principal_id, 'permission-id': ace.permission},True)
-
- room.deleted_sco_id = None # if we just cleaned a room we zero out the deleted_sco_id field to indicate the room is now ready for use
- room.save() # a second save here to avoid races
- return room
+ room.sco_id = sco_id
+ room.save()
+
+ user_principal = api.find_user(room.creator.username)
+ #api.request('permissions-reset',{'acl-id': sco_id},True)
+ api.request('permissions-update',{'acl-id': sco_id,'principal-id': user_principal.get('principal-id'),'permission-id':'host'},True) # owner is always host
+
+ if form:
+ if form.cleaned_data.has_key('access'):
+ access = form.cleaned_data['access']
+ if access == 'public':
+ allow(room,'anyone','view-hidden')
+ elif access == 'private':
+ allow(room,'anyone','remove')
+
+ # XXX figure out how to keep the room permissions in sync with the AC permissions
+ for ace in acl(room):
+ principal_id = None
+ if ace.group:
+ principal = api.find_group(ace.group.name)
+ if principal:
+ principal_id = principal.get('principal-id')
+ elif ace.user:
+ principal = api.find_user(ace.user.username)
+ if principal:
+ principal_id = principal.get('principal-id')
+ else:
+ principal_id = "public-access"
+
+ if principal_id:
+ api.request('permissions-update',{'acl-id': room.sco_id, 'principal-id': principal_id, 'permission-id': ace.permission},True)
+
+ room.deleted_sco_id = None # if we just cleaned a room we zero out the deleted_sco_id field to indicate the room is now ready for use
+ room.save() # a second save here to avoid races
+ return room
@never_cache
@login_required
@@ -272,12 +272,12 @@ def _import_room(request,acc,r):
return None
logging.debug("+++ looking at user counts")
- api = ac_api_client(request,acc)
- userlist = api.request('meeting-usermanager-user-list',{'sco-id': room.sco_id},False)
- if userlist.status_code() == 'ok':
- room.user_count = int(userlist.et.xpath("count(.//userdetails)"))
- room.host_count = int(userlist.et.xpath("count(.//userdetails/role[text() = 'host'])"))
- room.save()
+ with ac_api_client(acc) as api:
+ userlist = api.request('meeting-usermanager-user-list',{'sco-id': room.sco_id},False)
+ if userlist.status_code() == 'ok':
+ room.user_count = int(userlist.et.xpath("count(.//userdetails)"))
+ room.host_count = int(userlist.et.xpath("count(.//userdetails/role[text() = 'host'])"))
+ room.save()
return room
@@ -339,8 +339,8 @@ def delete(request,id):
if request.method == 'POST':
form = DeleteRoomForm(request.POST)
if form.is_valid():
- api = ac_api_client(request,room.acc)
- api.request('sco-delete',{'sco-id':room.sco_id},raise_error=True)
+ with ac_api_client(room.acc) as api:
+ api.request('sco-delete',{'sco-id':room.sco_id},raise_error=True)
clear_acl(room)
room.delete()
@@ -351,11 +351,11 @@ def delete(request,id):
return respond_to(request,{'text/html':'edit.html'},{'form':form,'formtitle': 'Delete %s' % room.name,'cancelname':'Cancel','submitname':'Delete Room'})
def _clean(request,room):
- api = ac_api_client(request, room.acc)
- room.deleted_sco_id = room.sco_id
- room.save()
- api.request('sco-delete',{'sco-id':room.sco_id},raise_error=False)
- room.sco_id = None
+ with ac_api_client(room.acc) as api:
+ room.deleted_sco_id = room.sco_id
+ room.save()
+ api.request('sco-delete',{'sco-id':room.sco_id},raise_error=False)
+ room.sco_id = None
return _update_room(request, room)
def go_by_id(request,id):
@@ -387,12 +387,12 @@ def _goto(request,room,clean=True,promote=False):
if room.is_locked():
return respond_to(request, {"text/html": "apps/room/retry.html"}, {'room': room, 'wait': 10})
- api = ac_api_client(request, room.acc)
now = time.time()
lastvisit = room.lastvisit()
room.lastvisited = datetime.now()
- api.poll_user_counts(room)
+ with ac_api_client(room.acc) as api:
+ api.poll_user_counts(room)
if clean:
# don't clean the room unless you get a good status code from the call to the usermanager api above
if room.self_cleaning and room.user_count == 0:
@@ -415,10 +415,11 @@ def _goto(request,room,clean=True,promote=False):
key = _random_key(20)
user_principal = api.find_user(request.user.username)
principal_id = user_principal.get('principal-id')
- api.request("user-update-pwd",{"user-id": principal_id, 'password': key,'password-verify': key},True)
- if promote and room.self_cleaning:
- if user_principal:
- api.request('permissions-update',{'acl-id': room.sco_id,'principal-id': user_principal.get('principal-id'),'permission-id':'host'},True)
+ with ac_api_client(room.acc) as api:
+ api.request("user-update-pwd",{"user-id": principal_id, 'password': key,'password-verify': key},True)
+ if promote and room.self_cleaning:
+ if user_principal:
+ api.request('permissions-update',{'acl-id': room.sco_id,'principal-id': user_principal.get('principal-id'),'permission-id':'host'},True)
r = api.request('sco-info',{'sco-id':room.sco_id},True)
urlpath = r.et.findtext('.//sco/url-path')
@@ -521,14 +522,14 @@ def tag(request,rid):
{'form': form,'formtitle': 'Add Tag','cancelname':'Done','submitname': 'Add Tag','room': room, 'tagstring': tn,'tags': tags})
def room_recordings(request,room):
- api = ac_api_client(request, room.acc)
- r = api.request('sco-expanded-contents',{'sco-id': room.sco_id,'filter-icon':'archive'},True)
- return [{'name': sco.findtext('name'),
- 'sco_id': sco.get('sco-id'),
- 'url': room.acc.make_url(sco.findtext('url-path')),
- 'description': sco.findtext('description'),
- 'date_created': iso8601.parse_date(sco.findtext('date-created')),
- 'date_modified': iso8601.parse_date(sco.findtext('date-modified'))} for sco in r.et.findall(".//sco")]
+ with ac_api_client(room.acc) as api:
+ r = api.request('sco-expanded-contents',{'sco-id': room.sco_id,'filter-icon':'archive'},True)
+ return [{'name': sco.findtext('name'),
+ 'sco_id': sco.get('sco-id'),
+ 'url': room.acc.make_url(sco.findtext('url-path')),
+ 'description': sco.findtext('description'),
+ 'date_created': iso8601.parse_date(sco.findtext('date-created')),
+ 'date_modified': iso8601.parse_date(sco.findtext('date-modified'))} for sco in r.et.findall(".//sco")]
@login_required
def recordings(request,rid):
diff --git a/src/meetingtools/apps/stats/views.py b/src/meetingtools/apps/stats/views.py
index 1342c2e..b028d18 100644
--- a/src/meetingtools/apps/stats/views.py
+++ b/src/meetingtools/apps/stats/views.py
@@ -59,148 +59,148 @@ def user_minutes_api(request,username=None):
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)
+ with ac_api_client(request) as api:
+ p = {'sort1-type': 'asc','sort2-type': 'asc','sort1': 'date-created','sort2': 'date-closed','filter-type': 'meeting','filter-login':username}
- d1 = _iso2datesimple(date_created_str)
- if d_created == None:
- d_created = d1
-
- d2 = _iso2datesimple(date_closed_str)
- if d_closed == None:
- d_closed = d2
-
- #duration = _iso2dt(date_closed_str) - _iso2dt(date_created_str)
- #sdiff = duration.total_seconds()
-
- if curdate == None:
- curdate = d1
+ 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)
- if curdate != d1:
- #logging.debug(" %s: %s - %s = %d %d" % (row.findtext("name"),date_created_str,date_closed_str,ms,sdiff*1000))
+ d1 = _iso2datesimple(date_created_str)
+ if d_created == None:
+ d_created = d1
+
+ d2 = _iso2datesimple(date_closed_str)
+ if d_closed == None:
+ d_closed = d2
+
+ #duration = _iso2dt(date_closed_str) - _iso2dt(date_created_str)
+ #sdiff = duration.total_seconds()
+
+ if curdate == None:
+ curdate = d1
+
+ if curdate != d1:
+ #logging.debug(" %s: %s - %s = %d %d" % (row.findtext("name"),date_created_str,date_closed_str,ms,sdiff*1000))
+ series.append([_date_ts(curdate),int(ms/60000)])
+ ms = 0
+ curdate = d1
+
+ if d1 == d2: #same date
+ diff = (ts_closed - ts_created)
+ #logging.debug("ms:: %d + %d" % (ms,diff))
+ ms = ms + diff
+ t_ms = t_ms + diff
+ else: # meeting spanned midnight
+ ts_date_ts = _date_ts(d2)
+ #logging.debug("ms: %d + %d" % (ms,(ts_date_ts - ts_created)))
+ ms = ms + (ts_date_ts - ts_created)
+ series.append([_date_ts(d1),int(ms/60000)])
+ #logging.debug("* %s: %s - %s = %d %d" % (row.findtext("name"),date_created_str,date_closed_str,ms,sdiff*1000))
+ t_ms = t_ms + ms
+ curdate = d2
+ #logging.debug("midnight: %d (%d)" % (ts_date_ts,ts_closed))
+ ms = (ts_closed - ts_date_ts)
+ #logging.debug("nms: %d" % ms)
+
+ if curdate != None and ms > 0:
series.append([_date_ts(curdate),int(ms/60000)])
- ms = 0
- curdate = d1
-
- if d1 == d2: #same date
- diff = (ts_closed - ts_created)
- #logging.debug("ms:: %d + %d" % (ms,diff))
- ms = ms + diff
- t_ms = t_ms + diff
- else: # meeting spanned midnight
- ts_date_ts = _date_ts(d2)
- #logging.debug("ms: %d + %d" % (ms,(ts_date_ts - ts_created)))
- ms = ms + (ts_date_ts - ts_created)
- series.append([_date_ts(d1),int(ms/60000)])
- #logging.debug("* %s: %s - %s = %d %d" % (row.findtext("name"),date_created_str,date_closed_str,ms,sdiff*1000))
- t_ms = t_ms + ms
- curdate = d2
- #logging.debug("midnight: %d (%d)" % (ts_date_ts,ts_closed))
- ms = (ts_closed - ts_date_ts)
- #logging.debug("nms: %d" % ms)
-
- 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)
+
+ 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 = {}
- uc = {}
- for row in r.et.xpath("//row"):
- login = row.findtext("login")
- if not login.endswith("@%s" % domain):
- continue
+ with ac_api_client(request) as api:
+ p = {'sort': 'asc','sort1': 'date-created','filter-type': 'meeting'}
- rc[row.get('sco-id')] = True
- uc[row.get('principal-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)
+ form = StatCaledarForm(request.GET)
+ if not form.is_valid():
+ return HttpResponseBadRequest()
- d1 = _iso2datesimple(date_created_str)
- if d_created == None:
- d_created = d1
-
- d2 = _iso2datesimple(date_closed_str)
- if d_closed == None:
- d_closed = d2
+ 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 = {}
+ uc = {}
+ for row in r.et.xpath("//row"):
+ login = row.findtext("login")
+ if not login.endswith("@%s" % domain):
+ continue
- if curdate == None:
- curdate = d1
+ rc[row.get('sco-id')] = True
+ uc[row.get('principal-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)
- if curdate != d1:
+ 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)])
- 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()), 'users': len(uc.keys()), 'minutes': int(t_ms/60000)},request)
+
+ return json_response({'data': sorted(series,key=lambda x: x[0]), 'rooms': len(rc.keys()), 'users': len(uc.keys()), 'minutes': int(t_ms/60000)},request)
@login_required
@@ -209,65 +209,65 @@ def room_minutes_api(request,rid):
if not room.creator == request.user:
return HttpResponseForbidden("You can only look at statistics for your own rooms!")
- api = ac_api_client(request)
- p = {'sort': 'asc','sort1': 'date-created','filter-type': 'meeting','filter-sco-id': room.sco_id}
-
- 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
- uc = {}
- for row in r.et.xpath("//row"):
- uc[row.get('principal-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)
+ with ac_api_client(request) as api:
+ p = {'sort': 'asc','sort1': 'date-created','filter-type': 'meeting','filter-sco-id': room.sco_id}
- 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
+ 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
+ uc = {}
+ for row in r.et.xpath("//row"):
+ uc[row.get('principal-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)
- if curdate != d1:
+ 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)])
- 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]), 'users': len(uc.keys()), 'minutes': int(t_ms/60000)},request) \ No newline at end of file
+
+ return json_response({'data': sorted(series,key=lambda x: x[0]), 'users': len(uc.keys()), 'minutes': int(t_ms/60000)},request) \ No newline at end of file