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)
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)
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 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 )
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)
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 )
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()))
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
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_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)
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)
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)
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)
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')
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)
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)