From 2bdad0ae7a3a6e4ec5116becd39910388b679ed2 Mon Sep 17 00:00:00 2001
From: Leif Johansson <leifj@sunet.se>
Date: Thu, 4 Oct 2012 15:39:08 +0200
Subject: restructure

---
 src/meetingtools/__init__.py                       |   0
 src/meetingtools/ac/__init__.py                    |  57 ---
 src/meetingtools/ac/api.py                         | 214 --------
 src/meetingtools/apps/__init__.py                  |   0
 src/meetingtools/apps/auth/__init__.py             |  79 ---
 src/meetingtools/apps/auth/utils.py                |  19 -
 src/meetingtools/apps/auth/views.py                | 169 -------
 src/meetingtools/apps/cluster/__init__.py          |   0
 src/meetingtools/apps/cluster/admin.py             |  10 -
 .../apps/cluster/migrations/0001_initial.py        |  45 --
 .../apps/cluster/migrations/__init__.py            |   0
 src/meetingtools/apps/cluster/models.py            |  35 --
 src/meetingtools/apps/room/__init__.py             |   0
 src/meetingtools/apps/room/admin.py                |  10 -
 src/meetingtools/apps/room/feeds.py                | 118 -----
 src/meetingtools/apps/room/forms.py                |  82 ---
 src/meetingtools/apps/room/management/__init__.py  |   1 -
 .../apps/room/management/commands/__init__.py      |   1 -
 .../apps/room/management/commands/import_rooms.py  |  11 -
 .../apps/room/migrations/0001_initial.py           | 120 -----
 .../0002_auto__add_field_room_deleted_sco_id.py    |  91 ----
 src/meetingtools/apps/room/migrations/__init__.py  |   0
 src/meetingtools/apps/room/models.py               | 142 ------
 src/meetingtools/apps/room/tasks.py                | 250 ----------
 src/meetingtools/apps/room/views.py                | 548 ---------------------
 src/meetingtools/apps/stats/__init__.py            |   0
 src/meetingtools/apps/stats/forms.py               |  11 -
 src/meetingtools/apps/stats/views.py               | 273 ----------
 src/meetingtools/apps/userprofile/__init__.py      |   0
 src/meetingtools/apps/userprofile/admin.py         |   4 -
 src/meetingtools/apps/userprofile/models.py        |  21 -
 src/meetingtools/context_processors.py             |  23 -
 .../django-crossdomainxhr-middleware.py            |  44 --
 src/meetingtools/extensions/__init__.py            |   0
 .../extensions/templatetags/__init__.py            |   0
 .../extensions/templatetags/datehumanize.py        |  36 --
 .../extensions/templatetags/roomurl.py             |  19 -
 src/meetingtools/manage.py                         |  11 -
 src/meetingtools/mimeparse.py                      | 123 -----
 src/meetingtools/multiresponse.py                  |  77 ---
 src/meetingtools/settings.py                       | 147 ------
 src/meetingtools/site_logging.py                   |  10 -
 src/meetingtools/urlmiddleware.py                  | 126 -----
 src/meetingtools/urls.py                           |  53 --
 src/meetingtools/utils.py                          |  20 -
 45 files changed, 3000 deletions(-)
 delete mode 100644 src/meetingtools/__init__.py
 delete mode 100644 src/meetingtools/ac/__init__.py
 delete mode 100644 src/meetingtools/ac/api.py
 delete mode 100644 src/meetingtools/apps/__init__.py
 delete mode 100644 src/meetingtools/apps/auth/__init__.py
 delete mode 100644 src/meetingtools/apps/auth/utils.py
 delete mode 100644 src/meetingtools/apps/auth/views.py
 delete mode 100644 src/meetingtools/apps/cluster/__init__.py
 delete mode 100644 src/meetingtools/apps/cluster/admin.py
 delete mode 100644 src/meetingtools/apps/cluster/migrations/0001_initial.py
 delete mode 100644 src/meetingtools/apps/cluster/migrations/__init__.py
 delete mode 100644 src/meetingtools/apps/cluster/models.py
 delete mode 100644 src/meetingtools/apps/room/__init__.py
 delete mode 100644 src/meetingtools/apps/room/admin.py
 delete mode 100644 src/meetingtools/apps/room/feeds.py
 delete mode 100644 src/meetingtools/apps/room/forms.py
 delete mode 100644 src/meetingtools/apps/room/management/__init__.py
 delete mode 100644 src/meetingtools/apps/room/management/commands/__init__.py
 delete mode 100644 src/meetingtools/apps/room/management/commands/import_rooms.py
 delete mode 100644 src/meetingtools/apps/room/migrations/0001_initial.py
 delete mode 100644 src/meetingtools/apps/room/migrations/0002_auto__add_field_room_deleted_sco_id.py
 delete mode 100644 src/meetingtools/apps/room/migrations/__init__.py
 delete mode 100644 src/meetingtools/apps/room/models.py
 delete mode 100644 src/meetingtools/apps/room/tasks.py
 delete mode 100644 src/meetingtools/apps/room/views.py
 delete mode 100644 src/meetingtools/apps/stats/__init__.py
 delete mode 100644 src/meetingtools/apps/stats/forms.py
 delete mode 100644 src/meetingtools/apps/stats/views.py
 delete mode 100644 src/meetingtools/apps/userprofile/__init__.py
 delete mode 100644 src/meetingtools/apps/userprofile/admin.py
 delete mode 100644 src/meetingtools/apps/userprofile/models.py
 delete mode 100644 src/meetingtools/context_processors.py
 delete mode 100644 src/meetingtools/django-crossdomainxhr-middleware.py
 delete mode 100644 src/meetingtools/extensions/__init__.py
 delete mode 100644 src/meetingtools/extensions/templatetags/__init__.py
 delete mode 100644 src/meetingtools/extensions/templatetags/datehumanize.py
 delete mode 100644 src/meetingtools/extensions/templatetags/roomurl.py
 delete mode 100644 src/meetingtools/manage.py
 delete mode 100644 src/meetingtools/mimeparse.py
 delete mode 100644 src/meetingtools/multiresponse.py
 delete mode 100644 src/meetingtools/settings.py
 delete mode 100644 src/meetingtools/site_logging.py
 delete mode 100644 src/meetingtools/urlmiddleware.py
 delete mode 100644 src/meetingtools/urls.py
 delete mode 100644 src/meetingtools/utils.py

(limited to 'src/meetingtools')

diff --git a/src/meetingtools/__init__.py b/src/meetingtools/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/ac/__init__.py b/src/meetingtools/ac/__init__.py
deleted file mode 100644
index 2bbd25f..0000000
--- a/src/meetingtools/ac/__init__.py
+++ /dev/null
@@ -1,57 +0,0 @@
-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
-
-_pools = {}
-
-MAXCALLS = 10    
-MAXIDLE = 10
-
-class ClientPool(object):
-    
-    def __init__(self,acc,maxsize=0,increment=2):
-        self._q = Queue(maxsize)
-        self._acc = acc
-        self._increment = increment
-    
-    def allocate(self):
-        now = time.time()
-        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
-        
-    return pool.allocate()
-
-
-
-    
\ No newline at end of file
diff --git a/src/meetingtools/ac/api.py b/src/meetingtools/ac/api.py
deleted file mode 100644
index 5fbcfbf..0000000
--- a/src/meetingtools/ac/api.py
+++ /dev/null
@@ -1,214 +0,0 @@
-'''
-Created on Jan 31, 2011
-
-@author: leifj
-'''
-from StringIO import StringIO
-
-import httplib2
-from urllib import quote_plus
-import logging
-from pprint import pformat
-import os
-import tempfile
-import time
-from lxml import etree
-from meetingtools.site_logging import logger
-import lxml
-from django.http import HttpResponseRedirect
-from celery.execute import send_task
-
-class ACPException(Exception):
-    def __init__(self, value):
-        self.value = value
-
-    def __str__(self):
-        return etree.tostring(self.value)
-
-def _first_or_none(x):
-    if not x:
-        return None
-    return x[0]
-
-class ACPResult():
-    
-    def __init__(self,content):
-        self.et = etree.fromstring(content)
-        self.status = _first_or_none(self.et.xpath('//status'))
-        
-    def is_error(self):
-        return self.status_code() != 'ok'
-
-    def status_code(self):
-        return self.status.get('code')
-    
-    def subcode(self):
-        return self.status.get('subcode')
-
-    def exception(self):
-        raise ACPException,self.status
-
-    def get_principal(self):
-        logger.debug(lxml.etree.tostring(self.et))
-        return _first_or_none(self.et.xpath('//principal'))
-
-def _enc(v):
-        ev = v
-        if isinstance(ev,str) or isinstance(ev,unicode):
-            ev = ev.encode('iso-8859-1')
-        return ev
-
-def _getset(d,key,value=None):
-    if value:
-        if d.has_key(key):
-            return d[key]
-        else:
-            return None
-    else:
-        d[key] = value
-
-class ACPClient():
-    
-    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 and not value:
-            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 = list()
-        u.append("action=%s" % method)
-        if self.session:
-            u.append("session=%s" % self.session)
-        for k,v in p.items():
-            value = v
-            if type(v) == int:
-                value = "%d" % value
-            u.append('%s=%s' % (k,quote_plus(value.encode("utf-8"))))
-        
-        url = self.url + '?' + '&'.join(u)
-    
-        h = httplib2.Http(tempfile.gettempdir()+os.sep+".cache",disable_ssl_certificate_validation=True);
-        logging.debug(url)
-        resp, content = h.request(url, "GET")
-        logging.debug(pformat(resp))
-        logging.debug(pformat(content))
-        if resp.status != 200:
-            raise ACPException,resp.reason
-        
-        if resp.has_key('set-cookie'):
-            cookie = resp['set-cookie']
-            if cookie:
-                avp = cookie.split(";")
-                if len(avp) > 0:
-                    av = avp[0].split('=')
-                    self.session = av[1]
-                    
-        r = ACPResult(content)
-        if r.is_error() and raise_error:
-            raise r.exception()
-        
-        return r;
-    
-    def redirect_to(self,url):
-        if self.session:
-            return HttpResponseRedirect("%s?session=%s" % (url,self.session))
-        else:
-            return HttpResponseRedirect(url)
-    
-    def login(self,username,password):
-        result = self.request('login',{'login':username,'password':password})
-        if result.is_error():
-            raise result.exception()
-        return result
-    
-    def find_or_create_principal(self,key,value,t,d):
-        if not self._cache.has_key(t):
-            self._cache[t] = {}
-        cache = self._cache[t]
-        
-        # lxml etree Elements are not picklable
-        p = None
-        if not cache.has_key(key):
-            p = self._find_or_create_principal(key,value,t,d)
-            cache[key] = etree.tostring(p)
-        else:   
-            p = etree.parse(StringIO(cache[key]))
-        return p
-        
-    def find_principal(self,key,value,t):
-        return self.find_or_create_principal(key,value,t,None)
-    
-    def _find_or_create_principal(self,key,value,t,d):
-        result = self.request('principal-list',{'filter-%s' % key: value,'filter-type': t}, True)
-        principal = result.get_principal()
-        if result.is_error():
-            if result.status_code() != 'no_data':
-                result.exception()
-        elif principal and d:
-            d['principal-id'] = principal.get('principal-id')
-        
-        rp = principal
-        if d:
-            update_result = self.request('principal-update',d)
-            rp = update_result.get_principal()
-            if not rp:
-                rp = principal
-        return rp
-    
-    def find_builtin(self,t):
-        result = self.request('principal-list', {'filter-type': t}, True)
-        return result.get_principal()
-    
-    def find_group(self,name):
-        result = self.request('principal-list',{'filter-name':name,'filter-type':'group'},True)
-        return result.get_principal()
-    
-    def find_user(self,login):
-        return self.find_principal("login", login, "user")
-    
-    def add_remove_member(self,principal_id,group_id,is_member):
-        m = "0"
-        if is_member:
-            m = "1"
-        self.request('group-membership-update',{'group-id': group_id, 'principal-id': principal_id,'is-member':m},True)
-        
-    def add_member(self,principal_id,group_id):
-        return self.add_remove_member(principal_id, group_id, True)
-    
-    def remove_member(self,principal_id,group_id):
-        return self.add_remove_member(principal_id, group_id, False)
-    
-    def user_counts(self,sco_id):
-        user_count = None
-        host_count = None
-        userlist = self.request('meeting-usermanager-user-list',{'sco-id': sco_id},False)
-        if userlist.status_code() == 'ok':
-            user_count = int(userlist.et.xpath("count(.//userdetails)"))
-            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
-            user_count = 0
-            host_count = 0
-        
-        return (user_count,host_count)
-    
-    def poll_user_counts(self,room):
-        (room.user_count,room.host_count) = self.user_counts(room.sco_id)
-        room.save()
-        return (room.user_count,room.host_count)
\ No newline at end of file
diff --git a/src/meetingtools/apps/__init__.py b/src/meetingtools/apps/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/auth/__init__.py b/src/meetingtools/apps/auth/__init__.py
deleted file mode 100644
index e69cc29..0000000
--- a/src/meetingtools/apps/auth/__init__.py
+++ /dev/null
@@ -1,79 +0,0 @@
-__author__ = 'leifj'
-
-from django.conf import settings
-from saml2.config import SPConfig
-import copy
-from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
-
-import logging
-logging.basicConfig()
-logger = logging.getLogger("djangosaml2")
-logger.setLevel(logging.DEBUG)
-
-def asgard_sp_config(request=None):
-    host = "localhost"
-    if request is not None:
-        host = request.get_host().replace(":","-")
-    x= {
-        # your entity id, usually your subdomain plus the url to the metadata view
-        'entityid': 'https://%s/saml2/sp/metadata' % host,
-        # directory with attribute mapping
-        "attribute_map_dir" : "%s/saml2/attributemaps" % settings.BASE_DIR,
-        # this block states what services we provide
-        'service': {
-            # we are just a lonely SP
-            'sp' : {
-                'name': 'meetingtools',
-                'endpoints': {
-                    # url and binding to the assertion consumer service view
-                    # do not change the binding osettingsr service name
-                    'assertion_consumer_service': [
-                        ('https://%s/saml2/sp/acs/' % host,
-                         BINDING_HTTP_POST),
-                        ],
-                    # url and binding to the single logout service view
-                    # do not change the binding or service name
-                    'single_logout_service': [
-                        ('https://%s/saml2/sp/ls/' % host,
-                         BINDING_HTTP_REDIRECT),
-                        ],
-                    },
-                # attributes that this project need to identify a user
-                'required_attributes': ['eduPersonPrincipalName','displayName','eduPersonScopedAffiliation'],
-                }
-        },
-
-        # where the remote metadata is stored
-        #'metadata': { 'remote': [{'url':'http://md.swamid.se/md/swamid-idp.xml',
-        #                          'cert':'%s/saml2/credentials/md-signer.crt' % settings.BASE_DIR}] },
-        'metadata': {'local': [settings.SAML_METADATA_FILE]},
-
-        # set to 1 to output debugging information
-        'debug': 1,
-
-        # certificate
-        "key_file" : "%s/%s.key" % (settings.SSL_KEY_DIR,host),
-        "cert_file" : "%s/%s.crt" % (settings.SSL_CRT_DIR,host),
-        # own metadata settings
-        'contact_person': [
-            {'given_name': 'Leif',
-             'sur_name': 'Johansson',
-             'company': 'NORDUnet',
-             'email_address': 'leifj@nordu.net',
-             'contact_type': 'technical'},
-            {'given_name': 'Johan',
-             'sur_name': 'Berggren',
-             'company': 'NORDUnet',
-             'email_address': 'jbn@nordu.net',
-             'contact_type': 'technical'},
-            ],
-        # you can set multilanguage information here
-        'organization': {
-            'name': [('NORDUNet', 'en')],
-            'display_name': [('NORDUnet A/S', 'en')],
-            'url': [('http://www.nordu.net', 'en')],
-            }
-    }
-    c = SPConfig()
-    c.load(copy.deepcopy(x))
-    return c
diff --git a/src/meetingtools/apps/auth/utils.py b/src/meetingtools/apps/auth/utils.py
deleted file mode 100644
index 1a0174c..0000000
--- a/src/meetingtools/apps/auth/utils.py
+++ /dev/null
@@ -1,19 +0,0 @@
-'''
-Created on Jul 7, 2010
-
-@author: leifj
-'''
-from uuid import uuid4
-
-def nonce():
-    return uuid4().hex
-
-def anonid():
-    return uuid4().urn
-
-def groups(request):
-    groups = []
-    if request.user.is_authenticated():
-        groups = request.user.groups
-
-    return groups
\ No newline at end of file
diff --git a/src/meetingtools/apps/auth/views.py b/src/meetingtools/apps/auth/views.py
deleted file mode 100644
index ee23df3..0000000
--- a/src/meetingtools/apps/auth/views.py
+++ /dev/null
@@ -1,169 +0,0 @@
-'''
-Created on Jul 5, 2010
-
-@author: leifj
-'''
-from django.http import HttpResponseRedirect
-from django.contrib.auth.models import User, Group
-import datetime
-from django.views.decorators.cache import never_cache
-import logging
-from meetingtools.apps.userprofile.models import UserProfile
-from meetingtools.multiresponse import redirect_to, make_response_dict
-from meetingtools.ac import ac_api_client
-from django.shortcuts import render_to_response
-from django.contrib import auth
-from django_co_connector.models import co_import_from_request, add_member,remove_member
-from meetingtools.apps.cluster.models import acc_for_user
-from django.conf import settings
-
-def meta(request,attr):
-    v = request.META.get(attr)
-    if not v:
-        return None
-    values = filter(lambda x: x != "(null)",v.split(";"))
-    return values;
-
-def meta1(request,attr):
-    v = meta(request,attr)
-    if v:
-        return str(v[0]).decode('utf-8')
-    else:
-        return None
-
-def _localpart(a):
-    if hasattr(a,'name'):
-        a = a.name
-    if '@' in a:
-        (lp,dp) = a.split('@')
-        a = lp
-    return a
-
-def _is_member_or_employee_old(affiliations):
-    lpa = map(_localpart,affiliations)
-    return 'student' in lpa or 'staff' in lpa or ('member' in lpa and not 'student' in lpa)
-
-def _is_member_or_employee(user):
-    lpa = map(_localpart,user.groups.all())
-    return 'student' in lpa or 'staff' in lpa or ('member' in lpa and not 'student' in lpa)
-
-@never_cache
-def logout(request):
-    auth.logout(request)
-    return HttpResponseRedirect('/Shibboleth.sso/Logout')
-
-@never_cache
-def login(request):
-    return render_to_response('apps/auth/login.html',make_response_dict(request,{'next': request.REQUEST.get("next")}));
-
-def join_group(group,**kwargs):
-    user = kwargs['user']
-    acc = acc_for_user(user)
-    with ac_api_client(acc) as api:    
-        principal = api.find_principal("login", user.username, "user")
-        if principal:
-            gp = api.find_group(group.name)
-            if gp:
-                api.add_member(principal.get('principal-id'),gp.get('principal-id'))
-    
-def leave_group(group,**kwargs):
-    user = kwargs['user']
-    acc = acc_for_user(user)
-    with ac_api_client(acc) as api:
-        principal = api.find_principal("login", user.username, "user")
-        if principal:
-            gp = api.find_group(group.name)
-            if gp:
-                api.remove_member(principal.get('principal-id'),gp.get('principal-id'))
-
-add_member.connect(join_group,sender=Group)
-remove_member.connect(leave_group,sender=Group)
-
-def accounts_login_federated(request):
-    if request.user.is_authenticated():
-        profile,created = UserProfile.objects.get_or_create(user=request.user)
-        if created:
-            profile.identifier = request.user.username
-            profile.user = request.user
-            profile.save()        
-        
-        update = False
-        fn = meta1(request,'givenName')
-        ln = meta1(request,'sn')
-        cn = meta1(request,'cn')
-        if not cn:
-            cn = meta1(request,'displayName')
-        logging.debug("cn=%s" % cn)
-        if not cn and fn and ln:
-            cn = "%s %s" % (fn,ln)
-        if not cn:
-            cn = profile.identifier
-            
-        mail = meta1(request,'mail')
-        
-        idp = meta1(request,'Shib-Identity-Provider')
-        
-        for attrib_name, meta_value in (('display_name',cn),('email',mail),('idp',idp)):
-            attrib_value = getattr(profile, attrib_name)
-            if meta_value and not attrib_value:
-                setattr(profile,attrib_name,meta_value)
-                update = True
-                
-        if request.user.password == "":
-            request.user.password = "(not used for federated logins)"
-            update = True
-            
-        if update:
-            request.user.save()
-        
-        # Allow auto_now to kick in for the lastupdated field
-        #profile.lastupdated = datetime.datetime.now()    
-        profile.save()
-
-        next = request.session.get("after_login_redirect", None)
-        if not next and request.GET.has_key('next'):
-            next = request.GET['next']
-        else:
-            next = settings.DEFAULT_URL
-
-        acc = acc_for_user(request.user)
-        with ac_api_client(request) as api:
-            # make sure the principal is created before shooting off 
-            principal = api.find_or_create_principal("login", request.user.username, "user", 
-                                                             {'type': "user",
-                                                              'has-children': "0",
-                                                              'first-name':fn,
-                                                              'last-name':ln,
-                                                              'email':mail,
-                                                              'send-email': 0,
-                                                              'login':request.user.username,
-                                                              'ext-login':request.user.username})
-            
-            
-            
-            co_import_from_request(request)
-            
-            member_or_employee = _is_member_or_employee(request.user)
-            for gn in ('live-admins','seminar-admins'):
-                group = api.find_builtin(gn)
-                if group:
-                    api.add_remove_member(principal.get('principal-id'),group.get('principal-id'),member_or_employee)
-            
-            #(lp,domain) = uid.split('@')
-            #for a in ('student','employee','member'):
-            #    affiliation = "%s@%s" % (a,domain)
-            #    group = connect_api.find_or_create_principal('name',affiliation,'group',{'type': 'group','has-children':'1','name': affiliation})
-            #    member = affiliation in affiliations
-            #    connect_api.add_remove_member(principal.get('principal-id'),group.get('principal-id'),member)
-                
-            #for e in epe:
-            #    group = connect_api.find_or_create_principal('name',e,'group',{'type': 'group','has-children':'1','name': e})
-            #    if group:
-            #        connect_api.add_remove_member(principal.get('principal-id'),group.get('principal-id'),True)
-
-            if next is not None:
-                return redirect_to(next)
-    else:
-        pass
-
-    return redirect_to(settings.LOGIN_URL)
diff --git a/src/meetingtools/apps/cluster/__init__.py b/src/meetingtools/apps/cluster/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/cluster/admin.py b/src/meetingtools/apps/cluster/admin.py
deleted file mode 100644
index 3fc9eea..0000000
--- a/src/meetingtools/apps/cluster/admin.py
+++ /dev/null
@@ -1,10 +0,0 @@
-'''
-Created on Jan 31, 2011
-
-@author: leifj
-'''
-
-from django.contrib import admin
-from meetingtools.apps.cluster.models import ACCluster
-
-admin.site.register(ACCluster)
\ No newline at end of file
diff --git a/src/meetingtools/apps/cluster/migrations/0001_initial.py b/src/meetingtools/apps/cluster/migrations/0001_initial.py
deleted file mode 100644
index f20f743..0000000
--- a/src/meetingtools/apps/cluster/migrations/0001_initial.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# 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
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/cluster/models.py b/src/meetingtools/apps/cluster/models.py
deleted file mode 100644
index 3c65d57..0000000
--- a/src/meetingtools/apps/cluster/models.py
+++ /dev/null
@@ -1,35 +0,0 @@
-'''
-Created on Feb 3, 2011
-
-@author: leifj
-'''
-
-from django.db import models
-from django.db.models.fields import CharField, URLField, TextField, IntegerField
-import re
-
-class ACCluster(models.Model):
-    api_url = URLField()
-    url = URLField()
-    user = CharField(max_length=128)
-    password = CharField(max_length=128)
-    name = CharField(max_length=128,blank=True,unique=True)
-    default_template_sco_id = IntegerField(blank=True,unique=True)
-    domain_match = TextField()
-    
-    def __unicode__(self):
-        return self.url
-    
-    def make_url(self,path=""):
-        return "%s%s" % (self.url,path)
-    
-def acc_for_user(user):
-    (local,domain) = user.username.split('@')
-    if not domain:
-        #raise Exception,"Improperly formatted user: %s" % user.username
-        domain = "nordu.net" # testing with local accts only
-    for acc in ACCluster.objects.all():
-        for regex in acc.domain_match.split():
-            if re.match(regex.strip(),domain):
-                return acc
-    raise Exception,"I don't know which cluster you belong to... (%s)" % user.username
diff --git a/src/meetingtools/apps/room/__init__.py b/src/meetingtools/apps/room/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/room/admin.py b/src/meetingtools/apps/room/admin.py
deleted file mode 100644
index 13d80a8..0000000
--- a/src/meetingtools/apps/room/admin.py
+++ /dev/null
@@ -1,10 +0,0 @@
-'''
-Created on Jan 31, 2011
-
-@author: leifj
-'''
-
-from django.contrib import admin
-from meetingtools.apps.room.models import Room
-
-admin.site.register(Room)
\ No newline at end of file
diff --git a/src/meetingtools/apps/room/feeds.py b/src/meetingtools/apps/room/feeds.py
deleted file mode 100644
index a72caaa..0000000
--- a/src/meetingtools/apps/room/feeds.py
+++ /dev/null
@@ -1,118 +0,0 @@
-'''
-Created on May 13, 2011
-
-@author: leifj
-'''
-
-from django.contrib.syndication.views import Feed
-from meetingtools.apps.room.models import Room
-from tagging.models import TaggedItem
-from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed
-from meetingtools.apps.room.views import room_recordings
-from django.shortcuts import get_object_or_404
-
-class TagsWrapper(object):
-    
-    def __init__(self,tn):
-        self.tags = tn.split('+')
-        self.rooms = TaggedItem.objects.get_by_model(Room, tn.split('+'))
-        
-    def title(self):
-        return "Rooms tagged with %s" % " and ".join(self.tags)
-
-    def description(self):
-        return self.title()
-    
-    def link(self,ext):
-        return "/room/+%s.%s" % ("+".join(self.tags),ext)
-
-class MeetingToolsFeed(Feed):
-    
-    item_author_name = 'SUNET e-meeting tools'
-    
-    def ext(self):
-        if self.feed_type == Atom1Feed:
-            return "atom"
-        
-        if self.feed_type == Rss201rev2Feed:
-            return "rss"
-        
-        return "rss"
-
-
-class RoomTagFeed(MeetingToolsFeed):
-    
-    def get_object(self,request,tn):
-        return TagsWrapper(tn)
-    
-    def title(self,t):
-        return t.title()
-    
-    def link(self,t):
-        return t.link(self.ext())
-    
-    def description(self,t):
-        return t.description()
-    
-    def items(self,t):
-        return t.rooms
-    
-    def item_title(self,room):
-        return room.name
-    
-    def item_description(self,room):
-        return room.description
-    
-    def item_link(self,room):
-        return room.go_url()
-    
-    def item_guid(self,room):
-        return room.permalink()
-    
-    def item_pubdate(self,room):
-        return room.lastupdated
-    
-    
-class RoomAtomTagFeed(RoomTagFeed):
-    feed_type = Atom1Feed
-    
-class RoomRSSTagField(RoomTagFeed):
-    feed_type = Rss201rev2Feed
-    
-class RecordingsWrapper(object):
-    def __init__(self,room,request):
-        self.room = room
-        self.items = room_recordings(request, room)
-    
-class RecordingFeed(MeetingToolsFeed):
-    
-    def get_object(self,request,rid):
-        room = get_object_or_404(Room,pk=rid)
-        return RecordingsWrapper(room,request)
-    
-    def title(self,recordings):
-        return "Recordings in room '%s'" % recordings.room.name
-    
-    def link(self,recordings):
-        return recordings.room.recordings_url()
-    
-    def items(self,recordings):
-        return recordings.items
-    
-    def item_title(self,recording):
-        return recording['name']
-    
-    def item_description(self,recording):
-        return recording['description']
-    
-    def item_link(self,recording):
-        return recording['url']
-    
-    def item_pubdate(self,recording):
-        return recording['date_created']
-    
-class AtomRecordingFeed(RecordingFeed):
-    feed_type = Atom1Feed
-    
-class RSSRecordingField(RecordingFeed):
-    feed_type = Rss201rev2Feed
\ No newline at end of file
diff --git a/src/meetingtools/apps/room/forms.py b/src/meetingtools/apps/room/forms.py
deleted file mode 100644
index 62b515b..0000000
--- a/src/meetingtools/apps/room/forms.py
+++ /dev/null
@@ -1,82 +0,0 @@
-'''
-Created on Feb 1, 2011
-
-@author: leifj
-'''
-
-from meetingtools.apps.room.models import Room
-from django.forms.widgets import Select, TextInput, RadioSelect, Textarea
-from django.forms.fields import BooleanField, ChoiceField, CharField
-from django.forms.forms import Form
-from form_utils.forms import BetterModelForm
-from django.utils.safestring import mark_safe
-from django.forms.models import ModelForm
-        
-PUBLIC = 0
-PROTECTED = 1
-PRIVATE = 2
-        
-class PrefixTextInput(TextInput):
-    def __init__(self, attrs=None, prefix=None):
-        super(PrefixTextInput, self).__init__(attrs)
-        self.prefix = prefix
-
-    def render(self, name, value, attrs=None):
-        return mark_safe("<div class=\"input-prepend\"><span class=\"add-on\">"+self.prefix+"</span>"+
-                         super(PrefixTextInput, self).render(name, value, attrs)+"</span></div>")
-        
-class ModifyRoomForm(ModelForm):
-    class Meta:
-        model = Room
-        fields = ['name','description','source_sco_id','self_cleaning','allow_host']
-        widgets = {'source_sco_id': Select(),
-                   'description': Textarea(attrs={'rows': 4, 'cols': 50}),
-                   'name': TextInput(attrs={'size': '40'})}
-
-
-class CreateRoomForm(BetterModelForm):
-
-    access = ChoiceField(choices=(('public','Public'),('private','Private')))
-    
-    class Meta:
-        model = Room
-        fields = ['name','description','urlpath','access','self_cleaning','allow_host']
-        fieldsets = [('name',{'fields': ['name'],
-                              'classes': ['step'],
-                              'legend': 'Step 1: Room name',
-                              'description': 'The room name should be short and descriptive.'
-                              }),
-                     ('description',{'fields': ['description'],
-                                  'classes': ['step'],
-                                  'legend': 'Step 2: Room description',
-                                  'description': 'Please provide a short summary of this room.'
-                                  }),
-                     ('properties',{'fields': ['self_cleaning','allow_host','urlpath','access'],
-                                    'classes': ['step'],
-                                    'legend': 'Step 3: Room properties',
-                                    'description': '''
-                                    <p>These are basic properties for your room. If you set your room to cleaned up after 
-                                    use it will be reset every time the last participant leaves the room. If you create a public room it 
-                                    will be open to anyone who has the room URL. If you create a private room then guests will have to be 
-                                    approved by an active meeting host before being able to join the room.</p>
-                                    
-                                    <div class="ui-widget">
-                                        <div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;"> 
-                                            <p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
-                                            <strong>Warning</strong> Setting a room to be cleaned up when empty will cause all existing content 
-                                            associated with the to be destroyed each time the room is reset.</p>
-                                        </div>
-                                    </div>
-                                    '''
-                                    }),               
-                    ]
-        widgets = {'access': RadioSelect(),
-                   'urlpath': PrefixTextInput(attrs={'size': '10'}),
-                   'description': Textarea(attrs={'rows': 4, 'cols': 50}),
-                   'name': TextInput(attrs={'size': '40'})}
-        
-class DeleteRoomForm(Form):
-    confirm = BooleanField(label="Confirm remove room")
-    
-class TagRoomForm(Form):
-    tag = CharField(max_length=256)
\ No newline at end of file
diff --git a/src/meetingtools/apps/room/management/__init__.py b/src/meetingtools/apps/room/management/__init__.py
deleted file mode 100644
index 3929ed7..0000000
--- a/src/meetingtools/apps/room/management/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__author__ = 'leifj'
diff --git a/src/meetingtools/apps/room/management/commands/__init__.py b/src/meetingtools/apps/room/management/commands/__init__.py
deleted file mode 100644
index 3929ed7..0000000
--- a/src/meetingtools/apps/room/management/commands/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__author__ = 'leifj'
diff --git a/src/meetingtools/apps/room/management/commands/import_rooms.py b/src/meetingtools/apps/room/management/commands/import_rooms.py
deleted file mode 100644
index 7944be8..0000000
--- a/src/meetingtools/apps/room/management/commands/import_rooms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.core.management import BaseCommand
-from meetingtools.apps.cluster.models import ACCluster
-from meetingtools.apps.room.tasks import import_acc
-
-__author__ = 'leifj'
-
-class Command(BaseCommand):
-
-    def handle(self, *args, **options):
-        for acc in ACCluster.objects.all():
-            import_acc(acc,since=0)
\ No newline at end of file
diff --git a/src/meetingtools/apps/room/migrations/0001_initial.py b/src/meetingtools/apps/room/migrations/0001_initial.py
deleted file mode 100644
index 4cb1bef..0000000
--- a/src/meetingtools/apps/room/migrations/0001_initial.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# 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
deleted file mode 100644
index bea1f14..0000000
--- a/src/meetingtools/apps/room/migrations/0002_auto__add_field_room_deleted_sco_id.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# 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
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/room/models.py b/src/meetingtools/apps/room/models.py
deleted file mode 100644
index 2177b24..0000000
--- a/src/meetingtools/apps/room/models.py
+++ /dev/null
@@ -1,142 +0,0 @@
-'''
-Created on Jan 31, 2011
-
-@author: leifj
-'''
-
-from django.db import models
-from django.db.models.fields import CharField, BooleanField, IntegerField,\
-    TextField
-from django.db.models.fields.related import ForeignKey
-from django.contrib.auth.models import User
-from meetingtools.apps.cluster.models import ACCluster
-import time
-import tagging
-from meetingtools.settings import LOCK_DIR
-from django.db.models.signals import post_save
-from tagging.models import Tag
-import os
-
-class FileLock(object):
-    
-    def __init__(self,obj):
-        self.obj = obj
-    
-    def __get__(self):
-        return os.access(LOCK_DIR+os.sep+self.obj.__class__+"_"+self.obj.id+".lock",os.F_OK)
-    def __set__(self,value):
-        if not isinstance(value,bool):
-            raise AttributeError
-        if value:
-            f = open(LOCK_DIR+os.sep+self.obj.__class__+"_"+self.obj.id+".lock")
-            f.close()
-        else:
-            os.remove(LOCK_DIR+os.sep+self.obj.__class__+"_"+self.obj.id+".lock")
-    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) 
-    urlpath = CharField(verbose_name="Custom URL",max_length=128,unique=True)
-    acc =  ForeignKey(ACCluster,verbose_name="Adobe Connect Cluster",editable=False)
-    self_cleaning = BooleanField(verbose_name="Clean-up when empty?")
-    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)
-    host_count = IntegerField(verbose_name="Host Count At Last Visit",editable=False,blank=True,null=True)
-    timecreated = models.DateTimeField(auto_now_add=True)
-    lastupdated = models.DateTimeField(auto_now=True)
-    lastvisited = models.DateTimeField(blank=True,null=True)
-    
-    class Meta:
-        unique_together = (('acc','sco_id'),('name','folder_sco_id'))
-    
-    def __unicode__(self):
-        return "%s (sco_id=%s,source_sco_id=%s,folder_sco_id=%s,urlpath=%s)" % (self.name,self.sco_id,self.source_sco_id,self.folder_sco_id,self.urlpath)
-    
-    def _lockf(self):
-        return "%s%sroom-%d.lock" % (LOCK_DIR,os.sep,+self.id)
-    
-    def lock(self,msg=None):
-        f = open(self._lockf(),'w')
-        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())
-        
-    def is_locked(self):
-        os.access(self._lockf(),os.F_OK)
-    
-    def lastvisit(self):
-        if not self.lastvisited:
-            return 0
-        else:
-            return int(time.mktime(self.lastvisited.timetuple())*1000)
-        
-    def lastupdate(self):
-        if not self.lastupdated:
-            return 0
-        else:
-            return int(time.mktime(self.lastupdated.timetuple()))
-        
-    def go_url(self):
-        return "/go/%s" % self.urlpath
-        
-    def go_url_internal(self):
-        return "/go/%d" % self.id
-    
-    def permalink(self):
-        return "/room/%d" % self.id
-    
-    def recordings_url(self):
-        return "/room/%d/recordings" % self.id
-        
-    def nusers(self):
-        if self.user_count == None:
-            return "unknown many"
-        else:
-            return self.user_count
-        
-    def nhosts(self):
-        if self.host_count == None:
-            return "unknown many"
-        else:
-            return self.host_count
-        
-tagging.register(Room)
-
-def _magic_tags(sender,**kwargs):
-    room = kwargs['instance']
-    if room.self_cleaning:
-        Tag.objects.add_tag(room, "cleaning")
-    else:
-        tags = Tag.objects.get_for_object(room)
-        ntags = []
-        for tag in tags:
-            if tag.name != "cleaning":
-                ntags.append(tag.name)
-        Tag.objects.update_tags(room, " ".join(ntags))
-    
-post_save.connect(_magic_tags,sender=Room)
\ No newline at end of file
diff --git a/src/meetingtools/apps/room/tasks.py b/src/meetingtools/apps/room/tasks.py
deleted file mode 100644
index ce9f275..0000000
--- a/src/meetingtools/apps/room/tasks.py
+++ /dev/null
@@ -1,250 +0,0 @@
-'''
-Created on Jan 18, 2012
-
-@author: leifj
-'''
-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
-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
-from django.db.models import Q
-from django.contrib.humanize.templatetags import humanize
-from django.conf import settings
-from django.core.mail import send_mail
-
-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 is not 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 is not 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("found room owned by %s time for and update" % username)
-        if username is None:
-            return
-
-        logging.debug(etree.tostring(row))
-        logging.debug(etree.tostring(r))
-        urlpath = row.findtext("url[0]").strip("/")
-        name = row.findtext('name[0]')
-        description = row.findtext('description[0]')
-        folder_sco_id = 0
-        source_sco_id = 0
-
-        def _ior0(elt,a,dflt):
-            str = elt.get(a,None)
-            if str is None or not str:
-                return dflt
-            else:
-                return int(str)
-
-
-        for elt in r.findall(".//sco[0]"):
-            folder_sco_id = _ior0(elt,'folder-id',0)
-            source_sco_id = _ior0(elt,'source-sco-id',0)
-
-        logging.debug("urlpath=%s, name=%s, folder_sco_id=%s, source_sco_id=%s" % (urlpath,name,folder_sco_id,source_sco_id))
-
-        if room is None:
-            if folder_sco_id:
-                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:
-            if folder_sco_id:
-                room.folder_sco_id = folder_sco_id
-            room.source_sco_id = source_sco_id
-            room.description = description
-            room.urlpath = urlpath
-
-        if room is not None:
-            room.save()
-            room.unlock()
-    else:
-        if room is not None:
-            room.unlock()
-    
-def import_acc(acc,since=0):
-    with ac_api_client(acc) as api:
-        r = None
-        if since > 0:
-            then = datetime.now()-timedelta(seconds=since)
-            then = then.replace(microsecond=0)
-            r = api.request('report-bulk-objects',{'filter-type': 'meeting','filter-gt-date-modified': then.isoformat()})
-        else:
-            r = api.request('report-bulk-objects',{'filter-type': 'meeting'})
-
-        for row in r.et.xpath("//row"):
-            try:
-                _import_one_room(acc,api,row)
-            except Exception,ex:
-                logging.error(ex)
-
-@periodic_task(run_every=crontab(hour="*", minute="*", day_of_week="*"))
-def import_all_rooms():
-    for acc in ACCluster.objects.all():
-        import_acc(acc,since=3600)
-  
-def start_user_counts_poll(room,niter):
-    poll_user_counts.apply_async(args=[room],kwargs={'niter': niter})
-  
-@task(name='meetingtools.apps.room.tasks.poll_user_counts',rate_limit="10/s")
-def poll_user_counts(room,niter=0):
-    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():
-        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)
-        
-# look for sessions that are newer than the one we know about for a room
-@periodic_task(run_every=crontab(hour="*", minute="*", day_of_week="*"))
-def import_sessions():
-    for room in Room.objects.all():
-        with ac_api_client(room.acc) as api:
-            p = {'sco-id': room.sco_id,'sort-date-created': 'asc'}
-            if room.lastvisited != None:
-                last = room.lastvisited
-                last.replace(microsecond=0)
-                p['filter-gt-date-created'] = last.isoformat()
-            r = api.request('report-meeting-sessions',p)
-            for row in r.et.xpath("//row"):
-                date_created = iso8601.parse_date(row.findtext("date-created"))
-                logging.debug("sco_id=%d lastvisited: %s" % (room.sco_id,date_created))
-                room.lastvisited = date_created
-                room.save()
-                break
-
-#@periodic_task(run_every=crontab(hour="*", minutes="*/5", day_of_week="*"))
-def import_transactions():
-    for acc in ACCluster.objects.all():
-        then = datetime.now() - timedelta(seconds=600)
-        then = then.replace(microsecond=0)
-        with ac_api_client(acc) as api:
-            seen = {}
-            r  = api.request('report-bulk-consolidated-transactions',{'filter-type':'meeting','sort-date-created': 'asc','filter-gt-date-created': then.isformat()})
-            for row in r.et.xpath("//row"):
-                sco_id = row.get('sco-id')
-                logging.debug("last session for sco_id=%d" % sco_id)
-                if not seen.get(sco_id,False): #pick the first session for each room - ie the one last created
-                    seen[sco_id] = True
-                    try:
-                        room = Room.objects.get(acc=acc,sco_id=sco_id)
-                        date_created = iso8601.parse_date(row.findtext("date-created"))
-                        room.lastvisited = date_created
-                        room.save()
-                    except ObjectDoesNotExist:
-                        pass # we only care about rooms we know about here
-                
-@task(name="meetingtools.apps.room.tasks.mail")
-def send_message(user,subject,message):
-    try:
-        p = user.get_profile()
-        if p and p.email:
-            send_mail(subject,message,settings.NOREPLY,[p.email])
-        else:
-            logging.info("User %s has no email address - email not sent" % user.username)
-    except ObjectDoesNotExist:
-        logging.info("User %s has no profile - email not sent" % user.username)
-    except Exception,exc:
-        logging.error("Error while sending email: \n%s" % exc)
-        send_message.retry(exc=exc)
-                
-@periodic_task(run_every=crontab(hour="1", minute="5", day_of_week="*"))
-def clean_old_rooms():
-    for acc in ACCluster.objects.all():
-        then = datetime.now() - timedelta(days=30)
-        then = then.replace(microsecond=0)
-        with ac_api_client(acc) as api:
-            for room in Room.objects.filter(lastvisited__lt=then):
-                logging.debug("room %s was last used %s" % (room.name,humanize.naturalday(room.lastvisited)))
-                send_message.apply_async([room.creator,"You have an unused meetingroom at %s" % acc.name ,"Do you still need %s (%s)?" % (room.name,room.permalink())])
\ No newline at end of file
diff --git a/src/meetingtools/apps/room/views.py b/src/meetingtools/apps/room/views.py
deleted file mode 100644
index c46ab6e..0000000
--- a/src/meetingtools/apps/room/views.py
+++ /dev/null
@@ -1,548 +0,0 @@
-'''
-Created on Jan 31, 2011
-
-@author: leifj
-'''
-from meetingtools.apps.room.models import Room, ACCluster
-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
-import re
-from meetingtools.apps import room
-from django.contrib.auth.decorators import login_required
-import logging
-from pprint import pformat
-from meetingtools.utils import session, base_url
-import time
-from django.conf import settings
-from django.utils.datetime_safe import datetime
-from django.http import HttpResponseRedirect
-from django.core.exceptions import ObjectDoesNotExist
-from django_co_acls.models import allow, deny, acl, clear_acl
-from meetingtools.ac.api import ACPClient
-from tagging.models import Tag, TaggedItem
-import random, string
-from django.utils.feedgenerator import rfc3339_date
-from django.views.decorators.cache import never_cache
-from meetingtools.apps.cluster.models import acc_for_user
-from django.contrib.auth.models import User
-import iso8601
-from celery.execute import send_task
-from meetingtools.apps.room.tasks import start_user_counts_poll
-
-def _user_meeting_folder(request,acc):
-    if not session(request,'my_meetings_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'):
-        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:
-        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 = []
-    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
-
-def _find_current_session(session_info):
-    for r in session_info.et.xpath('//row'):
-        #logging.debug(pformat(etree.tostring(r)))
-        end = r.findtext('date-end')
-        if end is None:
-            return r
-    return None
-
-def _nusers(session_info):
-    cur = _find_current_session(session_info)
-    if cur is not None:
-        return cur.get('num-participants')
-    else:
-        return 0
-
-@login_required
-def view(request,id):
-    room = get_object_or_404(Room,pk=id)
-    return respond_to(request,
-                      {'text/html':'apps/room/list.html'},
-                      {'user':request.user,
-                       'rooms':[room],
-                       'title': room.name,
-                       'baseurl': base_url(request),
-                       'active': True,
-                       })
-
-def _init_update_form(request,form,acc,my_meetings_sco_id):
-    if form.fields.has_key('urlpath'):
-        url = base_url(request)
-        form.fields['urlpath'].widget.prefix = url
-    if form.fields.has_key('source_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):        
-    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')):
-        v = None
-        if hasattr(room,attr):
-            v = getattr(room,attr) 
-        logging.debug("%s,%s = %s" % (attr,param,v))
-        if form and form.cleaned_data.has_key(attr) and form.cleaned_data[attr]:
-            v = form.cleaned_data[attr]
-        
-        if v:
-            if isinstance(v,(str,unicode)):
-                params[param] = v
-            elif hasattr(v,'__getitem__'):
-                params[param] = v[0]
-            else:
-                params[param] = repr(v)
-        
-    logging.debug(pformat(params))
-    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')
-        
-        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
-def create(request):
-    acc = acc_for_user(request.user)
-    my_meetings_sco_id = _user_meeting_folder(request,acc)
-    template_sco_id = acc.default_template_sco_id
-    if not template_sco_id:
-        template_sco_id = DEFAULT_TEMPLATE_SCO
-    room = Room(creator=request.user,acc=acc,folder_sco_id=my_meetings_sco_id,source_sco_id=template_sco_id)
-    what = "Create"
-    title = "Create a new room"
-    
-    if request.method == 'POST':
-        form = CreateRoomForm(request.POST,instance=room)
-        _init_update_form(request, form, acc, room.folder_sco_id)
-        if form.is_valid():
-            _update_room(request, room, form)
-            room = form.save()
-            return redirect_to("/rooms#%d" % room.id)
-    else:
-        form = CreateRoomForm(instance=room)
-        _init_update_form(request, form, acc, room.folder_sco_id)
-        
-    return respond_to(request,{'text/html':'apps/room/create.html'},{'form':form,'formtitle': title,'cancelname':'Cancel','submitname':'%s Room' % what})
-
-@never_cache
-@login_required
-def update(request,id):
-    room = get_object_or_404(Room,pk=id)
-    acc = room.acc
-    what = "Update"
-    title = "Modify %s" % room.name
-    
-    if request.method == 'POST':
-        form = ModifyRoomForm(request.POST,instance=room)
-        _init_update_form(request, form, acc, room.folder_sco_id)
-        if form.is_valid():
-            _update_room(request, room, form)
-            room = form.save()
-            return redirect_to("/rooms#%d" % room.id)
-    else:
-        form = ModifyRoomForm(instance=room)
-        _init_update_form(request, form, acc, room.folder_sco_id)
-        
-    return respond_to(request,{'text/html':'apps/room/update.html'},{'form':form,'formtitle': title,'cancelname': 'Cancel','submitname':'%s Room' % what})
-
-def _import_room(request,acc,r):
-    modified = False
-    room = None
-    
-    if room and (abs(room.lastupdate() - time.time()) < settings.IMPORT_TTL):
-        return room
-    
-    if r.has_key('urlpath'):
-        r['urlpath'] = r['urlpath'].strip('/')
-    
-    try:
-        room = Room.objects.get(sco_id=r['sco_id'],acc=acc)
-        for key in ('sco_id','name','source_sco_id','urlpath','description','user_count','host_count'):
-            if r.has_key(key) and hasattr(room,key):
-                rv = getattr(room,key)
-                if rv != r[key] and r[key] != None and r[key]:
-                    setattr(room,key,r[key])
-                    modified = True
-        
-        if modified:
-            logging.debug("+++ saving room ... %s" % pformat(room))
-            room.save()
-        
-    except ObjectDoesNotExist:
-        if r['folder_sco_id']:
-            try:
-                room = Room.objects.create(sco_id=r['sco_id'],
-                                           source_sco_id=r['source_sco_id'],
-                                           acc=acc,
-                                           name=r['name'],
-                                           urlpath=r['urlpath'],
-                                           description=r['description'],
-                                           creator=request.user,
-                                           folder_sco_id=r['folder_sco_id'])
-            except Exception,e:
-                room = None
-                pass
-            
-    if not room:
-        return None
-            
-    logging.debug("+++ looking at user counts")
-    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
-
-@login_required
-def list_rooms(request,username=None):
-    user = request.user
-    if username:
-        try:
-            user = User.objects.get(username=username)
-        except ObjectDoesNotExist:
-            user = None
-            
-    rooms = []
-    if user:
-        rooms = Room.objects.filter(creator=user).order_by('name').all()
-    
-    return respond_to(request,
-                      {'text/html':'apps/room/list.html'},
-                      {'title':'Your Rooms','edit':True,'active':len(rooms) == 1,'rooms':rooms})
-
-@login_required
-def user_rooms(request,user=None):
-    if user is None:
-        user = request.user
-        
-    acc = acc_for_user(user)
-    my_meetings_sco_id = _user_meeting_folder(request,acc)
-    user_rooms = _user_rooms(request,acc,my_meetings_sco_id)
-    
-    ar = []
-    for r in user_rooms:
-        logging.debug(pformat(r))
-        ar.append(int(r['sco_id']))
-    
-    for r in Room.objects.filter(creator=user).all():
-        if (not r.sco_id in ar): # and (not r.self_cleaning): #XXX this logic isn't right!
-            for t in Tag.objects.get_for_object(r):
-                t.delete()
-            r.delete() 
-    
-    for r in user_rooms:
-        r['folder_sco_id'] = my_meetings_sco_id
-        room = _import_room(request,acc,r)
-        
-    rooms = Room.objects.filter(creator=user).order_by('name').all()
-    return respond_to(request,
-                      {'text/html':'apps/room/list.html'},
-                      {'title':'Your Rooms','edit':True,'active':len(rooms) == 1,'rooms':rooms})
-
-@login_required
-def unlock(request,id):
-    room = get_object_or_404(Room,pk=id)
-    room.unlock()
-    return redirect_to("/rooms#%d" % room.id)
-
-@login_required
-def delete(request,id):
-    room = get_object_or_404(Room,pk=id)
-    if request.method == 'POST':
-        form = DeleteRoomForm(request.POST)
-        if form.is_valid():
-            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()
-            
-            return redirect_to("/rooms")
-    else:
-        form = DeleteRoomForm()
-        
-    return respond_to(request,{'text/html':'edit.html'},{'form':form,'formtitle': 'Delete %s' % room.name,'cancelname':'Cancel','submitname':'Delete Room'})      
-
-def _clean(request,room):
-    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 occupation(request,rid):
-    room = get_object_or_404(Room,pk=rid)
-    with ac_api_client(room.acc) as api:
-        api.poll_user_counts(room)
-        d = {'nusers': room.user_count, 'nhosts': room.host_count} 
-        return respond_to(request,
-                          {'text/html': 'apps/room/fragments/occupation.txt',
-                           'application/json': json_response(d, request)},
-                          d)
-
-def go_by_id(request,id):
-    room = get_object_or_404(Room,pk=id)
-    return goto(request,room)
-
-def go_by_path(request,path):
-    room = get_object_or_404(Room,urlpath=path)
-    return goto(request,room)
-        
-@login_required
-def promote_and_launch(request,rid):
-    room = get_object_or_404(Room,pk=rid)
-    return _goto(request,room,clean=False,promote=True)
-
-def launch(request,rid):
-    room = get_object_or_404(Room,pk=rid)
-    return _goto(request,room,clean=False)
-        
-def goto(request,room):
-    return _goto(request,room,clean=True)
-
-def _random_key(length=20):
-    rg = random.SystemRandom()
-    alphabet = string.letters + string.digits
-    return str().join(rg.choice(alphabet) for _ in range(length))
-
-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})
-    
-    now = time.time()
-    lastvisit = room.lastvisit()
-    room.lastvisited = datetime.now()
-    
-    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:
-            if (room.user_count == 0) and (abs(lastvisit - now) > settings.GRACE):
-                room.lock("Locked for cleaning")
-                try:
-                    room = _clean(request,room)
-                except Exception,e:
-                    room.unlock()
-                    raise e
-                room.unlock()
-                
-        if room.host_count == 0 and room.allow_host:
-            return respond_to(request, {"text/html": "apps/room/launch.html"}, {'room': room})
-    else:
-        room.save()
-    
-    key = None
-    if request.user.is_authenticated():
-        key = _random_key(20)
-        user_principal = api.find_user(request.user.username)
-        principal_id =  user_principal.get('principal-id')
-        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')
-    start_user_counts_poll(room,10)
-    if key:
-        try:
-            user_client = ACPClient(room.acc.api_url, request.user.username, key, cache=False)
-            return user_client.redirect_to(room.acc.url+urlpath)
-        except Exception,e:
-            pass
-    return HttpResponseRedirect(room.acc.url+urlpath)
-    
-## Tagging
-
-def _room2dict(room):
-    return {'name':room.name,
-            'description':room.description,
-            'user_count':room.nusers(),
-            'host_count':room.nhosts(),
-            'updated': rfc3339_date(room.lastupdated),
-            'self_cleaning': room.self_cleaning,
-            'url': room.go_url()}
-
-# should not require login
-def list_by_tag(request,tn):
-    tags = tn.split('+')
-    rooms = TaggedItem.objects.get_by_model(Room, tags).order_by('name').all()
-    title = 'Rooms tagged with %s' % " and ".join(tags)
-    return respond_to(request,
-                      {'text/html':'apps/room/list.html',
-                       'application/json': json_response([_room2dict(room) for room in rooms],request)},
-                      {'title':title,
-                       'description':title ,
-                       'edit':False,
-                       'active':len(rooms) == 1,
-                       'baseurl': base_url(request),
-                       'tagstring': tn,
-                       'rooms':rooms})
-
-# should not require login
-def list_and_import_by_tag(request,tn):
-    tags = tn.split('+')
-    rooms = TaggedItem.objects.get_by_model(Room, tags).order_by('name').all()
-    for room in rooms:
-        _import_room(request,room.acc,{'sco_id': room.sco_id})
-    title = 'Rooms tagged with %s' % " and ".join(tags)
-    return respond_to(request,
-                      {'text/html':'apps/room/list.html',
-                       'application/json': json_response([_room2dict(room) for room in rooms],request)},
-                      {'title':title,
-                       'description':title ,
-                       'edit':False,
-                       'active':len(rooms) == 1,
-                       'baseurl': base_url(request),
-                       'tagstring': tn,
-                       'rooms':rooms})
-    
-def widget(request,tags=None):
-    title = 'Meetingtools jQuery widget'
-    return respond_to(request,{'text/html':'apps/room/widget.html'},{'title': title,'tags':tags})
-    
-def _can_tag(request,tag):
-    if tag in ('selfcleaning','cleaning','public','private'):
-        return False,"'%s' is reserved" % tag
-    # XXX implement access model for tags here soon
-    return True,""
-
-@login_required
-def untag(request,rid,tag):
-    room = get_object_or_404(Room,pk=rid)
-    new_tags = []
-    for t in Tag.objects.get_for_object(room):
-        if t.name != tag:
-            new_tags.append(t.name)
-    
-    Tag.objects.update_tags(room, ' '.join(new_tags))
-    return redirect_to("/room/%d/tag" % room.id) 
-    
-@never_cache
-@login_required  
-def tag(request,rid):
-    room = get_object_or_404(Room,pk=rid)
-    if request.method == 'POST':
-        form = TagRoomForm(request.POST)
-        if form.is_valid():
-            for tag in re.split('[,\s]+',form.cleaned_data['tag']):
-                tag = tag.strip()
-                ok,reason = _can_tag(request,tag)
-                if ok:
-                    Tag.objects.add_tag(room, tag)
-                else:
-                    form._errors['tag'] = form.error_class([u'%s ... please choose another tag!' % reason])
-    else:
-        form = TagRoomForm()
-    
-    tags = Tag.objects.get_for_object(room)
-    tn = "+".join([t.name for t in tags])
-    return respond_to(request, 
-                      {'text/html': "apps/room/tag.html"}, 
-                      {'form': form,'formtitle': 'Add Tag','cancelname':'Done','submitname': 'Add Tag','room': room, 'tagstring': tn,'tags': tags})
-
-def room_recordings(request,room):
-    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):
-    room = get_object_or_404(Room,pk=rid)
-    return respond_to(request,
-                      {'text/html': 'apps/room/recordings.html'},
-                      {'recordings': room_recordings(request,room),'room':room})
\ No newline at end of file
diff --git a/src/meetingtools/apps/stats/__init__.py b/src/meetingtools/apps/stats/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/stats/forms.py b/src/meetingtools/apps/stats/forms.py
deleted file mode 100644
index d9cf555..0000000
--- a/src/meetingtools/apps/stats/forms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-'''
-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
deleted file mode 100644
index b028d18..0000000
--- a/src/meetingtools/apps/stats/views.py
+++ /dev/null
@@ -1,273 +0,0 @@
-'''
-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
-from django.shortcuts import get_object_or_404
-from meetingtools.apps.room.models import Room
-import logging
-
-def _iso2datesimple(iso):
-    (date,rest) = iso.split("T")
-    return date
-
-def _iso2ts(iso):
-    return mktime(iso8601.parse_date(iso).timetuple())*1000
-
-def _iso2dt(iso):
-    return iso8601.parse_date(iso);
-
-def _date_ts(date):
-    (y,m,d) = date.split("-")
-    return int(mktime((int(y),int(m),int(d),0,0,0,0,0,-1)))*1000 # midnight
-
-@login_required
-def user(request,username=None):
-    if username == None:
-        username = request.user.username
-    (local,domain) = username.split('@')
-    return respond_to(request,{'text/html': 'apps/stats/user.html'},{'domain': domain,'username': username})
-
-@login_required
-def domain(request,domain):
-    (l,d) = request.user.username.split('@')
-    if d != domain:
-        return HttpResponseForbidden("You can only look at statistics for your own domain!")
-    
-    return respond_to(request,{'text/html': 'apps/stats/domain.html'},{'domain': domain})
-
-@login_required
-def room(request,rid):
-    room = get_object_or_404(Room,pk=rid)
-    if not room.creator == request.user:
-        return HttpResponseForbidden("You can only look at statistics for your own rooms!")
-    
-    return respond_to(request,{'text/html': 'apps/stats/room.html'},{'room': room})
-
-@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
-    
-    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}
-        
-        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
-                
-            #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)])
-        
-        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):
-    with ac_api_client(request) as api:
-        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
-            
-            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)
-            
-            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()), 'users': len(uc.keys()), 'minutes': int(t_ms/60000)},request)
-
-
-@login_required
-def room_minutes_api(request,rid):
-    room = get_object_or_404(Room,pk=rid)
-    if not room.creator == request.user:
-        return HttpResponseForbidden("You can only look at statistics for your own rooms!")
-    
-    with ac_api_client(request) as api:
-        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)
-            
-            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]), 'users': len(uc.keys()), 'minutes': int(t_ms/60000)},request)
\ No newline at end of file
diff --git a/src/meetingtools/apps/userprofile/__init__.py b/src/meetingtools/apps/userprofile/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/apps/userprofile/admin.py b/src/meetingtools/apps/userprofile/admin.py
deleted file mode 100644
index 21ca598..0000000
--- a/src/meetingtools/apps/userprofile/admin.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from django.contrib import admin
-from meetingtools.apps.userprofile.models import UserProfile
-
-admin.site.register(UserProfile)
\ No newline at end of file
diff --git a/src/meetingtools/apps/userprofile/models.py b/src/meetingtools/apps/userprofile/models.py
deleted file mode 100644
index b0bc7ae..0000000
--- a/src/meetingtools/apps/userprofile/models.py
+++ /dev/null
@@ -1,21 +0,0 @@
-'''
-Created on Jul 5, 2010
-
-@author: leifj
-'''
-from django.db import models
-from django.contrib.auth.models import User
-
-class UserProfile(models.Model):
-    user = models.ForeignKey(User,blank=True,related_name='profile')
-    display_name = models.CharField(max_length=255,blank=True)
-    email = models.EmailField(blank=True)
-    idp = models.CharField(max_length=255)
-    timecreated = models.DateTimeField(auto_now_add=True)
-    lastupdated = models.DateTimeField(auto_now=True)
-    
-    def __unicode__(self):
-        return "%s - %s" % (self.user.username,self.display_name)
-
-def profile(user):
-    return UserProfile.objects.get(user=user)
diff --git a/src/meetingtools/context_processors.py b/src/meetingtools/context_processors.py
deleted file mode 100644
index 5bd5885..0000000
--- a/src/meetingtools/context_processors.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from django.core.exceptions import ImproperlyConfigured
-
-__author__ = 'leifj'
-
-from django.conf import settings
-import logging
-
-def theme(request):
-
-    def _w(x):
-        return {'theme': x}
-
-    vhost = request.get_host()
-    vhost = vhost.replace(':','_')
-
-    ctx = {'vhost': vhost}
-    if hasattr(settings,'THEMES'):
-        if settings.THEMES.has_key(vhost):
-            ctx.update(settings.THEMES[vhost])
-        elif settings.THEMES.has_key('__default__'):
-            ctx.update(settings.THEMES['__default__'])
-
-    return _w(ctx)
diff --git a/src/meetingtools/django-crossdomainxhr-middleware.py b/src/meetingtools/django-crossdomainxhr-middleware.py
deleted file mode 100644
index 786b72a..0000000
--- a/src/meetingtools/django-crossdomainxhr-middleware.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import re
-
-from django.utils.text import compress_string
-from django.utils.cache import patch_vary_headers
-
-from django import http
-
-try:
-    import settings 
-    XS_SHARING_ALLOWED_ORIGINS = settings.XS_SHARING_ALLOWED_ORIGINS
-    XS_SHARING_ALLOWED_METHODS = settings.XS_SHARING_ALLOWED_METHODS
-except:
-    XS_SHARING_ALLOWED_ORIGINS = '*'
-    XS_SHARING_ALLOWED_METHODS = ['POST','GET','OPTIONS', 'PUT', 'DELETE']
-
-
-class XsSharing(object):
-    """
-        This middleware allows cross-domain XHR using the html5 postMessage API.
-         
-
-        Access-Control-Allow-Origin: http://foo.example
-        Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
-    """
-    def process_request(self, request):
-
-        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
-            response = http.HttpResponse()
-            response['Access-Control-Allow-Origin']  = XS_SHARING_ALLOWED_ORIGINS 
-            response['Access-Control-Allow-Methods'] = ",".join( XS_SHARING_ALLOWED_METHODS ) 
-            response['P3P'] = "CP=IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
-            return response
-
-        return None
-
-    def process_response(self, request, response):
-        # Avoid unnecessary work
-        if response.has_header('Access-Control-Allow-Origin'):
-            return response
-
-        response['Access-Control-Allow-Origin']  = XS_SHARING_ALLOWED_ORIGINS 
-        response['Access-Control-Allow-Methods'] = ",".join( XS_SHARING_ALLOWED_METHODS )
-        response['P3P'] = "CP=IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
-        return response
\ No newline at end of file
diff --git a/src/meetingtools/extensions/__init__.py b/src/meetingtools/extensions/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/extensions/templatetags/__init__.py b/src/meetingtools/extensions/templatetags/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/meetingtools/extensions/templatetags/datehumanize.py b/src/meetingtools/extensions/templatetags/datehumanize.py
deleted file mode 100644
index 9b75cae..0000000
--- a/src/meetingtools/extensions/templatetags/datehumanize.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from django import template
-from django.template import defaultfilters
- 
-register = template.Library()
- 
-MOMENT = 120    # duration in seconds within which the time difference 
-                # will be rendered as 'a moment ago'
- 
-def datehumanize(value):
-    """
-    Finds the difference between the datetime value given and now()
-    and returns appropriate humanize form
-    """
- 
-    from datetime import datetime
- 
-    if isinstance(value, datetime):
-        value = value.replace(tzinfo=None)
-        delta = datetime.now() - value
-        if delta.days > 6:
-            return value.strftime("on %b %d")                    # May 15
-        if delta.days > 1:
-            return value.strftime("on %A")                       # Wednesday
-        elif delta.days == 1:
-            return 'yesterday'                                # yesterday
-        elif delta.seconds > 3600:
-            return str(delta.seconds / 3600 ) + ' hours ago'  # 3 hours ago
-        elif delta.seconds >  MOMENT:
-            return str(delta.seconds/60) + ' minutes ago'     # 29 minutes ago
-        else:
-            return 'a moment ago'                             # a moment ago
-        return defaultfilters.date(value)
-    else:
-        return str(value)
-datehumanize.is_safe = True
-register.filter(datehumanize)
\ No newline at end of file
diff --git a/src/meetingtools/extensions/templatetags/roomurl.py b/src/meetingtools/extensions/templatetags/roomurl.py
deleted file mode 100644
index e5abe57..0000000
--- a/src/meetingtools/extensions/templatetags/roomurl.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from django import template
- 
-register = template.Library()
- 
-MOMENT = 120    # duration in seconds within which the time difference 
-                # will be rendered as 'a moment ago'
- 
-def roomurl(room):
-    """
-    Display the public 'go' URL of a meetingroom
-    """
-    path = room.id
-    if room.urlpath:
-        path = room.urlpath
-    
-    return "/go/%s" % path
-    
-roomurl.is_safe = True
-register.filter(roomurl)
\ No newline at end of file
diff --git a/src/meetingtools/manage.py b/src/meetingtools/manage.py
deleted file mode 100644
index 5e78ea9..0000000
--- a/src/meetingtools/manage.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python
-from django.core.management import execute_manager
-try:
-    import settings # Assumed to be in the same directory.
-except ImportError:
-    import sys
-    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
-    sys.exit(1)
-
-if __name__ == "__main__":
-    execute_manager(settings)
diff --git a/src/meetingtools/mimeparse.py b/src/meetingtools/mimeparse.py
deleted file mode 100644
index 0fd91e7..0000000
--- a/src/meetingtools/mimeparse.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""MIME-Type Parser
-
-This module provides basic functions for handling mime-types. It can handle
-matching mime-types against a list of media-ranges. See section 14.1 of 
-the HTTP specification [RFC 2616] for a complete explanation.
-
-   http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
-
-Contents:
-    - parse_mime_type():   Parses a mime-type into its component parts.
-    - parse_media_range(): Media-ranges are mime-types with wild-cards and a 'q' quality parameter.
-    - quality():           Determines the quality ('q') of a mime-type when compared against a list of media-ranges.
-    - quality_parsed():    Just like quality() except the second parameter must be pre-parsed.
-    - best_match():        Choose the mime-type with the highest quality ('q') from a list of candidates. 
-"""
-
-__version__ = "0.1.2"
-__author__ = 'Joe Gregorio'
-__email__ = "joe@bitworking.org"
-__credits__ = ""
-
-def parse_mime_type(mime_type):
-    """Carves up a mime-type and returns a tuple of the
-       (type, subtype, params) where 'params' is a dictionary
-       of all the parameters for the media range.
-       For example, the media range 'application/xhtml;q=0.5' would
-       get parsed into:
-
-       ('application', 'xhtml', {'q', '0.5'})
-       """
-    parts = mime_type.split(";")
-    params = dict([tuple([s.strip() for s in param.split("=")])\
-            for param in parts[1:] ])
-    full_type = parts[0].strip()
-    # Java URLConnection class sends an Accept header that includes a single "*"
-    # Turn it into a legal wildcard.
-    if full_type == '*': full_type = '*/*'
-    (type, subtype) = full_type.split("/")
-    return (type.strip(), subtype.strip(), params)
-
-def parse_media_range(range):
-    """Carves up a media range and returns a tuple of the
-       (type, subtype, params) where 'params' is a dictionary
-       of all the parameters for the media range.
-       For example, the media range 'application/*;q=0.5' would
-       get parsed into:
-
-       ('application', '*', {'q', '0.5'})
-
-       In addition this function also guarantees that there 
-       is a value for 'q' in the params dictionary, filling it
-       in with a proper default if necessary.
-       """
-    (type, subtype, params) = parse_mime_type(range)
-    if not params.has_key('q') or not params['q'] or \
-            not float(params['q']) or float(params['q']) > 1\
-            or float(params['q']) < 0:
-        params['q'] = '1'
-    return (type, subtype, params)
-
-def fitness_and_quality_parsed(mime_type, parsed_ranges):
-    """Find the best match for a given mime-type against 
-       a list of media_ranges that have already been 
-       parsed by parse_media_range(). Returns a tuple of
-       the fitness value and the value of the 'q' quality
-       parameter of the best match, or (-1, 0) if no match
-       was found. Just as for quality_parsed(), 'parsed_ranges'
-       must be a list of parsed media ranges. """
-    best_fitness = -1 
-    best_fit_q = 0
-    (target_type, target_subtype, target_params) =\
-            parse_media_range(mime_type)
-    for (type, subtype, params) in parsed_ranges:
-        if (type == target_type or type == '*' or target_type == '*') and \
-                (subtype == target_subtype or subtype == '*' or target_subtype == '*'):
-            param_matches = reduce(lambda x, y: x+y, [1 for (key, value) in \
-                    target_params.iteritems() if key != 'q' and \
-                    params.has_key(key) and value == params[key]], 0)
-            fitness = (type == target_type) and 100 or 0
-            fitness += (subtype == target_subtype) and 10 or 0
-            fitness += param_matches
-            if fitness > best_fitness:
-                best_fitness = fitness
-                best_fit_q = params['q']
-            
-    return best_fitness, float(best_fit_q)
-
-def quality_parsed(mime_type, parsed_ranges):
-    """Find the best match for a given mime-type against
-    a list of media_ranges that have already been
-    parsed by parse_media_range(). Returns the
-    'q' quality parameter of the best match, 0 if no
-    match was found. This function bahaves the same as quality()
-    except that 'parsed_ranges' must be a list of
-    parsed media ranges. """
-    return fitness_and_quality_parsed(mime_type, parsed_ranges)[1]
-
-def quality(mime_type, ranges):
-    """Returns the quality 'q' of a mime-type when compared
-    against the media-ranges in ranges. For example:
-
-    >>> quality('text/html','text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5')
-    0.7
-    
-    """ 
-    parsed_ranges = [parse_media_range(r) for r in ranges.split(",")]
-    return quality_parsed(mime_type, parsed_ranges)
-
-def best_match(supported, header):
-    """Takes a list of supported mime-types and finds the best
-    match for all the media-ranges listed in header. The value of
-    header must be a string that conforms to the format of the 
-    HTTP Accept: header. The value of 'supported' is a list of
-    mime-types.
-    
-    >>> best_match(['application/xbel+xml', 'text/xml'], 'text/*;q=0.5,*/*; q=0.1')
-    'text/xml'
-    """
-    parsed_header = [parse_media_range(r) for r in header.split(",")]
-    weighted_matches = [(fitness_and_quality_parsed(mime_type, parsed_header), mime_type)\
-            for mime_type in supported]
-    weighted_matches.sort()
-    return weighted_matches[-1][0][1] and weighted_matches[-1][1] or ''
diff --git a/src/meetingtools/multiresponse.py b/src/meetingtools/multiresponse.py
deleted file mode 100644
index f599323..0000000
--- a/src/meetingtools/multiresponse.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from meetingtools import context_processors
-import meetingtools.mimeparse as mimeparse
-import re
-import rfc822
-from django.conf import settings
-from django.shortcuts import render_to_response
-from django.http import HttpResponse, HttpResponseForbidden,\
-    HttpResponseRedirect
-from django.utils import simplejson
-from django.template import loader, RequestContext
-
-default_suffix_mapping = {"\.htm(l?)$": "text/html",
-                          "\.json$": "application/json",
-                          "\.rss$": "application/rss+xml",
-                          "\.atom$": "application/atom+xml",
-                          "\.torrent$": "application/x-bittorrent"}
-
-def _accept_types(request, suffix):
-    for r in suffix.keys():
-        p = re.compile(r)
-        if p.search(request.path):
-            return suffix.get(r)
-    return None
-
-
-def timeAsrfc822 ( theTime ) :
-    return rfc822 . formatdate ( rfc822 . mktime_tz ( rfc822 . parsedate_tz ( theTime . strftime ( "%a, %d %b %Y %H:%M:%S" ) ) ) )
-
-def make_response_dict(request,d={}):
- 
-    if request.user.is_authenticated():
-        d['user'] = request.user
-
-    ctx = RequestContext(request,d,[context_processors.theme])
-    print repr(ctx['theme'])
-    return ctx
-
-def json_response(data,request=None):
-    response_data = None
-    if request and request.GET.has_key('callback'):
-        callback = request.GET['callback']
-        json = simplejson.dumps(data)
-        response_data = "%s(%s)" % (callback, json)
-    else:
-        response_data = simplejson.dumps(data)
-    r = HttpResponse(response_data,content_type='application/json')
-    r['Cache-Control'] = 'no-cache, must-revalidate'
-    r['Pragma'] = 'no-cache'
-    
-    return r
-
-def render403(message="You don't seem to have enough rights for what you are trying to do....",dict={}):
-    dict['message'] = message
-    return HttpResponseForbidden(loader.render_to_string("403.html",dict))
-    
-def respond_to(request, template_mapping, dict={}, suffix_mapping=default_suffix_mapping):
-    accept = _accept_types(request, suffix_mapping)
-    if accept is None:
-        accept = (request.META['HTTP_ACCEPT'].split(','))[0]
-    content_type = mimeparse.best_match(template_mapping.keys(), accept)
-    template = None
-    if template_mapping.has_key(content_type):
-        template = template_mapping[content_type]
-    else:
-        template = template_mapping["text/html"]
-    if callable(template):
-        response = template(make_response_dict(request,dict))
-    elif isinstance(template, HttpResponse):
-        response = template
-        response['Content-Type'] = "%s; charset=%s" % (content_type, settings.DEFAULT_CHARSET)
-    else:
-        response = render_to_response(template,make_response_dict(request,dict))
-        response['Content-Type'] = "%s; charset=%s" % (content_type, settings.DEFAULT_CHARSET)
-    return response
-
-def redirect_to(path):
-    return HttpResponseRedirect(path)
\ No newline at end of file
diff --git a/src/meetingtools/settings.py b/src/meetingtools/settings.py
deleted file mode 100644
index 8e72dca..0000000
--- a/src/meetingtools/settings.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Django settings for meetingtools project.
-from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
-
-import meetingtools.site_logging
-import os
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-
-ADMINS = (
-    # ('Your Name', 'your_email@domain.com'),
-)
-
-SRC_DIR = os.path.dirname(os.path.abspath(__file__))
-BASE_DIR = os.path.abspath(os.path.join(SRC_DIR, '..'))
-
-MANAGERS = ADMINS
-
-LOCK_DIR = "/var/lock"
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': '%s/db/sqlite.db' % BASE_DIR,                      # Or path to database file if using sqlite3.
-        'USER': '',                      # Not used with sqlite3.
-        'PASSWORD': '',                  # Not used with sqlite3.
-        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
-        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
-    }
-}
-
-GRACE = 10
-IMPORT_TTL = 30
-DEFAULT_TEMPLATE_SCO=18807
-APPEND_SLASH = False
-
-# Local time zone for this installation. Choices can be found here:
-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
-# although not all choices may be available on all operating systems.
-# On Unix systems, a value of None will cause Django to use the same
-# timezone as the operating system.
-# If running in a Windows environment this must be set to the same as your
-# system time zone.
-TIME_ZONE = 'Europe/Stockholm'
-
-# Language code for this installation. All choices can be found here:
-# http://www.i18nguy.com/unicode/language-identifiers.html
-LANGUAGE_CODE = 'en-us'
-
-SITE_ID = 1
-
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
-USE_I18N = True
-
-# If you set this to False, Django will not format dates, numbers and
-# calendars according to the current locale
-USE_L10N = True
-
-STATIC_ROOT = "%s/static" % BASE_DIR
-STATIC_URL = "/static/"
-
-LOGIN_URL = "/accounts/login"
-LOGOUT_URL = "/accounts/logout"
-DEFAULT_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_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'
-    }
-}
-
-THEMES = {
-    '__default__': {'base': "%s/themes/default" % STATIC_URL },
-    'meetingtools.nordu.net': {'base': "%s/themes/meetingtools.nordu.net" % STATIC_URL}
-}
-
-# List of callables that know how to import templates from various sources.
-TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.Loader',
-    'django.template.loaders.app_directories.Loader',
-#     'django.template.loaders.eggs.Loader',
-)
-
-MIDDLEWARE_CLASSES = (
-    'django.middleware.common.CommonMiddleware',
-    'meetingtools.urlmiddleware.UrlMiddleware',
-    'meetingtools.django-crossdomainxhr-middleware.XsSharing',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.contrib.messages.middleware.MessageMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-    #'django.contrib.auth.middleware.RemoteUserMiddleware'
-)
-
-AUTHENTICATION_BACKENDS = (
-    'django.contrib.auth.backends.RemoteUserBackend',
-    'django.contrib.auth.backends.ModelBackend',
-)
-
-ROOT_URLCONF = 'meetingtools.urls'
-
-TEMPLATE_DIRS = (
-    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
-    # Always use forward slashes, even on Windows.
-    # Don't forget to use absolute paths, not relative paths.
-    "%s/templates" % BASE_DIR
-)
-
-INSTALLED_APPS = (
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    'django.contrib.admin',
-    'django.contrib.humanize',
-    'django_extensions',
-    'south',
-    'djcelery',
-    'ghettoq',
-    'djkombu',
-    'django_co_connector',
-    'django_co_acls',
-    'tagging',
-    'meetingtools.extensions',
-    'meetingtools.apps.auth',
-    'meetingtools.apps.room',
-    'meetingtools.apps.cluster',
-    'meetingtools.apps.userprofile',
-    'meetingtools.apps.stats'
-)
-
-CARROT_BACKEND = "django"
-
-import djcelery 
-djcelery.setup_loader()
-
-NOREPLY = "no-reply@sunet.se"
-AUTH_PROFILE_MODULE = "userprofile.UserProfile"
diff --git a/src/meetingtools/site_logging.py b/src/meetingtools/site_logging.py
deleted file mode 100644
index cdbe3c2..0000000
--- a/src/meetingtools/site_logging.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import logging
-import sys
-
-logger = logging.getLogger('')
-logger.setLevel(logging.DEBUG)
-handler = logging.StreamHandler(sys.stderr)
-handler.setLevel(logging.DEBUG)
-formatter = logging.Formatter('%(levelname)-8s %(message)s')
-handler.setFormatter(formatter)
-logger.addHandler(handler) 
diff --git a/src/meetingtools/urlmiddleware.py b/src/meetingtools/urlmiddleware.py
deleted file mode 100644
index 3d77caa..0000000
--- a/src/meetingtools/urlmiddleware.py
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-URL Middleware
-Stefano J. Attardi (attardi.org)
-
-$Id$
-$URL$
-
-Cleans up urls by adding/removing trailing slashes, adding/removing
-the www. prefix, and allowing the language to be set from the url.
-
-If APPEND_SLASH is set to False, trailing slashes are removed from the
-urls, except for urls which have an explicit trailing slash in
-urls.py, in which case a trailing slash is added.
-
-If REMOVE_WWW is set to True, the www. prefix is removed.
-
-Finally, ?lang=xx can be appended to any url to override the default
-language setting. This override is remembered for the following
-requests. For example, /article?lang=it would show the article in
-Italian regardless of brower settings or cookies, and any following
-request to the site would be shown in Italian by default.
-
-Changelog
-
-1.3.2
-Fixed an indentation issue. Added a check for those backends
-which set an empty path (e.g. runfcgi).
-
-1.3.1
-Added support for running in a test
-suite (doesn't assume that HTTP_HOST is set)
-
-1.3
-Only use sessions for the language preference if the session
-cookie has already been set (regardless of whether session middleware
-is active). Otherwise use the plain django_language cookie.
-Only import the FlatPages module if it is active.
-
-1.2
-Added support for FlatPages.
-Switched to Django's resolve function (with workaround for when it
-returns None).
-
-1.1
-Various bugfixes.
-
-1.0
-First release.
-"""
-__version__ = "1.3.2"
-__license__ = "Python"
-__copyright__ = "Copyright (C) 2006-2007, Stefano J. Attardi"
-__author__ = "Stefano J. Attardi <http://attardi.org/>"
-__contributors__ = ["Antonio Cavedoni <http://cavedoni.com/>"]
-
-from django.conf import settings
-from django.http import HttpResponseRedirect, Http404
-from django.core.urlresolvers import resolve
-from django.utils.translation import check_for_language
-import os
-
-class UrlMiddleware:
-
-    def process_request(self, request):
-
-        # Change the language setting for the current page
-        if "lang" in request.GET and check_for_language(request.GET["lang"]):
-            if hasattr(request, "session"):
-                request.session["django_language"] = request.GET["lang"]
-            else:
-                request.COOKIES["django_language"] = request.GET["lang"]
-
-        # work-around for runfcgi
-        if request.path == "": request.path = "/"
-        request.path = '/'+request.path.lstrip('/')
-
-        # Check for a redirect based on settings.APPEND_SLASH and settings.PREPEND_WWW
-        old_url = [request.META.get("HTTP_HOST", "localhost"), request.path]
-        new_url = old_url[:]
-
-        # if REMOVE_WWW is True, remove the www. from the urls if necessary
-        if hasattr(settings, "REMOVE_WWW") and settings.REMOVE_WWW and old_url[0].startswith("www."):
-            new_url[0] = old_url[0][4:]
-
-        if hasattr(settings, "APPEND_SLASH") and not settings.APPEND_SLASH:
-            # if the url is not found, try with(out) the trailing slash
-            if old_url[1] != "/" and not self._urlExists(old_url[1]):
-
-                if old_url[1][-1] == "/":
-                    other = old_url[1][:-1]
-                else:
-                    other = old_url[1] + "/"
-
-                if self._urlExists(other):
-                    new_url[1] = other
-
-        if new_url != old_url:
-            # Redirect
-            newurl = "%s://%s%s" % (os.environ.get("HTTPS") == "on" and "https" or "http", new_url[0], new_url[1])
-            if request.GET:
-                newurl += "?" + request.GET.urlencode()
-
-            return HttpResponseRedirect(newurl)
-
-        return None
-
-    def process_response(self, request, response):
-
-        # Change the language setting for future pages
-        if "lang" in request.GET and check_for_language(request.GET["lang"]):
-            if "sessionid" in request.COOKIES:
-                request.session["django_language"] = request.GET["lang"]
-            else:
-                response.set_cookie("django_language", request.GET["lang"])
-
-        return response
-
-    def _urlExists(self, path):
-        try:
-            if resolve(path) is None: raise Http404 # None?!? You mean 404...
-            return True
-        except Http404:
-            # check for flatpages
-            if "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware" in settings.MIDDLEWARE_CLASSES:
-                from django.contrib.flatpages.models import FlatPage
-                return FlatPage.objects.filter(url=path, sites__id=settings.SITE_ID).count() == 1
diff --git a/src/meetingtools/urls.py b/src/meetingtools/urls.py
deleted file mode 100644
index 1c42d08..0000000
--- a/src/meetingtools/urls.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from django.conf.urls.defaults import patterns,include
-
-# Uncomment the next two lines to enable the admin:
-from django.contrib import admin
-from meetingtools.settings import STATIC_ROOT
-from meetingtools.multiresponse import redirect_to
-from meetingtools.apps.room.feeds import RoomAtomTagFeed,RoomRSSTagField,\
-    AtomRecordingFeed, RSSRecordingField
-admin.autodiscover()
-
-def welcome(request):
-    return redirect_to('/rooms')
-
-urlpatterns = patterns('',
-    (r'^$',welcome),
-    (r'^admin/', include(admin.site.urls)),
-    (r'^static/(?P<path>.*)$','django.views.static.serve',{'document_root': STATIC_ROOT}),
-    # Login/Logout
-    (r'^accounts/login?$','meetingtools.apps.auth.views.login'),
-    (r'^accounts/login-federated$','meetingtools.apps.auth.views.accounts_login_federated'),
-    (r'^accounts/logout$','meetingtools.apps.auth.views.logout'),
-    (r'^user/?(.*)$','meetingtools.apps.room.views.list_rooms'),
-    (r'^(?:room|rooms)$','meetingtools.apps.room.views.list_rooms'),
-    (r'^go/(\d+)$','meetingtools.apps.room.views.go_by_id'),
-    (r'^go/(.+)$','meetingtools.apps.room.views.go_by_path'),
-    (r'^launch/(\d+)$','meetingtools.apps.room.views.launch'),
-    (r'^promote/(\d+)$','meetingtools.apps.room.views.promote_and_launch'),
-    (r'^room/create$','meetingtools.apps.room.views.create'),
-    (r'^room/(\d+)$','meetingtools.apps.room.views.view'),
-    (r'^room/(\d+)/modify$','meetingtools.apps.room.views.update'),
-    (r'^room/(\d+)/delete$','meetingtools.apps.room.views.delete'),
-    (r'^room/(\d+)/unlock$','meetingtools.apps.room.views.unlock'),
-    (r'^room/(\d+)/tag$','meetingtools.apps.room.views.tag'),
-    (r'^room/(\d+)/untag/(.+)$','meetingtools.apps.room.views.untag'),
-    (r'^room/(\d+)/recordings$','meetingtools.apps.room.views.recordings'),
-    (r'^room/\+(.+)\.(?:json|html|htm)$','meetingtools.apps.room.views.list_by_tag'),
-    (r'^room/\+(.+)\.(?:atom)$',RoomAtomTagFeed()),
-    (r'^room/\+(.+)\.(?:rss)$',RoomRSSTagField()),
-    (r'^room/(\d+)/recordings\.(?:atom)$',AtomRecordingFeed()),
-    (r'^room/(\d+)/recordings\.(?:rss)$',RSSRecordingField()),
-    (r'^room/\+(.+)$','meetingtools.apps.room.views.list_by_tag'),
-    (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'^api/stats/room/(\d+)$','meetingtools.apps.stats.views.room_minutes_api'),
-    (r'^api/room/(\d+)/occupation$','meetingtools.apps.room.views.occupation'),
-    (r'^stats$','meetingtools.apps.stats.views.user'),
-    (r'^stats/user/(.+)$','meetingtools.apps.stats.views.user'),
-    (r'^stats/domain/(.+)$','meetingtools.apps.stats.views.domain'),
-    (r'^stats/room/(\d+)$','meetingtools.apps.stats.views.room'),
-)
diff --git a/src/meetingtools/utils.py b/src/meetingtools/utils.py
deleted file mode 100644
index eee0d80..0000000
--- a/src/meetingtools/utils.py
+++ /dev/null
@@ -1,20 +0,0 @@
-'''
-Created on Feb 4, 2011
-
-@author: leifj
-'''
-
-def session(request,key=None,val=None):
-    if key:
-        if val:
-            request.session[key] = val
-            return val
-        else:
-            if not request.session.has_key(key):
-                request.session[key] = None
-            return request.session[key]
-    else:
-        return request.session
-
-def base_url(request):
-    return "%s://%s/" % ({True: 'https',False:'http'}[request.is_secure()],request.get_host())
\ No newline at end of file
-- 
cgit v1.1