From f23e8f623a0670883682399799d40abda730ff16 Mon Sep 17 00:00:00 2001 From: hernani Date: Tue, 22 Jun 2010 13:13:26 +0000 Subject: [PATCH] More polished PAI for module html injection and added a couple more places to inject stuff. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@440 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/models/user.py | 11 +- forum/modules/ui.py | 18 +-- forum/modules/ui_objects.py | 139 +++++++++++------- forum/skins/default/templates/badges.html | 8 - forum/skins/default/templates/footer.html | 21 +-- forum/skins/default/templates/header.html | 2 +- .../default/templates/notifications/base.html | 2 +- .../templates/notifications/base_text.html | 2 +- .../templates/subscription_status.html | 2 +- forum/skins/default/templates/tags.html | 1 - forum/skins/default/templates/users/menu.html | 6 +- forum/skins/default/templates/users/tabs.html | 22 +-- .../skins/default/templates/users/users.html | 1 - forum/startup.py | 50 ++++--- forum/templatetags/ui_registry.py | 10 +- forum/urls.py | 4 +- forum/views/decorators.py | 8 +- forum/views/meta.py | 10 +- forum/views/readers.py | 37 ++--- forum/views/users.py | 80 +++++----- 20 files changed, 231 insertions(+), 203 deletions(-) diff --git a/forum/models/user.py b/forum/models/user.py index 8837ef3..89bea28 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -20,10 +20,6 @@ QUESTIONS_PER_PAGE_CHOICES = ( (50, u'50'), ) -class UserManager(CachedManager): - def get_site_owner(self): - return self.all().order_by('date_joined')[0] - class AnonymousUser(DjangoAnonymousUser): def get_visible_answers(self, question): return question.answers.filter_state(deleted=False) @@ -115,11 +111,14 @@ class User(BaseModel, DjangoUser): vote_up_count = DenormalizedField("actions", canceled=False, action_type="voteup") vote_down_count = DenormalizedField("actions", canceled=False, action_type="votedown") - objects = UserManager() - def __unicode__(self): return self.username + @property + def is_siteowner(self): + #temporary thing, for now lets just assume that the site owner will always be the first user of the application + return self.id == 1 + @property def gravatar(self): return md5(self.email).hexdigest() diff --git a/forum/modules/ui.py b/forum/modules/ui.py index 5cfcac4..e21527f 100644 --- a/forum/modules/ui.py +++ b/forum/modules/ui.py @@ -9,29 +9,27 @@ class Registry(list): self.append(register) -"""Links next in the very top of the page""" -HEADER_LINKS = 'HEADER_LINKS' -"""The tabs next to the top of the page""" +HEADER_LINKS = 'HEADER_LINKS' PAGE_TOP_TABS = 'PAGE_TOP_TABS' +FOOTER_LINKS = 'FOOTER_LINKS' +PROFILE_TABS = 'PROFILE_TABS' __CONTAINER = { HEADER_LINKS: Registry(), - PAGE_TOP_TABS: Registry() + PAGE_TOP_TABS: Registry(), + FOOTER_LINKS: Registry(), + PROFILE_TABS: Registry(), } -def register(registry, ui_object): +def register(registry, *ui_objects): if not registry in __CONTAINER: raise('unknown registry') - __CONTAINER[registry].add(ui_object) - -def register_multi(registry, *ui_objects): for ui_object in ui_objects: - register(registry, ui_object) - + __CONTAINER[registry].add(ui_object) def get_registry_by_name(name): name = name.upper() diff --git a/forum/modules/ui_objects.py b/forum/modules/ui_objects.py index 01a61d3..70bee93 100644 --- a/forum/modules/ui_objects.py +++ b/forum/modules/ui_objects.py @@ -1,70 +1,81 @@ from django.core.urlresolvers import reverse +from django.template.defaultfilters import slugify from forum.utils import html -class UiObjectUserLevelBase(object): - def show_to(self, user): - return True - -class SuperuserUiObject(UiObjectUserLevelBase): - def show_to(self, user): - return user.is_superuser - -class StaffUiObject(UiObjectUserLevelBase): - def show_to(self, user): - return user.is_staff or user.is_superuser - -class ReputedUserUiObject(UiObjectUserLevelBase): - def __init__(self, min_rep): - self.min_rep = min_rep +class Visibility(object): + def __init__(self, level='public'): + if level not in ['public', 'authenticated', 'staff', 'superuser', 'owner']: + try: + int(level) + self.by_reputation = True + except: + raise "Invalid visibility level for ui object: %s" % level + else: + self.by_reputation = False - def show_to(self, user): - return user.is_authenticated() and user.reputation >= int(self.min_rep) + self.level = level -class LoggedInUserUiObject(UiObjectUserLevelBase): def show_to(self, user): - return user.is_authenticated() - -class PublicUiObject(UiObjectUserLevelBase): - pass - + if self.by_reputation: + return user.is_authenticated() and (user.reputation >= int(self.level) or user.is_staff or user.is_superuser) + else: + return self.level == 'public' or (user.is_authenticated() and ( + self.level == 'authenticated' or ( + self.level == 'superuser' and user.is_superuser) or ( + self.level == 'staff' and (user.is_staff or user.is_superuser)) or ( + self.level == 'owner' and user.is_siteowner))) + +Visibility.PUBLIC = Visibility('public') +Visibility.AUTHENTICATED = Visibility('authenticated') +Visibility.STAFF = Visibility('staff') +Visibility.SUPERUSER = Visibility('superuser') +Visibility.OWNER = Visibility('owner') +Visibility.REPUTED = lambda r: Visibility(r) + + +class Url(object): + def __init__(self, url_pattern): + self.url_pattern = url_pattern + def __call__(self, u, c): + return reverse(self.url_pattern) -class UiObjectArgument(object): - def __init__(self, argument): - self.argument = argument - def __call__(self, context): - if callable(self.argument): - return self.argument(context) - else: - return self.argument +class ObjectBase(object): + class Argument(object): + def __init__(self, argument): + self.argument = argument + def __call__(self, context): + if callable(self.argument): + return self.argument(context['request'].user, context) + else: + return self.argument -class UiObjectBase(object): - def __init__(self, user_level=None, weight=500): - self.user_level = user_level or PublicUiObject() + def __init__(self, visibility=None, weight=500): + self.visibility = visibility self.weight = weight def can_render(self, context): - return self.user_level.show_to(context['request'].user) + return (not self.visibility) or (self.visibility and self.visibility.show_to(context['request'].user)) def render(self, context): return '' -class UiLoopObjectBase(UiObjectBase): +class LoopBase(ObjectBase): def update_context(self, context): pass -class UiLinkObject(UiObjectBase): - def __init__(self, text, url, attrs=None, pre_code='', post_code='', user_level=None, weight=500): - super(UiLinkObject, self).__init__(user_level, weight) - self.text = UiObjectArgument(text) - self.url = UiObjectArgument(url) - self.attrs = UiObjectArgument(attrs or {}) - self.pre_code = UiObjectArgument(pre_code) - self.post_code = UiObjectArgument(post_code) +class Link(ObjectBase): + def __init__(self, text, url, attrs=None, pre_code='', post_code='', visibility=None, weight=500): + super(Link, self).__init__(visibility, weight) + self.text = self.Argument(text) + self.url = self.Argument(url) + self.attrs = self.Argument(attrs or {}) + self.pre_code = self.Argument(pre_code) + self.post_code = self.Argument(post_code) def render(self, context): return "%s %s %s" % (self.pre_code(context), @@ -72,25 +83,47 @@ class UiLinkObject(UiObjectBase): self.post_code(context)) -class UiLoopContextObject(UiLoopObjectBase): - def __init__(self, loop_context, user_level=None, weight=500): - super(UiLoopContextObject, self).__init__(user_level, weight) - self.loop_context = UiObjectArgument(loop_context) +class LoopContext(LoopBase): + def __init__(self, loop_context, visibility=None, weight=500): + super(LoopContext, self).__init__(visibility, weight) + self.loop_context = self.Argument(loop_context) def update_context(self, context): context.update(self.loop_context(context)) -class UiTopPageTabObject(UiLoopObjectBase): - def __init__(self, tab_name, tab_title, url_pattern, weight): - super(UiTopPageTabObject, self).__init__(weight=weight) +class PageTab(LoopBase): + def __init__(self, tab_name, tab_title, url_getter, weight): + super(PageTab, self).__init__(weight=weight) self.tab_name = tab_name self.tab_title = tab_title - self.url_pattern = url_pattern + self.url_getter = url_getter def update_context(self, context): context.update(dict( tab_name=self.tab_name, tab_title=self.tab_title, - tab_url=reverse(self.url_pattern) + tab_url=self.url_getter() )) + + +class ProfileTab(LoopBase): + def __init__(self, name, title, description, url_getter, private=False, weight=500): + super(ProfileTab, self).__init__(weight=weight) + self.name = name + self.title = title + self.description = description + self.url_getter = url_getter + self.private = private + + def can_render(self, context): + return not self.private or ( + context['view_user'] == context['request'].user or context['request'].user.is_superuser) + + def update_context(self, context): + context.update(dict( + tab_name=self.name, + tab_title=self.title, + tab_description = self.description, + tab_url=self.url_getter(context['view_user']) + )) \ No newline at end of file diff --git a/forum/skins/default/templates/badges.html b/forum/skins/default/templates/badges.html index e3a91e0..aaac3ad 100644 --- a/forum/skins/default/templates/badges.html +++ b/forum/skins/default/templates/badges.html @@ -4,14 +4,6 @@ {% load humanize %} {% load i18n %} {% block title %}{% spaceless %}{% trans "Badges summary" %}{% endspaceless %}{% endblock %} -{% block forejs %} - -{% endblock %} {% block content %}
{% trans "Badges" %} diff --git a/forum/skins/default/templates/footer.html b/forum/skins/default/templates/footer.html index 4e1b97b..e9c9b51 100644 --- a/forum/skins/default/templates/footer.html +++ b/forum/skins/default/templates/footer.html @@ -1,26 +1,9 @@ -{% load extra_tags %} -{% load i18n %} +{% load extra_tags ui_registry i18n %}

diff --git a/forum/skins/default/templates/header.html b/forum/skins/default/templates/header.html index 12a684a..5710550 100644 --- a/forum/skins/default/templates/header.html +++ b/forum/skins/default/templates/header.html @@ -4,7 +4,7 @@