'profile_link': self.hyperlink(self.user.get_profile_url(), _('profile')),
}
+class BonusRepAction(ActionProxy):
+ def process_data(self, value):
+ self._value = value
+
+ def repute_users(self):
+ self.repute(self.user, self._value)
+ self.user.message_set.create(message=_("Congratulations, you have been awarded an extra %s reputation points.") % self._value +
+ '<br />%s' % self.extra.get('message', _('Thank you')))
+
+ def describe(self, viewer=None):
+ value = self.extra.get('value', _('unknown'))
+ message = self.extra.get('message', '')
+
+ return _("%(user)s %(was_were)s awarded %(value)s reputation points: %(message)s") % {
+ 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
+ 'was_were': self.viewer_or_user_verb(viewer, self.user, _('were'), _('was')),
+ 'value': value, 'message': message
+ }
+
class AwardAction(ActionProxy):
def process_data(self, badge, trigger):
self.__dict__['_badge'] = badge
notify_comments = forms.BooleanField(required=False, initial=False)
notify_accepted = forms.BooleanField(required=False, initial=False)
+
+class AwardPointsForm(forms.Form):
+ points = forms.IntegerField(min_value=1, initial=50, label=_('Points to award'))
+ message = forms.CharField(widget=forms.Textarea(), label=_('Message'), required=False)
--- /dev/null
+
+function show_dialog (html, extra_class, pos, dim, yes, no_text) {
+ $dialog = $('<div class="dialog ' + extra_class + '" style="width: 1px; height: 1px;">'
+ + '<div class="dialog-content">' + html + '</div><div class="dialog-buttons">'
+ + '<button class="dialog-no">' + no_text + '</button>'
+ + '<button class="dialog-yes">' + yes.text + '</button>'
+ + '</div></div>');
+
+ $('body').append($dialog);
+
+ $dialog.css({
+ top: pos.y,
+ left: pos.x
+ });
+
+ $dialog.animate({
+ top: "-=" + (dim.h / 2),
+ left: "-=" + (dim.w / 2),
+ width: dim.w,
+ height: dim.h
+ }, 200, function() {
+ $dialog.find('.dialog-no').click(function() {
+ $dialog.fadeOut('fast');
+ });
+ $dialog.find('.dialog-yes').click(function() {
+ yes.callback($dialog);
+ });
+ });
+
+}
+
+
+$().ready(function() {
+ var $dropdown = $('#user-menu-dropdown');
+
+ $('#user-menu').click(function(){
+ $('.dialog').fadeOut('fast');
+ $dropdown.slideToggle('fast');
+ });
+
+ $('.confirm').each(function() {
+ var $link = $(this);
+
+ $link.click(function(e) {
+ $dropdown.slideUp('fast');
+ var html = messages.confirm;
+
+ show_dialog(html, 'confirm', {x: e.pageX, y: e.pageY}, {w: 200, h: 100}, {
+ text: messages.yes,
+ callback: function() {
+ window.location = $link.attr('href');
+ }
+ }, messages.no);
+
+ return false;
+ });
+ });
+
+ $('#award-rep-points').click(function(e) {
+ $dropdown.slideUp('fast');
+
+ var html = '<table><tr><th>' + messages.points + '</th><td><input type="text" id="points-to-award" value="1" /></td></tr>'
+ + '<tr><th>' + messages.message + '</th><td><textarea id="award-message"></textarea></td></tr></table>';
+
+ show_dialog(html, 'award-rep-points', {x: e.pageX, y: e.pageY}, {w: 300, h: 125}, {
+ text: messages.award,
+ callback: function($dialog) {
+ var $points_input = $('#points-to-award');
+ var _points = parseInt($points_input.val());
+
+ if(!isNaN(_points)) {
+ $dialog.fadeOut('fast');
+ var _message = $('#award-message').val();
+ $.post($('#award-rep-points').attr('href'), {points: _points, message: _message}, function(data) {
+ if (data.success) {
+ $('#user-reputation').css('background', 'yellow');
+ $('#user-reputation').html(data.reputation);
+
+ $('#user-reputation').animate({ backgroundColor: "transparent" }, 1000);
+
+ }
+ }, 'json')
+ }
+ }
+ }, messages.cancel);
+
+
+ return false;
+ });
+});
\ No newline at end of file
.moderation #action_status {
font-weight: bold;
text-align: center;
+}
+
+.moderation-table input[type=text], .moderation-table textarea {
+ width: 150px;
+ max-height: 50px;
+}
+
+.moderation-table th {
+ vertical-align: top;
+ text-align: left;
+}
+
+.moderation-table-footer {
+ text-align: right;
}
\ No newline at end of file
--- /dev/null
+#user-menu-container {
+ position: relative;
+ text-align: right;
+}
+
+#user-menu {
+ cursor: pointer;
+ height: 1em;
+ font-size: 120%;
+ font-weight: bold;
+ color: #3060A8;
+}
+
+#user-menu-dropdown, div.dialog {
+ position: absolute;
+ background-color: #B6C4E2;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -moz-box-shadow: 2px 2px 5px #3060A8;
+ -webkit-box-shadow: 2px 2px 5px #3060A8;
+}
+
+div.dialog .dialog-buttons {
+ margin: 0px;
+ height: 25px;
+ text-align: center;
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+ width: 100%;
+}
+
+.dialog-yes, .dialog-no {
+ margin: 0 3px 5px 3px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ background-color: #3060A8;
+ color: white;
+ height: 20px;
+ line-height: 20px;
+ font-weight: bold;
+ border: 0;
+}
+
+div.dialog.confirm {
+ text-align: center;
+ line-height: 75px;
+ font-size: 140%;
+ font-weight: bold;
+}
+
+div.dialog.award-rep-points table {
+ margin: auto;
+ margin-top: 8px;
+}
+
+div.dialog.award-rep-points table th {
+ text-align: left;
+}
+
+div.dialog.award-rep-points table input, div.dialog.award-rep-points table textarea {
+ width: 150px;
+ max-height: 35px;
+}
+
+#user-menu-dropdown {
+ display: none;
+ right: 0px;
+ top: 1.5em;
+ text-align: left;
+ list-style-type: none;
+}
+
+#user-menu-dropdown li.item {
+ padding: 4px 8px 4px 8px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+
+#user-menu-dropdown li.item a {
+ color: inherit;
+ white-space: nowrap;
+ text-decoration: none;
+}
+
+#user-menu-dropdown li.separator {
+ text-align: center;
+ padding: 10px 0 4px 0;
+ font-size: 120%;
+ font-weight: bold;
+}
+
+#user-menu-dropdown li.item:hover {
+ background-color: #3060A8;
+ color: white;
+}
+
+#user-menu-dropdown span {
+ margin-right: 4px;
+ float: left;
+ width: 16px;
+ height: 16px;
+}
+
+.user-auth { background: url('/m/default/media/images/user-sprite.png') no-repeat 0 0; }
+.user-award_rep { background: url('/m/default/media/images/user-sprite.png') no-repeat 0 -17px; }
+.user-edit { background: url('/m/default/media/images/user-sprite.png') no-repeat 0 -34px; }
+.user-moderator { background: url('/m/default/media/images/user-sprite.png') no-repeat 0 -51px; }
+.user-subscriptions { background: url('/m/default/media/images/user-sprite.png') no-repeat 0 -68px; }
+.user-superuser { background: url('/m/default/media/images/user-sprite.png') no-repeat 0 -85px; }
-{% extends "base.html" %}
+{% extends "user.html" %}
<!-- changepw.html -->
{% load i18n %}
{% block head %}{% endblock %}
{% block title %}{% spaceless %}{% trans "Authentication settings" %}{% endspaceless %}{% endblock %}
-{% block content %}
-<div class="headNormal">{% trans "Authentication settings" %}</div>
+{% block usercontent %}
+<h2>{% trans "Authentication settings" %}</h2>
{% if auth_keys %}
<p class="message">{% blocktrans %}These are the external authentication providers currently associated with your account.{% endblocktrans %}</p>
<div>
{% if not auth_keys %}
<p class="message">{% blocktrans %}You currently have no external authentication provider associated with your account.{% endblocktrans %}</p>
{% endif %}
-{% ifequal user request.user %}
+{% ifequal view_user request.user %}
<input type="button" class="submit" value="{% trans "Add new provider" %}" onclick="window.location='{% url user_add_external_provider %}'" />
{% endifequal %}
{% if has_password %}
{% load extra_tags %}
{% load extra_filters %}
{% load humanize %}
+{% load smart_if %}
+
{% block title %}{% spaceless %}{{ page_title }}{% endspaceless %}{% endblock %}
{% block forestyle%}
<style type="text/css">
</style>
{% endblock %}
{% block forejs %}
- {% if request.user.is_superuser %}
+ {% if request.user.is_superuser or request.user == view_user %}
<script type='text/javascript' src='{% media "/media/js/jquery.form.js" %}'></script>
+ <script type="text/javascript">google.load("jquery", "1.4.2");google.load("jqueryui", "1.8.1");</script>
+ <script src="{% media "/media/js/osqa.user.js" %}" type="text/javascript"></script>
+
+ <link rel="stylesheet" href="http://jquery-ui.googlecode.com/svn/tags/latest/themes/base/jquery-ui.css" type="text/css" media="all" />
+ <link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />
+ <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/user.css" %}"/>
{% endif %}
<script type="text/javascript">
var viewUserID = {{view_user.id}};
{% load i18n %}
{% load markup %}
{% load user_tags %}
+
<div id="subheader" class="headUser">
{{view_user.username}}
</div>
</tr>
<tr>
<td align="center">
- <div class="scoreNumber">{{view_user.reputation|intcomma}}</div>
+ <div class="scoreNumber" id="user-reputation">{{view_user.reputation|intcomma}}</div>
<p><b style="color:#777;">{% trans "reputation" %}</b></p>
</td>
</tr>
</table>
</td>
<td width="360" style="vertical-align: top;">
+ {% if can_view_private %}{% user_menu request.user view_user %}{% endif %}
<table class="user-details">
- {% if view_user != request.user and request.user.is_superuser %}
- <tr>
- <td class="moderation" align="left" colspan="2">
- {% user_moderation request.user view_user %}
- </td>
- </tr>
- {% endif %}
- {% if can_view_private %}
- <tr>
- <td class="user-profile-tool-links" align="left" colspan="2">
- {% joinitems using ' | ' %}
- <span class="user-edit-link"><a href="{% url edit_user id=view_user.id %}">{% trans "update profile" %}</a></span>
- {% separator %}
- <a href="{% url user_authsettings id=view_user.id %}">{% trans "authentication settings" %}</a>
- {% endjoinitems %}
- </td>
- </tr>
- {% endif %}
<tr>
<th colspan="2" align="left"><h3>{% trans "Registered user" %}</h3></th>
</tr>
--- /dev/null
+{% load i18n %}\r
+{% load smart_if %}\r
+\r
+<script type="text/javascript">\r
+var messages = {\r
+ username: '{{ user.username }}}',\r
+ confirm: "{% trans "Are you sure?" %}",\r
+ yes: "{% trans "Yes" %}",\r
+ no: "{% trans "No" %}",\r
+ points: "{% trans "Points to award:" %}",\r
+ message: "{% trans "Message:" %}",\r
+ award: "{% trans "Award" %}",\r
+ cancel: "{% trans "Cancel" %}"\r
+}\r
+</script>\r
+\r
+<div id="user-menu-container">\r
+ <span id="user-menu">{% trans "User tools" %} ▼</span>\r
+ <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
+ {% ifnotequal user viewer %}\r
+ {% if viewer.is_superuser %}\r
+ <li class="separator">{% trans "Moderation tools" %}</li>\r
+ <li class="item"><span class="user-award_rep"></span><a href="{% url user_award_points id=user.id %}" id="award-rep-points">{% trans "reputation bonus" %}</a></li>\r
+ {% if not user.is_superuser %}\r
+ {% if not user.is_staff %}\r
+ <li class="item"><span class="user-moderator"></span>\r
+ <a class="confirm" href="{% url user_powers id=user.id,action="grant",status="staff" %}">{% trans "grant moderator status" %}</a>\r
+ </li>\r
+ {% else %}\r
+ <li class="item"><span class="user-moderator"></span>\r
+ <a class="confirm" href="{% url user_powers id=user.id,action="remove",status="staff" %}">{% trans "remove moderator status" %}</a>\r
+ </li>\r
+ {% endif %}\r
+ <li class="item"><span class="user-superuser"></span>\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
+ <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
+ {% endifnotequal %}\r
+ </ul>\r
+</div>\r
+\r
+{% comment %}\r
+<h3>{% trans "Moderation tools" %}</h3>\r
+<p><a href="#" id="point-award-action">{% trans "Reputation bonus" %}</a></p>\r
+<form action="" method="POST">\r
+ <table style="display: none" id="award-points-table" class="moderation-table">\r
+ {{ awardform.as_table }}\r
+ <tr><td colspan="2" class="moderation-table-footer"><input type="submit" id="award-points-submit" value="{% trans "Send" %}" /></td></tr>\r
+ </table> \r
+</form>\r
+<script>\r
+ $(function() {\r
+ $('#point-award-action').click(function() {\r
+ $('#award-points-table').slideToggle('slow');\r
+ });\r
+\r
+ $('#award-points-submit').click(function() {\r
+ $('#award-points-table').find('.error').remove();\r
+ var $points_input = $('#award-points-table').find('input[type=text]');\r
+ var points = parseInt($points_input.val());\r
+\r
+ if (isNaN(points) || points < 1) {\r
+ $points_input.before('<p class="error">{% trans "Sorry but that\'s not a valid input" %}</p>');\r
+ return false;\r
+ }\r
+\r
+ $.post('{% url user_award_points id=user.id %}')\r
+ });\r
+ });\r
+</script>\r
+{% if not user.is_superuser %}\r
+<p><a href="{% url user_powers id=user.id,action="grant",status="super" %}">{% trans "Grant super user status" %}</a></p>\r
+ {% if not user.is_staff %}\r
+ <p><a href="{% url user_powers id=user.id,action="grant",status="staff" %}">{% trans "Grant moderator status" %}</a></p>\r
+ {% else %}\r
+ <p><a href="{% url user_powers id=user.id,action="remove",status="staff" %}" class="">{% trans "Remove moderator status" %}</a></p>\r
+ {% endif %}\r
+{% else %}\r
+ {% ifequal moderator.id 1 %}\r
+ {% ifnotequal user.id 1 %}\r
+ <p><a href="{% url user_powers id=user.id,action="remove",status="super" %}">{% trans "Remove super user status" %}</a></p>\r
+ {% endifnotequal %}\r
+ {% endifequal %}\r
+{% endif %}\r
+\r
+{% endcomment %}\r
+++ /dev/null
-{% load i18n %}\r
-\r
-<h3>{% trans "Moderation tools" %}</h3>\r
-<p><a href="#" class="ajax-command">{% trans "Reputation bonus" %}</a></p>\r
-{% if not user.is_superuser %}\r
-<p><a href="{% url user_powers id=user.id,action="grant",status="super" %}">{% trans "Grant super user status" %}</a></p>\r
- {% if not user.is_staff %}\r
- <p><a href="{% url user_powers id=user.id,action="grant",status="staff" %}">{% trans "Grant moderator status" %}</a></p>\r
- {% else %}\r
- <p><a href="{% url user_powers id=user.id,action="remove",status="staff" %}" class="">{% trans "Remove moderator status" %}</a></p>\r
- {% endif %}\r
-{% else %}\r
- {% ifequal moderator.id 1 %}\r
- {% ifnotequal user.id 1 %}\r
- <p><a href="{% url user_powers id=user.id,action="remove",status="super" %}">{% trans "Remove super user status" %}</a></p>\r
- {% endifnotequal %}\r
- {% endifequal %}\r
-{% endif %}\r
<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>
- {% if can_view_private %}
- <a id="email_subscriptions" {% ifequal tab_name "subscriptions" %}class="on"{% endifequal %}
- title="{% trans "email subscription settings" %}"
- href="{% url user_subscriptions id=view_user.id,slug=user_slug %}">{% trans "subscriptions" %}</a>
- {% endif %}
</div>
</div>
{% endwith %}
from django import template\r
from django.utils.translation import ugettext as _\r
from django.utils.safestring import mark_safe\r
+from forum.forms import AwardPointsForm\r
import logging\r
\r
register = template.Library()\r
return ActivityNode(activity, viewer)\r
\r
\r
-@register.inclusion_tag('users/moderation.html')\r
-def user_moderation(moderator, user):\r
- return dict(moderator=moderator, user=user)\r
+@register.inclusion_tag('users/menu.html')\r
+def user_menu(request, user):\r
+ return dict(viewer=request.user, user=user)\r
\r
url(r'^%s$' % _('users/'),app.users.users, name='users'),
url(r'^%s(?P<id>\d+)/%s$' % (_('users/'), _('edit/')), app.users.edit_user, name='edit_user'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('users/'), _('award/')), app.users.award_points, name='user_award_points'),
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+)/(?P<slug>.+)/%s$' % (_('users/'), _('subscriptions/')), app.users.user_subscriptions, name='user_subscriptions'),
+ url(r'^%s(?P<id>\d+)/%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'),
url(r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % (_('users/'), _('reputation/')), app.users.user_reputation, name='user_reputation'),
url(r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % (_('users/'), _('votes/')), app.users.user_votes, name='user_votes'),
})
return render_to_response('auth/auth_settings.html', {
- 'user': user_,
+ 'view_user': user_,
+ "can_view_private": (user_ == request.user) or request.user.is_superuser,
'form': form,
'has_password': user_.has_usable_password(),
'auth_keys': auth_keys_list,
\r
response['success'] = True\r
except Exception, e:\r
- #import sys, traceback\r
- #traceback.print_exc(file=sys.stdout)\r
+ import sys, traceback\r
+ traceback.print_exc(file=sys.stdout)\r
\r
if isinstance(e, CommandException):\r
response = {\r
from forum.utils.html import sanitize_html\r
from datetime import date\r
import decorators\r
-from forum.actions import EditProfileAction, FavoriteAction\r
+from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction\r
\r
import time\r
\r
return HttpResponseRedirect(user.get_profile_url())\r
\r
\r
+@decorators.command\r
+def award_points(request, id):\r
+ if (not request.POST) and request.POST.get('points', None):\r
+ raise decorators.CommandException(_("Invalid request type"))\r
+\r
+ if not request.user.is_superuser:\r
+ raise decorators.CommandException(_("Only superusers are allowed to award reputation points"))\r
+\r
+ user = get_object_or_404(User, id=id)\r
+ points = int(request.POST['points'])\r
+\r
+ extra = dict(message=request.POST.get('message', ''), awarding_user=request.user.id, value=points)\r
+\r
+ BonusRepAction(user=user, extra=extra).save(data=dict(value=points))\r
+\r
+ return dict(reputation=user.reputation)\r
+\r
+\r
def user_view(template, tab_name, tab_description, page_title, private=False):\r
def decorator(fn):\r
def decorated(request, id, slug=None):\r