From 1f67a01eb66c17f2e7a3fb55266c905000d55491 Mon Sep 17 00:00:00 2001
From: Thomas NOEL <tnoel@entrouvert.com>
Date: Thu, 12 Feb 2015 14:52:00 +0100
Subject: [PATCH] remove multitenant, now in hobo (#6491)

---
 entrouvert/djommon/multitenant/README              |  99 ------------
 entrouvert/djommon/multitenant/__init__.py         |   0
 .../djommon/multitenant/management/__init__.py     |   0
 .../multitenant/management/commands/__init__.py    | 171 --------------------
 .../management/commands/create_schemas.py          |  19 ---
 .../management/commands/create_tenant.py           |  36 -----
 .../management/commands/createsuperuser.py         |  11 --
 .../multitenant/management/commands/deploy.py      |  30 ----
 .../management/commands/legacy/__init__.py         |   0
 .../management/commands/legacy/migrate_schemas.py  |  91 -----------
 .../management/commands/list_tenants.py            |  14 --
 .../multitenant/management/commands/migrate.py     |  27 ----
 .../management/commands/migrate_schemas.py         |  68 --------
 .../management/commands/safemigrate_schemas.py     | 105 ------------
 .../management/commands/sync_schemas.py            |  87 ----------
 .../multitenant/management/commands/syncdb.py      |  26 ---
 .../management/commands/tenant_command.py          |  40 -----
 entrouvert/djommon/multitenant/middleware.py       | 180 ---------------------
 entrouvert/djommon/multitenant/models.py           |  11 --
 entrouvert/djommon/multitenant/storage.py          |  24 ---
 entrouvert/djommon/multitenant/template_loader.py  | 115 -------------
 entrouvert/djommon/multitenant/tests.py            | 128 ---------------
 entrouvert/djommon/multitenant/views.py            |   1 -
 23 files changed, 1283 deletions(-)
 delete mode 100644 entrouvert/djommon/multitenant/README
 delete mode 100644 entrouvert/djommon/multitenant/__init__.py
 delete mode 100644 entrouvert/djommon/multitenant/management/__init__.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/__init__.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/create_schemas.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/create_tenant.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/createsuperuser.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/deploy.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/legacy/__init__.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/legacy/migrate_schemas.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/list_tenants.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/migrate.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/migrate_schemas.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/safemigrate_schemas.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/sync_schemas.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/syncdb.py
 delete mode 100644 entrouvert/djommon/multitenant/management/commands/tenant_command.py
 delete mode 100644 entrouvert/djommon/multitenant/middleware.py
 delete mode 100644 entrouvert/djommon/multitenant/models.py
 delete mode 100644 entrouvert/djommon/multitenant/storage.py
 delete mode 100644 entrouvert/djommon/multitenant/template_loader.py
 delete mode 100644 entrouvert/djommon/multitenant/tests.py
 delete mode 100644 entrouvert/djommon/multitenant/views.py

diff --git a/entrouvert/djommon/multitenant/README b/entrouvert/djommon/multitenant/README
deleted file mode 100644
index fb2b176..0000000
--- a/entrouvert/djommon/multitenant/README
+++ /dev/null
@@ -1,99 +0,0 @@
-Multitenant
------------
-
-An application for making a Django application multitenant for Entr'ouvert
-customers.
-
-Based on https://django-tenant-schemas.readthedocs.org/
-
-It is developed, tested and supported on Django 1.7, but it should work with
-Django 1.6 + south.
-
-
-Install
--------
-
-See also : https://django-tenant-schemas.readthedocs.org/
-
-Set the tenant model:
-
-    TENANT_MODEL = 'multitenant.Tenant'
-
-Where are tenants:
-
-    TENANT_BASE = '/var/lib/<project>/tenants'
-
-Add the middlewares for multitenant, they must be first:
-
-    MIDDLEWARE_CLASSES = (
-        'entrouvert.djommon.multitenant.middleware.TenantMiddleware',
-        'entrouvert.djommon.multitenant.middleware.JSONSettingsMiddleware',
-        'entrouvert.djommon.multitenant.middleware.PythonSettingsMiddleware',
-    ) + MIDDLEWARE_CLASSES
-
-Define the shared applications:
-
-    SHARED_APPS = (
-        'tenant_schemas',
-        'entrouvert.djommon.multitenant',
-        # those are needed for the public apps to work
-        # add also any application needed by the public app
-        'django.contrib.auth',
-        'django.contrib.contenttypes',
-        'django.contrib.sessions',
-        'django.contrib.messages',
-        'django.contrib.staticfiles',
-    )
-
-    TENANT_APPS = INSTALLED_APPS
-
-    INSTALLED_APPS = ('entrouvert.djommon.multitenant',
-        'tenant_schemas') + INSTALLED_APPS
-
-    # or, with Django 1.6 or older:
-    # INSTALLED_APPS += ('tenant_schemas', 'entrouvert.djommon.multitenant')
-
-Use multitenant database engine:
-
-    DATABASES = {
-        'default': {
-            'ENGINE': 'tenant_schemas.postgresql_backend',
-            'NAME': '<db_name>',
-        },
-    }
-    DATABASE_ROUTERS = (
-        'tenant_schemas.routers.TenantSyncRouter',
-    )
-
-    # With Django 1.6 or older, use multitenant south adapter:
-    # SOUTH_DATABASE_ADAPTERS = {'default': 'south.db.postgresql_psycopg2'}
-
-Add the multitenant filesystem template loader and configure where the
-multitenant templates are located:
-
-    TEMPLATE_LOADERS = (
-        'entrouvert.djommon.multitenant.template_loader.FilesystemLoader',
-    ) + TEMPLATE_LOADERS
-    TENANT_TEMPLATE_DIRS = (TENANT_BASE,)
-
-    TEMPLATE_CONTEXT_PROCESSORS = (
-        'django.core.context_processors.request',
-    ) + TEMPLATE_CONTEXT_PROCESSORS
-
-
-Usage
------
-
-Create a tenant:
-   manage.py create_tenant www.example.net
-Migration of all tenants:
-   manage.py migrate_schemas
-Add a super user to tenant:
-   manage.py tenant_command createsuperuser --domain www.example.net
-
-Tenants are created in TENANT_BASE directory, for example :
-    /var/lib/project/tenants/www.example.net/
-               templates/  <-- override project templates
-               static/     <-- to be handled by HTTP server
-               media/
-Each tenant is a PostgreSQL schema, named www_example_net
diff --git a/entrouvert/djommon/multitenant/__init__.py b/entrouvert/djommon/multitenant/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/entrouvert/djommon/multitenant/management/__init__.py b/entrouvert/djommon/multitenant/management/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/entrouvert/djommon/multitenant/management/commands/__init__.py b/entrouvert/djommon/multitenant/management/commands/__init__.py
deleted file mode 100644
index 601f3fd..0000000
--- a/entrouvert/djommon/multitenant/management/commands/__init__.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-from optparse import make_option
-from django.conf import settings
-from django.core.management import call_command, get_commands, load_command_class
-from django.core.management.base import BaseCommand, CommandError
-from django.db import connection
-try:
-    from django.utils.six.moves import input
-except ImportError:
-    input = raw_input
-from tenant_schemas.utils import get_public_schema_name
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-
-
-class BaseTenantCommand(BaseCommand):
-    """
-    Generic command class useful for iterating any existing command
-    over all schemata. The actual command name is expected in the
-    class variable COMMAND_NAME of the subclass.
-    """
-    def __new__(cls, *args, **kwargs):
-        """
-        Sets option_list and help dynamically.
-        """
-        obj = super(BaseTenantCommand, cls).__new__(cls, *args, **kwargs)
-
-        app_name = get_commands()[obj.COMMAND_NAME]
-        if isinstance(app_name, BaseCommand):
-            # If the command is already loaded, use it directly.
-            cmdclass = app_name
-        else:
-            cmdclass = load_command_class(app_name, obj.COMMAND_NAME)
-
-        # inherit the options from the original command
-        obj.option_list = cmdclass.option_list
-        obj.option_list += (
-            make_option("-d", "--domain", dest="domain"),
-        )
-        obj.option_list += (
-            make_option("-p", "--skip-public", dest="skip_public", action="store_true", default=False),
-        )
-
-        # prepend the command's original help with the info about schemata iteration
-        obj.help = "Calls %s for all registered schemata. You can use regular %s options. "\
-                   "Original help for %s: %s" % (obj.COMMAND_NAME, obj.COMMAND_NAME, obj.COMMAND_NAME,
-                                                 getattr(cmdclass, 'help', 'none'))
-        return obj
-
-    def execute_command(self, tenant, command_name, *args, **options):
-        verbosity = int(options.get('verbosity'))
-
-        if verbosity >= 1:
-            print()
-            print(self.style.NOTICE("=== Switching to schema '") \
-                + self.style.SQL_TABLE(tenant.schema_name)\
-                + self.style.NOTICE("' then calling %s:" % command_name))
-
-        connection.set_tenant(tenant)
-
-        # call the original command with the args it knows
-        call_command(command_name, *args, **options)
-
-    def handle(self, *args, **options):
-        """
-        Iterates a command over all registered schemata.
-        """
-        if options['domain']:
-            # only run on a particular schema
-            connection.set_schema_to_public()
-            self.execute_command(TenantMiddleware.get_tenant_by_hostname(options['domain']), self.COMMAND_NAME, *args, **options)
-        else:
-            for tenant in TenantMiddleware.get_tenants():
-                if not(options['skip_public'] and tenant.schema_name == get_public_schema_name()):
-                    self.execute_command(tenant, self.COMMAND_NAME, *args, **options)
-
-
-class InteractiveTenantOption(object):
-    def __init__(self, *args, **kwargs):
-        super(InteractiveTenantOption, self).__init__(*args, **kwargs)
-        self.option_list += (
-            make_option("-d", "--domain", dest="domain", help="specify tenant domain"),
-        )
-
-    def get_tenant_from_options_or_interactive(self, **options):
-        all_tenants = list(TenantMiddleware.get_tenants())
-
-        if not all_tenants:
-            raise CommandError("""There are no tenants in the system.
-To learn how create a tenant, see:
-https://django-tenant-schemas.readthedocs.org/en/latest/use.html#creating-a-tenant""")
-
-        if options.get('domain'):
-            domain = options['domain']
-        else:
-            while True:
-                domain = input("Enter Tenant Domain ('?' to list): ")
-                if domain == '?':
-                    print('\n'.join(["%s (schema %s)" % (t.domain_url, t.schema_name) for t in all_tenants]))
-                else:
-                    break
-
-        if domain not in [t.domain_url for t in all_tenants]:
-            raise CommandError("Invalid tenant, '%s'" % (domain,))
-
-        return TenantMiddleware.get_tenant_by_hostname(domain)
-
-
-class TenantWrappedCommand(InteractiveTenantOption, BaseCommand):
-    """
-    Generic command class useful for running any existing command
-    on a particular tenant. The actual command name is expected in the
-    class variable COMMAND_NAME of the subclass.
-    """
-    def __new__(cls, *args, **kwargs):
-        obj = super(TenantWrappedCommand, cls).__new__(cls, *args, **kwargs)
-        obj.command_instance = obj.COMMAND()
-        obj.option_list = obj.command_instance.option_list
-        return obj
-
-    def handle(self, *args, **options):
-        tenant = self.get_tenant_from_options_or_interactive(**options)
-        connection.set_tenant(tenant)
-
-        self.command_instance.execute(*args, **options)
-
-
-class SyncCommon(BaseCommand):
-    option_list = (
-        make_option('--tenant', action='store_true', dest='tenant', default=False,
-                    help='Tells Django to populate only tenant applications.'),
-        make_option('--shared', action='store_true', dest='shared', default=False,
-                    help='Tells Django to populate only shared applications.'),
-        make_option("-d", "--domain", dest="domain"),
-    )
-
-    def handle(self, *args, **options):
-        self.sync_tenant = options.get('tenant')
-        self.sync_public = options.get('shared')
-        self.domain = options.get('domain')
-        self.installed_apps = settings.INSTALLED_APPS
-        self.args = args
-        self.options = options
-
-        if self.domain:
-            self.schema_name = TenantMiddleware.hostname2schema(domain)
-        else:
-            self.schema_name = options.get('schema_name')
-
-        if self.schema_name:
-            if self.sync_public:
-                raise CommandError("domain should only be used with the --tenant switch.")
-            elif self.schema_name == get_public_schema_name():
-                self.sync_public = True
-            else:
-                self.sync_tenant = True
-        elif not self.sync_public and not self.sync_tenant:
-            # no options set, sync both
-            self.sync_tenant = True
-            self.sync_public = True
-
-        if hasattr(settings, 'TENANT_APPS'):
-            self.tenant_apps = settings.TENANT_APPS
-        if hasattr(settings, 'SHARED_APPS'):
-            self.shared_apps = settings.SHARED_APPS
-
-    def _notice(self, output):
-        self.stdout.write(self.style.NOTICE(output))
diff --git a/entrouvert/djommon/multitenant/management/commands/create_schemas.py b/entrouvert/djommon/multitenant/management/commands/create_schemas.py
deleted file mode 100644
index a92e783..0000000
--- a/entrouvert/djommon/multitenant/management/commands/create_schemas.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from django.core.management.base import BaseCommand
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-from django.db import connection
-
-class Command(BaseCommand):
-    help = "Create schemas for all declared tenants"
-
-    def handle(self, *args, **options):
-        verbosity = int(options.get('verbosity'))
-
-        connection.set_schema_to_public()
-        all_tenants = TenantMiddleware.get_tenants()
-        for tenant in all_tenants:
-            if verbosity >= 1:
-                print
-                print self.style.NOTICE("=== Creating schema ") \
-                    + self.style.SQL_TABLE(tenant.schema_name)
-
-            tenant.create_schema(check_if_exists=True)
diff --git a/entrouvert/djommon/multitenant/management/commands/create_tenant.py b/entrouvert/djommon/multitenant/management/commands/create_tenant.py
deleted file mode 100644
index ed9dded..0000000
--- a/entrouvert/djommon/multitenant/management/commands/create_tenant.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import os
-
-from django.db import connection
-from django.core.management.base import CommandError, BaseCommand
-
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-
-class Command(BaseCommand):
-    help = "Create tenant(s) by hostname(s)"
-
-    def handle(self, *args, **options):
-        verbosity = int(options.get('verbosity'))
-        if not args:
-            raise CommandError("you must give at least one tenant hostname")
-
-        for hostname in args:
-            try:
-                tenant_base = TenantMiddleware.base()
-            except AttributeError:
-                raise CommandError("you must configure TENANT_BASE in your settings")
-            if not tenant_base:
-                raise CommandError("you must set a value to TENANT_BASE in your settings")
-            tenant_dir = os.path.join(tenant_base, hostname)
-            if not os.path.exists(tenant_dir):
-                os.mkdir(tenant_dir, 0755)
-            for folder in ('media', 'static', 'templates'):
-                path = os.path.join(tenant_dir, folder)
-                if not os.path.exists(path):
-                    os.mkdir(path, 0755)
-            connection.set_schema_to_public()
-            tenant = TenantMiddleware.get_tenant_by_hostname(hostname)
-            if verbosity >= 1:
-                print
-                print self.style.NOTICE("=== Creating schema ") \
-                    + self.style.SQL_TABLE(tenant.schema_name)
-            tenant.create_schema(check_if_exists=True)
diff --git a/entrouvert/djommon/multitenant/management/commands/createsuperuser.py b/entrouvert/djommon/multitenant/management/commands/createsuperuser.py
deleted file mode 100644
index 54fc9f3..0000000
--- a/entrouvert/djommon/multitenant/management/commands/createsuperuser.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-from entrouvert.djommon.multitenant.management.commands import TenantWrappedCommand
-from django.contrib.auth.management.commands import createsuperuser
-
-
-class Command(TenantWrappedCommand):
-    COMMAND = createsuperuser.Command
diff --git a/entrouvert/djommon/multitenant/management/commands/deploy.py b/entrouvert/djommon/multitenant/management/commands/deploy.py
deleted file mode 100644
index f37d155..0000000
--- a/entrouvert/djommon/multitenant/management/commands/deploy.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import urllib2
-import json
-import sys
-
-from django.core.management import call_command
-from django.core.management.base import BaseCommand, CommandError
-
-from tenant_schemas.utils import tenant_context
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-
-class Command(BaseCommand):
-    help = 'Deploy a tenant from hobo'
-
-    def handle(self, base_url, **options):
-        environment = json.load(sys.stdin)
-        for service in environment['services']:
-            if service['base_url'] == base_url:
-                break
-        else:
-            raise CommandError('Service %s not found' % base_url)
-        hostname = urllib2.urlparse.urlsplit(base_url).netloc
-
-        call_command('create_tenant', hostname)
-
-        tenant = TenantMiddleware.get_tenant_by_hostname(hostname)
-        with tenant_context(tenant):
-            self.deploy_tenant(environment, service, options)
-
-    def deploy_tenant(self, environment, service, options):
-        pass
diff --git a/entrouvert/djommon/multitenant/management/commands/legacy/__init__.py b/entrouvert/djommon/multitenant/management/commands/legacy/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/entrouvert/djommon/multitenant/management/commands/legacy/migrate_schemas.py b/entrouvert/djommon/multitenant/management/commands/legacy/migrate_schemas.py
deleted file mode 100644
index 5dd204a..0000000
--- a/entrouvert/djommon/multitenant/management/commands/legacy/migrate_schemas.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-from django.conf import settings
-from django.db import connection
-from south import migration
-from south.migration.base import Migrations
-from south.management.commands.migrate import Command as MigrateCommand
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-from entrouvert.djommon.multitenant.management.commands import SyncCommon
-
-
-class Command(SyncCommon):
-    help = "Migrate schemas with South"
-    option_list = MigrateCommand.option_list + SyncCommon.option_list
-
-    def handle(self, *args, **options):
-        super(Command, self).handle(*args, **options)
-
-        if self.sync_public:
-            self.migrate_public_apps()
-        if self.sync_tenant:
-            self.migrate_tenant_apps(self.domain)
-
-    def _set_managed_apps(self, included_apps, excluded_apps):
-        """ while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """
-        ignored_apps = []
-        if excluded_apps:
-            for item in excluded_apps:
-                if item not in included_apps:
-                    ignored_apps.append(item)
-
-        for app in ignored_apps:
-            app_label = app.split('.')[-1]
-            settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore'
-
-    def _save_south_settings(self):
-        self._old_south_modules = None
-        if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None:
-            self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy()
-        else:
-            settings.SOUTH_MIGRATION_MODULES = dict()
-
-    def _restore_south_settings(self):
-        settings.SOUTH_MIGRATION_MODULES = self._old_south_modules
-
-    def _clear_south_cache(self):
-        for mig in list(migration.all_migrations()):
-            delattr(mig._application, "migrations")
-        Migrations._clear_cache()
-
-    def _migrate_schema(self, tenant):
-        connection.set_tenant(tenant, include_public=False)
-        MigrateCommand().execute(*self.args, **self.options)
-
-    def migrate_tenant_apps(self, schema_name=None):
-        self._save_south_settings()
-
-        apps = self.tenant_apps or self.installed_apps
-        self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps)
-
-        if schema_name:
-            self._notice("=== Running migrate for schema: %s" % schema_name)
-            connection.set_schema_to_public()
-            tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
-            self._migrate_schema(tenant)
-        else:
-            all_tenants = TenantMiddleware.get_tenants()
-            if not all_tenants:
-                self._notice("No tenants found")
-
-            for tenant in all_tenants:
-                Migrations._dependencies_done = False  # very important, the dependencies need to be purged from cache
-                self._notice("=== Running migrate for schema %s" % tenant.schema_name)
-                self._migrate_schema(tenant)
-
-        self._restore_south_settings()
-
-    def migrate_public_apps(self):
-        self._save_south_settings()
-
-        apps = self.shared_apps or self.installed_apps
-        self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps)
-
-        self._notice("=== Running migrate for schema public")
-        MigrateCommand().execute(*self.args, **self.options)
-
-        self._clear_south_cache()
-        self._restore_south_settings()
diff --git a/entrouvert/djommon/multitenant/management/commands/list_tenants.py b/entrouvert/djommon/multitenant/management/commands/list_tenants.py
deleted file mode 100644
index 708e17c..0000000
--- a/entrouvert/djommon/multitenant/management/commands/list_tenants.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from django.core.management.base import BaseCommand
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-
-class Command(BaseCommand):
-    requires_model_validation = True
-    can_import_settings = True
-    option_list = BaseCommand.option_list
-
-    def handle(self, **options):
-        all_tenants = TenantMiddleware.get_tenants()
-
-        for tenant in all_tenants:
-            print("{0} {1}".format(tenant.schema_name, tenant.domain_url))
-
diff --git a/entrouvert/djommon/multitenant/management/commands/migrate.py b/entrouvert/djommon/multitenant/management/commands/migrate.py
deleted file mode 100644
index a43849c..0000000
--- a/entrouvert/djommon/multitenant/management/commands/migrate.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-import django
-from django.conf import settings
-from django.core.management.base import CommandError, BaseCommand
-
-if django.VERSION < (1, 7, 0):
-    try:
-        from south.management.commands.migrate import Command as MigrateCommand
-    except ImportError:
-        MigrateCommand = BaseCommand
-else:
-    MigrateCommand = BaseCommand
-
-class Command(MigrateCommand):
-
-    def handle(self, *args, **options):
-        database = options.get('database', 'default')
-        if (settings.DATABASES[database]['ENGINE'] == 'tenant_schemas.postgresql_backend' or
-                MigrateCommand is BaseCommand):
-            raise CommandError("migrate has been disabled, for database '{}'. Use migrate_schemas "
-                               "instead. Please read the documentation if you don't know why you "
-                               "shouldn't call migrate directly!".format(database))
-        super(Command, self).handle(*args, **options)
diff --git a/entrouvert/djommon/multitenant/management/commands/migrate_schemas.py b/entrouvert/djommon/multitenant/management/commands/migrate_schemas.py
deleted file mode 100644
index 074dfd2..0000000
--- a/entrouvert/djommon/multitenant/management/commands/migrate_schemas.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import django
-from optparse import NO_DEFAULT
-
-if django.VERSION >= (1, 7, 0):
-    from django.core.management.commands.migrate import Command as MigrateCommand
-    from django.db.migrations.recorder import MigrationRecorder
-from django.db import connection
-from django.conf import settings
-
-from tenant_schemas.utils import get_public_schema_name
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware, TenantNotFound
-from entrouvert.djommon.multitenant.management.commands import SyncCommon
-
-
-class MigrateSchemasCommand(SyncCommon):
-    help = "Updates database schema. Manages both apps with migrations and those without."
-
-    def run_from_argv(self, argv):
-        """
-        Changes the option_list to use the options from the wrapped command.
-        Adds schema parameter to specify which schema will be used when
-        executing the wrapped command.
-        """
-        self.option_list += MigrateCommand.option_list
-        super(MigrateSchemasCommand, self).run_from_argv(argv)
-
-    def handle(self, *args, **options):
-        super(MigrateSchemasCommand, self).handle(*args, **options)
-        self.PUBLIC_SCHEMA_NAME = get_public_schema_name()
-
-        if self.sync_public and not self.schema_name:
-            self.schema_name = self.PUBLIC_SCHEMA_NAME
-
-        if self.sync_public:
-            self.run_migrations(self.schema_name, settings.SHARED_APPS)
-        if self.sync_tenant:
-            if self.schema_name and self.schema_name != self.PUBLIC_SCHEMA_NAME:
-                self.run_migrations(self.schema_name, settings.TENANT_APPS)
-            else:
-                all_tenants = TenantMiddleware.get_tenants()
-                for tenant in all_tenants:
-                    self.run_migrations(tenant.schema_name, settings.TENANT_APPS)
-
-    def run_migrations(self, schema_name, included_apps):
-        self._notice("=== Running migrate for schema %s" % schema_name)
-        connection.set_schema(schema_name)
-        command = MigrateCommand()
-
-        defaults = {}
-        for opt in MigrateCommand.option_list:
-            if opt.dest in self.options:
-                defaults[opt.dest] = self.options[opt.dest]
-            elif opt.default is NO_DEFAULT:
-                defaults[opt.dest] = None
-            else:
-                defaults[opt.dest] = opt.default
-
-        command.execute(*self.args, **defaults)
-        connection.set_schema_to_public()
-
-    def _notice(self, output):
-        self.stdout.write(self.style.NOTICE(output))
-
-
-if django.VERSION >= (1, 7, 0):
-    Command = MigrateSchemasCommand
-else:
-    from .legacy.migrate_schemas import Command
diff --git a/entrouvert/djommon/multitenant/management/commands/safemigrate_schemas.py b/entrouvert/djommon/multitenant/management/commands/safemigrate_schemas.py
deleted file mode 100644
index 207441a..0000000
--- a/entrouvert/djommon/multitenant/management/commands/safemigrate_schemas.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-import django
-
-if django.VERSION < (1, 7, 0):
-    from django.conf import settings
-    from django.db import connection
-    from south import migration
-    from south.migration.base import Migrations
-    from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-    from entrouvert.djommon.management.commands.safemigrate import Command as SafeMigrateCommand
-    from entrouvert.djommon.multitenant.management.commands.sync_schemas import Command as MTSyncCommand
-    from entrouvert.djommon.multitenant.management.commands.migrate_schemas import Command as MTMigrateCommand
-from entrouvert.djommon.multitenant.management.commands import SyncCommon
-
-
-class SafeMigrateCommand(SyncCommon):
-    help = "Safely migrate schemas with South"
-    option_list = MTMigrateCommand.option_list
-
-    def handle(self, *args, **options):
-        super(Command, self).handle(*args, **options)
-
-        MTSyncCommand().execute(*args, **options)
-        connection.set_schema_to_public()
-        if self.sync_public:
-            self.fake_public_apps()
-        if self.sync_tenant:
-            self.fake_tenant_apps(self.domain)
-        connection.set_schema_to_public()
-        MTMigrateCommand().execute(*args, **options)
-
-    def _set_managed_apps(self, included_apps, excluded_apps):
-        """ while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """
-        ignored_apps = []
-        if excluded_apps:
-            for item in excluded_apps:
-                if item not in included_apps:
-                    ignored_apps.append(item)
-
-        for app in ignored_apps:
-            app_label = app.split('.')[-1]
-            settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore'
-
-    def _save_south_settings(self):
-        self._old_south_modules = None
-        if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None:
-            self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy()
-        else:
-            settings.SOUTH_MIGRATION_MODULES = dict()
-
-    def _restore_south_settings(self):
-        settings.SOUTH_MIGRATION_MODULES = self._old_south_modules
-
-    def _clear_south_cache(self):
-        for mig in list(migration.all_migrations()):
-            delattr(mig._application, "migrations")
-        Migrations._clear_cache()
-
-    def _fake_schema(self, tenant):
-        connection.set_tenant(tenant, include_public=False)
-        SafeMigrateCommand().fake_if_needed()
-
-    def fake_tenant_apps(self, schema_name=None):
-        self._save_south_settings()
-
-        apps = self.tenant_apps or self.installed_apps
-        self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps)
-
-        if schema_name:
-            self._notice("=== Running fake_if_needed for schema: %s" % schema_name)
-            connection.set_schema_to_public()
-            tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
-            self._fake_schema(tenant)
-        else:
-            all_tenants = TenantMiddleware.get_tenants()
-            if not all_tenants:
-                self._notice("No tenants found")
-
-            for tenant in all_tenants:
-                Migrations._dependencies_done = False  # very important, the dependencies need to be purged from cache
-                self._notice("=== Running fake_if_needed for schema %s" % tenant.schema_name)
-                self._fake_schema(tenant)
-
-        self._restore_south_settings()
-
-    def fake_public_apps(self):
-        self._save_south_settings()
-
-        apps = self.shared_apps or self.installed_apps
-        self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps)
-
-        self._notice("=== Running fake_if_needed for schema public")
-        SafeMigrateCommand().fake_if_needed()
-
-        self._clear_south_cache()
-        self._restore_south_settings()
-
-if django.VERSION < (1, 7, 0):
-    Command = SafeMigrateCommand
-else:
-    raise RuntimeError('Django 1.7: please use migrate_schemas')
diff --git a/entrouvert/djommon/multitenant/management/commands/sync_schemas.py b/entrouvert/djommon/multitenant/management/commands/sync_schemas.py
deleted file mode 100644
index fa4acd9..0000000
--- a/entrouvert/djommon/multitenant/management/commands/sync_schemas.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-import django
-from django.core.management.base import CommandError
-
-from django.conf import settings
-from django.contrib.contenttypes.models import ContentType
-from django.db.models import get_apps, get_models
-if 'south' in settings.INSTALLED_APPS:
-    from south.management.commands.syncdb import Command as SyncdbCommand
-else:
-    from django.core.management.commands.syncdb import Command as SyncdbCommand
-from django.db import connection
-from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-from entrouvert.djommon.multitenant.management.commands import SyncCommon
-
-
-class Command(SyncCommon):
-    help = "Sync schemas based on TENANT_APPS and SHARED_APPS settings"
-    option_list = SyncdbCommand.option_list + SyncCommon.option_list
-
-    def handle(self, *args, **options):
-        if django.VERSION >= (1, 7, 0):
-            raise CommandError('This command is only meant to be used for 1.6'
-                               ' and older version of django. For 1.7, use'
-                               ' `migrate_schemas` instead.')
-        super(Command, self).handle(*args, **options)
-
-        if "south" in settings.INSTALLED_APPS:
-            self.options["migrate"] = False
-
-        # save original settings
-        for model in get_models(include_auto_created=True):
-            setattr(model._meta, 'was_managed', model._meta.managed)
-
-        ContentType.objects.clear_cache()
-
-        if self.sync_public:
-            self.sync_public_apps()
-        if self.sync_tenant:
-            self.sync_tenant_apps(self.domain)
-
-        # restore settings
-        for model in get_models(include_auto_created=True):
-            model._meta.managed = model._meta.was_managed
-
-    def _set_managed_apps(self, included_apps):
-        """ sets which apps are managed by syncdb """
-        for model in get_models(include_auto_created=True):
-            model._meta.managed = False
-
-        verbosity = int(self.options.get('verbosity'))
-        for app_model in get_apps():
-            app_name = app_model.__name__.replace('.models', '')
-            if app_name in included_apps:
-                for model in get_models(app_model, include_auto_created=True):
-                    model._meta.managed = model._meta.was_managed
-                    if model._meta.managed and verbosity >= 3:
-                        self._notice("=== Include Model: %s: %s" % (app_name, model.__name__))
-
-    def _sync_tenant(self, tenant):
-        self._notice("=== Running syncdb for schema: %s" % tenant.schema_name)
-        connection.set_tenant(tenant, include_public=False)
-        SyncdbCommand().execute(**self.options)
-
-    def sync_tenant_apps(self, schema_name=None):
-        apps = self.tenant_apps or self.installed_apps
-        self._set_managed_apps(apps)
-        if schema_name:
-            tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
-            self._sync_tenant(tenant)
-        else:
-            all_tenants = TenantMiddleware.get_tenants()
-            if not all_tenants:
-                self._notice("No tenants found!")
-
-            for tenant in all_tenants:
-                self._sync_tenant(tenant)
-
-    def sync_public_apps(self):
-        self._notice("=== Running syncdb for schema public")
-        apps = self.shared_apps or self.installed_apps
-        self._set_managed_apps(apps)
-        SyncdbCommand().execute(**self.options)
diff --git a/entrouvert/djommon/multitenant/management/commands/syncdb.py b/entrouvert/djommon/multitenant/management/commands/syncdb.py
deleted file mode 100644
index b37ce4f..0000000
--- a/entrouvert/djommon/multitenant/management/commands/syncdb.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-from django.core.management.base import CommandError
-from django.conf import settings
-from tenant_schemas.utils import django_is_in_test_mode
-
-if 'south' in settings.INSTALLED_APPS:
-    from south.management.commands import syncdb
-else:
-    from django.core.management.commands import syncdb
-
-
-class Command(syncdb.Command):
-
-    def handle(self, *args, **options):
-        database = options.get('database', 'default')
-        if (settings.DATABASES[database]['ENGINE'] == 'tenant_schemas.postgresql_backend' and not
-                django_is_in_test_mode()):
-            raise CommandError("syncdb has been disabled, for database '{0}'. "
-                               "Use sync_schemas instead. Please read the "
-                               "documentation if you don't know why "
-                               "you shouldn't call syncdb directly!".format(database))
-        super(Command, self).handle(*args, **options)
diff --git a/entrouvert/djommon/multitenant/management/commands/tenant_command.py b/entrouvert/djommon/multitenant/management/commands/tenant_command.py
deleted file mode 100644
index a1e08e1..0000000
--- a/entrouvert/djommon/multitenant/management/commands/tenant_command.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# this file derive from django-tenant-schemas
-#   Author: Bernardo Pires Carneiro
-#   Email: carneiro.be@gmail.com
-#   License: MIT license
-#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
-from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
-from django.core.management import call_command, get_commands, load_command_class
-from django.db import connection
-from entrouvert.djommon.multitenant.management.commands import InteractiveTenantOption
-
-
-class Command(InteractiveTenantOption, BaseCommand):
-    help = "Wrapper around django commands for use with an individual tenant"
-
-    def run_from_argv(self, argv):
-        """
-        Changes the option_list to use the options from the wrapped command.
-        Adds schema parameter to specifiy which schema will be used when
-        executing the wrapped command.
-        """
-        # load the command object.
-        try:
-            app_name = get_commands()[argv[2]]
-        except KeyError:
-            raise CommandError("Unknown command: %r" % argv[2])
-
-        if isinstance(app_name, BaseCommand):
-            # if the command is already loaded, use it directly.
-            klass = app_name
-        else:
-            klass = load_command_class(app_name, argv[2])
-
-        super(Command, self).run_from_argv(argv)
-
-    def handle(self, *args, **options):
-        tenant = self.get_tenant_from_options_or_interactive(**options)
-        connection.set_tenant(tenant)
-
-        call_command(*args, **options)
diff --git a/entrouvert/djommon/multitenant/middleware.py b/entrouvert/djommon/multitenant/middleware.py
deleted file mode 100644
index f805a25..0000000
--- a/entrouvert/djommon/multitenant/middleware.py
+++ /dev/null
@@ -1,180 +0,0 @@
-import os
-import json
-import glob
-
-from django.conf import settings, UserSettingsHolder
-from django.db import connection
-from django.http import Http404
-from django.contrib.contenttypes.models import ContentType
-from tenant_schemas.utils import get_tenant_model, remove_www_and_dev, get_public_schema_name
-
-SENTINEL = object()
-
-class TenantNotFound(RuntimeError):
-    pass
-
-class TenantMiddleware(object):
-    """
-    This middleware should be placed at the very top of the middleware stack.
-    Selects the proper database schema using the request host. Can fail in
-    various ways which is better than corrupting or revealing data...
-    """
-    @classmethod
-    def base(cls):
-        return settings.TENANT_BASE
-
-    @classmethod
-    def hostname2schema(cls, hostname):
-        '''Convert hostname to PostgreSQL schema name'''
-        if hostname in getattr(settings, 'TENANT_MAPPING', {}):
-            return settings.TENANT_MAPPING[hostname]
-        return hostname.replace('.', '_').replace('-', '_')
-
-    @classmethod
-    def get_tenant_by_hostname(cls, hostname):
-        '''Retrieve a tenant object for this hostname'''
-        if not os.path.exists(os.path.join(cls.base(), hostname)):
-            raise TenantNotFound
-        schema = cls.hostname2schema(hostname)
-        return get_tenant_model()(schema_name=schema, domain_url=hostname)
-
-    @classmethod
-    def get_tenants(cls):
-        self = cls()
-        for path in glob.glob(os.path.join(cls.base(), '*')):
-            hostname = os.path.basename(path)
-            yield get_tenant_model()(
-                    schema_name=self.hostname2schema(hostname),
-                    domain_url=hostname)
-
-    def process_request(self, request):
-        # connection needs first to be at the public schema, as this is where the
-        # tenant informations are saved
-        connection.set_schema_to_public()
-        hostname_without_port = remove_www_and_dev(request.get_host().split(':')[0])
-
-        try:
-            request.tenant = self.get_tenant_by_hostname(hostname_without_port)
-        except TenantNotFound:
-            raise Http404
-        connection.set_tenant(request.tenant)
-
-        # content type can no longer be cached as public and tenant schemas have different
-        # models. if someone wants to change this, the cache needs to be separated between
-        # public and shared schemas. if this cache isn't cleared, this can cause permission
-        # problems. for example, on public, a particular model has id 14, but on the tenants
-        # it has the id 15. if 14 is cached instead of 15, the permissions for the wrong
-        # model will be fetched.
-        ContentType.objects.clear_cache()
-
-        # do we have a public-specific token?
-        if hasattr(settings, 'PUBLIC_SCHEMA_URLCONF') and request.tenant.schema_name == get_public_schema_name():
-            request.urlconf = settings.PUBLIC_SCHEMA_URLCONF
-
-
-
-
-class TenantSettingBaseMiddleware(object):
-    '''Base middleware classe for loading settings based on tenants
-
-       Child classes MUST override the load_tenant_settings() method.
-    '''
-    def __init__(self, *args, **kwargs):
-        self.tenants_settings = {}
-
-    def get_tenant_settings(self, wrapped, tenant):
-        '''Get last loaded settings for tenant, try to update it by loading
-           settings again is last loading time is less recent thant settings data
-           store. Compare with last modification time is done in the
-           load_tenant_settings() method.
-        '''
-        tenant_settings, last_time = self.tenants_settings.get(tenant.schema_name, (None,None))
-        if tenant_settings is None:
-            tenant_settings = UserSettingsHolder(wrapped)
-        tenant_settings, last_time = self.load_tenant_settings(wrapped, tenant, tenant_settings, last_time)
-        self.tenants_settings[tenant.schema_name] = tenant_settings, last_time
-        return tenant_settings
-
-    def load_tenant_settings(self, wrapped, tenant, tenant_settings, last_time):
-        '''Load tenant settings into tenant_settings object, eventually skip if
-           last_time is more recent than last update time for settings and return
-           the new value for tenant_settings and last_time'''
-        raise NotImplemented
-
-    def process_request(self, request):
-        if not hasattr(request, '_old_settings_wrapped'):
-            request._old_settings_wrapped = []
-        request._old_settings_wrapped.append(settings._wrapped)
-        settings._wrapped = self.get_tenant_settings(settings._wrapped, request.tenant)
-
-    def process_response(self, request, response):
-        if hasattr(request, '_old_settings_wrapped') and request._old_settings_wrapped:
-            settings._wrapped = request._old_settings_wrapped.pop()
-        return response
-
-
-class FileBasedTenantSettingBaseMiddleware(TenantSettingBaseMiddleware):
-    FILENAME = None
-
-    def load_tenant_settings(self, wrapped, tenant, tenant_settings, last_time):
-        path = os.path.join(settings.TENANT_BASE, tenant.domain_url, self.FILENAME)
-        try:
-            new_time = os.stat(path).st_mtime
-        except OSError:
-            # file was removed
-            if not last_time is None:
-                return UserSettingsHolder(wrapped), None
-        else:
-            if last_time is None or new_time >= last_time:
-                # file is new
-                tenant_settings = UserSettingsHolder(wrapped)
-                self.load_file(tenant_settings, path)
-                return tenant_settings, new_time
-        # nothing has changed
-        return tenant_settings, last_time
-
-
-class JSONSettingsMiddleware(FileBasedTenantSettingBaseMiddleware):
-    '''Load settings from a JSON file whose path is given by:
-
-            os.path.join(settings.TENANT_BASE % schema_name, 'settings.json')
-
-       The JSON file must be a dictionnary whose key/value will override
-       current settings.
-    '''
-    FILENAME = 'settings.json'
-
-    def load_file(sef, tenant_settings, path):
-        with file(path) as f:
-            json_settings = json.load(f)
-            for key in json_settings:
-                setattr(tenant_settings, key, json_settings[key])
-
-
-class DictAdapter(dict):
-    '''Give dict interface to plain objects'''
-    def __init__(self, wrapped):
-        self.wrapped = wrapped
-
-    def __setitem__(self, key, value):
-        setattr(self.wrapped, key, value)
-
-    def __getitem__(self, key):
-        try:
-            return getattr(self.wrapped, key)
-        except AttributeError:
-            raise KeyError
-
-
-class PythonSettingsMiddleware(FileBasedTenantSettingBaseMiddleware):
-    '''Load settings from a file whose path is given by:
-
-            os.path.join(settings.TENANT_BASE % schema_name, 'settings.py')
-
-       The file is executed in the same context as the classic settings file
-       using execfile.
-    '''
-    FILENAME = 'settings.py'
-
-    def load_file(self, tenant_settings, path):
-        execfile(path, DictAdapter(tenant_settings))
diff --git a/entrouvert/djommon/multitenant/models.py b/entrouvert/djommon/multitenant/models.py
deleted file mode 100644
index 8acb0ac..0000000
--- a/entrouvert/djommon/multitenant/models.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from tenant_schemas.models import TenantMixin
-
-class Tenant(TenantMixin):
-    # default true, schema will be automatically created and synced when it is saved
-    auto_create_schema = False
-
-    def save(self):
-        pass
-
-    def __unicode__(self):
-        return u'%s' % self.schema_name
diff --git a/entrouvert/djommon/multitenant/storage.py b/entrouvert/djommon/multitenant/storage.py
deleted file mode 100644
index 2bd3391..0000000
--- a/entrouvert/djommon/multitenant/storage.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import os
-
-from django.conf import settings
-from django.core.exceptions import SuspiciousOperation
-from django.utils._os import safe_join
-
-from django.db import connection
-
-from django.core.files.storage import FileSystemStorage
-
-__all__ = ('TenantFileSystemStorage', )
-
-class TenantFileSystemStorage(FileSystemStorage):
-    '''Lookup files first in $TENANT_BASE/<tenant.schema>/media/ then in default location'''
-    def path(self, name):
-        if connection.tenant:
-            location = safe_join(settings.TENANT_BASE, connection.tenant.domain_url, 'media')
-        else:
-            location = self.location
-        try:
-            path = safe_join(location, name)
-        except ValueError:
-            raise SuspiciousOperation("Attempted access to '%s' denied." % name)
-        return os.path.normpath(path)
diff --git a/entrouvert/djommon/multitenant/template_loader.py b/entrouvert/djommon/multitenant/template_loader.py
deleted file mode 100644
index 6e0190c..0000000
--- a/entrouvert/djommon/multitenant/template_loader.py
+++ /dev/null
@@ -1,115 +0,0 @@
-"""
-Wrapper class that takes a list of template loaders as an argument and attempts
-to load templates from them in order, caching the result.
-"""
-
-import hashlib
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader, get_template_from_string, find_template_loader, make_origin
-from django.utils.encoding import force_bytes
-from django.utils._os import safe_join
-from django.db import connection
-
-class CachedLoader(BaseLoader):
-    is_usable = True
-
-    def __init__(self, loaders):
-        self.template_cache = {}
-        self._loaders = loaders
-        self._cached_loaders = []
-
-    @property
-    def loaders(self):
-        # Resolve loaders on demand to avoid circular imports
-        if not self._cached_loaders:
-            # Set self._cached_loaders atomically. Otherwise, another thread
-            # could see an incomplete list. See #17303.
-            cached_loaders = []
-            for loader in self._loaders:
-                cached_loaders.append(find_template_loader(loader))
-            self._cached_loaders = cached_loaders
-        return self._cached_loaders
-
-    def find_template(self, name, dirs=None):
-        for loader in self.loaders:
-            try:
-                template, display_name = loader(name, dirs)
-                return (template, make_origin(display_name, loader, name, dirs))
-            except TemplateDoesNotExist:
-                pass
-        raise TemplateDoesNotExist(name)
-
-    def load_template(self, template_name, template_dirs=None):
-        if connection.tenant:
-            key = '-'.join([str(connection.tenant.pk), template_name])
-        else:
-            key = template_name
-        if template_dirs:
-            # If template directories were specified, use a hash to differentiate
-            if connection.tenant:
-                key = '-'.join([str(connection.tenant.schema_name), template_name, hashlib.sha1(force_bytes('|'.join(template_dirs))).hexdigest()])
-            else:
-                key = '-'.join([template_name, hashlib.sha1(force_bytes('|'.join(template_dirs))).hexdigest()])
-
-        if key not in self.template_cache:
-            template, origin = self.find_template(template_name, template_dirs)
-            if not hasattr(template, 'render'):
-                try:
-                    template = get_template_from_string(template, origin, template_name)
-                except TemplateDoesNotExist:
-                    # If compiling the template we found raises TemplateDoesNotExist,
-                    # back off to returning the source and display name for the template
-                    # we were asked to load. This allows for correct identification (later)
-                    # of the actual template that does not exist.
-                    return template, origin
-            self.template_cache[key] = template
-        return self.template_cache[key], None
-
-    def reset(self):
-        "Empty the template cache."
-        self.template_cache.clear()
-
-class FilesystemLoader(BaseLoader):
-    is_usable = True
-
-    def get_template_sources(self, template_name, template_dirs=None):
-        """
-        Returns the absolute paths to "template_name", when appended to each
-        directory in "template_dirs". Any paths that don't lie inside one of the
-        template dirs are excluded from the result set, for security reasons.
-        """
-        if not connection.tenant:
-            return
-        if not template_dirs:
-            try:
-                template_dirs = settings.TENANT_TEMPLATE_DIRS
-            except AttributeError:
-                raise ImproperlyConfigured('To use %s.%s you must define the TENANT_TEMPLATE_DIRS' % (__name__, FilesystemLoader.__name__))
-        for template_dir in template_dirs:
-            try:
-                yield safe_join(template_dir, connection.tenant.domain_url, 'templates', template_name)
-            except UnicodeDecodeError:
-                # The template dir name was a bytestring that wasn't valid UTF-8.
-                raise
-            except ValueError:
-                # The joined path was located outside of this particular
-                # template_dir (it might be inside another one, so this isn't
-                # fatal).
-                pass
-
-    def load_template_source(self, template_name, template_dirs=None):
-        tried = []
-        for filepath in self.get_template_sources(template_name, template_dirs):
-            try:
-                with open(filepath, 'rb') as fp:
-                    return (fp.read().decode(settings.FILE_CHARSET), filepath)
-            except IOError:
-                tried.append(filepath)
-        if tried:
-            error_msg = "Tried %s" % tried
-        else:
-            error_msg = "Your TENANT_TEMPLATE_DIRS setting is empty. Change it to point to at least one template directory."
-        raise TemplateDoesNotExist(error_msg)
-    load_template_source.is_usable = True
diff --git a/entrouvert/djommon/multitenant/tests.py b/entrouvert/djommon/multitenant/tests.py
deleted file mode 100644
index 92272a3..0000000
--- a/entrouvert/djommon/multitenant/tests.py
+++ /dev/null
@@ -1,128 +0,0 @@
-"""
-Test multitenant framework
-"""
-
-import tempfile
-import shutil
-import os
-import json
-import StringIO
-
-from django.conf.urls import patterns
-from django.test import TestCase, Client
-from django.http import HttpResponse
-from django.template.response import TemplateResponse
-
-try:
-    from django.test import override_settings
-except ImportError: # django < 1.7
-    from django.test.utils import override_settings
-
-
-def json_key(request, *args, **kwargs):
-    from django.conf import settings
-    return HttpResponse(settings.JSON_KEY + ' json')
-
-def python_key(request, *args, **kwargs):
-    from django.conf import settings
-    return HttpResponse(settings.PYTHON_KEY + ' python')
-
-def template(request, *args, **kwargs):
-    return TemplateResponse(request, 'tenant.html')
-
-def upload(request):
-    from django.core.files.storage import default_storage
-    default_storage.save('upload', request.FILES['upload'])
-    return HttpResponse('')
-
-def download(request):
-    from django.core.files.storage import default_storage
-    return HttpResponse(default_storage.open('upload').read())
-
-urlpatterns = patterns('',
-        ('^json_key/$', json_key),
-        ('^python_key/$', python_key),
-        ('^template/$', template),
-        ('^upload/$', upload),
-        ('^download/$', download),
-)
-
-@override_settings(
-        ROOT_URLCONF=__name__,
-        MIDDLEWARE_CLASSES=(
-            'entrouvert.djommon.multitenant.middleware.TenantMiddleware',
-            'entrouvert.djommon.multitenant.middleware.JSONSettingsMiddleware',
-            'entrouvert.djommon.multitenant.middleware.PythonSettingsMiddleware',
-        ),
-        TEMPLATE_LOADERS = (
-           'entrouvert.djommon.multitenant.template_loader.FilesystemLoader',
-        ),
-        DEFAULT_FILE_STORAGE = 'entrouvert.djommon.multitenant.storage.TenantFileSystemStorage',
-)
-class SimpleTest(TestCase):
-    TENANTS = ['tenant1', 'tenant2']
-
-    def setUp(self):
-        self.tenant_base = tempfile.mkdtemp()
-        for tenant in self.TENANTS:
-            tenant_dir = os.path.join(self.tenant_base, tenant)
-            os.mkdir(tenant_dir)
-            settings_py = os.path.join(tenant_dir, 'settings.json')
-            with file(settings_py, 'w') as f:
-                json.dump({'JSON_KEY': tenant}, f)
-            settings_json = os.path.join(tenant_dir, 'settings.py')
-            with file(settings_json, 'w') as f:
-                print >>f, 'PYTHON_KEY = %r' % tenant
-            templates_dir = os.path.join(tenant_dir, 'templates')
-            os.mkdir(templates_dir)
-            tenant_html = os.path.join(templates_dir, 'tenant.html')
-            with file(tenant_html, 'w') as f:
-                print >>f, tenant + ' template',
-            media_dir = os.path.join(tenant_dir, 'media')
-            os.mkdir(media_dir)
-
-    def tearDown(self):
-        shutil.rmtree(self.tenant_base, ignore_errors=True) 
-
-    def tenant_settings(self):
-        return self.settings(
-                TENANT_BASE=self.tenant_base,
-                TENANT_TEMPLATE_DIRS=(self.tenant_base,)
-        )
-
-    def test_tenants(self):
-        with self.tenant_settings():
-            for tenant in self.TENANTS:
-                c = Client(HTTP_HOST=tenant)
-                response = c.get('/json_key/')
-                self.assertEqual(response.content, tenant + ' json')
-                response = c.get('/python_key/')
-                self.assertEqual(response.content, tenant + ' python')
-                response = c.get('/template/')
-                self.assertEqual(response.content, tenant + ' template')
-
-    def test_list_tenants(self):
-        from entrouvert.djommon.multitenant.middleware import TenantMiddleware
-        from tenant_schemas.utils import get_tenant_model
-
-        with self.tenant_settings():
-            l1 = set(map(str, TenantMiddleware.get_tenants()))
-            l2 = set(str(get_tenant_model()(schema_name=tenant,
-                        domain_url=tenant)) for tenant in self.TENANTS)
-            self.assertEquals(l1, l2)
-
-    def test_storage(self):
-        from django.core.files.base import ContentFile
-        with self.tenant_settings():
-            for tenant in self.TENANTS:
-                c = Client(HTTP_HOST=tenant)
-                uploaded_file_path = os.path.join(self.tenant_base, tenant, 'media', 'upload')
-                self.assertFalse(os.path.exists(uploaded_file_path), uploaded_file_path)
-                response = c.post('/upload/', {'upload': ContentFile(tenant + ' upload', name='upload.txt')})
-                self.assertEqual(response.status_code, 200)
-                self.assertEqual(response.content, '')
-                self.assertTrue(os.path.exists(uploaded_file_path))
-                self.assertEqual(file(uploaded_file_path).read(), tenant + ' upload')
-                response = c.get('/download/')
-                self.assertEqual(response.status_code, 200)
-                self.assertEqual(response.content, tenant + ' upload')
diff --git a/entrouvert/djommon/multitenant/views.py b/entrouvert/djommon/multitenant/views.py
deleted file mode 100644
index 60f00ef..0000000
--- a/entrouvert/djommon/multitenant/views.py
+++ /dev/null
@@ -1 +0,0 @@
-# Create your views here.
-- 
2.1.4

