Example #1
0
 def test_answer_to_private_question_is_not_globally_visible(self):
     question = self.post_question(user=self.admin, is_private=True)
     answer = self.post_answer(question=question,
                               user=self.admin,
                               is_private=False)
     global_group = get_global_group()
     self.assertEqual(global_group in set(answer.groups.all()), False)
Example #2
0
 def test_problem_to_private_exercise_is_not_globally_visible(self):
     exercise = self.post_exercise(user=self.admin, is_private=True)
     problem = self.post_problem(exercise=exercise,
                                 user=self.admin,
                                 is_private=False)
     global_group = get_global_group()
     self.assertEqual(global_group in set(problem.groups.all()), False)
    def test_post_private_question(self):
        data = self.qdata
        data['post_privately'] = 'checked'
        response1 = self.client.post(reverse('ask'), data=data)
        response2 = self.client.get(response1['location'])
        dom = BeautifulSoup(response2.content)
        title = dom.find('h1').text
        self.assertTrue(const.POST_STATUS['private'] in title)
        question = models.Thread.objects.get(id=1)
        self.assertEqual(question.title, self.qdata['title'])
        self.assertFalse(get_global_group() in set(question.groups.all()))

        #private question is not accessible to unauthorized users
        self.client.logout()
        response = self.client.get(question._question_post().get_absolute_url())
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.content, '')
        #private question link is not shown on the main page
        #to unauthorized users
        response = self.client.get(reverse('questions'))
        self.assertFalse(self.qdata['title'] in response.content)
        #private question link is not shown on the poster profile
        #to the unauthorized users
        response = self.client.get(self.user.get_profile_url())
        self.assertFalse(self.qdata['title'] in response.content)
Example #4
0
 def test_problem_to_private_exercise_is_not_globally_visible(self):
     exercise = self.post_exercise(user=self.admin, is_private=True)
     problem = self.post_problem(exercise=exercise, user=self.admin, is_private=False)
     global_group = get_global_group()
     self.assertEqual(
         global_group in set(problem.groups.all()),
         False
     )
Example #5
0
 def get_for_user(self, user=None, private=False):
     if private:
         global_group = get_global_group()
         return self.filter(
                     user=user
                 ).exclude(id=global_group.id)
     else:
         return self.filter(user = user)
 def test_answer_to_private_question_is_not_globally_visible(self):
     question = self.post_question(user=self.admin, is_private=True)
     answer = self.post_answer(question=question, user=self.admin, is_private=False)
     global_group = get_global_group()
     self.assertEqual(
         global_group in set(answer.groups.all()),
         False
     )
Example #7
0
 def get_for_user(self, user=None, private=False):
     if private:
         global_group = get_global_group()
         return self.filter(
                     user=user
                 ).exclude(id=global_group.id)
     else:
         return self.filter(user = user)
Example #8
0
 def test_problem_to_group_exercise_is_not_globally_visible(self):
     #ask into group where user is not a member
     exercise = self.post_exercise(user=self.user, group_id=self.group.id)
     #problem posted by a group member
     problem = self.post_problem(exercise=exercise,
                                 user=self.admin,
                                 is_private=False)
     global_group = get_global_group()
     self.assertEqual(global_group in set(problem.groups.all()), False)
Example #9
0
 def test_answer_to_group_question_is_not_globally_visible(self):
     #ask into group where user is not a member
     question = self.post_question(user=self.user, group_id=self.group.id)
     #answer posted by a group member
     answer = self.post_answer(question=question,
                               user=self.admin,
                               is_private=False)
     global_group = get_global_group()
     self.assertEqual(global_group in set(answer.groups.all()), False)
Example #10
0
 def test_problem_to_group_exercise_is_not_globally_visible(self):
     #ask into group where user is not a member
     exercise = self.post_exercise(user=self.user, group_id=self.group.id)
     #problem posted by a group member
     problem = self.post_problem(exercise=exercise, user=self.admin, is_private=False)
     global_group = get_global_group()
     self.assertEqual(
         global_group in set(problem.groups.all()),
         False
     )
 def test_answer_to_group_question_is_not_globally_visible(self):
     #ask into group where user is not a member
     question = self.post_question(user=self.user, group_id=self.group.id)
     #answer posted by a group member
     answer = self.post_answer(question=question, user=self.admin, is_private=False)
     global_group = get_global_group()
     self.assertEqual(
         global_group in set(answer.groups.all()),
         False
     )
Example #12
0
 def test_post_private_question(self):
     data = self.qdata
     data['post_privately'] = 'true'
     response1 = self.client.post(reverse('ask'), data=data)
     response2 = self.client.get(response1['location'])
     dom = BeautifulSoup(response2.content)
     title = dom.find('h1').text
     self.assertTrue(const.POST_STATUS['private'] in title)
     question = models.Thread.objects.get(id=1)
     self.assertEqual(question.title, self.qdata['title'])
     self.assertFalse(get_global_group() in set(question.groups.all()))
Example #13
0
def group_name_update_callback(old_name, new_name):
    from askbot.models.tag import get_global_group, clean_group_name
    cleaned_new_name = clean_group_name(new_name.strip())

    if new_name == '':
        #name cannot be empty
        return old_name

    group = get_global_group()
    group.name = cleaned_new_name
    group.save()
    return new_name
 def test_publish_private_answer(self):
     answer = self.post_answer(
         question=self.question, user=self.user, is_private=True
     )
     self.client.post(
         reverse('edit_answer', kwargs={'id': answer.id}),
         data={'text': 'edited answer text', 'select_revision': 'false'}
     )
     answer = self.reload_object(answer)
     self.assertTrue(get_global_group() in answer.groups.all())
     self.client.logout()
     response = self.client.get(self.question.get_absolute_url())
     self.assertTrue('edited answer text' in response.content)
def group_name_update_callback(old_name, new_name):
    from askbot.models.tag import get_global_group, clean_group_name

    cleaned_new_name = clean_group_name(new_name.strip())

    if new_name == "":
        # name cannot be empty
        return old_name

    group = get_global_group()
    group.name = cleaned_new_name
    group.save()
    return new_name
Example #16
0
    def test_thread_add_to_groups_recursive(self):
        data = self.post_question_answer_and_comments()

        private_group = self.create_group(group_name='private')
        thread = data['thread']
        thread.add_to_groups([private_group], recursive=True)

        global_group = get_global_group()
        groups = [global_group, private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(thread, groups)
        self.assertObjectGroupsEqual(data['question'], groups)
        self.assertObjectGroupsEqual(data['question_comment'], groups)
        self.assertObjectGroupsEqual(data['answer'], groups)
        self.assertObjectGroupsEqual(data['answer_comment'], groups)
    def test_thread_add_to_groups_recursive(self):
        data = self.post_question_answer_and_comments()

        private_group = self.create_group(group_name='private')
        thread = data['thread']
        thread.add_to_groups([private_group], recursive=True)

        global_group = get_global_group()
        groups = [global_group, private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(thread, groups)
        self.assertObjectGroupsEqual(data['question'], groups)
        self.assertObjectGroupsEqual(data['question_comment'], groups)
        self.assertObjectGroupsEqual(data['answer'], groups)
        self.assertObjectGroupsEqual(data['answer_comment'], groups)
Example #18
0
    def test_thread_add_to_groups_recursive(self):
        data = self.post_exercise_problem_and_comments()

        private_group = self.create_group(group_name='private')
        thread = data['thread']
        thread.add_to_groups([private_group], recursive=True)

        global_group = get_global_group()
        groups = [global_group, private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(thread, groups)
        self.assertObjectGroupsEqual(data['exercise'], groups)
        self.assertObjectGroupsEqual(data['exercise_comment'], groups)
        self.assertObjectGroupsEqual(data['problem'], groups)
        self.assertObjectGroupsEqual(data['problem_comment'], groups)
Example #19
0
 def test_privatize_public_question(self):
     question = self.post_question(user=self.user, is_private=True)
     title = question.thread.get_title()
     self.assertTrue(const.POST_STATUS['private'] in title)
     data = self.qdata
     data['post_privately'] = 'true'
     data['select_revision'] = 'false'
     response1 = self.client.post(
         reverse('edit_question', kwargs={'id':question.id}),
         data=data
     )
     response2 = self.client.get(question.get_absolute_url())
     dom = BeautifulSoup(response2.content)
     title = dom.find('h1').text
     self.assertFalse(get_global_group() in set(question.groups.all()))
     self.assertTrue(const.POST_STATUS['private'] in title)
Example #20
0
 def test_publish_private_exercise(self):
     exercise = self.post_exercise(user=self.user, is_private=True)
     title = exercise.thread.get_title()
     self.assertTrue(const.POST_STATUS['private'] in title)
     data = self.qdata
     data['post_privately'] = 'false'
     data['select_revision'] = 'false'
     response1 = self.client.post(
         reverse('edit_exercise', kwargs={'id':exercise.id}),
         data=data
     )
     response2 = self.client.get(exercise.get_absolute_url())
     dom = BeautifulSoup(response2.content)
     title = dom.find('h1').text
     self.assertTrue(get_global_group() in set(exercise.groups.all()))
     #todo: fix this fail
     self.assertEqual(title, self.qdata['title'])
    def test_post_private_answer(self):
        response1 = self.client.post(
            reverse('answer', kwargs={'id': self.question.id}),
            data={'text': 'some answer text', 'post_privately': 'checked'}
        )
        answer = self.question.thread.get_answers(user=self.user)[0]
        self.assertFalse(get_global_group() in set(answer.groups.all()))
        self.client.logout()

        user2 = self.create_user('user2')
        self.client.login(user_id=user2.id, method='force')
        response = self.client.get(self.question.get_absolute_url())
        self.assertFalse('some answer text' in response.content)

        self.client.logout()
        response = self.client.get(self.question.get_absolute_url())
        self.assertFalse('some answer text' in response.content)
 def test_privatize_public_answer(self):
     answer = self.post_answer(question=self.question, user=self.user)
     self.client.post(
         reverse('edit_answer', kwargs={'id': answer.id}),
         data={
             'text': 'edited answer text',
             'post_privately': 'checked',
             'select_revision': 'false'
         }
     )
     #check that answer is not visible to the "everyone" group
     answer = self.reload_object(answer)
     self.assertFalse(get_global_group() in answer.groups.all())
     #check that countent is not seen by an anonymous user
     self.client.logout()
     response = self.client.get(self.question.get_absolute_url())
     self.assertFalse('edited answer text' in response.content)
    def test_thread_make_public_recursive(self):
        private_group = self.create_group(group_name='private')
        self.u1.join_group(private_group)
        data = self.post_question_answer_and_comments(is_private=True)

        groups = [private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(data['thread'], groups)
        self.assertObjectGroupsEqual(data['question'], groups)
        self.assertObjectGroupsEqual(data['question_comment'], groups)
        self.assertObjectGroupsEqual(data['answer'], groups)
        self.assertObjectGroupsEqual(data['answer_comment'], groups)

        data['thread'].make_public(recursive=True)

        global_group = get_global_group()
        groups = [global_group, private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(data['thread'], groups)
        self.assertObjectGroupsEqual(data['question'], groups)
        self.assertObjectGroupsEqual(data['question_comment'], groups)
        self.assertObjectGroupsEqual(data['answer'], groups)
        self.assertObjectGroupsEqual(data['answer_comment'], groups)
Example #24
0
    def test_thread_make_public_recursive(self):
        private_group = self.create_group(group_name='private')
        self.u1.join_group(private_group)
        data = self.post_question_answer_and_comments(is_private=True)

        groups = [private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(data['thread'], groups)
        self.assertObjectGroupsEqual(data['question'], groups)
        self.assertObjectGroupsEqual(data['question_comment'], groups)
        self.assertObjectGroupsEqual(data['answer'], groups)
        self.assertObjectGroupsEqual(data['answer_comment'], groups)

        data['thread'].make_public(recursive=True)

        global_group = get_global_group()
        groups = [global_group, private_group, self.u1.get_personal_group()]
        self.assertObjectGroupsEqual(data['thread'], groups)
        self.assertObjectGroupsEqual(data['question'], groups)
        self.assertObjectGroupsEqual(data['question_comment'], groups)
        self.assertObjectGroupsEqual(data['answer'], groups)
        self.assertObjectGroupsEqual(data['answer_comment'], groups)
Example #25
0
def show_users(request, by_group=False, group_id=None, group_slug=None):
    """Users view, including listing of users by group"""

    if askbot_settings.GROUPS_ENABLED and not by_group:
        default_group = get_global_group()
        group_slug = slugify(default_group.name)
        new_url = reverse('users_by_group',
                          kwargs={
                              'group_id': default_group.id,
                              'group_slug': group_slug
                          })
        return HttpResponseRedirect(new_url)

    users = models.User.objects.exclude(status='b')
    group = None
    group_email_moderation_enabled = False
    user_acceptance_level = 'closed'
    user_membership_level = 'none'
    if by_group == True:
        if askbot_settings.GROUPS_ENABLED == False:
            raise Http404
        if group_id:
            if all((group_id, group_slug)) == False:
                return HttpResponseRedirect('groups')
            else:
                try:
                    group = models.Group.objects.get(id=group_id)
                    group_email_moderation_enabled = \
                        (
                            askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \
                            and askbot_settings.ENABLE_CONTENT_MODERATION
                        )
                    user_acceptance_level = group.get_openness_level_for_user(
                        request.user)
                except models.Group.DoesNotExist:
                    raise Http404
                if group_slug == slugify(group.name):
                    #filter users by full group memberships
                    #todo: refactor as Group.get_full_members()
                    full_level = models.GroupMembership.FULL
                    memberships = models.GroupMembership.objects.filter(
                        group=group, level=full_level)
                    user_ids = memberships.values_list('user__id', flat=True)
                    users = users.filter(id__in=user_ids)
                    if request.user.is_authenticated():
                        membership = request.user.get_group_membership(group)
                        if membership:
                            user_membership_level = membership.get_level_display(
                            )

                else:
                    group_page_url = reverse('users_by_group',
                                             kwargs={
                                                 'group_id': group.id,
                                                 'group_slug':
                                                 slugify(group.name)
                                             })
                    return HttpResponseRedirect(group_page_url)

    is_paginated = True

    sortby = request.GET.get('sort', 'reputation')
    if askbot_settings.KARMA_MODE == 'private' and sortby == 'reputation':
        sortby = 'newest'

    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    search_query = request.REQUEST.get('query', "")
    if search_query == "":
        if sortby == "newest":
            order_by_parameter = '-date_joined'
        elif sortby == "last":
            order_by_parameter = 'date_joined'
        elif sortby == "user":
            order_by_parameter = 'username'
        else:
            # default
            order_by_parameter = '-reputation'

        objects_list = Paginator(users.order_by(order_by_parameter),
                                 const.USERS_PAGE_SIZE)
        base_url = request.path + '?sort=%s&' % sortby
    else:
        sortby = "reputation"
        matching_users = models.get_users_by_text_query(search_query, users)
        objects_list = Paginator(matching_users.order_by('-reputation'),
                                 const.USERS_PAGE_SIZE)
        base_url = request.path + '?name=%s&sort=%s&' % (search_query,
                                                                 sortby)

    try:
        users_page = objects_list.page(page)
    except (EmptyPage, InvalidPage):
        users_page = objects_list.page(objects_list.num_pages)

    paginator_data = {
        'is_paginated': is_paginated,
        'pages': objects_list.num_pages,
        'page': page,
        'has_previous': users_page.has_previous(),
        'has_next': users_page.has_next(),
        'previous': users_page.previous_page_number(),
        'next': users_page.next_page_number(),
        'base_url': base_url
    }
    paginator_context = functions.setup_paginator(paginator_data)  #

    #todo: move to contexts
    #extra context for the groups
    if askbot_settings.GROUPS_ENABLED:
        #todo: cleanup this branched code after groups are migrated to auth_group
        user_groups = get_groups().exclude_personal()
        if len(user_groups) <= 1:
            assert (user_groups[0].name == askbot_settings.GLOBAL_GROUP_NAME)
            user_groups = None
        group_openness_choices = models.Group().get_openness_choices()
    else:
        user_groups = None
        group_openness_choices = None

    data = {
        'active_tab': 'users',
        'page_class': 'users-page',
        'users': users_page,
        'group': group,
        'search_query': search_query,
        'tab_id': sortby,
        'paginator_context': paginator_context,
        'group_email_moderation_enabled': group_email_moderation_enabled,
        'user_acceptance_level': user_acceptance_level,
        'user_membership_level': user_membership_level,
        'user_groups': user_groups,
        'group_openness_choices': group_openness_choices
    }

    return render_into_skin('users.html', data, request)
Example #26
0
def user_stats(request, user, context):
    question_filter = {}
    if request.user != user:
        question_filter['is_anonymous'] = False

    if askbot_settings.ENABLE_CONTENT_MODERATION:
        question_filter['approved'] = True

    #
    # Questions
    #
    questions = user.posts.get_questions().filter(**question_filter).\
                    order_by('-points', '-thread__last_activity_at').\
                    select_related('thread', 'thread__last_activity_by')[:100]

    #added this if to avoid another query if questions is less than 100
    if len(questions) < 100:
        question_count = len(questions)
    else:
        question_count = user.posts.get_questions().filter(**question_filter).count()

    #
    # Top answers
    #
    top_answers = user.posts.get_answers(
        request.user
    ).filter(
        deleted=False,
        thread__posts__deleted=False,
        thread__posts__post_type='question',
    ).select_related(
        'thread'
    ).order_by(
        '-points', '-added_at'
    )[:100]

    top_answer_count = len(top_answers)
    #
    # Votes
    #
    up_votes = models.Vote.objects.get_up_vote_count_from_user(user)
    down_votes = models.Vote.objects.get_down_vote_count_from_user(user)
    votes_today = models.Vote.objects.get_votes_count_today_from_user(user)
    votes_total = askbot_settings.MAX_VOTES_PER_USER_PER_DAY

    #
    # Tags
    #
    # INFO: There's bug in Django that makes the following query kind of broken (GROUP BY clause is problematic):
    #       http://stackoverflow.com/questions/7973461/django-aggregation-does-excessive-group-by-clauses
    #       Fortunately it looks like it returns correct results for the test data
    user_tags = models.Tag.objects.filter(threads__posts__author=user).distinct().\
                    annotate(user_tag_usage_count=Count('threads')).\
                    order_by('-user_tag_usage_count')[:const.USER_VIEW_DATA_SIZE]
    user_tags = list(user_tags) # evaluate

    when = askbot_settings.MARKED_TAGS_ARE_PUBLIC_WHEN
    if when == 'always' or \
        (when == 'when-user-wants' and user.show_marked_tags == True):
        #refactor into: user.get_marked_tag_names('good'/'bad'/'subscribed')
        interesting_tag_names = user.get_marked_tag_names('good')
        ignored_tag_names = user.get_marked_tag_names('bad')
        subscribed_tag_names = user.get_marked_tag_names('subscribed')
    else:
        interesting_tag_names = None
        ignored_tag_names = None
        subscribed_tag_names = None

#    tags = models.Post.objects.filter(author=user).values('id', 'thread', 'thread__tags')
#    post_ids = set()
#    thread_ids = set()
#    tag_ids = set()
#    for t in tags:
#        post_ids.add(t['id'])
#        thread_ids.add(t['thread'])
#        tag_ids.add(t['thread__tags'])
#        if t['thread__tags'] == 11:
#            print t['thread'], t['id']
#    import ipdb; ipdb.set_trace()

    #
    # Badges/Awards (TODO: refactor into Managers/QuerySets when a pattern emerges; Simplify when we get rid of Question&Answer models)
    #
    post_type = ContentType.objects.get_for_model(models.Post)

    user_awards = models.Award.objects.filter(user=user).select_related('badge')

    awarded_post_ids = []
    for award in user_awards:
        if award.content_type_id == post_type.id:
            awarded_post_ids.append(award.object_id)

    awarded_posts = models.Post.objects.filter(id__in=awarded_post_ids)\
                    .select_related('thread') # select related to avoid additional queries in Post.get_absolute_url()

    awarded_posts_map = {}
    for post in awarded_posts:
        awarded_posts_map[post.id] = post

    badges_dict = collections.defaultdict(list)

    for award in user_awards:
        # Fetch content object
        if award.content_type_id == post_type.id:
            #here we go around a possibility of awards
            #losing the content objects when the content
            #objects are deleted for some reason
            awarded_post = awarded_posts_map.get(award.object_id, None)
            if awarded_post is not None:
                #protect from awards that are associated with deleted posts
                award.content_object = awarded_post
                award.content_object_is_post = True
            else:
                award.content_object_is_post = False
        else:
            award.content_object_is_post = False

        # "Assign" to its Badge
        badges_dict[award.badge].append(award)

    badges = badges_dict.items()
    badges.sort(key=operator.itemgetter(1), reverse=True)

    user_groups = models.Group.objects.get_for_user(user = user)
    user_groups = user_groups.exclude_personal()
    global_group = get_global_group()
    user_groups = user_groups.exclude(name=global_group.name)

    if request.user == user:
        groups_membership_info = user.get_groups_membership_info(user_groups)
    else:
        groups_membership_info = collections.defaultdict()

    data = {
        'active_tab':'users',
        'page_class': 'user-profile-page',
        'support_custom_avatars': ('avatar' in django_settings.INSTALLED_APPS),
        'tab_name' : 'stats',
        'tab_description' : _('user profile'),
        'page_title' : _('user profile overview'),
        'user_status_for_display': user.get_status_display(soft = True),
        'questions' : questions,
        'question_count': question_count,

        'top_answers': top_answers,
        'top_answer_count': top_answer_count,

        'up_votes' : up_votes,
        'down_votes' : down_votes,
        'total_votes': up_votes + down_votes,
        'votes_today_left': votes_total - votes_today,
        'votes_total_per_day': votes_total,

        'user_tags' : user_tags,
        'user_groups': user_groups,
        'groups_membership_info': groups_membership_info,
        'interesting_tag_names': interesting_tag_names,
        'ignored_tag_names': ignored_tag_names,
        'subscribed_tag_names': subscribed_tag_names,
        'badges': badges,
        'total_badges' : len(badges),
    }
    context.update(data)

    return render_into_skin('user_profile/user_stats.html', context, request)
 def test_ask_global_group_by_id_works(self):
     group = get_global_group()
     q = self.post_question(user=self.u1, group_id=group.id)
     self.assertEqual(q.groups.count(), 2)
     self.assertEqual(q.groups.filter(name=group.name).exists(), True)
 def test_global_group_name_setting_changes_group_name(self):
     askbot_settings.update('GLOBAL_GROUP_NAME', 'all-people')
     group = get_global_group()
     self.assertEqual(group.name, 'all-people')
Example #29
0
def show_users(request, by_group=False, group_id=None, group_slug=None):
    """Users view, including listing of users by group"""

    if askbot_settings.GROUPS_ENABLED and not by_group:
        default_group = get_global_group()
        group_slug = slugify(default_group.name)
        new_url = reverse('users_by_group',
                kwargs={'group_id': default_group.id,
                        'group_slug': group_slug})
        return HttpResponseRedirect(new_url)

    users = models.User.objects.exclude(status = 'b')
    group = None
    group_email_moderation_enabled = False
    user_acceptance_level = 'closed'
    user_membership_level = 'none'
    if by_group == True:
        if askbot_settings.GROUPS_ENABLED == False:
            raise Http404
        if group_id:
            if all((group_id, group_slug)) == False:
                return HttpResponseRedirect('groups')
            else:
                try:
                    group = models.Group.objects.get(id = group_id)
                    group_email_moderation_enabled = \
                        (
                            askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \
                            and askbot_settings.ENABLE_CONTENT_MODERATION
                        )
                    user_acceptance_level = group.get_openness_level_for_user(
                                                                    request.user
                                                                )
                except models.Group.DoesNotExist:
                    raise Http404
                if group_slug == slugify(group.name):
                    #filter users by full group memberships
                    #todo: refactor as Group.get_full_members()
                    full_level = models.GroupMembership.FULL
                    memberships = models.GroupMembership.objects.filter(
                                                    group=group, level=full_level
                                                )
                    user_ids = memberships.values_list('user__id', flat=True)
                    users = users.filter(id__in=user_ids)
                    if request.user.is_authenticated():
                        membership = request.user.get_group_membership(group)
                        if membership:
                            user_membership_level = membership.get_level_display()

                else:
                    group_page_url = reverse(
                                        'users_by_group',
                                        kwargs = {
                                            'group_id': group.id,
                                            'group_slug': slugify(group.name)
                                        }
                                    )
                    return HttpResponseRedirect(group_page_url)

    is_paginated = True

    sortby = request.GET.get('sort', 'reputation')
    if askbot_settings.KARMA_MODE == 'private' and sortby == 'reputation':
        sortby = 'newest'

    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    search_query = request.REQUEST.get('query',  "")
    if search_query == "":
        if sortby == "newest":
            order_by_parameter = '-date_joined'
        elif sortby == "last":
            order_by_parameter = 'date_joined'
        elif sortby == "user":
            order_by_parameter = 'username'
        else:
            # default
            order_by_parameter = '-reputation'

        objects_list = Paginator(
                            users.order_by(order_by_parameter),
                            const.USERS_PAGE_SIZE
                        )
        base_url = request.path + '?sort=%s&amp;' % sortby
    else:
        sortby = "reputation"
        matching_users = models.get_users_by_text_query(search_query, users)
        objects_list = Paginator(
                            matching_users.order_by('-reputation'),
                            const.USERS_PAGE_SIZE
                        )
        base_url = request.path + '?name=%s&amp;sort=%s&amp;' % (search_query, sortby)

    try:
        users_page = objects_list.page(page)
    except (EmptyPage, InvalidPage):
        users_page = objects_list.page(objects_list.num_pages)

    paginator_data = {
        'is_paginated' : is_paginated,
        'pages': objects_list.num_pages,
        'page': page,
        'has_previous': users_page.has_previous(),
        'has_next': users_page.has_next(),
        'previous': users_page.previous_page_number(),
        'next': users_page.next_page_number(),
        'base_url' : base_url
    }
    paginator_context = functions.setup_paginator(paginator_data) #

    #todo: move to contexts
    #extra context for the groups
    if askbot_settings.GROUPS_ENABLED:
        #todo: cleanup this branched code after groups are migrated to auth_group
        user_groups = get_groups().exclude_personal()
        if len(user_groups) <= 1:
            assert(user_groups[0].name == askbot_settings.GLOBAL_GROUP_NAME)
            user_groups = None
        group_openness_choices = models.Group().get_openness_choices()
    else:
        user_groups = None
        group_openness_choices = None

    data = {
        'active_tab': 'users',
        'page_class': 'users-page',
        'users' : users_page,
        'group': group,
        'search_query' : search_query,
        'tab_id' : sortby,
        'paginator_context' : paginator_context,
        'group_email_moderation_enabled': group_email_moderation_enabled,
        'user_acceptance_level': user_acceptance_level,
        'user_membership_level': user_membership_level,
        'user_groups': user_groups,
        'group_openness_choices': group_openness_choices
    }

    return render_into_skin('users.html', data, request)
Example #30
0
 def test_ask_global_group_by_id_works(self):
     group = get_global_group()
     q = self.post_question(user=self.u1, group_id=group.id)
     self.assertEqual(q.groups.count(), 2)
     self.assertEqual(q.groups.filter(name=group.name).exists(), True)
Example #31
0
 def test_global_group_name_setting_changes_group_name(self):
     askbot_settings.update('GLOBAL_GROUP_NAME', 'all-people')
     group = get_global_group()
     self.assertEqual(group.name, 'all-people')
Example #32
0
def user_stats(request, user, context):
    question_filter = {}
    if request.user != user:
        question_filter['is_anonymous'] = False

    if askbot_settings.ENABLE_CONTENT_MODERATION:
        question_filter['approved'] = True

    #
    # Questions
    #
    questions = user.posts.get_questions().filter(**question_filter).\
                    order_by('-points', '-thread__last_activity_at').\
                    select_related('thread', 'thread__last_activity_by')[:100]

    #added this if to avoid another query if questions is less than 100
    if len(questions) < 100:
        question_count = len(questions)
    else:
        question_count = user.posts.get_questions().filter(
            **question_filter).count()

    #
    # Top answers
    #
    top_answers = user.posts.get_answers(request.user).filter(
        deleted=False,
        thread__posts__deleted=False,
        thread__posts__post_type='question',
    ).select_related('thread').order_by('-points', '-added_at')[:100]

    top_answer_count = len(top_answers)
    #
    # Votes
    #
    up_votes = models.Vote.objects.get_up_vote_count_from_user(user)
    down_votes = models.Vote.objects.get_down_vote_count_from_user(user)
    votes_today = models.Vote.objects.get_votes_count_today_from_user(user)
    votes_total = askbot_settings.MAX_VOTES_PER_USER_PER_DAY

    #
    # Tags
    #
    # INFO: There's bug in Django that makes the following query kind of broken (GROUP BY clause is problematic):
    #       http://stackoverflow.com/questions/7973461/django-aggregation-does-excessive-group-by-clauses
    #       Fortunately it looks like it returns correct results for the test data
    user_tags = models.Tag.objects.filter(threads__posts__author=user).distinct().\
                    annotate(user_tag_usage_count=Count('threads')).\
                    order_by('-user_tag_usage_count')[:const.USER_VIEW_DATA_SIZE]
    user_tags = list(user_tags)  # evaluate

    when = askbot_settings.MARKED_TAGS_ARE_PUBLIC_WHEN
    if when == 'always' or \
        (when == 'when-user-wants' and user.show_marked_tags == True):
        #refactor into: user.get_marked_tag_names('good'/'bad'/'subscribed')
        interesting_tag_names = user.get_marked_tag_names('good')
        ignored_tag_names = user.get_marked_tag_names('bad')
        subscribed_tag_names = user.get_marked_tag_names('subscribed')
    else:
        interesting_tag_names = None
        ignored_tag_names = None
        subscribed_tag_names = None


#    tags = models.Post.objects.filter(author=user).values('id', 'thread', 'thread__tags')
#    post_ids = set()
#    thread_ids = set()
#    tag_ids = set()
#    for t in tags:
#        post_ids.add(t['id'])
#        thread_ids.add(t['thread'])
#        tag_ids.add(t['thread__tags'])
#        if t['thread__tags'] == 11:
#            print t['thread'], t['id']
#    import ipdb; ipdb.set_trace()

#
# Badges/Awards (TODO: refactor into Managers/QuerySets when a pattern emerges; Simplify when we get rid of Question&Answer models)
#
    post_type = ContentType.objects.get_for_model(models.Post)

    user_awards = models.Award.objects.filter(
        user=user).select_related('badge')

    awarded_post_ids = []
    for award in user_awards:
        if award.content_type_id == post_type.id:
            awarded_post_ids.append(award.object_id)

    awarded_posts = models.Post.objects.filter(id__in=awarded_post_ids)\
                    .select_related('thread') # select related to avoid additional queries in Post.get_absolute_url()

    awarded_posts_map = {}
    for post in awarded_posts:
        awarded_posts_map[post.id] = post

    badges_dict = collections.defaultdict(list)

    for award in user_awards:
        # Fetch content object
        if award.content_type_id == post_type.id:
            #here we go around a possibility of awards
            #losing the content objects when the content
            #objects are deleted for some reason
            awarded_post = awarded_posts_map.get(award.object_id, None)
            if awarded_post is not None:
                #protect from awards that are associated with deleted posts
                award.content_object = awarded_post
                award.content_object_is_post = True
            else:
                award.content_object_is_post = False
        else:
            award.content_object_is_post = False

        # "Assign" to its Badge
        badges_dict[award.badge].append(award)

    badges = badges_dict.items()
    badges.sort(key=operator.itemgetter(1), reverse=True)

    user_groups = models.Group.objects.get_for_user(user=user)
    user_groups = user_groups.exclude_personal()
    global_group = get_global_group()
    user_groups = user_groups.exclude(name=global_group.name)

    if request.user == user:
        groups_membership_info = user.get_groups_membership_info(user_groups)
    else:
        groups_membership_info = collections.defaultdict()

    data = {
        'active_tab': 'users',
        'page_class': 'user-profile-page',
        'support_custom_avatars': ('avatar' in django_settings.INSTALLED_APPS),
        'tab_name': 'stats',
        'tab_description': _('user profile'),
        'page_title': _('user profile overview'),
        'user_status_for_display': user.get_status_display(soft=True),
        'questions': questions,
        'question_count': question_count,
        'top_answers': top_answers,
        'top_answer_count': top_answer_count,
        'up_votes': up_votes,
        'down_votes': down_votes,
        'total_votes': up_votes + down_votes,
        'votes_today_left': votes_total - votes_today,
        'votes_total_per_day': votes_total,
        'user_tags': user_tags,
        'user_groups': user_groups,
        'groups_membership_info': groups_membership_info,
        'interesting_tag_names': interesting_tag_names,
        'ignored_tag_names': ignored_tag_names,
        'subscribed_tag_names': subscribed_tag_names,
        'badges': badges,
        'total_badges': len(badges),
    }
    context.update(data)

    return render_into_skin('user_profile/user_stats.html', context, request)