]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/views/users.py
use latest jQuery version
[osqa.git] / forum / views / users.py
index 836b62172ef5829f07aff78931221290eb4e1b3f..db65003c7130c1f51571e84bd746dd4492715ab4 100644 (file)
@@ -1,4 +1,3 @@
-from django.contrib.auth.decorators import login_required\r
 from forum.models import User\r
 from django.db.models import Q, Count\r
 from django.core.paginator import Paginator, EmptyPage, InvalidPage\r
 from forum.models import User\r
 from django.db.models import Q, Count\r
 from django.core.paginator import Paginator, EmptyPage, InvalidPage\r
@@ -12,17 +11,19 @@ from forum.http_responses import HttpResponseUnauthorized
 from django.utils.translation import ugettext as _\r
 from django.utils.http import urlquote_plus\r
 from django.utils.html import strip_tags\r
 from django.utils.translation import ugettext as _\r
 from django.utils.http import urlquote_plus\r
 from django.utils.html import strip_tags\r
+from django.utils.encoding import smart_unicode\r
 from django.utils import simplejson\r
 from django.core.urlresolvers import reverse, NoReverseMatch\r
 from forum.forms import *\r
 from forum.utils.html import sanitize_html\r
 from django.utils import simplejson\r
 from django.core.urlresolvers import reverse, NoReverseMatch\r
 from forum.forms import *\r
 from forum.utils.html import sanitize_html\r
-from forum.modules import decorate\r
+from forum.modules import decorate, ReturnImediatelyException\r
 from datetime import datetime, date\r
 from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction\r
 from forum.modules import ui\r
 from forum.utils import pagination\r
 from forum.views.readers import QuestionListPaginatorContext, AnswerPaginatorContext\r
 from datetime import datetime, date\r
 from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction\r
 from forum.modules import ui\r
 from forum.utils import pagination\r
 from forum.views.readers import QuestionListPaginatorContext, AnswerPaginatorContext\r
-\r
+from forum.settings import ONLINE_USERS\r
\r
 import time\r
 import datetime\r
 import decorators\r
 import time\r
 import datetime\r
 import decorators\r
@@ -32,13 +33,13 @@ class UserReputationSort(pagination.SimpleSort):
         return objects.order_by('-is_active', self.order_by)\r
 \r
 class UserListPaginatorContext(pagination.PaginatorContext):\r
         return objects.order_by('-is_active', self.order_by)\r
 \r
 class UserListPaginatorContext(pagination.PaginatorContext):\r
-    def __init__(self):\r
+    def __init__(self, pagesizes=(20, 35, 60)):\r
         super (UserListPaginatorContext, self).__init__('USERS_LIST', sort_methods=(\r
             (_('reputation'), UserReputationSort(_('reputation'), '-reputation', _("sorted by reputation"))),\r
             (_('newest'), pagination.SimpleSort(_('recent'), '-date_joined', _("newest members"))),\r
             (_('last'), pagination.SimpleSort(_('oldest'), 'date_joined', _("oldest members"))),\r
             (_('name'), pagination.SimpleSort(_('by username'), 'username', _("sorted by username"))),\r
         super (UserListPaginatorContext, self).__init__('USERS_LIST', sort_methods=(\r
             (_('reputation'), UserReputationSort(_('reputation'), '-reputation', _("sorted by reputation"))),\r
             (_('newest'), pagination.SimpleSort(_('recent'), '-date_joined', _("newest members"))),\r
             (_('last'), pagination.SimpleSort(_('oldest'), 'date_joined', _("oldest members"))),\r
             (_('name'), pagination.SimpleSort(_('by username'), 'username', _("sorted by username"))),\r
-        ), pagesizes=(20, 35, 60))\r
+        ), pagesizes=pagesizes)\r
 \r
 class SubscriptionListPaginatorContext(pagination.PaginatorContext):\r
     def __init__(self):\r
 \r
 class SubscriptionListPaginatorContext(pagination.PaginatorContext):\r
     def __init__(self):\r
@@ -68,22 +69,69 @@ def users(request):
     })\r
 \r
 \r
     })\r
 \r
 \r
-#@decorators.render('users/online_users.html', 'online_users', _('Online Users'), weight=200)\r
+@decorators.render('users/online_users.html', 'online_users', _('Online Users'), weight=200, tabbed=False)\r
 def online_users(request):\r
     suser = request.REQUEST.get('q', "")\r
 \r
 def online_users(request):\r
     suser = request.REQUEST.get('q', "")\r
 \r
-    one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)\r
-    sql_datetime = datetime.datetime.strftime(one_hour_ago, '%Y-%m-%d %H:%M:%S')\r
-    users = User.objects.order_by('-last_seen')\r
+    sort = ""\r
+    if request.GET.get("sort", None):\r
+        try:\r
+            sort = int(request.GET["sort"])\r
+        except ValueError:\r
+            logging.error('Found invalid sort "%s", loading %s, refered by %s' % (\r
+                request.GET.get("sort", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
+            ))\r
+            raise Http404()\r
+\r
+    page = 0\r
+    if request.GET.get("page", None):\r
+        try:\r
+            page = int(request.GET["page"])\r
+        except ValueError:\r
+            logging.error('Found invalid page "%s", loading %s, refered by %s' % (\r
+                request.GET.get("page", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
+            ))\r
+            raise Http404()\r
 \r
 \r
-    return pagination.paginated(request, ('users', UserListPaginatorContext()), {\r
+    pagesize = 10\r
+    if request.GET.get("pagesize", None):\r
+        try:\r
+            pagesize = int(request.GET["pagesize"])\r
+        except ValueError:\r
+            logging.error('Found invalid pagesize "%s", loading %s, refered by %s' % (\r
+                request.GET.get("pagesize", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
+            ))\r
+            raise Http404()\r
+\r
+\r
+    users = None\r
+    if sort == "reputation":\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.reputation)\r
+    elif sort == "newest" :\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)\r
+    elif sort == "last":\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.last)\r
+    elif sort == "name":\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.name)\r
+    elif sort == "oldest":\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.oldest)\r
+    elif sort == "newest":\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)\r
+    elif sort == "votes":\r
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.votes)\r
+    else:\r
+        users = sorted(ONLINE_USERS.iteritems(), key=lambda x: x[1])\r
+\r
+    return render_to_response('users/online_users.html', {\r
         "users" : users,\r
         "suser" : suser,\r
         "users" : users,\r
         "suser" : suser,\r
+        "sort" : sort,\r
+        "page" : page,\r
+        "pageSize" : pagesize,\r
     })\r
 \r
 \r
     })\r
 \r
 \r
-@login_required\r
-def edit_user(request, id):\r
+def edit_user(request, id, slug):\r
     user = get_object_or_404(User, id=id)\r
     if not (request.user.is_superuser or request.user == user):\r
         return HttpResponseUnauthorized(request)\r
     user = get_object_or_404(User, id=id)\r
     if not (request.user.is_superuser or request.user == user):\r
         return HttpResponseUnauthorized(request)\r
@@ -188,10 +236,10 @@ def suspend(request, id):
             return render_to_response('users/suspend_user.html')\r
 \r
     data = {\r
             return render_to_response('users/suspend_user.html')\r
 \r
     data = {\r
-    'bantype': request.POST.get('bantype', 'indefinetly').strip(),\r
-    'publicmsg': request.POST.get('publicmsg', _('Bad behaviour')),\r
-    'privatemsg': request.POST.get('privatemsg', None) or request.POST.get('publicmsg', ''),\r
-    'suspended': user\r
+        'bantype': request.POST.get('bantype', 'indefinetly').strip(),\r
+        'publicmsg': request.POST.get('publicmsg', _('Bad behaviour')),\r
+        'privatemsg': request.POST.get('privatemsg', None) or request.POST.get('publicmsg', ''),\r
+        'suspended': user\r
     }\r
 \r
     if data['bantype'] == 'forxdays':\r
     }\r
 \r
     if data['bantype'] == 'forxdays':\r
@@ -207,20 +255,39 @@ def suspend(request, id):
 \r
 def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500):\r
     def decorator(fn):\r
 \r
 def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500):\r
     def decorator(fn):\r
-        def params(request, id, slug=None):\r
-            user = get_object_or_404(User, id=id)\r
+        def params(request, id=None, slug=None):\r
+            # Get the user object by id if the id parameter has been passed\r
+            if id is not None:\r
+                user = get_object_or_404(User, id=id)\r
+            # ...or by slug if the slug has been given\r
+            elif slug is not None:\r
+                try:\r
+                    user = User.objects.get(username__iexact=slug)\r
+                except User.DoesNotExist:\r
+                    raise Http404\r
+\r
             if private and not (user == request.user or request.user.is_superuser):\r
             if private and not (user == request.user or request.user.is_superuser):\r
-                return HttpResponseUnauthorized(request)\r
+                raise ReturnImediatelyException(HttpResponseUnauthorized(request))\r
 \r
             if render_to and (not render_to(user)):\r
 \r
             if render_to and (not render_to(user)):\r
-                return HttpResponseRedirect(user.get_profile_url())\r
+                raise ReturnImediatelyException(HttpResponseRedirect(user.get_profile_url()))\r
 \r
 \r
-            return [request, user], {}\r
+            return [request, user], { 'slug' : slug, }\r
 \r
         decorated = decorate.params.withfn(params)(fn)\r
 \r
 \r
         decorated = decorate.params.withfn(params)(fn)\r
 \r
-        def result(context, request, user):\r
-            rev_page_title = user.username + " - " + tab_description\r
+        def result(context_or_response, request, user, **kwargs):\r
+            rev_page_title = smart_unicode(user.username) + " - " + tab_description\r
+\r
+            # Check whether the return type of the decorated function is a context or Http Response\r
+            if isinstance(context_or_response, HttpResponse):\r
+                response = context_or_response\r
+\r
+                # If it is a response -- show it\r
+                return response\r
+            else:\r
+                # ...if it is a context move forward, update it and render it to response\r
+                context = context_or_response\r
 \r
             context.update({\r
                 "tab": "users",\r
 \r
             context.update({\r
                 "tab": "users",\r
@@ -236,9 +303,12 @@ def user_view(template, tab_name, tab_title, tab_description, private=False, tab
         if tabbed:\r
             def url_getter(vu):\r
                 try:\r
         if tabbed:\r
             def url_getter(vu):\r
                 try:\r
-                    return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(vu.username)})\r
+                    return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(smart_unicode(vu.username))})\r
                 except NoReverseMatch:\r
                 except NoReverseMatch:\r
-                    return reverse(fn.__name__, kwargs={'id': vu.id})\r
+                    try:\r
+                        return reverse(fn.__name__, kwargs={'id': vu.id})\r
+                    except NoReverseMatch:\r
+                        return reverse(fn.__name__, kwargs={'slug': slugify(smart_unicode(vu.username))})\r
 \r
             ui.register(ui.PROFILE_TABS, ui.ProfileTab(\r
                 tab_name, tab_title, tab_description,url_getter, private, render_to, weight\r
 \r
             ui.register(ui.PROFILE_TABS, ui.ProfileTab(\r
                 tab_name, tab_title, tab_description,url_getter, private, render_to, weight\r
@@ -249,14 +319,19 @@ def user_view(template, tab_name, tab_title, tab_description, private=False, tab
 \r
 \r
 @user_view('users/stats.html', 'stats', _('overview'), _('user overview'))\r
 \r
 \r
 @user_view('users/stats.html', 'stats', _('overview'), _('user overview'))\r
-def user_profile(request, user):\r
+def user_profile(request, user, **kwargs):\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
     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
+    # Check whether the passed slug matches the one for the user object\r
+    slug = kwargs['slug']\r
+    if slug != slugify(smart_unicode(user.username)):\r
+        return HttpResponseRedirect(user.get_absolute_url())\r
+\r
     up_votes = user.vote_up_count\r
     down_votes = user.vote_down_count\r
     votes_today = user.get_vote_count_today()\r
     up_votes = user.vote_up_count\r
     down_votes = user.vote_down_count\r
     votes_today = user.get_vote_count_today()\r
-    votes_total = int(settings.MAX_VOTES_PER_DAY)\r
+    votes_total = user.can_vote_count_today()\r
 \r
     user_tags = Tag.objects.filter(Q(nodes__author=user) | Q(nodes__children__author=user)) \\r
         .annotate(user_tag_usage_count=Count('name')).order_by('-user_tag_usage_count')\r
 \r
     user_tags = Tag.objects.filter(Q(nodes__author=user) | Q(nodes__children__author=user)) \\r
         .annotate(user_tag_usage_count=Count('name')).order_by('-user_tag_usage_count')\r
@@ -265,7 +340,7 @@ def user_profile(request, user):
               Badge.objects.filter(awards__user=user).values('id').annotate(count=Count('cls')).order_by('-count')]\r
 \r
     return pagination.paginated(request, (\r
               Badge.objects.filter(awards__user=user).values('id').annotate(count=Count('cls')).order_by('-count')]\r
 \r
     return pagination.paginated(request, (\r
-    ('questions', QuestionListPaginatorContext('USER_QUESTION_LIST', _('questions'), 15)),\r
+    ('questions', QuestionListPaginatorContext('USER_QUESTION_LIST', _('questions'), default_pagesize=15)),\r
     ('answers', UserAnswersPaginatorContext())), {\r
     "view_user" : user,\r
     "questions" : questions,\r
     ('answers', UserAnswersPaginatorContext())), {\r
     "view_user" : user,\r
     "questions" : questions,\r
@@ -281,7 +356,7 @@ def user_profile(request, user):
     })\r
     \r
 @user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))\r
     })\r
     \r
 @user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))\r
-def user_recent(request, user):\r
+def user_recent(request, user, **kwargs):\r
     activities = user.actions.exclude(\r
             action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(\r
             '-action_date')[:USERS_PAGE_SIZE]\r
     activities = user.actions.exclude(\r
             action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(\r
             '-action_date')[:USERS_PAGE_SIZE]\r
@@ -289,14 +364,14 @@ def user_recent(request, user):
     return {"view_user" : user, "activities" : activities}\r
 \r
 \r
     return {"view_user" : user, "activities" : activities}\r
 \r
 \r
-@user_view('users/reputation.html', 'reputation', _('karma history'), _('graph of user karma'))\r
-def user_reputation(request, user):\r
+@user_view('users/reputation.html', 'reputation', _('reputation history'), _('graph of user karma'))\r
+def user_reputation(request, user, **kwargs):\r
     rep = list(user.reputes.order_by('date'))\r
     values = [r.value for r in rep]\r
     redux = lambda x, y: x+y\r
 \r
     graph_data = simplejson.dumps([\r
     rep = list(user.reputes.order_by('date'))\r
     values = [r.value for r in rep]\r
     redux = lambda x, y: x+y\r
 \r
     graph_data = simplejson.dumps([\r
-    (time.mktime(rep[i].date.timetuple()) * 1000, reduce(redux, values[:i], 0))\r
+    (time.mktime(rep[i].date.timetuple()) * 1000, reduce(redux, values[:i+1], 0))\r
     for i in range(len(values))\r
     ])\r
 \r
     for i in range(len(values))\r
     ])\r
 \r
@@ -305,69 +380,69 @@ def user_reputation(request, user):
     return {"view_user": user, "reputation": rep, "graph_data": graph_data}\r
 \r
 @user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)\r
     return {"view_user": user, "reputation": rep, "graph_data": graph_data}\r
 \r
 @user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)\r
-def user_votes(request, user):\r
+def user_votes(request, user, **kwargs):\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
     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
+def user_favorites(request, user, **kwargs):\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'), _('subscriptions'), True, tabbed=False)\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'), _('subscriptions'), True, tabbed=False)\r
-def user_subscriptions(request, user):\r
-    enabled = user.subscription_settings.enable_notifications\r
-    auto = request.GET.get('auto', 'True')\r
-    show_auto = True\r
-    manage_open = False\r
-    \r
-    if len(request.GET) > 0:\r
+def user_subscriptions(request, user, **kwargs):\r
+    enabled = True\r
+\r
+    tab = request.GET.get('tab', "settings")\r
+\r
+    # Manage tab\r
+    if tab == 'manage':\r
         manage_open = True\r
         manage_open = True\r
-        \r
-    if auto == 'True':\r
-        show_auto = True\r
-        subscriptions = user.subscriptions.all().order_by('-questionsubscription__last_view')\r
-    else:\r
-        show_auto = False\r
-        subscriptions = user.subscriptions.filter(questionsubscription__auto_subscription=False).order_by('-questionsubscription__last_view')\r
 \r
 \r
-    if request.method == 'POST':\r
+        auto = request.GET.get('auto', 'True')\r
+        if auto == 'True':\r
+            show_auto = True\r
+            subscriptions = QuestionSubscription.objects.filter(user=user).order_by('-last_view')\r
+        else:\r
+            show_auto = False\r
+            subscriptions = QuestionSubscription.objects.filter(user=user, auto_subscription=False).order_by('-last_view')\r
+\r
+        return pagination.paginated(request, ('subscriptions', SubscriptionListPaginatorContext()), {\r
+            'subscriptions':subscriptions,\r
+            'view_user':user,\r
+            "auto":show_auto,\r
+            'manage_open':manage_open,\r
+        })\r
+    # Settings Tab and everything else\r
+    else:\r
         manage_open = False\r
         manage_open = False\r
-        form = SubscriptionSettingsForm(data=request.POST, instance=user.subscription_settings)\r
+        if request.method == 'POST':\r
+            manage_open = False\r
+            form = SubscriptionSettingsForm(data=request.POST, instance=user.subscription_settings)\r
 \r
 \r
-        if form.is_valid():\r
-            form.save()\r
-            message = _('New subscription settings are now saved')\r
+            if form.is_valid():\r
+                form.save()\r
+                message = _('New subscription settings are now saved')\r
 \r
 \r
-            if 'notswitch' in request.POST:\r
-                enabled = not enabled\r
+                user.subscription_settings.enable_notifications = enabled\r
+                user.subscription_settings.save()\r
 \r
 \r
-                if enabled:\r
-                    message = _('Notifications are now enabled')\r
-                else:\r
-                    message = _('Notifications are now disabled')\r
+                request.user.message_set.create(message=message)\r
+        else:\r
+            form = SubscriptionSettingsForm(instance=user.subscription_settings)\r
 \r
 \r
-            user.subscription_settings.enable_notifications = enabled\r
-            user.subscription_settings.save()\r
-\r
-            request.user.message_set.create(message=message)\r
-    else:\r
-        form = SubscriptionSettingsForm(instance=user.subscription_settings)\r
-\r
-    return pagination.paginated(request, ('subscriptions', SubscriptionListPaginatorContext()), {\r
-        'subscriptions':subscriptions,\r
-        'view_user':user,\r
-        'notificatons_on': enabled,\r
-        'form':form,\r
-        "auto":show_auto,\r
-        "manage_open":manage_open\r
-    })\r
+        return {\r
+            'view_user':user,\r
+            'notificatons_on': enabled,\r
+            'form':form,\r
+            'manage_open':manage_open,\r
+        }\r
 \r
 @user_view('users/preferences.html', 'preferences', _('preferences'), _('preferences'), True, tabbed=False)\r
 \r
 @user_view('users/preferences.html', 'preferences', _('preferences'), _('preferences'), True, tabbed=False)\r
-def user_preferences(request, user):\r
+def user_preferences(request, user, **kwargs):\r
     if request.POST:\r
         form = UserPreferencesForm(request.POST)\r
 \r
     if request.POST:\r
         form = UserPreferencesForm(request.POST)\r
 \r
@@ -385,13 +460,4 @@ def user_preferences(request, user):
             \r
     return {'view_user': user, 'form': form}\r
 \r
             \r
     return {'view_user': user, 'form': form}\r
 \r
-@login_required\r
-def account_settings(request):\r
-    logging.debug('')\r
-    msg = request.GET.get('msg', '')\r
-    is_openid = False\r
 \r
 \r
-    return render_to_response('account_settings.html', {\r
-    'msg': msg,\r
-    'is_openid': is_openid\r
-    }, context_instance=RequestContext(request))\r