summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/meetingtools/ac/api.py3
-rw-r--r--src/meetingtools/apps/cluster/migrations/0001_initial.py45
-rw-r--r--src/meetingtools/apps/cluster/migrations/__init__.py0
-rw-r--r--src/meetingtools/apps/room/migrations/0001_initial.py120
-rw-r--r--src/meetingtools/apps/room/migrations/0002_auto__add_field_room_deleted_sco_id.py91
-rw-r--r--src/meetingtools/apps/room/migrations/__init__.py0
-rw-r--r--src/meetingtools/apps/room/models.py16
-rw-r--r--src/meetingtools/apps/room/tasks.py186
-rw-r--r--src/meetingtools/settings.py24
9 files changed, 482 insertions, 3 deletions
diff --git a/src/meetingtools/ac/api.py b/src/meetingtools/ac/api.py
index b89aae7..ebf38ea 100644
--- a/src/meetingtools/ac/api.py
+++ b/src/meetingtools/ac/api.py
@@ -38,6 +38,9 @@ class ACPResult():
def status_code(self):
return self.status.get('code')
+
+ def subcode(self):
+ return self.status.get('subcode')
def exception(self):
raise ACPException,self.status
diff --git a/src/meetingtools/apps/cluster/migrations/0001_initial.py b/src/meetingtools/apps/cluster/migrations/0001_initial.py
new file mode 100644
index 0000000..f20f743
--- /dev/null
+++ b/src/meetingtools/apps/cluster/migrations/0001_initial.py
@@ -0,0 +1,45 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'ACCluster'
+ db.create_table('cluster_accluster', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('api_url', self.gf('django.db.models.fields.URLField')(max_length=200)),
+ ('url', self.gf('django.db.models.fields.URLField')(max_length=200)),
+ ('user', self.gf('django.db.models.fields.CharField')(max_length=128)),
+ ('password', self.gf('django.db.models.fields.CharField')(max_length=128)),
+ ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128, blank=True)),
+ ('default_template_sco_id', self.gf('django.db.models.fields.IntegerField')(unique=True, blank=True)),
+ ('domain_match', self.gf('django.db.models.fields.TextField')()),
+ ))
+ db.send_create_signal('cluster', ['ACCluster'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'ACCluster'
+ db.delete_table('cluster_accluster')
+
+
+ models = {
+ 'cluster.accluster': {
+ 'Meta': {'object_name': 'ACCluster'},
+ 'api_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'default_template_sco_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'blank': 'True'}),
+ 'domain_match': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'user': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ }
+ }
+
+ complete_apps = ['cluster']
diff --git a/src/meetingtools/apps/cluster/migrations/__init__.py b/src/meetingtools/apps/cluster/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/meetingtools/apps/cluster/migrations/__init__.py
diff --git a/src/meetingtools/apps/room/migrations/0001_initial.py b/src/meetingtools/apps/room/migrations/0001_initial.py
new file mode 100644
index 0000000..4cb1bef
--- /dev/null
+++ b/src/meetingtools/apps/room/migrations/0001_initial.py
@@ -0,0 +1,120 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'Room'
+ db.create_table('room_room', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('creator', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=128)),
+ ('urlpath', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128)),
+ ('acc', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cluster.ACCluster'])),
+ ('self_cleaning', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('allow_host', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('sco_id', self.gf('django.db.models.fields.IntegerField')()),
+ ('source_sco_id', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('folder_sco_id', self.gf('django.db.models.fields.IntegerField')()),
+ ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+ ('user_count', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('host_count', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('timecreated', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+ ('lastupdated', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+ ('lastvisited', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('room', ['Room'])
+
+ # Adding unique constraint on 'Room', fields ['acc', 'sco_id']
+ db.create_unique('room_room', ['acc_id', 'sco_id'])
+
+ # Adding unique constraint on 'Room', fields ['name', 'folder_sco_id']
+ db.create_unique('room_room', ['name', 'folder_sco_id'])
+
+
+ def backwards(self, orm):
+
+ # Removing unique constraint on 'Room', fields ['name', 'folder_sco_id']
+ db.delete_unique('room_room', ['name', 'folder_sco_id'])
+
+ # Removing unique constraint on 'Room', fields ['acc', 'sco_id']
+ db.delete_unique('room_room', ['acc_id', 'sco_id'])
+
+ # Deleting model 'Room'
+ db.delete_table('room_room')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'cluster.accluster': {
+ 'Meta': {'object_name': 'ACCluster'},
+ 'api_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'default_template_sco_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'blank': 'True'}),
+ 'domain_match': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'user': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'room.room': {
+ 'Meta': {'unique_together': "(('acc', 'sco_id'), ('name', 'folder_sco_id'))", 'object_name': 'Room'},
+ 'acc': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cluster.ACCluster']"}),
+ 'allow_host': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'folder_sco_id': ('django.db.models.fields.IntegerField', [], {}),
+ 'host_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lastupdated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'lastvisited': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'sco_id': ('django.db.models.fields.IntegerField', [], {}),
+ 'self_cleaning': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'source_sco_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'timecreated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'urlpath': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
+ 'user_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['room']
diff --git a/src/meetingtools/apps/room/migrations/0002_auto__add_field_room_deleted_sco_id.py b/src/meetingtools/apps/room/migrations/0002_auto__add_field_room_deleted_sco_id.py
new file mode 100644
index 0000000..bea1f14
--- /dev/null
+++ b/src/meetingtools/apps/room/migrations/0002_auto__add_field_room_deleted_sco_id.py
@@ -0,0 +1,91 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'Room.deleted_sco_id'
+ db.add_column('room_room', 'deleted_sco_id', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'Room.deleted_sco_id'
+ db.delete_column('room_room', 'deleted_sco_id')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'cluster.accluster': {
+ 'Meta': {'object_name': 'ACCluster'},
+ 'api_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'default_template_sco_id': ('django.db.models.fields.IntegerField', [], {'unique': 'True', 'blank': 'True'}),
+ 'domain_match': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
+ 'user': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'room.room': {
+ 'Meta': {'unique_together': "(('acc', 'sco_id'), ('name', 'folder_sco_id'))", 'object_name': 'Room'},
+ 'acc': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cluster.ACCluster']"}),
+ 'allow_host': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'deleted_sco_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'folder_sco_id': ('django.db.models.fields.IntegerField', [], {}),
+ 'host_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lastupdated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'lastvisited': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'sco_id': ('django.db.models.fields.IntegerField', [], {}),
+ 'self_cleaning': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'source_sco_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'timecreated': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'urlpath': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
+ 'user_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['room']
diff --git a/src/meetingtools/apps/room/migrations/__init__.py b/src/meetingtools/apps/room/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/meetingtools/apps/room/migrations/__init__.py
diff --git a/src/meetingtools/apps/room/models.py b/src/meetingtools/apps/room/models.py
index 731e8b9..249b1bf 100644
--- a/src/meetingtools/apps/room/models.py
+++ b/src/meetingtools/apps/room/models.py
@@ -35,6 +35,12 @@ class FileLock(object):
def __delete__(self):
raise AttributeError
+class RoomLockedException(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
class Room(models.Model):
creator = ForeignKey(User,editable=False)
name = CharField(max_length=128)
@@ -44,6 +50,7 @@ class Room(models.Model):
allow_host = BooleanField(verbose_name="Allow first participant to become host?",default=True)
sco_id = IntegerField(verbose_name="Adobe Connect Room")
source_sco_id = IntegerField(verbose_name="Template",blank=True,null=True)
+ deleted_sco_id = IntegerField(verbose_name="Previous Room ID",editable=False,blank=True,null=True)
folder_sco_id = IntegerField(verbose_name="Adobe Connect Room Folder",editable=False)
description = TextField(blank=True,null=True)
user_count = IntegerField(verbose_name="User Count At Last Visit",editable=False,blank=True,null=True)
@@ -66,6 +73,15 @@ class Room(models.Model):
if msg:
f.write(msg)
f.close()
+
+ def trylock(self,raise_on_locked=True):
+ if self.is_locked():
+ if raise_on_locked:
+ raise RoomLockedException,"room %s is locked" % self.__unicode__()
+ else:
+ return False
+ self.lock() #race!! - must use flock
+ return True
def unlock(self):
os.remove(self._lockf())
diff --git a/src/meetingtools/apps/room/tasks.py b/src/meetingtools/apps/room/tasks.py
new file mode 100644
index 0000000..2042e36
--- /dev/null
+++ b/src/meetingtools/apps/room/tasks.py
@@ -0,0 +1,186 @@
+'''
+Created on Jan 18, 2012
+
+@author: leifj
+'''
+from celery.decorators import periodic_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.apps.room.models import Room
+import iso8601
+from django.contrib.auth.models import User
+from django.core.cache import cache
+from django.core.exceptions import ObjectDoesNotExist
+import logging
+from datetime import datetime,timedelta
+from lxml import etree
+
+def _owner_username(api,sco):
+ logging.debug(sco)
+ key = '_sco_owner_%s' % sco.get('sco-id')
+ logging.debug(key)
+ try:
+ if cache.get(key) is None:
+ fid = sco.get('folder-id')
+ if not fid:
+ logging.debug("No folder-id")
+ return None
+
+ folder_id = int(fid)
+ r = api.request('sco-info',{'sco-id':folder_id},False)
+ if r.status_code() == 'no-data':
+ return None
+
+ parent = r.et.xpath("//sco")[0]
+ logging.debug("p %s",repr(parent))
+ logging.debug("r %s",etree.tostring(parent))
+ name = None
+ if parent:
+ logging.debug("parent: %s" % parent)
+ if parent.findtext('name') == 'User Meetings':
+ name = sco.findtext('name')
+ else:
+ name = _owner_username(api,parent)
+
+ cache.set(key,name)
+
+ return cache.get(key)
+ except Exception,e:
+ logging.debug(e)
+ return None
+
+def _extended_info(api,sco_id):
+ r = api.request('sco-info',{'sco-id':sco_id},False)
+ if r.status_code == 'no-data':
+ return None
+ return (r.et,_owner_username(api,r.et.xpath('//sco')[0]))
+
+def _import_one_room(acc,api,row):
+ sco_id = int(row.get('sco-id'))
+ last = iso8601.parse_date(row.findtext("date-modified[0]"))
+ room = None
+
+ try:
+ room = Room.objects.get(acc=acc,deleted_sco_id=sco_id)
+ if room != None:
+ return # We hit a room in the process of being cleaned - let it simmer until next pass
+ except ObjectDoesNotExist:
+ pass
+ except Exception,e:
+ logging.debug(e)
+ return
+
+ try:
+ logging.debug("finding acc=%s,sco_id=%d in our DB" % (acc,sco_id))
+ room = Room.objects.get(acc=acc,sco_id=sco_id)
+ if room.deleted_sco_id != None:
+ return # We hit a room in the process of being cleaned - let it simmer until next pass
+ room.trylock()
+ except ObjectDoesNotExist:
+ pass
+
+ last = last.replace(tzinfo=None)
+ 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)
+ if not room or lastupdated < last:
+ (r,username) = _extended_info(api, sco_id)
+ logging.debug("owner: %s" % username)
+ if username is None:
+ return
+
+ urlpath = row.findtext("url[0]").strip("/")
+ name = row.findtext('name[0]')
+ description = row.findtext('description[0]')
+ folder_sco_id = int(r.xpath('//sco[0]/@folder-id') or 0) or None
+ source_sco_id = int(r.xpath('//sco[0]/@source-sco-id') or 0) or None
+
+ if room == None:
+ user,created = User.objects.get_or_create(username=username)
+ if created:
+ user.set_unusable_password()
+ room = Room.objects.create(acc=acc,sco_id=sco_id,creator=user,name=name,description=description,folder_sco_id=folder_sco_id,source_sco_id=source_sco_id,urlpath=urlpath)
+ room.trylock()
+ else:
+ room.folder_sco_id = folder_sco_id
+ room.source_sco_id = source_sco_id
+ room.description = description
+ room.urlpath = urlpath
+
+ 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()
+ room.unlock()
+ else:
+ 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)
+
+
+@periodic_task(run_every=crontab(hour="*", minute="*/1", day_of_week="*"))
+def import_all_rooms():
+ for acc in ACCluster.objects.all():
+ _import_acc(acc)
+
+def _import_meeting_room_session(api,acc,sco_id,row=None,room=None):
+ try:
+ if room == None:
+ room = Room.objects.get(acc=acc,sco_id=sco_id)
+ if row and row.findtext("date-end"):
+ room.user_count = 0
+ room.host_count = 0
+ else:
+ 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'])"))
+ elif userlist.status_code() == 'no-access' and userlist.subcode() == 'not-available': #no active session
+ room.user_count = 0
+ room.host_count = 0
+ room.save()
+ except ObjectDoesNotExist:
+ pass
+
+def _import_meeting_sessions_acc(acc):
+ api = ac_api_client_direct(acc)
+ backthen = datetime.now()-timedelta(seconds=600000)
+ backthen = backthen.replace(microsecond=0)
+ logging.debug(backthen.isoformat())
+ r = api.request('report-meeting-sessions',{'filter-gt-date-created': backthen.isoformat()})
+ seen = {}
+ for row in r.et.xpath("//row"):
+ try:
+ sco_id = int(row.get('sco-id'))
+ _import_meeting_room_session(api,acc,sco_id,row,None)
+ seen[sco_id] = True
+ except Exception,ex:
+ logging.error(ex)
+
+ for room in Room.objects.filter(acc=acc,user_count=None):
+ logging.debug("checking sessions on room: %s" % room)
+ if seen.get(room.sco_id,False):
+ continue
+ try:
+ logging.debug("importing sessions")
+ _import_meeting_room_session(api,acc,room.sco_id,None,room)
+ except Exception,ex:
+ logging.error(ex)
+
+@periodic_task(run_every=crontab(hour="*", minute="*/1", day_of_week="*"))
+def _import_meeting_sessions():
+ for acc in ACCluster.objects.all():
+ _import_meeting_sessions_acc(acc) \ No newline at end of file
diff --git a/src/meetingtools/settings.py b/src/meetingtools/settings.py
index 2659ee1..46c3d72 100644
--- a/src/meetingtools/settings.py
+++ b/src/meetingtools/settings.py
@@ -69,10 +69,18 @@ LOGOUT_URL = "%s/accounts/logout" % PREFIX_URL
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'tz78l!c=cl2=jic5$2#(bq)7-4s1ivtm*a+q0w1yi0$)hrmc7l'
-SESSION_ENGINE = "django.contrib.sessions.backends.file"
-SESSION_FILE_PATH = "/tmp"
+#SESSION_ENGINE = "django.contrib.sessions.backends.file"
+SESSION_ENGINE = "django.contrib.sessions.backends.cache"
+#SESSION_FILE_PATH = "/tmp"
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+CACHES = {
+ 'default': {
+ 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
+ 'LOCATION': 'unique-snowflake'
+ }
+}
+
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
@@ -86,7 +94,7 @@ MIDDLEWARE_CLASSES = (
'meetingtools.django-crossdomainxhr-middleware.XsSharing',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.auth.middleware.RemoteUserMiddleware'
+ #'django.contrib.auth.middleware.RemoteUserMiddleware'
)
AUTHENTICATION_BACKENDS = (
@@ -111,6 +119,10 @@ INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.humanize',
'django_extensions',
+ 'south',
+ 'djcelery',
+ 'ghettoq',
+ 'djkombu',
'django_co_connector',
'django_co_acls',
'tagging',
@@ -119,4 +131,10 @@ INSTALLED_APPS = (
'meetingtools.apps.room',
'meetingtools.apps.cluster',
'meetingtools.apps.userprofile',
+ 'meetingtools.apps.stats'
)
+
+CARROT_BACKEND = "django"
+
+import djcelery
+djcelery.setup_loader()