1 from django.core.urlresolvers import reverse
2 from django.template.defaultfilters import slugify
3 from django import template
4 from forum.utils import html
5 from forum.models.user import AnonymousUser
6 from ui import Registry
9 class Visibility(object):
10 def __init__(self, level='public', negated=False):
11 if level not in ['public', 'authenticated', 'staff', 'superuser', 'owner']:
14 self.by_reputation = True
16 raise "Invalid visibility level for ui object: %s" % level
18 self.by_reputation = False
21 self.negated = negated
23 def show_to(self, user):
24 if self.by_reputation:
25 res = user.is_authenticated() and (user.reputation >= int(self.level) or user.is_staff or user.is_superuser)
27 res = self.level == 'public' or (user.is_authenticated() and (
28 self.level == 'authenticated' or (
29 self.level == 'superuser' and user.is_superuser) or (
30 self.level == 'staff' and (user.is_staff or user.is_superuser)) or (
31 self.level == 'owner' and user.is_siteowner)))
39 return Visibility(self.level, not self.negated)
42 Visibility.PUBLIC = Visibility('public')
43 Visibility.ANONYMOUS = Visibility('authenticated', negated=True)
44 Visibility.AUTHENTICATED = Visibility('authenticated')
45 Visibility.STAFF = Visibility('staff')
46 Visibility.SUPERUSER = Visibility('superuser')
47 Visibility.OWNER = Visibility('owner')
48 Visibility.REPUTED = lambda r: Visibility(r)
52 def __init__(self, url_pattern):
53 self.url_pattern = url_pattern
55 def __call__(self, u, c):
56 return reverse(self.url_pattern)
59 class ObjectBase(object):
60 class Argument(object):
61 def __init__(self, argument):
62 self.argument = argument
64 def __call__(self, context):
65 if callable(self.argument):
66 user = context.get('request', None) and context['request'].user or AnonymousUser()
67 return self.argument(user, context)
71 def __init__(self, visibility=None, weight=500, name=''):
72 self.visibility = visibility
76 def _visible_to(self, user):
77 return (not self.visibility) or (self.visibility and self.visibility.show_to(user))
79 def can_render(self, context):
81 return self._visible_to(context['request'].user)
84 return self._visible_to(context['viewer'])
86 return self._visible_to(AnonymousUser())
88 def render(self, context):
91 class LoopBase(ObjectBase):
92 def update_context(self, context):
97 class Link(ObjectBase):
98 def __init__(self, text, url, attrs=None, pre_code='', post_code='', visibility=None, weight=500, name=''):
99 super(Link, self).__init__(visibility, weight, name)
100 self.text = self.Argument(text)
101 self.url = self.Argument(url)
102 self.attrs = self.Argument(attrs or {})
103 self.pre_code = self.Argument(pre_code)
104 self.post_code = self.Argument(post_code)
106 def render(self, context):
107 return "%s %s %s" % (self.pre_code(context),
108 html.hyperlink(self.url(context), self.text(context), **self.attrs(context)),
109 self.post_code(context))
111 class Include(ObjectBase):
112 def __init__(self, tpl, visibility=None, weight=500, name=''):
113 super(Include, self).__init__(visibility, weight, name)
114 self.template = template.loader.get_template(tpl)
116 def render(self, context):
117 if not isinstance(context, template.Context):
118 context = template.Context(context)
119 return self.template.render(context)
122 class LoopContext(LoopBase):
123 def __init__(self, loop_context, visibility=None, weight=500, name=''):
124 super(LoopContext, self).__init__(visibility, weight, name)
125 self.loop_context = self.Argument(loop_context)
127 def update_context(self, context):
128 context.update(self.loop_context(context))
131 class PageTab(LoopBase):
132 def __init__(self, tab_name, tab_title, url_getter, weight, name=''):
133 super(PageTab, self).__init__(weight=weight, name=name)
134 self.tab_name = tab_name
135 self.tab_title = tab_title
136 self.url_getter = url_getter
138 def update_context(self, context):
140 tab_name=self.tab_name,
141 tab_title=self.tab_title,
142 tab_url=self.url_getter()
146 class ProfileTab(LoopBase):
147 def __init__(self, name, title, description, url_getter, private=False, render_to=None, weight=500):
148 super(ProfileTab, self).__init__(weight=weight, name=name)
151 self.description = description
152 self.url_getter = url_getter
153 self.private = private
154 self.render_to = render_to
156 def can_render(self, context):
157 return (not self.render_to or (self.render_to(context['view_user']))) and (
158 not self.private or (
159 context['view_user'] == context['request'].user or context['request'].user.is_superuser))
161 def update_context(self, context):
164 tab_title=self.title,
165 tab_description = self.description,
166 tab_url=self.url_getter(context['view_user'])
170 class AjaxMenuItem(ObjectBase):
171 def __init__(self, label, url, a_attrs=None, span_label='', span_attrs=None, visibility=None, weight=500, name=''):
172 super(AjaxMenuItem, self).__init__(visibility, weight, name)
173 self.label = self.Argument(label)
174 self.url = self.Argument(url)
175 self.a_attrs = self.Argument(a_attrs or {})
176 self.span_label = self.Argument(span_label)
177 self.span_attrs = self.Argument(span_attrs or {})
179 def render(self, context):
180 return html.buildtag('li',
181 html.buildtag('span', self.span_label(context), **self.span_attrs(context)) + \
182 html.hyperlink(self.url(context), self.label(context), **self.a_attrs(context)),
185 class AjaxMenuGroup(ObjectBase, Registry):
186 def __init__(self, label, items, visibility=None, weight=500, name=''):
187 super(AjaxMenuGroup, self).__init__(visibility, weight, name)
193 def can_render(self, context):
194 if super(AjaxMenuGroup, self).can_render(context):
196 if item.can_render(context): return True
200 def render(self, context):
201 return html.buildtag('li', self.label, **{'class': 'separator'}) + "".join([
202 item.render(context) for item in self if item.can_render(context)
205 class UserMenuItem(AjaxMenuItem):
206 def __init__(self, render_to=None, *args, **kwargs):
207 super(UserMenuItem, self).__init__(*args, **kwargs)
208 self.render_to = render_to
210 def can_render(self, context):
211 return (not self.render_to or (self.render_to(context['user']))) and super(UserMenuItem, self)._visible_to(context['viewer'])