def list_suggested_tags(request): """moderators and administrators can list tags that are in the moderation queue, apply suggested tag to questions or cancel the moderation reuest.""" if askbot_settings.ENABLE_TAG_MODERATION == False: raise Http404 tags = Tag.objects.filter(status=Tag.STATUS_SUGGESTED) tags = tags.order_by('-used_count', 'name') #paginate moderated tags paginator = Paginator(tags, 20) page_no = request.GET.get('page', '1') try: page = paginator.page(page_no) except (EmptyPage, InvalidPage): page = paginator.page(paginator.num_pages) paginator_context = functions.setup_paginator({ 'is_paginated': True, 'pages': paginator.num_pages, 'current_page_number': page_no, 'page_object': page, 'base_url': request.path }) data = { 'tags': page.object_list, 'active_tab': 'tags', 'tab_id': 'suggested', 'page_class': 'moderate-tags-page', 'page_title': _('Suggested tags'), 'paginator_context': paginator_context, } return render(request, 'list_suggested_tags.html', data)
def badge(request, id): #todo: supplement database data with the stuff from badges.py badge = get_object_or_404(BadgeData, id=id) all_badge_recipients = User.objects.filter( award_user__badge=badge).annotate( last_awarded_at=Max('award_user__awarded_at'), award_count=Count('award_user')).order_by('-last_awarded_at') objects_list = Paginator(all_badge_recipients, askbot_settings.USERS_PAGE_SIZE) page = PageField().clean(request.GET.get('page')) try: badge_recipients = objects_list.page(page) except (EmptyPage, InvalidPage): badge_recipients = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated': (objects_list.num_pages > 1), 'pages': objects_list.num_pages, 'current_page_number': page, 'page_object': badge_recipients, 'base_url': reverse('badge', kwargs={'id': badge.id}) + '?' } paginator_context = functions.setup_paginator(paginator_data) data = { 'active_tab': 'badges', 'badge_recipients': badge_recipients, 'badge': badge, 'page_class': 'meta', 'paginator_context': paginator_context } return render(request, 'badge.html', data)
def user_favorites(request, user, context): favorite_threads = user.user_favorite_questions.values_list('thread', flat=True) questions_qs = models.Post.objects.filter( post_type='question', thread__in=favorite_threads ).select_related( 'thread', 'thread__last_activity_by' ).order_by( '-points', '-thread__last_activity_at' )[:const.USER_VIEW_DATA_SIZE] q_paginator = Paginator(questions_qs, const.USER_POSTS_PAGE_SIZE) questions = q_paginator.page(1).object_list question_count = q_paginator.count q_paginator_context = functions.setup_paginator({ 'is_paginated' : (question_count > const.USER_POSTS_PAGE_SIZE), 'pages': q_paginator.num_pages, 'current_page_number': 1, 'page_object': q_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) data = { 'active_tab':'users', 'page_class': 'user-profile-page', 'tab_name' : 'favorites', 'page_title' : _('profile - favorites'), 'questions' : questions, 'q_paginator_context': q_paginator_context, 'question_count': question_count, 'page_size': const.USER_POSTS_PAGE_SIZE } context.update(data) return render(request, 'user_profile/user_favorites.html', context)
def list_suggested_tags(request): """moderators and administrators can list tags that are in the moderation queue, apply suggested tag to questions or cancel the moderation reuest.""" if askbot_settings.ENABLE_TAG_MODERATION == False: raise Http404 tags = Tag.objects.filter(status = Tag.STATUS_SUGGESTED) tags = tags.order_by('-used_count', 'name') #paginate moderated tags paginator = Paginator(tags, 20) page_no = request.GET.get('page', '1') try: page = paginator.page(page_no) except (EmptyPage, InvalidPage): page = paginator.page(paginator.num_pages) paginator_context = functions.setup_paginator({ 'is_paginated' : True, 'pages': paginator.num_pages, 'current_page_number': page_no, 'page_object': page, 'base_url' : request.path }) data = { 'tags': page.object_list, 'active_tab': 'tags', 'tab_id': 'suggested', 'page_class': 'moderate-tags-page', 'page_title': _('Suggested tags'), 'paginator_context' : paginator_context, } return render(request, 'list_suggested_tags.html', data)
def users(request): is_paginated = True sortby = request.GET.get("sort", "reputation") suser = request.REQUEST.get("query", "") try: page = int(request.GET.get("page", "1")) except ValueError: page = 1 if suser == "": 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(models.User.objects.all().order_by(order_by_parameter), const.USERS_PAGE_SIZE) base_url = reverse("users") + "?sort=%s&" % sortby else: sortby = "reputation" objects_list = Paginator( models.User.objects.filter(username__icontains=suser).order_by("-reputation"), const.USERS_PAGE_SIZE ) base_url = reverse("users") + "?name=%s&sort=%s&" % (suser, 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) # data = { "active_tab": "users", "page_class": "users-page", "users": users_page, "suser": suser, "keywords": suser, "tab_id": sortby, "paginator_context": paginator_context, } return render_into_skin("users.html", data, request)
def list_suggested_tags(request): """moderators and administrators can list tags that are in the moderation queue, apply suggested tag to questions or cancel the moderation reuest.""" if askbot_settings.ENABLE_TAG_MODERATION == False: raise Http404 tags = Tag.objects.filter(status=Tag.STATUS_SUGGESTED) tags = tags.order_by("-used_count", "name") # paginate moderated tags paginator = Paginator(tags, 20) page_no = request.GET.get("page", "1") try: page = paginator.page(page_no) except (EmptyPage, InvalidPage): page = paginator.page(paginator.num_pages) paginator_context = functions.setup_paginator( { "is_paginated": True, "pages": paginator.num_pages, "page": page_no, "has_previous": page.has_previous(), "has_next": page.has_next(), "previous": page.previous_page_number(), "next": page.next_page_number(), "base_url": request.path, } ) data = { "tags": page.object_list, "active_tab": "tags", "tab_id": "suggested", "page_class": "moderate-tags-page", "page_title": _("Suggested tags"), "paginator_context": paginator_context, } return render_into_skin("list_suggested_tags.html", data, request)
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(name__startswith='_internal_') 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 tags(request):#view showing a listing of available tags - plain list form = ShowTagsForm(request.REQUEST) form.full_clean() #always valid page = form.cleaned_data['page'] sort_method = form.cleaned_data['sort'] query = form.cleaned_data['query'] tag_list_type = askbot_settings.TAG_LIST_FORMAT #2) Get query set for the tags. query_params = { 'deleted': False, 'language_code': translation.get_language() } if query != '': query_params['name__icontains'] = query tags_qs = Tag.objects.filter(**query_params).exclude(used_count=0) if sort_method == 'name': order_by = 'name' else: order_by = '-used_count' tags_qs = tags_qs.order_by(order_by) #3) Start populating the template context. data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tag_list_type' : tag_list_type, 'query' : query, 'tab_id' : sort_method, 'keywords' : query, 'search_state': SearchState(*[None for x in range(8)]) } if tag_list_type == 'list': #plain listing is paginated objects_list = Paginator(tags_qs, const.TAGS_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated' : (objects_list.num_pages > 1), 'pages': objects_list.num_pages, 'current_page_number': page, 'page_object': tags, 'base_url' : reverse('tags') + '?sort=%s&' % sort_method } paginator_context = functions.setup_paginator(paginator_data) data['paginator_context'] = paginator_context else: #tags for the tag cloud are given without pagination tags = tags_qs font_size = extra_tags.get_tag_font_size(tags) data['font_size'] = font_size data['tags'] = tags data.update(context.get_extra('ASKBOT_TAGS_PAGE_EXTRA_CONTEXT', request, data)) if request.is_ajax(): template = get_template('tags/content.html') template_context = RequestContext(request, data) json_data = {'success': True, 'html': template.render(template_context)} json_string = simplejson.dumps(json_data) return HttpResponse(json_string, content_type='application/json') else: return render(request, 'tags.html', data)
def user_stats(request, user, context): question_filter = {} if request.user != user: question_filter['is_anonymous'] = False if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation': question_filter['approved'] = True # # Questions # questions_qs = user.posts.get_questions( user=request.user ).filter( **question_filter ).order_by( '-points', '-thread__last_activity_at' ).select_related( 'thread', 'thread__last_activity_by' ) q_paginator = Paginator(questions_qs, const.USER_POSTS_PAGE_SIZE) questions = q_paginator.page(1).object_list question_count = q_paginator.count q_paginator_context = functions.setup_paginator({ 'is_paginated' : (question_count > const.USER_POSTS_PAGE_SIZE), 'pages': q_paginator.num_pages, 'current_page_number': 1, 'page_object': q_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) # # Top answers # a_paginator = user.get_top_answers_paginator(request.user) top_answers = a_paginator.page(1).object_list top_answer_count = a_paginator.count a_paginator_context = functions.setup_paginator({ 'is_paginated' : (top_answer_count > const.USER_POSTS_PAGE_SIZE), 'pages': a_paginator.num_pages, 'current_page_number': 1, 'page_object': a_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) # # 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, language_code=get_language() ).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: if award.badge.is_enabled() == False: continue # 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 = models.Group.objects.get_global_group() user_groups = user_groups.exclude(name=global_group.name) if request.user.pk == user.pk: 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', 'page_title' : _('user profile overview'), 'questions' : questions, 'question_count': question_count, 'q_paginator_context': q_paginator_context, 'top_answers': top_answers, 'top_answer_count': top_answer_count, 'a_paginator_context': a_paginator_context, 'page_size': const.USER_POSTS_PAGE_SIZE, '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) extra_context = view_context.get_extra( 'ASKBOT_USER_PROFILE_PAGE_EXTRA_CONTEXT', request, context ) context.update(extra_context) return render(request, 'user_profile/user_stats.html', context)
def questions(request, **kwargs): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ #before = datetime.datetime.now() if request.method != 'GET': return HttpResponseNotAllowed(['GET']) search_state = SearchState( user_logged_in=request.user.is_authenticated(), **kwargs ) page_size = int(askbot_settings.DEFAULT_QUESTIONS_PAGE_SIZE) qs, meta_data = models.Thread.objects.run_advanced_search( request_user=request.user, search_state=search_state ) current_lang = request.session['django_language'] langs = settings.ASKBOT_LANG_TAGS.copy() if current_lang in langs: langs.pop(current_lang) if current_lang == 'en': qs = qs.exclude(tags__name__in=langs) else: qs = qs.filter(tags__name=current_lang) if meta_data['non_existing_tags']: search_state = search_state.remove_tags(meta_data['non_existing_tags']) paginator = Paginator(qs, page_size) if paginator.num_pages < search_state.page: search_state.page = 1 page = paginator.page(search_state.page) page.object_list = list(page.object_list) # evaluate the queryset # INFO: Because for the time being we need question posts and thread authors # down the pipeline, we have to precache them in thread objects models.Thread.objects.precache_view_data_hack(threads=page.object_list) related_tags = Tag.objects.get_related_to_search( threads=page.object_list, ignored_tag_names=meta_data.get('ignored_tag_names',[]) ) tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'cloud': #force cloud to sort by name related_tags = sorted(related_tags, key = operator.attrgetter('name')) contributors = list( models.Thread.objects.get_thread_contributors( thread_list=page.object_list ).only('id', 'username', 'gravatar') ) paginator_context = { 'is_paginated' : (paginator.count > page_size), 'pages': paginator.num_pages, 'page': search_state.page, 'has_previous': page.has_previous(), 'has_next': page.has_next(), 'previous': page.previous_page_number(), 'next': page.next_page_number(), 'base_url' : search_state.query_string(), 'page_size' : page_size, } # We need to pass the rss feed url based # on the search state to the template. # We use QueryDict to get a querystring # from dicts and arrays. Much cleaner # than parsing and string formating. rss_query_dict = QueryDict("").copy() if search_state.query: # We have search string in session - pass it to # the QueryDict rss_query_dict.update({"q": search_state.query}) if search_state.tags: # We have tags in session - pass it to the # QueryDict but as a list - we want tags+ rss_query_dict.setlist("tags", search_state.tags) context_feed_url = '/%sfeeds/rss/?%s' % (settings.ASKBOT_URL, rss_query_dict.urlencode()) # Format the url with the QueryDict reset_method_count = len(filter(None, [search_state.query, search_state.tags, meta_data.get('author_name', None)])) if request.is_ajax(): q_count = paginator.count question_counter = ungettext('%(q_num)s question', '%(q_num)s questions', q_count) question_counter = question_counter % {'q_num': humanize.intcomma(q_count),} if q_count > page_size: paginator_tpl = get_template('main_page/paginator.html') paginator_html = paginator_tpl.render( RequestContext( request, { 'context': functions.setup_paginator(paginator_context), 'questions_count': q_count, 'page_size' : page_size, 'search_state': search_state, } ) ) else: paginator_html = '' questions_tpl = get_template('main_page/questions_loop.html') questions_html = questions_tpl.render( RequestContext( request, { 'threads': page, 'search_state': search_state, 'reset_method_count': reset_method_count, 'request': request } ) ) ajax_data = { 'query_data': { 'tags': search_state.tags, 'sort_order': search_state.sort, 'ask_query_string': search_state.ask_query_string(), }, 'paginator': paginator_html, 'question_counter': question_counter, 'faces': [],#[extra_tags.gravatar(contributor, 48) for contributor in contributors], 'feed_url': context_feed_url, 'query_string': search_state.query_string(), 'page_size' : page_size, 'questions': questions_html.replace('\n',''), 'non_existing_tags': meta_data['non_existing_tags'] } ajax_data['related_tags'] = [{ 'name': escape(tag.name), 'used_count': humanize.intcomma(tag.local_used_count) } for tag in related_tags] return HttpResponse(simplejson.dumps(ajax_data), mimetype = 'application/json') else: # non-AJAX branch template_data = { 'active_tab': 'questions', 'author_name' : meta_data.get('author_name',None), 'contributors' : contributors, 'context' : paginator_context, 'is_unanswered' : False,#remove this from template 'interesting_tag_names': meta_data.get('interesting_tag_names', None), 'ignored_tag_names': meta_data.get('ignored_tag_names', None), 'subscribed_tag_names': meta_data.get('subscribed_tag_names', None), 'language_code': translation.get_language(), 'name_of_anonymous_user' : models.get_name_of_anonymous_user(), 'page_class': 'main-page', 'page_size': page_size, 'query': search_state.query, 'threads' : page, 'questions_count' : paginator.count, 'reset_method_count': reset_method_count, 'scope': search_state.scope, 'show_sort_by_relevance': conf.should_show_sort_by_relevance(), 'search_tags' : search_state.tags, 'sort': search_state.sort, 'tab_id' : search_state.sort, 'tags' : related_tags, 'tag_list_type' : tag_list_type, 'font_size' : extra_tags.get_tag_font_size(related_tags), 'display_tag_filter_strategy_choices': conf.get_tag_display_filter_strategy_choices(), 'email_tag_filter_strategy_choices': const.TAG_EMAIL_FILTER_STRATEGY_CHOICES, 'update_avatar_data': schedules.should_update_avatar_data(request), 'query_string': search_state.query_string(), 'search_state': search_state, 'feed_url': context_feed_url, 'lang_tags': settings.ASKBOT_LANG_TAGS, } return render(request, 'main_page.html', template_data)
question_post = question_post, user_id = request.user.id, update_view_count = update_view_count ) paginator_data = { 'is_paginated' : (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'page': show_page, 'has_previous': page_objects.has_previous(), 'has_next': page_objects.has_next(), 'previous': page_objects.previous_page_number(), 'next': page_objects.next_page_number(), 'base_url' : request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) #todo: maybe consolidate all activity in the thread #for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False initial = { 'wiki': question_post.wiki and askbot_settings.WIKI_ON, 'email_notify': thread.is_followed_by(request.user) }
def tags(request): #view showing a listing of available tags - plain list #1) Get parameters. This normally belongs to form cleaning. post_data = request.GET sortby = post_data.get('sort', 'used') try: page = int(post_data.get('page', '1')) except ValueError: page = 1 if sortby == 'name': order_by = 'name' else: order_by = '-used_count' query = post_data.get('query', '').strip() tag_list_type = askbot_settings.TAG_LIST_FORMAT #2) Get query set for the tags. query_params = {'deleted': False} if query != '': query_params['name__icontains'] = query tags_qs = Tag.objects.filter(**query_params).exclude(used_count=0) tags_qs = tags_qs.order_by(order_by) #3) Start populating the template context. data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tag_list_type': tag_list_type, 'stag': query, 'tab_id': sortby, 'keywords': query, 'search_state': SearchState(*[None for x in range(7)]) } if tag_list_type == 'list': #plain listing is paginated objects_list = Paginator(tags_qs, DEFAULT_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated': (objects_list.num_pages > 1), 'pages': objects_list.num_pages, 'current_page_number': page, 'page_object': tags, 'base_url': reverse('tags') + '?sort=%s&' % sortby } paginator_context = functions.setup_paginator(paginator_data) data['paginator_context'] = paginator_context else: #tags for the tag cloud are given without pagination tags = tags_qs font_size = extra_tags.get_tag_font_size(tags) data['font_size'] = font_size data['tags'] = tags data.update( context.get_extra('ASKBOT_TAGS_PAGE_EXTRA_CONTEXT', request, data)) if request.is_ajax(): template = get_template('tags/content.html') template_context = RequestContext(request, data) json_data = { 'success': True, 'html': template.render(template_context) } json_string = simplejson.dumps(json_data) return HttpResponse(json_string, mimetype='application/json') else: return render(request, 'tags.html', data)
def tags(request): # view showing a listing of available tags - plain list tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == "list": stag = "" is_paginated = True sortby = request.GET.get("sort", "used") try: page = int(request.GET.get("page", "1")) except ValueError: page = 1 stag = request.GET.get("query", "").strip() if stag != "": objects_list = Paginator( models.Tag.objects.filter(deleted=False, name__icontains=stag).exclude(used_count=0), DEFAULT_PAGE_SIZE ) else: if sortby == "name": objects_list = Paginator( models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name"), DEFAULT_PAGE_SIZE, ) else: objects_list = Paginator( models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE, ) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { "is_paginated": is_paginated, "pages": objects_list.num_pages, "page": page, "has_previous": tags.has_previous(), "has_next": tags.has_next(), "previous": tags.previous_page_number(), "next": tags.next_page_number(), "base_url": reverse("tags") + "?sort=%s&" % sortby, } paginator_context = functions.setup_paginator(paginator_data) data = { "active_tab": "tags", "page_class": "tags-page", "tags": tags, "tag_list_type": tag_list_type, "stag": stag, "tab_id": sortby, "keywords": stag, "paginator_context": paginator_context, } else: stag = "" sortby = request.GET.get("sort", "name") if request.method == "GET": stag = request.GET.get("query", "").strip() if stag != "": tags = models.Tag.objects.filter(deleted=False, name__icontains=stag).exclude(used_count=0) else: if sortby == "name": tags = models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name") else: tags = models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count") font_size = extra_tags.get_tag_font_size(tags) data = { "active_tab": "tags", "page_class": "tags-page", "tags": tags, "tag_list_type": tag_list_type, "font_size": font_size, "stag": stag, "tab_id": sortby, "keywords": stag, "search_state": SearchState(*[None for x in range(7)]), } return render_into_skin("tags.html", data, request)
def questions(request, **kwargs): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ if request.method != 'GET': return HttpResponseNotAllowed(['GET']) search_state = SearchState(user_logged_in=request.user.is_authenticated(), **kwargs) ####### page_size = int(askbot_settings.DEFAULT_QUESTIONS_PAGE_SIZE) qs, meta_data, related_tags = models.Thread.objects.run_advanced_search(request_user=request.user, search_state=search_state, page_size=page_size) tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'cloud': #force cloud to sort by name related_tags = sorted(related_tags, key = operator.attrgetter('name')) paginator = Paginator(qs, page_size) if paginator.num_pages < search_state.page: search_state.page = 1 page = paginator.page(search_state.page) contributors_threads = models.Thread.objects.filter(id__in=[post.thread_id for post in page.object_list]) contributors = models.Thread.objects.get_thread_contributors(contributors_threads) paginator_context = { 'is_paginated' : (paginator.count > page_size), 'pages': paginator.num_pages, 'page': search_state.page, 'has_previous': page.has_previous(), 'has_next': page.has_next(), 'previous': page.previous_page_number(), 'next': page.next_page_number(), 'base_url' : search_state.query_string(),#todo in T sort=>sort_method 'page_size' : page_size,#todo in T pagesize -> page_size } # We need to pass the rss feed url based # on the search state to the template. # We use QueryDict to get a querystring # from dicts and arrays. Much cleaner # than parsing and string formating. rss_query_dict = QueryDict("").copy() if search_state.query: # We have search string in session - pass it to # the QueryDict rss_query_dict.update({"q": search_state.query}) if search_state.tags: # We have tags in session - pass it to the # QueryDict but as a list - we want tags+ rss_query_dict.setlist("tags", search_state.tags) context_feed_url = '/feeds/rss/?%s' % rss_query_dict.urlencode() # Format the url with the QueryDict reset_method_count = len(filter(None, [search_state.query, search_state.tags, meta_data.get('author_name', None)])) if request.is_ajax(): q_count = paginator.count if search_state.tags: question_counter = ungettext('%(q_num)s question, tagged', '%(q_num)s questions, tagged', q_count) else: question_counter = ungettext('%(q_num)s question', '%(q_num)s questions', q_count) question_counter = question_counter % {'q_num': humanize.intcomma(q_count),} if q_count > page_size: paginator_tpl = get_template('main_page/paginator.html', request) paginator_html = paginator_tpl.render(Context({ 'context': functions.setup_paginator(paginator_context), 'questions_count': q_count, 'page_size' : page_size, 'search_state': search_state, })) else: paginator_html = '' questions_tpl = get_template('main_page/questions_loop.html', request) questions_html = questions_tpl.render(Context({ 'questions': page, 'search_state': search_state, 'reset_method_count': reset_method_count, })) ajax_data = { 'query_data': { 'tags': search_state.tags, 'sort_order': search_state.sort, 'ask_query_string': search_state.ask_query_string(), }, 'paginator': paginator_html, 'question_counter': question_counter, 'questions': list(), 'faces': [extra_tags.gravatar(contributor, 48) for contributor in contributors], 'feed_url': context_feed_url, 'query_string': search_state.query_string(), 'page_size' : page_size, 'questions': questions_html.replace('\n',''), } ajax_data['related_tags'] = [{ 'name': tag.name, 'used_count': humanize.intcomma(tag.local_used_count) } for tag in related_tags] return HttpResponse(simplejson.dumps(ajax_data), mimetype = 'application/json') else: # non-AJAX branch template_data = { 'active_tab': 'questions', 'author_name' : meta_data.get('author_name',None), 'contributors' : contributors, 'context' : paginator_context, 'is_unanswered' : False,#remove this from template 'interesting_tag_names': meta_data.get('interesting_tag_names',None), 'ignored_tag_names': meta_data.get('ignored_tag_names',None), 'language_code': translation.get_language(), 'name_of_anonymous_user' : models.get_name_of_anonymous_user(), 'page_class': 'main-page', 'page_size': page_size, 'query': search_state.query, 'questions' : page, 'questions_count' : paginator.count, 'reset_method_count': reset_method_count, 'scope': search_state.scope, 'show_sort_by_relevance': askbot.conf.should_show_sort_by_relevance(), 'search_tags' : search_state.tags, 'sort': search_state.sort, 'tab_id' : search_state.sort, 'tags' : related_tags, 'tag_list_type' : tag_list_type, 'font_size' : extra_tags.get_tag_font_size(related_tags), 'tag_filter_strategy_choices': const.TAG_FILTER_STRATEGY_CHOICES, 'update_avatar_data': schedules.should_update_avatar_data(request), 'query_string': search_state.query_string(), 'search_state': search_state, 'feed_url': context_feed_url, } return render_into_skin('main_page.html', template_data, request)
def question(request, id): # refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it TODO: convert this view into class """ # process url parameters # TODO: fix inheritance of sort method from questions form = ShowQuestionForm(dict(tuple(request.POST.items()) + tuple(request.GET.items()))) form.full_clean() # always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] # load question and maybe refuse showing deleted question # if the question does not exist - try mapping to old questions # and and if it is not found again - then give up qs = Post.objects.filter(post_type='question').select_related('thread') question_post = qs.filter(id=id).first() if question_post is None: # Handle URL mapping - from old Q/A/C/ URLs to the new one question_post = qs.filter(old_question_id=id).first() if question_post is None: raise Http404 if show_answer: try: old_answer = Post.objects.get_answers().get(old_answer_id=show_answer) except Post.DoesNotExist: pass else: return redirect(old_answer) elif show_comment: try: old_comment = Post.objects.get_comments().get(old_comment_id=show_comment) except Post.DoesNotExist: pass else: return redirect(old_comment) if show_comment or show_answer: try: show_post = Post.objects.get(pk=(show_comment or show_answer)) except Post.DoesNotExist: # missing target post will be handled later pass else: if (show_comment and not show_post.is_comment()) or \ (show_answer and not show_post.is_answer()): return redirect(show_post) try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden as error: traceback.print_exc() # request.user.message_set.create(message=force_text(error)) django_messages.info(request, force_text(error)) return redirect('index') # redirect if slug in the url is wrong if request.path.split('/')[-2] != question_post.slug: logging.debug('no slug match!') lang = translation.get_language() question_url = question_post.get_absolute_url(language=lang) if request.GET: question_url += '?' + urlencode(request.GET) return redirect(question_url) # resolve comment and answer permalinks # they go first because in theory both can be moved to another question # this block "returns" show_post and assigns actual comment and answer # to show_comment and show_answer variables # in the case if the permalinked items or their parents are gone - redirect # redirect also happens if id of the object's origin post != requested id show_post = None # used for permalinks if show_comment: # if url calls for display of a specific comment, # check that comment exists, that it belongs to # the current question # if it is an answer comment and the answer is hidden - # redirect to the default view of the question # if the question is hidden - redirect to the main page # in addition - if url points to a comment and the comment # is for the answer - we need the answer object try: show_comment = Post.objects.get_comments().get(id=show_comment) except Post.DoesNotExist as e: traceback.print_exc() error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) # request.user.message_set.create(message=error_message) django_messages.info(request, error_message) return redirect(question_post.thread) if str(show_comment.thread._question_post().id) != str(id): return redirect(show_comment) show_post = show_comment.parent try: show_comment.assert_is_visible_to(request.user) except exceptions.AnswerHidden as e: traceback.print_exc() # request.user.message_set.create(message=force_text(e)) django_messages.info(request, force_text(e)) # use reverse function here because question is not yet loaded return redirect('question', id=id) except exceptions.QuestionHidden as e: traceback.print_exc() # request.user.message_set.create(message=force_text(e)) django_messages.info(request, force_text(e)) return redirect('index') elif show_answer: # if the url calls to view a particular answer to # question - we must check whether the question exists # whether answer is actually corresponding to the current question # and that the visitor is allowed to see it show_post = get_object_or_404(Post, post_type='answer', id=show_answer) if str(show_post.thread._question_post().id) != str(id): return redirect(show_post) try: show_post.assert_is_visible_to(request.user) except django_exceptions.PermissionDenied as e: traceback.print_exc() # request.user.message_set.create(message=force_text(e)) django_messages.info(request, force_text(e)) return redirect('question', id=id) thread = question_post.thread logging.debug('answer_sort_method=' + force_text(answer_sort_method)) # load answers and post id's->athor_id mapping # posts are pre-stuffed with the correctly ordered comments question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view( sort_method=answer_sort_method, user=request.user) user_votes = {} user_post_id_list = list() # TODO: cache this query set, but again takes only 3ms! if request.user.is_authenticated(): user_votes = Vote.objects.\ filter(user=request.user, voted_post__id__in=post_to_author.keys()).\ values_list('voted_post_id', 'vote') user_votes = dict(user_votes) # we can avoid making this query by iterating through # already loaded posts user_post_id_list = [ post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id ] # resolve page number and comment number for permalinks show_comment_position = None if show_comment: show_page = show_comment.get_page_number(answer_posts=answers) show_comment_position = show_comment.get_order_number() elif show_answer: show_page = show_post.get_page_number(answer_posts=answers) objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE) if show_page > objects_list.num_pages: return redirect(question_post) page_objects = objects_list.page(show_page) # count visits signals.question_visited.send(None, request=request, question=question_post) paginator_data = { 'is_paginated': (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'current_page_number': show_page, 'page_object': page_objects, 'base_url': request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) # TODO: maybe consolidate all activity in the thread # for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif (show_comment_position or 0) > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False # maybe load draft initial = {} if request.user.is_authenticated(): # TODO: refactor into methor on thread drafts = DraftAnswer.objects.filter(author=request.user, thread=thread) if drafts.count() > 0: initial['text'] = drafts[0].text custom_answer_form_path = getattr(django_settings, 'ASKBOT_NEW_ANSWER_FORM', None) if custom_answer_form_path: answer_form_class = load_module(custom_answer_form_path) else: answer_form_class = AnswerForm answer_form = answer_form_class(initial=initial, user=request.user) user_can_post_comment = (request.user.is_authenticated() and request.user.can_post_comment(question_post)) new_answer_allowed = True previous_answer = None if request.user.is_authenticated(): if askbot_settings.LIMIT_ONE_ANSWER_PER_USER: for answer in answers: if answer.author_id == request.user.pk: new_answer_allowed = False previous_answer = answer break if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED: group_read_only = request.user.is_read_only() else: group_read_only = False data = { 'active_tab': 'questions', 'answer': answer_form, 'answers': page_objects.object_list, 'answer_count': thread.get_answer_count(request.user), 'blank_comment': MockPost(post_type='comment', author=request.user), # data for the js comment template 'category_tree_data': askbot_settings.CATEGORY_TREE, 'editor_is_unfolded': answer_form.has_data(), 'favorited': favorited, 'group_read_only': group_read_only, 'is_cacheable': False, # is_cacheable, # temporary, until invalidation fix 'language_code': translation.get_language(), 'long_time': const.LONG_TIME, # "forever" caching 'new_answer_allowed': new_answer_allowed, 'oldest_answer_id': thread.get_oldest_answer_id(request.user), 'page_class': 'question-page', 'paginator_context': paginator_context, 'previous_answer': previous_answer, 'published_answer_ids': published_answer_ids, 'question': question_post, 'show_comment': show_comment, 'show_comment_position': show_comment_position, 'show_post': show_post, 'similar_threads': thread.get_similar_threads(), 'tab_id': answer_sort_method, 'thread': thread, 'thread_is_moderated': thread.is_moderated(), 'user_is_thread_moderator': thread.has_moderator(request.user), 'user_votes': user_votes, 'user_post_id_list': user_post_id_list, 'user_can_post_comment': user_can_post_comment, # in general } # shared with ... if askbot_settings.GROUPS_ENABLED: data['sharing_info'] = thread.get_sharing_info() data.update(context.get_for_tag_editor()) extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data) data.update(extra) return render(request, 'question.jinja', data)
def users(request): is_paginated = True sortby = request.GET.get('sort', 'reputation') suser = request.REQUEST.get('query', "") try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 if suser == "": 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( models.User.objects.all().order_by( order_by_parameter ), const.USERS_PAGE_SIZE ) base_url = reverse('users') + '?sort=%s&' % sortby else: sortby = "reputation" objects_list = Paginator( models.User.objects.filter( username__icontains = suser ).order_by( '-reputation' ), const.USERS_PAGE_SIZE ) base_url = reverse('users') + '?name=%s&sort=%s&' % (suser, 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) # data = { 'active_tab': 'users', 'page_class': 'users-page', 'users' : users_page, 'suser' : suser, 'keywords' : suser, 'tab_id' : sortby, 'paginator_context' : paginator_context } return render_into_skin('users.html', data, request)
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 = models.Group.objects.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.GET.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, "current_page_number": page, "page_object": users_page, "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 = models.Group.objects.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(request, "users.html", data)
def user_stats(request, user, context): question_filter = {} if request.user != user: question_filter['is_anonymous'] = False if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation': question_filter['approved'] = True # # Questions # questions_qs = user.posts.get_questions( user=request.user ).filter( **question_filter ).order_by( '-points', '-thread__last_activity_at' ).select_related( 'thread', 'thread__last_activity_by' ) q_paginator = Paginator(questions_qs, const.USER_POSTS_PAGE_SIZE) questions = q_paginator.page(1).object_list question_count = q_paginator.count q_paginator_context = functions.setup_paginator({ 'is_paginated' : (question_count > const.USER_POSTS_PAGE_SIZE), 'pages': q_paginator.num_pages, 'current_page_number': 1, 'page_object': q_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) # # Top answers # a_paginator = user.get_top_answers_paginator(request.user) top_answers = a_paginator.page(1).object_list top_answer_count = a_paginator.count a_paginator_context = functions.setup_paginator({ 'is_paginated' : (top_answer_count > const.USER_POSTS_PAGE_SIZE), 'pages': a_paginator.num_pages, 'current_page_number': 1, 'page_object': a_paginator.page(1), 'base_url' : '?' #this paginator will be ajax }) # # 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, language_code=get_language() ).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 = models.Group.objects.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', 'page_title' : _('user profile overview'), 'questions' : questions, 'question_count': question_count, 'q_paginator_context': q_paginator_context, 'top_answers': top_answers, 'top_answer_count': top_answer_count, 'a_paginator_context': a_paginator_context, 'page_size': const.USER_POSTS_PAGE_SIZE, '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) extra_context = view_context.get_extra( 'ASKBOT_USER_PROFILE_PAGE_EXTRA_CONTEXT', request, context ) context.update(extra_context) return render(request, 'user_profile/user_stats.html', context)
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 = models.Group.objects.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(askbot_profile__status='b').exclude( is_active=False).select_related('askbot_profile') if askbot.is_multilingual(): users = users.filter( localized_askbot_profiles__language_code=get_language(), localized_askbot_profiles__is_claimed=True) 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.CONTENT_MODERATION_MODE == 'premoderation' ) 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 form = forms.ShowUsersForm(request.REQUEST) form.full_clean() #always valid sort_method = form.cleaned_data['sort'] page = form.cleaned_data['page'] search_query = form.cleaned_data['query'] if search_query == '': if sort_method == 'newest': order_by_parameter = '-date_joined' elif sort_method == 'last': order_by_parameter = 'date_joined' elif sort_method == 'name': order_by_parameter = 'username' else: # default if askbot.is_multilingual(): order_by_parameter = '-localized_askbot_profiles__reputation' else: order_by_parameter = '-askbot_profile__reputation' objects_list = Paginator(users.order_by(order_by_parameter), askbot_settings.USERS_PAGE_SIZE) base_url = request.path + '?sort=%s&' % sort_method else: sort_method = 'reputation' matching_users = models.get_users_by_text_query(search_query, users) objects_list = Paginator( matching_users.order_by('-askbot_profile__reputation'), askbot_settings.USERS_PAGE_SIZE) base_url = request.path + '?name=%s&sort=%s&' % (search_query, sort_method) 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, 'current_page_number': page, 'page_object': users_page, '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 = models.Group.objects.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', 'group': group, 'group_email_moderation_enabled': group_email_moderation_enabled, 'group_openness_choices': group_openness_choices, 'page_class': 'users-page', 'paginator_context': paginator_context, 'search_query': search_query, 'tab_id': sort_method, 'user_acceptance_level': user_acceptance_level, 'user_count': objects_list.count, 'user_groups': user_groups, 'user_membership_level': user_membership_level, 'users': users_page, } return render(request, 'users.html', data)
def show_users(request, by_group = False, group_id = None, group_slug = None): """Users view, including listing of users by group""" users = models.User.objects.exclude(status = 'b') group = None group_email_moderation_enabled = False user_can_join_group = False user_is_group_member = False 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.Tag.group_tags.get(id = group_id) group_email_moderation_enabled = \ ( askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \ and askbot_settings.ENABLE_CONTENT_MODERATION ) user_can_join_group = group.group_profile.can_accept_user(request.user) except models.Tag.DoesNotExist: raise Http404 if group_slug == slugify(group.name): users = users.filter( group_memberships__group__id = group_id ) if request.user.is_authenticated(): user_is_group_member = bool( users.filter( id = request.user.id ).count() ) 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) 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) # 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_can_join_group': user_can_join_group, 'user_is_group_member': user_is_group_member } return render_into_skin('users.html', data, request)
def questions(request, **kwargs): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ # before = datetime.datetime.now() if request.method != "GET": return HttpResponseNotAllowed(["GET"]) search_state = SearchState(user_logged_in=request.user.is_authenticated(), **kwargs) page_size = int(askbot_settings.DEFAULT_QUESTIONS_PAGE_SIZE) qs, meta_data = models.Thread.objects.run_advanced_search(request_user=request.user, search_state=search_state) if meta_data["non_existing_tags"]: search_state = search_state.remove_tags(meta_data["non_existing_tags"]) paginator = Paginator(qs, page_size) if paginator.num_pages < search_state.page: search_state.page = 1 page = paginator.page(search_state.page) page.object_list = list(page.object_list) # evaluate the queryset # INFO: Because for the time being we need question posts and thread authors # down the pipeline, we have to precache them in thread objects models.Thread.objects.precache_view_data_hack(threads=page.object_list) related_tags = Tag.objects.get_related_to_search( threads=page.object_list, ignored_tag_names=meta_data.get("ignored_tag_names", []) ) tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == "cloud": # force cloud to sort by name related_tags = sorted(related_tags, key=operator.attrgetter("name")) contributors = list( models.Thread.objects.get_thread_contributors(thread_list=page.object_list).only("id", "username", "gravatar") ) paginator_context = { "is_paginated": (paginator.count > page_size), "pages": paginator.num_pages, "page": search_state.page, "has_previous": page.has_previous(), "has_next": page.has_next(), "previous": page.previous_page_number(), "next": page.next_page_number(), "base_url": search_state.query_string(), "page_size": page_size, } # We need to pass the rss feed url based # on the search state to the template. # We use QueryDict to get a querystring # from dicts and arrays. Much cleaner # than parsing and string formating. rss_query_dict = QueryDict("").copy() if search_state.query: # We have search string in session - pass it to # the QueryDict rss_query_dict.update({"q": search_state.query}) if search_state.tags: # We have tags in session - pass it to the # QueryDict but as a list - we want tags+ rss_query_dict.setlist("tags", search_state.tags) context_feed_url = "/%sfeeds/rss/?%s" % ( settings.ASKBOT_URL, rss_query_dict.urlencode(), ) # Format the url with the QueryDict reset_method_count = len(filter(None, [search_state.query, search_state.tags, meta_data.get("author_name", None)])) if request.is_ajax(): q_count = paginator.count question_counter = ungettext("%(q_num)s question", "%(q_num)s questions", q_count) question_counter = question_counter % {"q_num": humanize.intcomma(q_count)} if q_count > page_size: paginator_tpl = get_template("main_page/paginator.html", request) paginator_html = paginator_tpl.render( Context( { "context": functions.setup_paginator(paginator_context), "questions_count": q_count, "page_size": page_size, "search_state": search_state, } ) ) else: paginator_html = "" questions_tpl = get_template("main_page/questions_loop.html", request) questions_html = questions_tpl.render( Context( { "threads": page, "search_state": search_state, "reset_method_count": reset_method_count, "request": request, } ) ) ajax_data = { "query_data": { "tags": search_state.tags, "sort_order": search_state.sort, "ask_query_string": search_state.ask_query_string(), }, "paginator": paginator_html, "question_counter": question_counter, "faces": [], # [extra_tags.gravatar(contributor, 48) for contributor in contributors], "feed_url": context_feed_url, "query_string": search_state.query_string(), "page_size": page_size, "questions": questions_html.replace("\n", ""), "non_existing_tags": meta_data["non_existing_tags"], } ajax_data["related_tags"] = [ {"name": escape(tag.name), "used_count": humanize.intcomma(tag.local_used_count)} for tag in related_tags ] return HttpResponse(simplejson.dumps(ajax_data), mimetype="application/json") else: # non-AJAX branch template_data = { "active_tab": "questions", "author_name": meta_data.get("author_name", None), "contributors": contributors, "context": paginator_context, "is_unanswered": False, # remove this from template "interesting_tag_names": meta_data.get("interesting_tag_names", None), "ignored_tag_names": meta_data.get("ignored_tag_names", None), "subscribed_tag_names": meta_data.get("subscribed_tag_names", None), "language_code": translation.get_language(), "name_of_anonymous_user": models.get_name_of_anonymous_user(), "page_class": "main-page", "page_size": page_size, "query": search_state.query, "threads": page, "questions_count": paginator.count, "reset_method_count": reset_method_count, "scope": search_state.scope, "show_sort_by_relevance": conf.should_show_sort_by_relevance(), "search_tags": search_state.tags, "sort": search_state.sort, "tab_id": search_state.sort, "tags": related_tags, "tag_list_type": tag_list_type, "font_size": extra_tags.get_tag_font_size(related_tags), "display_tag_filter_strategy_choices": conf.get_tag_display_filter_strategy_choices(), "email_tag_filter_strategy_choices": const.TAG_EMAIL_FILTER_STRATEGY_CHOICES, "update_avatar_data": schedules.should_update_avatar_data(request), "query_string": search_state.query_string(), "search_state": search_state, "feed_url": context_feed_url, } return render_into_skin("main_page.html", template_data, request)
from askbot import tasks tasks.record_question_visit.delay(question_post=question_post, user=request.user, update_view_count=update_view_count) paginator_data = { 'is_paginated': (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'page': show_page, 'has_previous': page_objects.has_previous(), 'has_next': page_objects.has_next(), 'previous': page_objects.previous_page_number(), 'next': page_objects.next_page_number(), 'base_url': request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) #todo: maybe consolidate all activity in the thread #for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False answer_form = AnswerForm( initial={ 'wiki': question_post.wiki and askbot_settings.WIKI_ON, 'email_notify': thread.is_followed_by(request.user)
def tags(request):#view showing a listing of available tags - plain list #1) Get parameters. This normally belongs to form cleaning. post_data = request.GET sortby = post_data.get('sort', 'used') try: page = int(post_data.get('page', '1')) except ValueError: page = 1 if sortby == 'name': order_by = 'name' else: order_by = '-used_count' query = post_data.get('query', '').strip() tag_list_type = askbot_settings.TAG_LIST_FORMAT #2) Get query set for the tags. query_params = {'deleted': False} if query != '': query_params['name__icontains'] = query tags_qs = Tag.objects.filter(**query_params).exclude(used_count=0) tags_qs = tags_qs.order_by(order_by) #3) Start populating the template context. data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tag_list_type' : tag_list_type, 'stag' : query, 'tab_id' : sortby, 'keywords' : query, 'search_state': SearchState(*[None for x in range(7)]) } if tag_list_type == 'list': #plain listing is paginated objects_list = Paginator(tags_qs, DEFAULT_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated' : (objects_list.num_pages > 1), 'pages': objects_list.num_pages, 'page': page, 'has_previous': tags.has_previous(), 'has_next': tags.has_next(), 'previous': tags.previous_page_number(), 'next': tags.next_page_number(), 'base_url' : reverse('tags') + '?sort=%s&' % sortby } paginator_context = functions.setup_paginator(paginator_data) data['paginator_context'] = paginator_context else: #tags for the tag cloud are given without pagination tags = tags_qs font_size = extra_tags.get_tag_font_size(tags) data['font_size'] = font_size data['tags'] = tags data.update(context.get_extra('ASKBOT_TAGS_PAGE_EXTRA_CONTEXT', request, data)) if request.is_ajax(): template = get_template('tags/content.html') template_context = RequestContext(request, data) json_data = {'success': True, 'html': template.render(template_context)} json_string = simplejson.dumps(json_data) return HttpResponse(json_string, mimetype='application/json') else: return render(request, 'tags.html', data)
def tags(request): #view showing a listing of available tags - plain list tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'list': stag = "" is_paginated = True sortby = request.GET.get('sort', 'used') try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 if request.method == "GET": stag = request.GET.get("query", "").strip() if stag != '': objects_list = Paginator( models.Tag.objects.filter( deleted=False, name__icontains=stag).exclude(used_count=0), DEFAULT_PAGE_SIZE) else: if sortby == "name": objects_list = Paginator( models.Tag.objects.all().filter(deleted=False).exclude( used_count=0).order_by("name"), DEFAULT_PAGE_SIZE) else: objects_list = Paginator( models.Tag.objects.all().filter(deleted=False).exclude( used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated': is_paginated, 'pages': objects_list.num_pages, 'page': page, 'has_previous': tags.has_previous(), 'has_next': tags.has_next(), 'previous': tags.previous_page_number(), 'next': tags.next_page_number(), 'base_url': reverse('tags') + '?sort=%s&' % sortby } paginator_context = functions.setup_paginator(paginator_data) data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tags': tags, 'tag_list_type': tag_list_type, 'stag': stag, 'tab_id': sortby, 'keywords': stag, 'paginator_context': paginator_context, } else: stag = "" sortby = request.GET.get('sort', 'name') if request.method == "GET": stag = request.GET.get("query", "").strip() if stag != '': tags = models.Tag.objects.filter( deleted=False, name__icontains=stag).exclude(used_count=0) else: if sortby == "name": tags = models.Tag.objects.all().filter( deleted=False).exclude(used_count=0).order_by("name") else: tags = models.Tag.objects.all().filter( deleted=False).exclude( used_count=0).order_by("-used_count") font_size = extra_tags.get_tag_font_size(tags) data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tags': tags, 'tag_list_type': tag_list_type, 'font_size': font_size, 'stag': stag, 'tab_id': sortby, 'keywords': stag, 'search_state': SearchState(*[None for x in range(7)]) } return render_into_skin('tags.html', data, request)
def questions(request, **kwargs): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ if request.method != 'GET': return HttpResponseNotAllowed(['GET']) search_state = SearchState(user_logged_in=request.user.is_authenticated(), **kwargs) page_size = int(askbot_settings.DEFAULT_QUESTIONS_PAGE_SIZE) qs, meta_data = models.Thread.objects.run_advanced_search( request_user=request.user, search_state=search_state) if meta_data['non_existing_tags']: search_state = search_state.remove_tags(meta_data['non_existing_tags']) paginator = Paginator(qs, page_size) if paginator.num_pages < search_state.page: search_state.page = 1 page = paginator.page(search_state.page) page.object_list = list(page.object_list) # evaluate queryset # INFO: Because for the time being we need question posts and thread authors # down the pipeline, we have to precache them in thread objects models.Thread.objects.precache_view_data_hack(threads=page.object_list) related_tags = Tag.objects.get_related_to_search( threads=page.object_list, ignored_tag_names=meta_data.get('ignored_tag_names', [])) tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'cloud': #force cloud to sort by name related_tags = sorted(related_tags, key=operator.attrgetter('name')) contributors = list( models.Thread.objects.get_thread_contributors( thread_list=page.object_list).only('id', 'username', 'gravatar')) paginator_context = { 'is_paginated': (paginator.count > page_size), 'pages': paginator.num_pages, 'page': search_state.page, 'has_previous': page.has_previous(), 'has_next': page.has_next(), 'previous': page.previous_page_number(), 'next': page.next_page_number(), 'base_url': search_state.query_string(), 'page_size': page_size, } # We need to pass the rss feed url based # on the search state to the template. # We use QueryDict to get a querystring # from dicts and arrays. Much cleaner # than parsing and string formating. rss_query_dict = QueryDict("").copy() if search_state.query: # We have search string in session - pass it to # the QueryDict rss_query_dict.update({"q": search_state.query}) if search_state.tags: # We have tags in session - pass it to the # QueryDict but as a list - we want tags+ rss_query_dict.setlist("tags", search_state.tags) context_feed_url = '/feeds/rss/?%s' % rss_query_dict.urlencode( ) # Format the url with the QueryDict reset_method_count = len( filter(None, [ search_state.query, search_state.tags, meta_data.get('author_name', None) ])) if request.is_ajax(): q_count = paginator.count question_counter = ungettext('%(q_num)s question', '%(q_num)s questions', q_count) question_counter = question_counter % { 'q_num': humanize.intcomma(q_count), } if q_count > page_size: paginator_tpl = get_template('main_page/paginator.html', request) paginator_html = paginator_tpl.render( Context({ 'context': functions.setup_paginator(paginator_context), 'questions_count': q_count, 'page_size': page_size, 'search_state': search_state, })) else: paginator_html = '' questions_tpl = get_template('main_page/questions_loop.html', request) questions_html = questions_tpl.render( Context({ 'threads': page, 'search_state': search_state, 'reset_method_count': reset_method_count, })) ajax_data = { 'query_data': { 'tags': search_state.tags, 'sort_order': search_state.sort, 'ask_query_string': search_state.ask_query_string(), }, 'paginator': paginator_html, 'question_counter': question_counter, 'faces': [ extra_tags.gravatar(contributor, 48) for contributor in contributors ], 'feed_url': context_feed_url, 'query_string': search_state.query_string(), 'page_size': page_size, 'questions': questions_html.replace('\n', ''), 'non_existing_tags': meta_data['non_existing_tags'] } ajax_data['related_tags'] = [{ 'name': tag.name, 'used_count': humanize.intcomma(tag.local_used_count) } for tag in related_tags] return HttpResponse(simplejson.dumps(ajax_data), mimetype='application/json') else: # non-AJAX branch template_data = { 'active_tab': 'questions', 'author_name': meta_data.get('author_name', None), 'contributors': contributors, 'context': paginator_context, 'is_unanswered': False, #remove this from template 'interesting_tag_names': meta_data.get('interesting_tag_names', None), 'ignored_tag_names': meta_data.get('ignored_tag_names', None), 'subscribed_tag_names': meta_data.get('subscribed_tag_names', None), 'language_code': translation.get_language(), 'name_of_anonymous_user': models.get_name_of_anonymous_user(), 'page_class': 'main-page', 'page_size': page_size, 'query': search_state.query, 'threads': page, 'questions_count': paginator.count, 'reset_method_count': reset_method_count, 'scope': search_state.scope, 'show_sort_by_relevance': askbot.conf.should_show_sort_by_relevance(), 'search_tags': search_state.tags, 'sort': search_state.sort, 'tab_id': search_state.sort, 'tags': related_tags, 'tag_list_type': tag_list_type, 'font_size': extra_tags.get_tag_font_size(related_tags), 'display_tag_filter_strategy_choices': const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES, 'email_tag_filter_strategy_choices': const.TAG_EMAIL_FILTER_STRATEGY_CHOICES, 'update_avatar_data': schedules.should_update_avatar_data(request), 'query_string': search_state.query_string(), 'search_state': search_state, 'feed_url': context_feed_url, } return render_into_skin('main_page.html', template_data, request)
def users(request, by_group=False, group_id=None, group_slug=None): """Users view, including listing of users by group""" users = models.User.objects.all() group = None group_email_moderation_enabled = False user_can_join_group = False user_is_group_member = False 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.Tag.group_tags.get(id=group_id) group_email_moderation_enabled = ( askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED and askbot_settings.ENABLE_CONTENT_MODERATION ) user_can_join_group = group.group_profile.can_accept_user(request.user) except models.Tag.DoesNotExist: raise Http404 if group_slug == slugify(group.name): users = models.User.objects.filter(group_memberships__group__id=group_id) if request.user.is_authenticated(): user_is_group_member = bool(users.filter(id=request.user.id).count()) 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" suser = request.REQUEST.get("query", "") try: page = int(request.GET.get("page", "1")) except ValueError: page = 1 if suser == "": 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" objects_list = Paginator(users.filter(username__icontains=suser).order_by("-reputation"), const.USERS_PAGE_SIZE) base_url = request.path + "?name=%s&sort=%s&" % (suser, 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) # data = { "active_tab": "users", "page_class": "users-page", "users": users_page, "group": group, "suser": suser, "keywords": suser, "tab_id": sortby, "paginator_context": paginator_context, "group_email_moderation_enabled": group_email_moderation_enabled, "user_can_join_group": user_can_join_group, "user_is_group_member": user_is_group_member, } return render_into_skin("users.html", data, request)
def tags(request):#view showing a listing of available tags - plain list tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'list': stag = "" is_paginated = True sortby = request.GET.get('sort', 'used') try: page = int(request.GET.get('page', '1')) except ValueError: page = 1 stag = request.GET.get("query", "").strip() if stag != '': objects_list = Paginator( models.Tag.objects.filter( deleted=False, name__icontains=stag ).exclude( used_count=0 ), DEFAULT_PAGE_SIZE ) else: if sortby == "name": objects_list = Paginator(models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name"), DEFAULT_PAGE_SIZE) else: objects_list = Paginator(models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated' : is_paginated, 'pages': objects_list.num_pages, 'page': page, 'has_previous': tags.has_previous(), 'has_next': tags.has_next(), 'previous': tags.previous_page_number(), 'next': tags.next_page_number(), 'base_url' : reverse('tags') + '?sort=%s&' % sortby } paginator_context = functions.setup_paginator(paginator_data) data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tags' : tags, 'tag_list_type' : tag_list_type, 'stag' : stag, 'tab_id' : sortby, 'keywords' : stag, 'paginator_context' : paginator_context, } else: stag = "" sortby = request.GET.get('sort', 'name') if request.method == "GET": stag = request.GET.get("query", "").strip() if stag != '': tags = models.Tag.objects.filter(deleted=False, name__icontains=stag).exclude(used_count=0) else: if sortby == "name": tags = models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name") else: tags = models.Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count") font_size = extra_tags.get_tag_font_size(tags) data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tags' : tags, 'tag_list_type' : tag_list_type, 'font_size' : font_size, 'stag' : stag, 'tab_id' : sortby, 'keywords' : stag, 'search_state': SearchState(*[None for x in range(7)]) } return render(request, 'tags.html', data)
def questions(request, **kwargs): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ #before = datetime.datetime.now() if request.method != 'GET': return HttpResponseNotAllowed(['GET']) search_state = SearchState( user_logged_in=request.user.is_authenticated(), **kwargs ) page_size = int(askbot_settings.DEFAULT_QUESTIONS_PAGE_SIZE) qs, meta_data = models.Thread.objects.run_advanced_search( request_user=request.user, search_state=search_state ) if meta_data['non_existing_tags']: search_state = search_state.remove_tags(meta_data['non_existing_tags']) paginator = Paginator(qs, page_size) if paginator.num_pages < search_state.page: search_state.page = 1 page = paginator.page(search_state.page) page.object_list = list(page.object_list) # evaluate the queryset # INFO: Because for the time being we need question posts and thread authors # down the pipeline, we have to precache them in thread objects models.Thread.objects.precache_view_data_hack(threads=page.object_list) related_tags = Tag.objects.get_related_to_search( threads=page.object_list, ignored_tag_names=meta_data.get('ignored_tag_names',[]) ) tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'cloud': #force cloud to sort by name related_tags = sorted(related_tags, key = operator.attrgetter('name')) contributors = list( models.Thread.objects.get_thread_contributors( thread_list=page.object_list ).only('id', 'username', 'gravatar') ) paginator_context = { 'is_paginated' : (paginator.count > page_size), 'pages': paginator.num_pages, 'current_page_number': search_state.page, 'page_object': page, 'base_url' : search_state.query_string(), 'page_size' : page_size, } # We need to pass the rss feed url based # on the search state to the template. # We use QueryDict to get a querystring # from dicts and arrays. Much cleaner # than parsing and string formating. rss_query_dict = QueryDict("").copy() if search_state.query: # We have search string in session - pass it to # the QueryDict rss_query_dict.update({"q": search_state.query}) if search_state.tags: # We have tags in session - pass it to the # QueryDict but as a list - we want tags+ rss_query_dict.setlist("tags", search_state.tags) context_feed_url = '/%sfeeds/rss/?%s' % ( django_settings.ASKBOT_URL, rss_query_dict.urlencode() ) # Format the url with the QueryDict reset_method_count = len(filter(None, [search_state.query, search_state.tags, meta_data.get('author_name', None)])) if request.is_ajax(): q_count = paginator.count question_counter = ungettext('%(q_num)s question', '%(q_num)s questions', q_count) question_counter = question_counter % {'q_num': humanize.intcomma(q_count),} if q_count > page_size: paginator_tpl = get_template('main_page/paginator.html') paginator_html = paginator_tpl.render( RequestContext( request, { 'context': functions.setup_paginator(paginator_context), 'questions_count': q_count, 'page_size' : page_size, 'search_state': search_state, } ) ) else: paginator_html = '' questions_tpl = get_template('main_page/questions_loop.html') questions_html = questions_tpl.render( RequestContext( request, { 'threads': page, 'search_state': search_state, 'reset_method_count': reset_method_count, 'request': request } ) ) ajax_data = { 'query_data': { 'tags': search_state.tags, 'sort_order': search_state.sort, 'ask_query_string': search_state.ask_query_string(), }, 'paginator': paginator_html, 'question_counter': question_counter, 'faces': [],#[extra_tags.gravatar(contributor, 48) for contributor in contributors], 'feed_url': context_feed_url, 'query_string': search_state.query_string(), 'page_size' : page_size, 'questions': questions_html.replace('\n',''), 'non_existing_tags': meta_data['non_existing_tags'] } ajax_data['related_tags'] = [{ 'name': escape(tag.name), 'used_count': humanize.intcomma(tag.local_used_count) } for tag in related_tags] return HttpResponse(simplejson.dumps(ajax_data), mimetype = 'application/json') else: # non-AJAX branch template_data = { 'active_tab': 'questions', 'author_name' : meta_data.get('author_name',None), 'contributors' : contributors, 'context' : paginator_context, 'is_unanswered' : False,#remove this from template 'interesting_tag_names': meta_data.get('interesting_tag_names', None), 'ignored_tag_names': meta_data.get('ignored_tag_names', None), 'subscribed_tag_names': meta_data.get('subscribed_tag_names', None), 'language_code': translation.get_language(), 'name_of_anonymous_user' : models.get_name_of_anonymous_user(), 'page_class': 'main-page', 'page_size': page_size, 'query': search_state.query, 'threads' : page, 'questions_count' : paginator.count, 'reset_method_count': reset_method_count, 'scope': search_state.scope, 'show_sort_by_relevance': conf.should_show_sort_by_relevance(), 'search_tags' : search_state.tags, 'sort': search_state.sort, 'tab_id' : search_state.sort, 'tags' : related_tags, 'tag_list_type' : tag_list_type, 'font_size' : extra_tags.get_tag_font_size(related_tags), 'display_tag_filter_strategy_choices': conf.get_tag_display_filter_strategy_choices(), 'email_tag_filter_strategy_choices': conf.get_tag_email_filter_strategy_choices(), 'update_avatar_data': schedules.should_update_avatar_data(request), 'query_string': search_state.query_string(), 'search_state': search_state, 'feed_url': context_feed_url, } extra_context = context.get_extra( 'ASKBOT_QUESTIONS_PAGE_EXTRA_CONTEXT', request, template_data ) template_data.update(extra_context) #and one more thing:) give admin user heads up about #setting the domain name if they have not done that yet #todo: move this out to a separate middleware if request.user.is_authenticated() and request.user.is_administrator(): if domain_is_bad(): url = reverse( 'group_settings', kwargs = {'group': 'QA_SITE_SETTINGS'} ) url = url + '#id_QA_SITE_SETTINGS__APP_URL' msg = _( 'Please go to ' '<a href="%s">"settings->URLs, keywords and greetings"</a> ' 'and set the base url for your site to function properly' ) % url request.user.message_set.create(message=msg) return render(request, 'main_page.html', template_data)
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 = models.Group.objects.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' ).exclude( is_active=False ) 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.CONTENT_MODERATION_MODE == 'premoderation' ) 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 form = forms.ShowUsersForm(request.REQUEST) form.full_clean()#always valid sort_method = form.cleaned_data['sort_method'] page = form.cleaned_data['page'] search_query = form.cleaned_data['query'] if search_query == '': if sort_method == 'newest': order_by_parameter = '-date_joined' elif sort_method == 'last': order_by_parameter = 'date_joined' elif sort_method == '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&' % sort_method else: sort_method = '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, sort_method) 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, 'current_page_number': page, 'page_object': users_page, '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 = models.Group.objects.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', 'group': group, 'group_email_moderation_enabled': group_email_moderation_enabled, 'group_openness_choices': group_openness_choices, 'page_class': 'users-page', 'paginator_context' : paginator_context, 'search_query' : search_query, 'tab_id' : sort_method, 'user_acceptance_level': user_acceptance_level, 'user_count': users.count(), 'user_groups': user_groups, 'user_membership_level': user_membership_level, 'users' : users_page, } return render(request, 'users.html', data)
def show_users(request, by_group=False, group_id=None, group_slug=None): """Users view, including listing of users by group""" users = models.User.objects.exclude(status='b') group = None group_email_moderation_enabled = False user_can_join_group = False user_is_group_member = False 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.Tag.group_tags.get(id=group_id) group_email_moderation_enabled = \ ( askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \ and askbot_settings.ENABLE_CONTENT_MODERATION ) user_can_join_group = group.group_profile.can_accept_user( request.user) except models.Tag.DoesNotExist: raise Http404 if group_slug == slugify(group.name): users = users.filter(group_memberships__group__id=group_id) if request.user.is_authenticated(): user_is_group_member = bool( users.filter(id=request.user.id).count()) 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) 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) # 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_can_join_group': user_can_join_group, 'user_is_group_member': user_is_group_member } return render_into_skin('users.html', data, request)
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 = models.Group.objects.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.GET.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 = models.Group.objects.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(request, 'users.html', data)
def tags(request):#view showing a listing of available tags - plain list form = ShowTagsForm(request.REQUEST) form.full_clean() #always valid page = form.cleaned_data['page'] sort_method = form.cleaned_data['sort'] query = form.cleaned_data['query'] tag_list_type = askbot_settings.TAG_LIST_FORMAT #2) Get query set for the tags. query_params = { 'deleted': False, 'language_code': translation.get_language() } if query != '': query_params['name__icontains'] = query tags_qs = Tag.objects.filter(**query_params).exclude(used_count=0) if sort_method == 'name': order_by = 'name' else: order_by = '-used_count' tags_qs = tags_qs.order_by(order_by) #3) Start populating the template context. data = { 'active_tab': 'tags', 'page_class': 'tags-page', 'tag_list_type' : tag_list_type, 'query' : query, 'tab_id' : sort_method, 'keywords' : query, 'search_state': SearchState(*[None for x in range(8)]) } if tag_list_type == 'list': #plain listing is paginated objects_list = Paginator(tags_qs, DEFAULT_PAGE_SIZE) try: tags = objects_list.page(page) except (EmptyPage, InvalidPage): tags = objects_list.page(objects_list.num_pages) paginator_data = { 'is_paginated' : (objects_list.num_pages > 1), 'pages': objects_list.num_pages, 'current_page_number': page, 'page_object': tags, 'base_url' : reverse('tags') + '?sort=%s&' % sort_method } paginator_context = functions.setup_paginator(paginator_data) data['paginator_context'] = paginator_context else: #tags for the tag cloud are given without pagination tags = tags_qs font_size = extra_tags.get_tag_font_size(tags) data['font_size'] = font_size data['tags'] = tags data.update(context.get_extra('ASKBOT_TAGS_PAGE_EXTRA_CONTEXT', request, data)) if request.is_ajax(): template = get_template('tags/content.html') template_context = RequestContext(request, data) json_data = {'success': True, 'html': template.render(template_context)} json_string = simplejson.dumps(json_data) return HttpResponse(json_string, content_type='application/json') else: return render(request, 'tags.html', data)
def question(request, id):#refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it todo: convert this view into class """ #process url parameters #todo: fix inheritance of sort method from questions #before = timezone.now() form = ShowQuestionForm(request.REQUEST) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] #load question and maybe refuse showing deleted question #if the question does not exist - try mapping to old questions #and and if it is not found again - then give up try: question_post = models.Post.objects.filter( post_type = 'question', id = id ).select_related('thread')[0] except IndexError: # Handle URL mapping - from old Q/A/C/ URLs to the new one try: question_post = models.Post.objects.filter( post_type='question', old_question_id = id ).select_related('thread')[0] except IndexError: raise Http404 if show_answer: try: old_answer = models.Post.objects.get_answers().get(old_answer_id=show_answer) except models.Post.DoesNotExist: pass else: return HttpResponseRedirect(old_answer.get_absolute_url()) elif show_comment: try: old_comment = models.Post.objects.get_comments().get(old_comment_id=show_comment) except models.Post.DoesNotExist: pass else: return HttpResponseRedirect(old_comment.get_absolute_url()) if show_comment or show_answer: try: show_post = models.Post.objects.get(pk=(show_comment or show_answer)) except models.Post.DoesNotExist: #missing target post will be handled later pass else: if (show_comment and not show_post.is_comment()) \ or (show_answer and not show_post.is_answer()): return HttpResponseRedirect(show_post.get_absolute_url()) try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index')) #redirect if slug in the url is wrong if request.path.split('/')[-2] != question_post.slug: logging.debug('no slug match!') lang = translation.get_language() question_url = question_post.get_absolute_url(language=lang) if request.GET: question_url += u'?' + urllib.urlencode(request.GET) return HttpResponseRedirect(question_url) #resolve comment and answer permalinks #they go first because in theory both can be moved to another question #this block "returns" show_post and assigns actual comment and answer #to show_comment and show_answer variables #in the case if the permalinked items or their parents are gone - redirect #redirect also happens if id of the object's origin post != requested id show_post = None #used for permalinks if show_comment: #if url calls for display of a specific comment, #check that comment exists, that it belongs to #the current question #if it is an answer comment and the answer is hidden - #redirect to the default view of the question #if the question is hidden - redirect to the main page #in addition - if url points to a comment and the comment #is for the answer - we need the answer object try: show_comment = models.Post.objects.get_comments().get(id=show_comment) except models.Post.DoesNotExist: error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) request.user.message_set.create(message = error_message) return HttpResponseRedirect(question_post.thread.get_absolute_url()) if str(show_comment.thread._question_post().id) != str(id): return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.parent try: show_comment.assert_is_visible_to(request.user) except exceptions.AnswerHidden as error: request.user.message_set.create(message = unicode(error)) #use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) except exceptions.QuestionHidden as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index')) elif show_answer: #if the url calls to view a particular answer to #question - we must check whether the question exists #whether answer is actually corresponding to the current question #and that the visitor is allowed to see it show_post = get_object_or_404(models.Post, post_type='answer', id=show_answer) if str(show_post.thread._question_post().id) != str(id): return HttpResponseRedirect(show_post.get_absolute_url()) try: show_post.assert_is_visible_to(request.user) except django_exceptions.PermissionDenied as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) thread = question_post.thread if askbot.get_lang_mode() == 'url-lang': request_lang = translation.get_language() if request_lang != thread.language_code: template = get_template('question/lang_switch_message.html') message = template.render(Context({ 'post_lang': get_language_name(thread.language_code), 'request_lang': get_language_name(request_lang), 'home_url': reverse_i18n(request_lang, 'questions') })) request.user.message_set.create(message=message) return HttpResponseRedirect(thread.get_absolute_url()) logging.debug('answer_sort_method=' + unicode(answer_sort_method)) #load answers and post id's->athor_id mapping #posts are pre-stuffed with the correctly ordered comments question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view( sort_method=answer_sort_method, user=request.user ) user_votes = {} user_post_id_list = list() #todo: cache this query set, but again takes only 3ms! if request.user.is_authenticated(): user_votes = Vote.objects.filter( user=request.user, voted_post__id__in = post_to_author.keys() ).values_list('voted_post_id', 'vote') user_votes = dict(user_votes) #we can avoid making this query by iterating through #already loaded posts user_post_id_list = [ post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id ] #resolve page number and comment number for permalinks show_comment_position = None if show_comment: show_page = show_comment.get_page_number(answer_posts=answers) show_comment_position = show_comment.get_order_number() elif show_answer: show_page = show_post.get_page_number(answer_posts=answers) objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE) if show_page > objects_list.num_pages: return HttpResponseRedirect(question_post.get_absolute_url()) page_objects = objects_list.page(show_page) #count visits signals.question_visited.send(None, request=request, question=question_post, ) paginator_data = { 'is_paginated' : (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'current_page_number': show_page, 'page_object': page_objects, 'base_url' : request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) #todo: maybe consolidate all activity in the thread #for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False #maybe load draft initial = {} if request.user.is_authenticated(): #todo: refactor into methor on thread drafts = models.DraftAnswer.objects.filter( author=request.user, thread=thread ) if drafts.count() > 0: initial['text'] = drafts[0].get_text() custom_answer_form_path = django_settings.ASKBOT_NEW_ANSWER_FORM if custom_answer_form_path: answer_form_class = load_module(custom_answer_form_path) else: answer_form_class = AnswerForm answer_form = answer_form_class(initial=initial, user=request.user) user_can_post_comment = ( request.user.is_authenticated() \ and request.user.can_post_comment(question_post) ) new_answer_allowed = True previous_answer = None if request.user.is_authenticated(): if askbot_settings.LIMIT_ONE_ANSWER_PER_USER: for answer in answers: if answer.author_id == request.user.pk: new_answer_allowed = False previous_answer = answer break if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED: group_read_only = request.user.is_read_only() else: group_read_only = False #session variable added so that the session is #not empty and is not autodeleted, otherwise anonymous #answer posting is impossible request.session['askbot_write_intent'] = True data = { 'active_tab': 'questions', 'answer' : answer_form, 'answers' : page_objects.object_list, 'answer_count': thread.get_answer_count(request.user), 'blank_comment': MockPost(post_type='comment', author=request.user),#data for the js comment template 'category_tree_data': askbot_settings.CATEGORY_TREE, 'favorited' : favorited, 'group_read_only': group_read_only, 'is_cacheable': False,#is_cacheable, #temporary, until invalidation fix 'language_code': translation.get_language(), 'long_time': const.LONG_TIME,#"forever" caching 'new_answer_allowed': new_answer_allowed, 'oldest_answer_id': thread.get_oldest_answer_id(request.user), 'page_class': 'question-page', 'paginator_context' : paginator_context, 'previous_answer': previous_answer, 'published_answer_ids': published_answer_ids, 'question' : question_post, 'show_comment': show_comment, 'show_comment_position': show_comment_position, 'show_post': show_post, 'similar_threads' : thread.get_similar_threads(), 'tab_id' : answer_sort_method, 'thread': thread, 'thread_is_moderated': thread.is_moderated(), 'user_is_thread_moderator': thread.has_moderator(request.user), 'user_votes': user_votes, 'user_post_id_list': user_post_id_list, 'user_can_post_comment': user_can_post_comment,#in general } #shared with ... if askbot_settings.GROUPS_ENABLED: data['sharing_info'] = thread.get_sharing_info() data.update(context.get_for_tag_editor()) extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data) data.update(extra) return render(request, 'question.html', data)
def questions(request, **kwargs): """ List of Questions, Tagged questions, and Unanswered questions. matching search query or user selection """ #before = datetime.datetime.now() if request.method != 'GET': return HttpResponseNotAllowed(['GET']) search_state = SearchState( user_logged_in=request.user.is_authenticated(), **kwargs ) page_size = int(askbot_settings.DEFAULT_QUESTIONS_PAGE_SIZE) qs, meta_data = models.Thread.objects.run_advanced_search( request_user=request.user, search_state=search_state ) if meta_data['non_existing_tags']: search_state = search_state.remove_tags(meta_data['non_existing_tags']) paginator = Paginator(qs, page_size) if paginator.num_pages < search_state.page: search_state.page = 1 page = paginator.page(search_state.page) page.object_list = list(page.object_list) # evaluate the queryset # INFO: Because for the time being we need question posts and thread authors # down the pipeline, we have to precache them in thread objects models.Thread.objects.precache_view_data_hack(threads=page.object_list) related_tags = Tag.objects.get_related_to_search( threads=page.object_list, ignored_tag_names=meta_data.get('ignored_tag_names',[]) ) tag_list_type = askbot_settings.TAG_LIST_FORMAT if tag_list_type == 'cloud': #force cloud to sort by name related_tags = sorted(related_tags, key = operator.attrgetter('name')) contributors = list( models.Thread.objects.get_thread_contributors( thread_list=page.object_list ).only('id', 'username', 'gravatar') ) paginator_context = { 'is_paginated' : (paginator.count > page_size), 'pages': paginator.num_pages, 'current_page_number': search_state.page, 'page_object': page, 'base_url' : search_state.query_string(), 'page_size' : page_size, } # We need to pass the rss feed url based # on the search state to the template. # We use QueryDict to get a querystring # from dicts and arrays. Much cleaner # than parsing and string formating. rss_query_dict = QueryDict("").copy() if search_state.query: # We have search string in session - pass it to # the QueryDict rss_query_dict.update({"q": search_state.query}) if search_state.tags: # We have tags in session - pass it to the # QueryDict but as a list - we want tags+ rss_query_dict.setlist("tags", search_state.tags) context_feed_url = '/%sfeeds/rss/?%s' % ( django_settings.ASKBOT_URL, rss_query_dict.urlencode() ) # Format the url with the QueryDict reset_method_count = len(filter(None, [search_state.query, search_state.tags, meta_data.get('author_name', None)])) if request.is_ajax(): print "test" sys.exit() q_count = paginator.count question_counter = ungettext('%(q_num)s question', '%(q_num)s questions', q_count) question_counter = question_counter % {'q_num': humanize.intcomma(q_count),} if q_count > page_size: paginator_tpl = get_template('main_page/paginator.html') paginator_html = paginator_tpl.render( RequestContext( request, { 'context': functions.setup_paginator(paginator_context), 'questions_count': q_count, 'page_size' : page_size, 'search_state': search_state, } ) ) else: paginator_html = '' questions_tpl = get_template('main_page/questions_loop.html') questions_html = questions_tpl.render( RequestContext( request, { 'threads': page, 'search_state': search_state, 'reset_method_count': reset_method_count, 'request': request } ) ) ajax_data = { 'query_data': { 'tags': search_state.tags, 'sort_order': search_state.sort, 'ask_query_string': search_state.ask_query_string(), }, 'paginator': paginator_html, 'question_counter': question_counter, 'faces': [],#[extra_tags.gravatar(contributor, 48) for contributor in contributors], 'feed_url': context_feed_url, 'query_string': search_state.query_string(), 'page_size' : page_size, 'questions': questions_html.replace('\n',''), 'non_existing_tags': meta_data['non_existing_tags'] } ajax_data['related_tags'] = [{ 'name': escape(tag.name), 'used_count': humanize.intcomma(tag.local_used_count) } for tag in related_tags] return HttpResponse(simplejson.dumps(ajax_data), mimetype = 'application/json')