(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)
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()
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()
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),
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
{% load humanize %}
{% load i18n %}
{% block title %}{% spaceless %}{% trans "Badges summary" %}{% endspaceless %}{% endblock %}
-{% block forejs %}
- <script type="text/javascript">
- $().ready(function(){
- $("#nav_badges").attr('className',"on");
- });
-
- </script>
-{% endblock %}
{% block content %}
<div class="headlineA">
<span class="headMedals">{% trans "Badges" %}</span>
-{% load extra_tags %}
-{% load i18n %}
+{% load extra_tags ui_registry i18n %}
<div>
<div class="footerLinks" >
- <a href="{% url about %}">{% trans "about" %}</a><span class="link-separator"> |</span>
- <a href="{% url faq %}">{% trans "faq" %}</a><span class="link-separator"> |</span>
- <a href="{% url privacy %}">{% trans "privacy" %}</a><span class="link-separator"> |</span>
- {% if settings.SUPPORT_URL %}
- <a href="{{settings.SUPPORT_URL}}" target="_blank">{% trans "support" %}</a><span class="link-separator"> |</span>
- {% endif %}
- {% spaceless %}
- <a href=
- {% if settings.CONTACT_URL %}
- "{{settings.CONTACT_URL}}"
- target="_blank">
- {% else %}
- "{% url feedback %}?next={{request.path}}">
- {% endif %}
- {% trans "contact us" %}
- </a>
- {% endspaceless %}
+ {% loadregistry footer_links %}<span class="link-separator"> |</span>{% endloadregistry %}
</div>
<p>
<a href="http://osqa.net" target="_blank" title="OSQA {{ settings.OSQA_VERSION }} ({{ settings.SVN_REVISION }})">
<div id="roof">
<div id="navBar">
<div id="top">
- {% loadregistry header_links %}
+ {% loadregistry header_links %}{% endloadregistry %}
</div>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<p style="{{ p_style }}">{% trans "Thanks" %},<br />{{settings.APP_SHORT_NAME}}</p>
{% if not exclude_finetune %}
<p style="{{ p_style }}">{% trans "P.S. You can always fine-tune which notifications you receive" %}
-<a href="{{ settings.APP_URL }}{% url user_subscriptions id=recipient.id %}" style="{{ a_style }}">{% trans "here" %}</a>.
+<a href="{{ settings.APP_URL }}{% url user_subscriptions id=recipient.id,slug=recipient.username|slugify %}" style="{{ a_style }}">{% trans "here" %}</a>.
{% endif %}
</p>
<hr style="{{ hr_style }}" />
{% if not exclude_finetune %}
{% trans "P.S. You can always fine-tune which notifications you receive here:" %}
-{{ settings.APP_URL }}{% url user_subscriptions id=recipient.id %}
+{{ settings.APP_URL }}{% url user_subscriptions id=recipient.id,slug=recipient.username|slugify %}
{% endif %}
{{ postal_address }}
\ No newline at end of file
{% endif %}\r
</a></p>\r
<p>\r
- {% url user_subscriptions id=request.user.id as subscriptions_url %}\r
+ {% url user_subscriptions id=request.user.id,slug=request.user.username|slugify as subscriptions_url %}\r
{% blocktrans %}\r
(you can adjust your notification settings on your <a href="{{ subscriptions_url }}">profile</a>)\r
{% endblocktrans %}\r
<script type="text/javascript">
/*<![CDATA[*/
$().ready(function(){
- $("#nav_tags").attr('className',"on");
$("#ipSearchTag").focus();
var orderby = "{{ tab_id }}";
<ul id="user-menu-dropdown">\r
<li class="item"><span class="user-edit"></span><a href="{% url edit_user id=user.id %}">{% trans "edit profile" %}</a></li>\r
<li class="item"><span class="user-auth"></span><a href="{% url user_authsettings id=user.id %}">{% trans "authentication settings" %}</a></li>\r
- <li class="item"><span class="user-subscriptions"></span><a href="{% url user_subscriptions id=user.id %}">{% trans "email notification settings" %}</a></li>\r
+ <li class="item"><span class="user-subscriptions"></span><a href="{% url user_subscriptions id=user.id,slug=user.username|slugify %}">{% trans "email notification settings" %}</a></li>\r
{% ifnotequal user viewer %}\r
{% if viewer.is_superuser %}\r
<li class="separator">{% trans "Moderation tools" %}</li>\r
<a class="confirm" href="{% url user_powers id=user.id,action="grant",status="super" %}">{% trans "grant super user status" %}</a>\r
</li>\r
{% else %}\r
- {% ifequal viewer.id 1 %}\r
+ {% if viewer.is_siteowner %}\r
<li class="item"><span class="user-superuser"></span>\r
<a class="confirm" href="{% url user_powers id=user.id,action="remove",status="super" %}">{% trans "remove super user status" %}</a>\r
</li>\r
- {% endifequal %}\r
+ {% endif %}\r
{% endif %}\r
{% endif %}\r
{% endifnotequal %}\r
-{% load extra_filters %}
-{% load i18n %}
+{% load extra_filters ui_registry i18n %}
{% with view_user.username|slugify as user_slug %}
<div class="tabBar">
<div class="tabsA">
- <a id="stats" {% ifequal tab_name "stats" %}class="on"{% endifequal %}
- title="{% trans "User profile" %}" href="{% url user_profile id=view_user.id,slug=user_slug %}">{% trans "overview" %}</a>
- <a id="recent" {% ifequal tab_name "recent" %}class="on"{% endifequal %}
- title="{% trans "recent activity" %}" href="{% url user_recent id=view_user.id,slug=user_slug %}">{% trans "recent activity" %}</a>
- <a id="reputation" {% ifequal tab_name "reputation" %}class="on"{% endifequal %}
- title="{% trans "graph of user reputation" %}"
- href="{% url user_reputation id=view_user.id,slug=user_slug %}">{% trans "reputation history" %}</a>
- {% if can_view_private %}
- <a id="votes" {% ifequal tab_name "votes" %}class="on"{% endifequal %}
- title="{% trans "user vote record" %}" href="{% url user_votes id=view_user.id,slug=user_slug %}">{% trans "casted votes" %}</a>
- {% endif %}
- <a id="favorites" {% ifequal tab_name "favorites" %}class="on"{% endifequal %}
- title="{% trans "questions that user selected as his/her favorite" %}"
- href="{% url user_favorites id=view_user.id,slug=user_slug %}">{% trans "favorites" %}</a>
+ {% loopregistry profile_tabs %}{% spaceless %}
+ <a title="{{ tab_description }}" id="{{ tab_name }}" {% ifequal active_tab tab_name %}class="on"{% endifequal %} href="{{ tab_url }}">
+ {{ tab_title }}
+ </a>
+ {% endspaceless %}{% endloopregistry %}
</div>
</div>
{% endwith %}
<script type="text/javascript">
//todo move javascript out
$().ready(function(){
- $("#nav_users").attr('className',"on");
$("#type-user").attr('checked',true);
var orderby = "{{ tab_id }}";
$("#sort_" + orderby).attr('className',"on");
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from forum.templatetags.extra_tags import get_score_badge
+from forum import settings
-ui.register_multi(ui.HEADER_LINKS,
- ui.UiLinkObject(_('faq'), 'faq', weight=400),
- ui.UiLinkObject(_('about'), 'about', weight=300),
+ui.register(ui.HEADER_LINKS,
+ ui.Link(_('faq'), ui.Url('faq'), weight=400),
+ ui.Link(_('about'), ui.Url('about'), weight=300),
- ui.UiLinkObject(
- text=lambda c: c['request'].user.is_authenticated() and _('logout') or _('login'),
- url=lambda c: c['request'].user.is_authenticated() and reverse('logout') or reverse('auth_signin'),
+ ui.Link(
+ text=lambda u, c: u.is_authenticated() and _('logout') or _('login'),
+ url=lambda u, c: u.is_authenticated() and reverse('logout') or reverse('auth_signin'),
weight=200),
- ui.UiLinkObject(
- user_level=ui.LoggedInUserUiObject(),
- text=lambda c: c['request'].user.username,
- url=lambda c: c['request'].user.get_profile_url(),
- post_code=lambda c: get_score_badge(c['request'].user),
+ ui.Link(
+ visibility=ui.Visibility.AUTHENTICATED,
+ text=lambda u, c: u.username,
+ url=lambda u, c: u.get_profile_url(),
+ post_code=lambda u, c: get_score_badge(u),
weight=100),
- ui.UiLinkObject(
- user_level=ui.SuperuserUiObject(),
+ ui.Link(
+ visibility=ui.Visibility.SUPERUSER,
text=_('administration'),
- url=lambda c: reverse('admin_index'),
+ url=lambda u, c: reverse('admin_index'),
weight=0)
)
+class SupportLink(ui.Link):
+ def can_render(self, context):
+ return bool(settings.SUPPORT_URL)
-ui.register_multi(ui.PAGE_TOP_TABS,
- ui.UiTopPageTabObject('questions', _('questions'), 'questions', weight=0),
- ui.UiTopPageTabObject('tags', _('tags'), 'tags', weight=100),
- ui.UiTopPageTabObject('users', _('users'), 'users', weight=200),
- ui.UiTopPageTabObject('badges', _('badges'), 'badges', weight=300),
- ui.UiTopPageTabObject('unanswered', _('unanswered questions'), 'unanswered', weight=400),
+
+ui.register(ui.FOOTER_LINKS,
+ ui.Link(
+ text=_('contact'),
+ url=lambda u, c: settings.CONTACT_URL and settings.CONTACT_URL or "%s?next=%s" % (reverse('feedback'), c['request'].path),
+ weight=400),
+ SupportLink(_('support'), settings.SUPPORT_URL, attrs={'target': '_blank'}, weight=300),
+ ui.Link(_('privacy'), ui.Url('privacy'), weight=200),
+ ui.Link(_('faq'), ui.Url('faq'), weight=100),
+ ui.Link(_('about'), ui.Url('about'), weight=0),
)
-#register.header_link(lambda c: (_('faq'), reverse('faq')))
+
class LoadRegistryNode(template.Node):
- def __init__(self, registry):
+ def __init__(self, registry, separator):
self.registry = registry
+ self.separator = separator
def render(self, context):
+ separator = self.separator.render(context)
result = ''
for ui_object in self.registry:
if ui_object.can_render(context):
+ if result:
+ result += separator
result += ui_object.render(context)
return result
raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.contents.split()[0]
registry = ui.get_registry_by_name(registry)
- return LoadRegistryNode(registry)
+ separator = parser.parse(('endloadregistry',))
+ parser.delete_first_token()
+ return LoadRegistryNode(registry, separator)
class LoopRegistryNode(template.Node):
),
url(r'^%s(?P<id>\d+)/%s(?P<action>[a-z]+)/(?P<status>[a-z]+)/$' % (_('users/'), _('powers/')),
app.users.user_powers, name='user_powers'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('users/'), _('subscriptions/')), app.users.user_subscriptions,
+ url(r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % (_('users/'), _('subscriptions/')), app.users.user_subscriptions,
name='user_subscriptions'),
url(r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % (_('users/'), _('favorites/')),
app.users.user_favorites, name='user_favorites'),
name='user_votes'),
url(r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % (_('users/'), _('recent/')), app.users.user_recent,
name='user_recent'),
- url(r'^%s(?P<id>\d+)/(?P<slug>.+)/$' % _('users/'), app.users.user_stats, name='user_profile'),
+ url(r'^%s(?P<id>\d+)/(?P<slug>.+)/$' % _('users/'), app.users.user_profile, name='user_profile'),
url(r'^%s$' % _('badges/'), app.meta.badges, name='badges'),
url(r'^%s(?P<id>\d+)/(?P<slug>.+)$' % _('badges/'), app.meta.badge, name='badge'),
from django.utils import simplejson\r
from django.core.paginator import Paginator, EmptyPage\r
from django.shortcuts import render_to_response\r
+from django.core.urlresolvers import reverse\r
from django.template import RequestContext\r
from django.utils.translation import ungettext, ugettext as _\r
+from forum.modules import ui\r
import logging\r
\r
-def render(template=None, tab=None):\r
+def render(template=None, tab=None, tab_title='', weight=500, tabbed=True):\r
def decorator(func):\r
def decorated(request, *args, **kwargs):\r
context = func(request, *args, **kwargs)\r
return render_to_response(context.pop('template', template), context,\r
context_instance=RequestContext(request))\r
\r
+ if tabbed and tab:\r
+ ui.register(ui.PAGE_TOP_TABS,\r
+ ui.PageTab(tab, tab_title, lambda: reverse(func.__name__), weight=weight))\r
+ \r
return decorated\r
\r
return decorator\r
from forum.utils.mail import send_template_email
from django.utils.safestring import mark_safe
from forum.templatetags.extra_filters import or_preview
+import decorators
import re
def favicon(request):
'next' : get_next_url(request),
}, context_instance=RequestContext(request))
+@decorators.render('badges.html', 'badges', _('badges'), weight=300)
def badges(request):
badges = [b.ondb for b in sorted(BadgesMeta.by_id.values(), lambda b1, b2: cmp(b1.name, b2.name))]
else:
my_badges = []
- return render_to_response('badges.html', {
- 'badges' : badges,
- 'mybadges' : my_badges,
- }, context_instance=RequestContext(request))
+ return {
+ 'badges' : badges,
+ 'mybadges' : my_badges,
+ }
def badge(request, id, slug):
badge = Badge.objects.get(id=id)
sort=request.utils.set_sort_method('active'),
base_path=reverse('questions'))
-@decorators.render('questions.html', 'unanswered')
+@decorators.render('questions.html', 'unanswered', _('unanswered'), weight=400)
def unanswered(request):
return question_list(request,
Question.objects.filter(extra_ref=None),
None,
_("Unanswered Questions"))
-@decorators.render('questions.html', 'questions')
+@decorators.render('questions.html', 'questions', _('questions'), weight=0)
def questions(request):
return question_list(request, Question.objects.all(), _('questions'), request.utils.set_sort_method('active'))
_("questions matching '%(keywords)s'") % {'keywords': keywords})
-def tags(request):#view showing a listing of available tags - plain list
+@decorators.render('tags.html', 'tags', _('tags'), weight=100)
+def tags(request):
stag = ""
is_paginated = True
sortby = request.GET.get('sort', 'used')
except (EmptyPage, InvalidPage):
tags = objects_list.page(objects_list.num_pages)
- return render_to_response('tags.html', {
- "tags" : tags,
- "stag" : stag,
- "tab_id" : sortby,
- "keywords" : stag,
- "context" : {
- 'is_paginated' : is_paginated,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': tags.has_previous(),
- 'has_next': tags.has_next(),
- 'previous': tags.previous_page_number(),
- 'next': tags.next_page_number(),
- 'base_url' : reverse('tags') + '?sort=%s&' % sortby
+ return {
+ "tags" : tags,
+ "stag" : stag,
+ "tab_id" : sortby,
+ "keywords" : stag,
+ "context" : {
+ 'is_paginated' : is_paginated,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': tags.has_previous(),
+ 'has_next': tags.has_next(),
+ 'previous': tags.previous_page_number(),
+ 'next': tags.next_page_number(),
+ 'base_url' : reverse('tags') + '?sort=%s&' % sortby
+ }
}
- }, context_instance=RequestContext(request))
def get_answer_sort_order(request):
view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" }
from django.utils.http import urlquote_plus\r
from django.utils.html import strip_tags\r
from django.utils import simplejson\r
-from django.core.urlresolvers import reverse\r
+from django.core.urlresolvers import reverse, NoReverseMatch\r
from forum.forms import *\r
from forum.utils.html import sanitize_html\r
from datetime import datetime, date\r
import decorators\r
from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction\r
+from forum.modules import ui\r
\r
import time\r
+import decorators\r
\r
USERS_PAGE_SIZE = 35# refactor - move to some constants file\r
\r
+@decorators.render('users/users.html', 'users', _('users'), weight=200)\r
def users(request):\r
is_paginated = True\r
sortby = request.GET.get('sort', 'reputation')\r
except (EmptyPage, InvalidPage):\r
users = objects_list.page(objects_list.num_pages)\r
\r
- return render_to_response('users/users.html', {\r
- "users" : users,\r
- "suser" : suser,\r
- "keywords" : suser,\r
- "tab_id" : sortby,\r
- "context" : {\r
- 'is_paginated' : is_paginated,\r
- 'pages': objects_list.num_pages,\r
- 'page': page,\r
- 'has_previous': users.has_previous(),\r
- 'has_next': users.has_next(),\r
- 'previous': users.previous_page_number(),\r
- 'next': users.next_page_number(),\r
- 'base_url' : base_url\r
+ return {\r
+ "users" : users,\r
+ "suser" : suser,\r
+ "keywords" : suser,\r
+ "tab_id" : sortby,\r
+ "context" : {\r
+ 'is_paginated' : is_paginated,\r
+ 'pages': objects_list.num_pages,\r
+ 'page': page,\r
+ 'has_previous': users.has_previous(),\r
+ 'has_next': users.has_next(),\r
+ 'previous': users.previous_page_number(),\r
+ 'next': users.next_page_number(),\r
+ 'base_url' : base_url\r
+ }\r
}\r
\r
- }, context_instance=RequestContext(request))\r
-\r
def set_new_email(user, new_email, nomessage=False):\r
if new_email != user.email:\r
user.email = new_email\r
\r
return decorators.RefreshPageCommand()\r
\r
-def user_view(template, tab_name, tab_description, page_title, private=False):\r
+def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, weight=500):\r
def decorator(fn):\r
def decorated(request, id, slug=None):\r
user = get_object_or_404(User, id=id)\r
return HttpResponseUnauthorized(request)\r
context = fn(request, user)\r
\r
- rev_page_title = user.username + " - " + page_title\r
+ rev_page_title = user.username + " - " + tab_description\r
\r
context.update({\r
- "tab_name" : tab_name,\r
+ "active_tab" : tab_name,\r
"tab_description" : tab_description,\r
"page_title" : rev_page_title,\r
"can_view_private": (user == request.user) or request.user.is_superuser\r
})\r
return render_to_response(template, context, context_instance=RequestContext(request))\r
\r
+ if tabbed:\r
+ def url_getter(vu):\r
+ try:\r
+ return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(vu.username)})\r
+ except NoReverseMatch:\r
+ return reverse(fn.__name__, kwargs={'id': vu.id})\r
+\r
+ ui.register(ui.PROFILE_TABS, ui.ProfileTab(\r
+ tab_name, tab_title, tab_description,url_getter, private, weight\r
+ ))\r
+\r
return decorated\r
\r
return decorator\r
\r
\r
-@user_view('users/stats.html', 'stats', _('user profile'), _('user overview'))\r
-def user_stats(request, user):\r
+@user_view('users/stats.html', 'stats', _('overview'), _('user overview'))\r
+def user_profile(request, user):\r
questions = Question.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')\r
answers = Answer.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')\r
\r
"total_awards" : len(awards),\r
}\r
\r
-@user_view('users/recent.html', 'recent', _('recent user activity'), _('recent activity'))\r
+@user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))\r
def user_recent(request, user):\r
activities = user.actions.exclude(\r
action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(\r
return {"view_user" : user, "activities" : activities}\r
\r
\r
-@user_view('users/votes.html', 'votes', _('user vote record'), _('votes'), True)\r
-def user_votes(request, user):\r
- votes = user.votes.exclude(node__state_string__contains="(deleted").filter(\r
- node__node_type__in=("question", "answer")).order_by('-voted_at')[:USERS_PAGE_SIZE]\r
-\r
- return {"view_user" : user, "votes" : votes}\r
-\r
-\r
-@user_view('users/reputation.html', 'reputation', _('user reputation in the community'), _('user reputation'))\r
+@user_view('users/reputation.html', 'reputation', _('karma history'), _('graph of user karma'))\r
def user_reputation(request, user):\r
rep = list(user.reputes.order_by('date'))\r
values = [r.value for r in rep]\r
\r
return {"view_user": user, "reputation": rep, "graph_data": graph_data}\r
\r
-@user_view('users/questions.html', 'favorites', _('favorite questions'), _('favorite questions'))\r
+@user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)\r
+def user_votes(request, user):\r
+ votes = user.votes.exclude(node__state_string__contains="(deleted").filter(\r
+ node__node_type__in=("question", "answer")).order_by('-voted_at')[:USERS_PAGE_SIZE]\r
+\r
+ return {"view_user" : user, "votes" : votes}\r
+\r
+@user_view('users/questions.html', 'favorites', _('favorites'), _('questions that user selected as his/her favorite'))\r
def user_favorites(request, user):\r
favorites = FavoriteAction.objects.filter(canceled=False, user=user)\r
\r
return {"favorites" : favorites, "view_user" : user}\r
\r
-@user_view('users/subscriptions.html', 'subscriptions', _('subscription settings'), _('subscriptions'), True)\r
+@user_view('users/subscriptions.html', 'subscriptions', _('subscription settings'), _('subscriptions'), True, tabbed=False)\r
def user_subscriptions(request, user):\r
if request.method == 'POST':\r
form = SubscriptionSettingsForm(request.POST)\r