Skip to content

Commit

Permalink
Per thread context implemented (see #182, #186).
Browse files Browse the repository at this point in the history
  • Loading branch information
idlesign committed Dec 20, 2015
1 parent d0b8f40 commit cfe8f9a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 18 deletions.
38 changes: 23 additions & 15 deletions sitetree/sitetreeapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

_THREAD_LOCAL = local()
_THREAD_LANG = 'sitetree_lang'
_THREAD_CONTEXT = 'sitetree_ctx'


def get_sitetree():
Expand Down Expand Up @@ -325,8 +326,6 @@ def set_entry(self, entry_name, key, value):

class SiteTree(object):

_global_context = Context()

def __init__(self):
self.cache = Cache()

Expand All @@ -336,13 +335,18 @@ def set_global_context(cls, context):
Almost all variables are resolved against global context.
"""
if not cls._global_context or id(context) != id(cls._global_context):
cls._global_context = context
global_context = getattr(_THREAD_LOCAL, _THREAD_CONTEXT, None)

if not global_context or id(context) != id(global_context):
global_context = context
setattr(_THREAD_LOCAL, _THREAD_CONTEXT, context)

return global_context

@classmethod
def get_global_context(cls):
"""Returns current sitetree global context."""
return cls._global_context
return getattr(_THREAD_LOCAL, _THREAD_CONTEXT, None) or cls.set_global_context(Context())

def resolve_tree_i18n_alias(self, alias):
"""Resolves internationalized tree alias.
Expand Down Expand Up @@ -410,9 +414,10 @@ def attach_dynamic_tree_items(tree_alias, src_tree_items):

def current_app_is_admin(self):
"""Returns boolean whether current application is Admin contrib."""
global_context = self.get_global_context()
current_app = (
getattr(self._global_context.get('request', None), 'current_app',
self._global_context.current_app))
getattr(global_context.get('request', None), 'current_app',
global_context.current_app))

return current_app == 'admin'

Expand Down Expand Up @@ -515,14 +520,15 @@ def get_tree_current_item(self, tree_alias):

current_item = None

if 'request' not in self._global_context:
global_context = self.get_global_context()
if 'request' not in global_context:
if settings.DEBUG:
raise SiteTreeError(
'Sitetree needs "django.core.context_processors.request" to be in TEMPLATE_CONTEXT_PROCESSORS '
'in your settings file. If it is, check that your view pushes request data into the template.')
else:
# urlquote is an attempt to support non-ascii in url.
current_url = urlquote(self._global_context['request'].path)
current_url = urlquote(global_context['request'].path)
urls_cache = self.cache.get_entry('urls', '%s%s' % (tree_alias, self.lang_get()))
if urls_cache:
for url_item in urls_cache:
Expand Down Expand Up @@ -562,7 +568,7 @@ def url(self, sitetree_item, context=None):
"""

if context is None:
context = self._global_context
context = self.get_global_context()

if not isinstance(sitetree_item, MODEL_TREE_ITEM_CLASS):
sitetree_item = self.resolve_var(sitetree_item, context)
Expand Down Expand Up @@ -737,7 +743,7 @@ def apply_hook(self, items, sender):
def check_access(self, item, context):
"""Checks whether a current user has an access to a certain item."""

authenticated = self._global_context['request'].user.is_authenticated()
authenticated = self.get_global_context()['request'].user.is_authenticated()

if item.access_loggedin and not authenticated:
return False
Expand Down Expand Up @@ -826,7 +832,7 @@ def filter_items(self, items, navigation_type=None):
items_out = copy(items)
if not self.current_app_is_admin():
for item in items:
no_access = not self.check_access(item, self._global_context)
no_access = not self.check_access(item, self.get_global_context())
hidden_for_nav_type = navigation_type is not None and not getattr(item, 'in' + navigation_type, False)
if item.hidden or no_access or hidden_for_nav_type:
items_out.remove(item)
Expand All @@ -853,9 +859,11 @@ def tree_climber(self, tree_alias, start_from):

def breadcrumbs_climber(self, tree_alias, start_from):
"""Climbs up the site tree to build breadcrumb path."""
if start_from.inbreadcrumbs and start_from.hidden == False and self.check_access(start_from,
self._global_context):
if (start_from.inbreadcrumbs and
start_from.hidden == False and
self.check_access(start_from, self.get_global_context())):
self.cache_breadcrumbs.append(start_from)

if hasattr(start_from, 'parent') and start_from.parent is not None:
self.breadcrumbs_climber(tree_alias, self.get_item_by_id(tree_alias, start_from.parent.id))

Expand All @@ -866,7 +874,7 @@ def resolve_var(self, varname, context=None):
"""
if context is None:
context = self._global_context
context = self.get_global_context()

if isinstance(varname, FilterExpression):
varname = varname.resolve(context)
Expand Down
6 changes: 3 additions & 3 deletions sitetree/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ def test_get_title(self):
self.assertEqual(self.t3_en.get_title(), 'tree3en_title')

def test_children_filtering(self):
self.sitetree._global_context = get_mock_context(path='/')
self.sitetree.set_global_context(get_mock_context(path='/'))
self.sitetree.get_sitetree('tree3')
children = self.sitetree.get_children('tree3', self.t3_root)
filtered = self.sitetree.filter_items(children, 'menu')
Expand All @@ -602,7 +602,7 @@ def test_tree_filtering(self):

def test_register_i18n_trees(self):
register_i18n_trees(['tree3'])
self.sitetree._global_context = get_mock_context(path='/the_same_url/')
self.sitetree.set_global_context(get_mock_context(path='/the_same_url/'))

activate('en')
self.sitetree.get_sitetree('tree3')
Expand Down Expand Up @@ -683,7 +683,7 @@ def basic_test(self, new_style=False, reset_cache=False):
register_dynamic_trees(trees, **kwargs)

mock_context = get_mock_context(path='/the_same_url/')
self.sitetree._global_context = mock_context
self.sitetree.set_global_context(mock_context)
tree_alias, sitetree_items = self.sitetree.get_sitetree('main')

if reset_cache:
Expand Down

0 comments on commit cfe8f9a

Please sign in to comment.