diff --git a/cms/envs/common.py b/cms/envs/common.py index a1a25ad9c4..a757dbd4f1 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -348,7 +348,7 @@ MIDDLEWARE_CLASSES = ( 'method_override.middleware.MethodOverrideMiddleware', # Instead of AuthenticationMiddleware, we use a cache-backed version - 'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', + 'openedx.core.djangoapps.cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', # Enable SessionAuthenticationMiddleware in order to invalidate # user sessions after a password change. 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', diff --git a/lms/envs/common.py b/lms/envs/common.py index c03ec38834..52f3deb5f4 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1098,7 +1098,7 @@ MIDDLEWARE_CLASSES = ( # Instead of AuthenticationMiddleware, we use a cached backed version #'django.contrib.auth.middleware.AuthenticationMiddleware', - 'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', + 'openedx.core.djangoapps.cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', # Enable SessionAuthenticationMiddleware in order to invalidate # user sessions after a password change. 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', diff --git a/common/djangoapps/cache_toolbox/COPYING b/openedx/core/djangoapps/cache_toolbox/COPYING similarity index 100% rename from common/djangoapps/cache_toolbox/COPYING rename to openedx/core/djangoapps/cache_toolbox/COPYING diff --git a/common/djangoapps/cache_toolbox/README.rst b/openedx/core/djangoapps/cache_toolbox/README.rst similarity index 100% rename from common/djangoapps/cache_toolbox/README.rst rename to openedx/core/djangoapps/cache_toolbox/README.rst diff --git a/common/djangoapps/cache_toolbox/__init__.py b/openedx/core/djangoapps/cache_toolbox/__init__.py similarity index 100% rename from common/djangoapps/cache_toolbox/__init__.py rename to openedx/core/djangoapps/cache_toolbox/__init__.py diff --git a/common/djangoapps/cache_toolbox/app_settings.py b/openedx/core/djangoapps/cache_toolbox/app_settings.py similarity index 82% rename from common/djangoapps/cache_toolbox/app_settings.py rename to openedx/core/djangoapps/cache_toolbox/app_settings.py index 16e8c36bfa..ad78f383b6 100644 --- a/common/djangoapps/cache_toolbox/app_settings.py +++ b/openedx/core/djangoapps/cache_toolbox/app_settings.py @@ -1,3 +1,7 @@ +""" +Settings for cache_toolbox. +""" + from django.conf import settings # Default cache timeout diff --git a/common/djangoapps/cache_toolbox/core.py b/openedx/core/djangoapps/cache_toolbox/core.py similarity index 81% rename from common/djangoapps/cache_toolbox/core.py rename to openedx/core/djangoapps/cache_toolbox/core.py index 5d458f3e43..0aa0a66cec 100644 --- a/common/djangoapps/cache_toolbox/core.py +++ b/openedx/core/djangoapps/cache_toolbox/core.py @@ -34,40 +34,36 @@ def get_instance(model, instance_or_pk, timeout=None, using=None): True """ - pk = getattr(instance_or_pk, 'pk', instance_or_pk) + primary_key = getattr(instance_or_pk, 'pk', instance_or_pk) key = instance_key(model, instance_or_pk) data = cache.get(key) if data is not None: try: # Try and construct instance from dictionary - instance = model(pk=pk, **data) + instance = model(pk=primary_key, **data) # Ensure instance knows that it already exists in the database, # otherwise we will fail any uniqueness checks when saving the # instance. - instance._state.adding = False + instance._state.adding = False # pylint: disable=protected-access # Specify database so that instance is setup correctly. We don't # namespace cached objects by their origin database, however. - instance._state.db = using or DEFAULT_DB_ALIAS + instance._state.db = using or DEFAULT_DB_ALIAS # pylint: disable=protected-access return instance - except: + except: # pylint: disable=bare-except # Error when deserialising - remove from the cache; we will # fallback and return the underlying instance cache.delete(key) # Use the default manager so we are never filtered by a .get_queryset() -# import logging -# log = logging.getLogger("tracking") -# log.info( str(pk) ) - - instance = model._default_manager.using(using).get(pk=pk) + instance = model._default_manager.using(using).get(pk=primary_key) # pylint: disable=protected-access data = {} - for field in instance._meta.fields: + for field in instance._meta.fields: # pylint: disable=protected-access # Harmless to save, but saves space in the dictionary - we already know # the primary key when we lookup if field.primary_key: @@ -76,8 +72,8 @@ def get_instance(model, instance_or_pk, timeout=None, using=None): if field.get_internal_type() == 'FileField': # Avoid problems with serializing FileFields # by only serializing the file name - file = getattr(instance, field.attname) - data[field.attname] = file.name + file_value = getattr(instance, field.attname) + data[field.attname] = file_value.name else: data[field.attname] = getattr(instance, field.attname) diff --git a/common/djangoapps/cache_toolbox/middleware.py b/openedx/core/djangoapps/cache_toolbox/middleware.py similarity index 96% rename from common/djangoapps/cache_toolbox/middleware.py rename to openedx/core/djangoapps/cache_toolbox/middleware.py index 7c7839b9a5..4fdeb3c6be 100644 --- a/common/djangoapps/cache_toolbox/middleware.py +++ b/openedx/core/djangoapps/cache_toolbox/middleware.py @@ -67,7 +67,7 @@ with:: MIDDLEWARE_CLASSES = [ ... - 'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', + 'openedx.core.djangoapps.cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', ... ] @@ -93,6 +93,9 @@ log = getLogger(__name__) class CacheBackedAuthenticationMiddleware(AuthenticationMiddleware): + """ + See documentation above. + """ def __init__(self): cache_model(User) @@ -110,7 +113,7 @@ class CacheBackedAuthenticationMiddleware(AuthenticationMiddleware): # Raise an exception to fall through to the except clause below. raise Exception self._verify_session_auth(request) - except: + except: # pylint: disable=bare-except # Fallback to constructing the User from the database. super(CacheBackedAuthenticationMiddleware, self).process_request(request) diff --git a/common/djangoapps/cache_toolbox/model.py b/openedx/core/djangoapps/cache_toolbox/model.py similarity index 78% rename from common/djangoapps/cache_toolbox/model.py rename to openedx/core/djangoapps/cache_toolbox/model.py index 688b054bd5..c5600c5e6a 100644 --- a/common/djangoapps/cache_toolbox/model.py +++ b/openedx/core/djangoapps/cache_toolbox/model.py @@ -60,18 +60,28 @@ from .core import get_instance, delete_instance def cache_model(model, timeout=None): + """ + Adds utility methods to the given model to obtain + ``ForeignKey`` instances via the cache. + """ if hasattr(model, 'get_cached'): # Already patched return - def clear_cache(sender, instance, *args, **kwargs): + def clear_cache(sender, instance, *args, **kwargs): # pylint: disable=unused-argument + """ + Clears the cache for the given instance. + """ delete_instance(sender, instance) post_save.connect(clear_cache, sender=model, weak=False) post_delete.connect(clear_cache, sender=model, weak=False) @classmethod - def get(cls, pk, using=None): + def get(cls, pk, using=None): # pylint: disable=invalid-name + """ + Returns the model for the given primary key (pk). + """ if pk is None: return None return get_instance(cls, pk, timeout, using) diff --git a/common/djangoapps/cache_toolbox/relation.py b/openedx/core/djangoapps/cache_toolbox/relation.py similarity index 81% rename from common/djangoapps/cache_toolbox/relation.py rename to openedx/core/djangoapps/cache_toolbox/relation.py index da41c574db..a6216907d2 100644 --- a/common/djangoapps/cache_toolbox/relation.py +++ b/openedx/core/djangoapps/cache_toolbox/relation.py @@ -69,18 +69,25 @@ Support ``cache_relation`` currently only works with ``OneToOneField`` fields. Support for regular ``ForeignKey`` fields is planned. """ - from django.db.models.signals import post_save, post_delete from .core import get_instance, delete_instance def cache_relation(descriptor, timeout=None): + """ + Adds utility methods to a model to obtain related + model instances via a cache. + """ rel = descriptor.related related_name = '%s_cache' % rel.field.related_query_name() @property def get(self): + """ + Returns the cached value of the related model if found + in the cache. Otherwise gets and caches the related model. + """ # Always use the cached "real" instance if available try: return getattr(self, descriptor.cache_name) @@ -93,10 +100,6 @@ def cache_relation(descriptor, timeout=None): except AttributeError: pass -# import logging -# log = logging.getLogger("tracking") -# log.info( "DEBUG: "+str(str(rel.model)+"/"+str(self.pk) )) - instance = get_instance(rel.model, self.pk, timeout) setattr(self, '_%s_cache' % related_name, instance) @@ -107,13 +110,24 @@ def cache_relation(descriptor, timeout=None): # Clearing cache def clear(self): + """ + Clears the cache of all related models of self. + """ delete_instance(rel.model, self) @classmethod - def clear_pk(cls, *instances_or_pk): + def clear_pk(cls, *instances_or_pk): # pylint: disable=unused-argument + """ + Clears the cache of all related models of + the provided instances_or_pk. + """ delete_instance(rel.model, *instances_or_pk) - def clear_cache(sender, instance, *args, **kwargs): + def clear_cache(sender, instance, *args, **kwargs): # pylint: disable=unused-argument + """ + Clears the cache of all related models of the + given instance. + """ delete_instance(rel.model, instance) setattr(rel.parent_model, '%s_clear' % related_name, clear) diff --git a/common/djangoapps/cache_toolbox/templatetags/__init__.py b/openedx/core/djangoapps/cache_toolbox/templatetags/__init__.py similarity index 100% rename from common/djangoapps/cache_toolbox/templatetags/__init__.py rename to openedx/core/djangoapps/cache_toolbox/templatetags/__init__.py diff --git a/common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py b/openedx/core/djangoapps/cache_toolbox/templatetags/cache_toolbox.py similarity index 77% rename from common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py rename to openedx/core/djangoapps/cache_toolbox/templatetags/cache_toolbox.py index 0f746aecfb..7721227ba8 100644 --- a/common/djangoapps/cache_toolbox/templatetags/cache_toolbox.py +++ b/openedx/core/djangoapps/cache_toolbox/templatetags/cache_toolbox.py @@ -1,12 +1,21 @@ +""" +Implementation of custom django template tags for +automatically caching template fragments. +""" from django import template from django.core.cache import cache from django.template import Node, TemplateSyntaxError, Variable from django.template import resolve_variable -register = template.Library() +register = template.Library() # pylint: disable=invalid-name class CacheNode(Node): + """ + Subclass of django's template Node class that + caches the rendered value of a template fragment. This is a + simpler implementation of django.templatetags.cache.CacheNode. + """ def __init__(self, nodelist, expire_time, key): self.nodelist = nodelist self.expire_time = Variable(expire_time) @@ -46,6 +55,11 @@ def cachedeterministic(parser, token): class ShowIfCachedNode(Node): + """ + Subclass of django's template Node class that + renders the cached value for the given key, only + if already cached. + """ def __init__(self, key): self.key = key @@ -55,7 +69,7 @@ class ShowIfCachedNode(Node): @register.tag -def showifcached(parser, token): +def showifcached(parser, token): # pylint: disable=unused-argument """ Show content if it exists in the cache, otherwise display nothing. diff --git a/common/djangoapps/cache_toolbox/tests/__init__.py b/openedx/core/djangoapps/cache_toolbox/tests/__init__.py similarity index 100% rename from common/djangoapps/cache_toolbox/tests/__init__.py rename to openedx/core/djangoapps/cache_toolbox/tests/__init__.py diff --git a/common/djangoapps/cache_toolbox/tests/test_middleware.py b/openedx/core/djangoapps/cache_toolbox/tests/test_middleware.py similarity index 100% rename from common/djangoapps/cache_toolbox/tests/test_middleware.py rename to openedx/core/djangoapps/cache_toolbox/tests/test_middleware.py