From f589e41b46ab266706a7f82a5562f50805359b26 Mon Sep 17 00:00:00 2001 From: hernani Date: Thu, 8 Jul 2010 08:04:32 +0000 Subject: [PATCH] Makes some more fixes and tweaks on the module system. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@499 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/modules/decorators.py | 128 +++++++++++++++++++++--------------- forum/modules/ui_objects.py | 8 +-- forum/views/decorators.py | 10 ++- forum/views/readers.py | 2 +- forum/views/users.py | 23 ++++--- 5 files changed, 96 insertions(+), 75 deletions(-) diff --git a/forum/modules/decorators.py b/forum/modules/decorators.py index c7c5640..13bddac 100644 --- a/forum/modules/decorators.py +++ b/forum/modules/decorators.py @@ -5,17 +5,26 @@ class DecoratableObject(object): MODE_PARAMS = 1 MODE_RESULT = 2 - def __init__(self, fn): - a = inspect.getargspec(fn) + def __init__(self, fn, is_method=False): self._callable = fn + self.is_method = is_method + self._params_decoration = None self._result_decoration = None - def _decorate(self, fn, needs_origin, method=False): + def _decorate(self, fn, mode, **kwargs): + if mode == self.MODE_OVERRIDE: + self._decorate_full(fn, **kwargs) + elif mode == self.MODE_PARAMS: + self._decorate_params(fn) + elif mode == self.MODE_RESULT: + self._decorate_result(fn, **kwargs) + + def _decorate_full(self, fn, needs_origin=True): origin = self._callable if needs_origin: - if method: + if self.is_method: self._callable = lambda inst, *args, **kwargs: fn(inst, origin, *args, **kwargs) else: self._callable = lambda *args, **kwargs: fn(origin, *args, **kwargs) @@ -28,10 +37,11 @@ class DecoratableObject(object): self._params_decoration.append(fn) - def _decorate_result(self, fn): + def _decorate_result(self, fn, needs_params=False): if not self._result_decoration: self._result_decoration = [] + fn._needs_params = needs_params self._result_decoration.append(fn) def __call__(self, *args, **kwargs): @@ -43,86 +53,96 @@ class DecoratableObject(object): if self._result_decoration: for dec in self._result_decoration: - res = dec(res) + if dec._needs_params: + res = dec(res, *args, **kwargs) + else: + res = dec(res) return res +def _check_decoratable(origin, install=True): + if not isinstance(origin, DecoratableObject): + if inspect.ismethod(origin) and not hasattr(origin, '_decoratable_obj'): + decoratable = DecoratableObject(origin) -def _create_decorator(origin, needs_origin, mode, method=False): - def decorator(fn): - if mode == DecoratableObject.MODE_OVERRIDE: - origin._decorate(fn, needs_origin, method=method) - elif mode == DecoratableObject.MODE_PARAMS: - origin._decorate_params(fn) - elif mode == DecoratableObject.MODE_RESULT: - origin._decorate_result(fn) - - return fn + def decoratable_method(self, *args, **kwargs): + return decoratable(self, *args, **kwargs) - return decorator + decoratable_method._decoratable_obj = decoratable + def decoratable_decorate(fn, mode, **kwargs): + decoratable._decorate(fn, mode, **kwargs) -def _decorate_method(origin, needs_origin, mode): - if not hasattr(origin, '_decoratable_obj'): - name = origin.__name__ - cls = origin.im_class + decoratable_method._decorate = decoratable_decorate - decoratable = DecoratableObject(origin) + if install: + setattr(origin.im_class, origin.__name__, decoratable_method) - def decoratable_method(self, *args, **kwargs): - return decoratable(self, *args, **kwargs) + return decoratable_method + + elif inspect.isfunction(origin): + decoratable = DecoratableObject(origin) - decoratable_method._decoratable_obj = decoratable - setattr(cls, name, decoratable_method) - else: - decoratable = origin._decoratable_obj + if install: + setattr(inspect.getmodule(origin), origin.__name__, decoratable) - return _create_decorator(decoratable, needs_origin, mode, method=True) + return decoratable -def _decorate_function(origin, needs_origin, mode): - if not isinstance(origin, DecoratableObject): - mod = inspect.getmodule(origin) + return origin - name = origin.__name__ - origin = DecoratableObject(origin) - setattr(mod, name, origin) - return _create_decorator(origin, needs_origin, mode) +def decorate(origin, needs_origin=True): + origin = _check_decoratable(origin) + def decorator(fn): + origin._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=needs_origin) + + return decorator -def decorate(origin, needs_origin=True, mode=DecoratableObject.MODE_OVERRIDE): - if inspect.ismethod(origin): - return _decorate_method(origin, needs_origin, mode) - if inspect.isfunction(origin) or isinstance(origin, DecoratableObject): - return _decorate_function(origin, needs_origin, mode) +def _decorate_params(origin): + origin = _check_decoratable(origin) def decorator(fn): - return fn + origin._decorate(fn, DecoratableObject.MODE_PARAMS) return decorator +decorate.params = _decorate_params -def _decorate_params(origin): - return decorate(origin, mode=DecoratableObject.MODE_PARAMS) +def _decorate_result(origin, needs_params=False): + origin = _check_decoratable(origin) -decorate.params = _decorate_params + def decorator(fn): + origin._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params) -def _decorate_result(origin): - return decorate(origin, mode=DecoratableObject.MODE_RESULT) + return decorator decorate.result = _decorate_result def _decorate_with(fn): def decorator(origin): - if not isinstance(origin, DecoratableObject): - decoratable = DecoratableObject(origin) - else: - decoratable = origin + origin = _check_decoratable(origin) + origin._decorate(fn, DecoratableObject.MODE_OVERRIDE, needs_origin=True) + return origin + return decorator + +decorate.withfn = _decorate_with - decoratable._decorate(fn, True, False) - return decoratable +def _decorate_result_with(fn, needs_params=False): + def decorator(origin): + origin = _check_decoratable(origin) + origin._decorate(fn, DecoratableObject.MODE_RESULT, needs_params=needs_params) + return origin return decorator +decorate.result.withfn = _decorate_result_with + +def _decorate_params_with(fn): + def decorator(origin): + origin = _check_decoratable(origin) + origin._decorate(fn, DecoratableObject.MODE_PARAMS) + return origin + return decorator -decorate.withfn = _decorate_with \ No newline at end of file +decorate.params.withfn = _decorate_params_with \ No newline at end of file diff --git a/forum/modules/ui_objects.py b/forum/modules/ui_objects.py index e7f626f..e42c940 100644 --- a/forum/modules/ui_objects.py +++ b/forum/modules/ui_objects.py @@ -2,6 +2,7 @@ from django.core.urlresolvers import reverse from django.template.defaultfilters import slugify from django import template from forum.utils import html +from forum.models.user import AnonymousUser from ui import Registry from copy import copy @@ -62,7 +63,7 @@ class ObjectBase(object): def __call__(self, context): if callable(self.argument): - user = context.get('request', None) and context['request'].user or None + user = context.get('request', None) and context['request'].user or AnonymousUser() return self.argument(user, context) else: return self.argument @@ -81,10 +82,7 @@ class ObjectBase(object): try: return self._visible_to(context['viewer']) except KeyError: - if self.visibility: - return False - else: - return True + return self._visible_to(AnonymousUser()) def render(self, context): return '' diff --git a/forum/views/decorators.py b/forum/views/decorators.py index 2219f98..758b687 100644 --- a/forum/views/decorators.py +++ b/forum/views/decorators.py @@ -9,10 +9,8 @@ from forum.modules import ui, decorate import logging def render(template=None, tab=None, tab_title='', weight=500, tabbed=True): - def decorator(func): - def decorated(func, request, *args, **kwargs): - context = func(request, *args, **kwargs) - + def decorator(func): + def decorated(context, request, *args, **kwargs): if isinstance(context, HttpResponse): return context @@ -22,11 +20,11 @@ def render(template=None, tab=None, tab_title='', weight=500, tabbed=True): return render_to_response(context.pop('template', template), context, context_instance=RequestContext(request)) - if tabbed and tab: + if tabbed and tab and tab_title: ui.register(ui.PAGE_TOP_TABS, ui.PageTab(tab, tab_title, lambda: reverse(func.__name__), weight=weight)) - return decorate.withfn(decorated)(func) + return decorate.result.withfn(decorated, needs_params=True)(func) return decorator diff --git a/forum/views/readers.py b/forum/views/readers.py index 999d320..8ed1b27 100644 --- a/forum/views/readers.py +++ b/forum/views/readers.py @@ -279,7 +279,7 @@ def answer_redirect(request, answer): return HttpResponsePermanentRedirect("%s?%s=%s#%s" % ( answer.question.get_absolute_url(), _('page'), page, answer.id)) -@decorators.render("question.html", 'questions', tabbed=False) +@decorators.render("question.html", 'questions') def question(request, id, slug, answer=None): try: question = Question.objects.get(id=id) diff --git a/forum/views/users.py b/forum/views/users.py index 9cac193..fa57542 100644 --- a/forum/views/users.py +++ b/forum/views/users.py @@ -174,27 +174,32 @@ def suspend(request, id): def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500): def decorator(fn): - def decorated(fn, request, id, slug=None): + def params(request, id, slug=None): user = get_object_or_404(User, id=id) if private and not (user == request.user or request.user.is_superuser): return HttpResponseUnauthorized(request) if render_to and (not render_to(user)): return HttpResponseRedirect(user.get_profile_url()) - - context = fn(request, user) + return [request, user], {} + + decorated = decorate.params.withfn(params)(fn) + + def result(context, request, user): rev_page_title = user.username + " - " + tab_description context.update({ - "tab": "users", - "active_tab" : tab_name, - "tab_description" : tab_description, - "page_title" : rev_page_title, - "can_view_private": (user == request.user) or request.user.is_superuser + "tab": "users", + "active_tab" : tab_name, + "tab_description" : tab_description, + "page_title" : rev_page_title, + "can_view_private": (user == request.user) or request.user.is_superuser }) return render_to_response(template, context, context_instance=RequestContext(request)) + decorated = decorate.result.withfn(result, needs_params=True)(decorated) + if tabbed: def url_getter(vu): try: @@ -206,7 +211,7 @@ def user_view(template, tab_name, tab_title, tab_description, private=False, tab tab_name, tab_title, tab_description,url_getter, private, render_to, weight )) - return decorate.withfn(decorated)(fn) + return decorated return decorator -- 2.39.5