diff --git a/debian/settings.py b/debian/settings.py index 0902817f8..3d812b31f 100644 --- a/debian/settings.py +++ b/debian/settings.py @@ -68,6 +68,14 @@ MIDDLEWARE_CLASSES = ( 'hobo.middleware.cors.CORSMiddleware', ) + MIDDLEWARE_CLASSES +CACHES = { + 'default': { + 'BACKEND': 'wcs.cache.WcsTenantCache', + # add a real Django cache backend, with its parameters if needed + 'REAL_BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': '127.0.0.1:11211', + } +} WCS_LEGACY_CONFIG_FILE = '/etc/wcs/wcs.cfg' WCS_EXTRA_MODULES = [] diff --git a/tests/test_misc.py b/tests/test_misc.py index a757f524a..f9d4b8ca4 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -22,6 +22,9 @@ from wcs.qommon.http_request import HTTPRequest from wcs.qommon.backoffice.listing import pagination_links from wcs.qommon.emails import email as send_email, docutils +from django.core.cache import cache + + from utilities import get_app, create_temporary_pub, clean_temporary_pub def setup_module(module): @@ -296,3 +299,7 @@ def test_email_signature_rst(emails): assert emails.emails['test']['msg'].get_payload()[1].get_content_type() == 'text/html' assert 'Footer\nText' in emails.emails['test']['msg'].get_payload()[0].get_payload() assert '>Footer' in emails.emails['test']['msg'].get_payload()[1].get_payload() + +def test_cache(): + cache.set('hello', 'world') + assert cache.get('hello') == 'world' diff --git a/wcs/cache.py b/wcs/cache.py new file mode 100644 index 000000000..cbee4c235 --- /dev/null +++ b/wcs/cache.py @@ -0,0 +1,53 @@ +# w.c.s. - web application for online forms +# Copyright (C) 2005-2017 Entr'ouvert +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . + +from django.core.exceptions import ImproperlyConfigured +from django.utils.module_loading import import_string +from django.core.cache.backends.base import InvalidCacheBackendError + +from quixote import get_publisher + +class TenantBaseCache(object): + '''Prepend the tenant application directory to the cache prefix''' + def set_key_prefix(self, prefix): + self.__key_prefix = prefix + + def get_key_prefix(self): + if get_publisher(): + return '%s_%s' % (get_publisher().app_dir, self.__key_prefix) + return self.__key_prefix + + key_prefix = property(get_key_prefix, set_key_prefix) + +__DERIVED_CLASSES = {} + + +def WcsTenantCache(host, params, **kwargs): + try: + backend = params['REAL_BACKEND'] + except KeyError: + raise ImproperlyConfigured('The %s.WcsTenantCache backend needs a REAL_BACKEND parameter' % __name__) + try: + backend_cls = import_string(backend) + except ImportError as e: + raise InvalidCacheBackendError("Could not find backend '%s': %s" % (backend, e)) + derived_cls_name = 'Tenant' + backend_cls.__name__ + if derived_cls_name not in __DERIVED_CLASSES: + # dynamically create a new class with TenantBaseCache + # and the original class as parents + __DERIVED_CLASSES[derived_cls_name] = type(derived_cls_name, + (TenantBaseCache, backend_cls), {}) + return __DERIVED_CLASSES[derived_cls_name](host, params, **kwargs) diff --git a/wcs/settings.py b/wcs/settings.py index d7c76df05..5b52930c8 100644 --- a/wcs/settings.py +++ b/wcs/settings.py @@ -137,6 +137,15 @@ INSTALLED_APPS = ( 'django.contrib.staticfiles', ) +CACHES = { + 'default': { + 'BACKEND': 'wcs.cache.WcsTenantCache', + # add a real Django cache backend, with its parameters if needed + 'REAL_BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': 'wcs', + } +} + WCS_LEGACY_CONFIG_FILE = None local_settings_file = os.environ.get('WCS_SETTINGS_FILE',