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'):
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
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)))
40 inverted.negated = True
43 Visibility.PUBLIC = Visibility('public')
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):
72 self.visibility = visibility
75 def _visible_to(self, user):
76 return (not self.visibility) or (self.visibility and self.visibility.show_to(user))
78 def can_render(self, context):
80 return self._visible_to(context['request'].user)
83 return self._visible_to(context['viewer'])
85 return self._visible_to(AnonymousUser())
87 def render(self, context):
90 class LoopBase(ObjectBase):
91 def update_context(self, context):
96 class Link(ObjectBase):
97 def __init__(self, text, url, attrs=None, pre_code='', post_code='', visibility=None, weight=500):
98 super(Link, self).__init__(visibility, weight)
99 self.text = self.Argument(text)
100 self.url = self.Argument(url)
101 self.attrs = self.Argument(attrs or {})
102 self.pre_code = self.Argument(pre_code)
103 self.post_code = self.Argument(post_code)
105 def render(self, context):
106 return "%s %s %s" % (self.pre_code(context),
107 html.hyperlink(self.url(context), self.text(context), **self.attrs(context)),
108 self.post_code(context))
110 class Include(ObjectBase):
111 def __init__(self, tpl, visibility=None, weight=500):
112 super(Include, self).__init__(visibility, weight)
113 self.template = template.loader.get_template(tpl)
115 def render(self, context):
116 if not isinstance(context, template.Context):
117 context = template.Context(context)
118 return self.template.render(context)
121 class LoopContext(LoopBase):
122 def __init__(self, loop_context, visibility=None, weight=500):
123 super(LoopContext, self).__init__(visibility, weight)
124 self.loop_context = self.Argument(loop_context)
126 def update_context(self, context):
127 context.update(self.loop_context(context))
130 class PageTab(LoopBase):
131 def __init__(self, tab_name, tab_title, url_getter, weight):
132 super(PageTab, self).__init__(weight=weight)
133 self.tab_name = tab_name
134 self.tab_title = tab_title
135 self.url_getter = url_getter
137 def update_context(self, context):
139 tab_name=self.tab_name,
140 tab_title=self.tab_title,
141 tab_url=self.url_getter()
145 class ProfileTab(LoopBase):
146 def __init__(self, name, title, description, url_getter, private=False, render_to=None, weight=500):
147 super(ProfileTab, self).__init__(weight=weight)
150 self.description = description
151 self.url_getter = url_getter
152 self.private = private
153 self.render_to = render_to
155 def can_render(self, context):
156 return (not self.render_to or (self.render_to(context['view_user']))) and (
157 not self.private or (
158 context['view_user'] == context['request'].user or context['request'].user.is_superuser))
160 def update_context(self, context):
163 tab_title=self.title,
164 tab_description = self.description,
165 tab_url=self.url_getter(context['view_user'])
169 class AjaxMenuItem(ObjectBase):
170 def __init__(self, label, url, a_attrs=None, span_label='', span_attrs=None, visibility=None, weight=500):
171 super(AjaxMenuItem, self).__init__(visibility, weight)
172 self.label = self.Argument(label)
173 self.url = self.Argument(url)
174 self.a_attrs = self.Argument(a_attrs or {})
175 self.span_label = self.Argument(span_label)
176 self.span_attrs = self.Argument(span_attrs or {})
178 def render(self, context):
179 return html.buildtag('li',
180 html.buildtag('span', self.span_label(context), **self.span_attrs(context)) + \
181 html.hyperlink(self.url(context), self.label(context), **self.a_attrs(context)),
184 class AjaxMenuGroup(ObjectBase, Registry):
185 def __init__(self, label, items, visibility=None, weight=500):
186 super(AjaxMenuGroup, self).__init__(visibility, weight)
192 def can_render(self, context):
193 if super(AjaxMenuGroup, self).can_render(context):
195 if item.can_render(context): return True
199 def render(self, context):
200 return html.buildtag('li', self.label, **{'class': 'separator'}) + "".join([
201 item.render(context) for item in self if item.can_render(context)
204 class UserMenuItem(AjaxMenuItem):
205 def __init__(self, render_to=None, *args, **kwargs):
206 super(UserMenuItem, self).__init__(*args, **kwargs)
207 self.render_to = render_to
209 def can_render(self, context):
210 return (not self.render_to or (self.render_to(context['user']))) and super(UserMenuItem, self)._visible_to(context['viewer'])