コード例 #1
0
    def test_get_page(self):
        request = self.factory.get('/?page=2')
        page = get_page(self.posts, request, 3)
        self.assertEqual(page.number, 2)
        self.assertEqual(page.paginator.num_pages, 2)

        request = self.factory.get('/?page=1')
        page = get_page(self.posts, request, 3)
        self.assertEqual(page.number, 1)
        self.assertEqual(page.paginator.num_pages, 2)
コード例 #2
0
ファイル: test_utils.py プロジェクト: Azelphur/DjangoBB
    def test_get_page(self):
        request = self.factory.get('/?page=2')
        page = get_page(self.posts, request, 3)
        self.assertEqual(page.number, 2)
        self.assertEqual(page.paginator.num_pages, 2)

        request = self.factory.get('/?page=1')
        page = get_page(self.posts, request, 3)
        self.assertEqual(page.number, 1)
        self.assertEqual(page.paginator.num_pages, 2)
コード例 #3
0
ファイル: views.py プロジェクト: predatell/djangobb
def show_forum(request, forum_id, full=True):
    forum = get_object_or_404(Forum, pk=forum_id)
    if not forum.category.has_access(request.user):
        raise PermissionDenied
    topics = forum.topics.order_by('-sticky', '-updated').select_related()
    moderator = request.user.is_superuser or\
        request.user in forum.moderators.all()

    categories = []
    for category in Category.objects.all():
        if category.has_access(request.user):
            categories.append(category)

    to_return = {
        'categories': categories,
        'forum': forum,
        'posts': forum.post_count,
        'topics_page': get_page(topics, request,
                                forum_settings.FORUM_PAGE_SIZE),
        'moderator': moderator,
    }
    if full:
        return render(request, 'djangobb_forum/forum.html', to_return)
    else:
        return render(request, 'djangobb_forum/lofi/forum.html', to_return)
コード例 #4
0
ファイル: views.py プロジェクト: Azelphur/DjangoBB
def moderate(request, forum_id):
    forum = get_object_or_404(Forum, pk=forum_id)
    topics = forum.topics.order_by('-sticky', '-updated').select_related()
    if request.user.is_superuser or request.user in forum.moderators.all():
        topic_ids = request.POST.getlist('topic_id')
        if 'move_topics' in request.POST:
            return render(request, 'djangobb_forum/move_topic.html', {
                'categories': Category.objects.all(),
                'topic_ids': topic_ids,
                'exclude_forum': forum,
            })
        elif 'delete_topics' in request.POST:
            for topic_id in topic_ids:
                topic = get_object_or_404(Topic, pk=topic_id)
                topic.delete()
            messages.success(request, _("Topics deleted"))
            return HttpResponseRedirect(reverse('djangobb:index'))
        elif 'open_topics' in request.POST:
            for topic_id in topic_ids:
                open_close_topic(request, topic_id, 'o')
            messages.success(request, _("Topics opened"))
            return HttpResponseRedirect(reverse('djangobb:index'))
        elif 'close_topics' in request.POST:
            for topic_id in topic_ids:
                open_close_topic(request, topic_id, 'c')
            messages.success(request, _("Topics closed"))
            return HttpResponseRedirect(reverse('djangobb:index'))

        return render(request, 'djangobb_forum/moderate.html', {
                'forum': forum,
                'topics_page': get_page(topics, request, forum_settings.FORUM_PAGE_SIZE),
                'posts': forum.posts.count(),
        })
    else:
        raise Http404
コード例 #5
0
ファイル: views.py プロジェクト: Azelphur/DjangoBB
def users(request):
    users = User.objects.filter(forum_profile__post_count__gte=forum_settings.POST_USER_SEARCH).order_by('username')
    form = UserSearchForm(request.GET)
    users = form.filter(users)
    return render(request, 'djangobb_forum/users.html', {
        'users_page': get_page(users, request, forum_settings.USERS_PAGE_SIZE),
        'form': form,
    })
コード例 #6
0
ファイル: views.py プロジェクト: predatell/djangobb
def users(request):
    users = User.objects.filter(forum_profile__post_count__gte=forum_settings.
                                POST_USER_SEARCH).order_by('username')
    form = UserSearchForm(request.GET)
    users = form.filter(users)
    return render(
        request, 'djangobb_forum/users.html', {
            'users_page': get_page(users, request,
                                   forum_settings.USERS_PAGE_SIZE),
            'form': form,
        })
コード例 #7
0
ファイル: views.py プロジェクト: mjrulesamrat/djangobb
def review_content(request):
    """
    :param request:
    :return: render to review page or 404
    """
    posts = Post.objects.filter(is_moderated=False).values_list('topic', flat=True).distinct()
    topics = Topic.objects.filter(pk__in=posts)
    try:
        if request.user.is_superuser or request.user in user.groups.filter(name='topic_moderator').exists():
            return render(request, 'djangobb_forum/review.html', {
                'topics_page': get_page(topics, request, forum_settings.FORUM_PAGE_SIZE)
            })
        else:
            raise Http404
    except Exception as e:
        raise Http404
コード例 #8
0
def show_forum(request, forum_id, slug='', page=1, full=True):
    forum = get_object_or_404(Forum, pk=forum_id)
    if not forum.category.has_access(request.user):
        raise PermissionDenied
    if slug != forum.get_slug():
        if page > 1:
            return HttpResponseRedirect(
                reverse('djangobb:forum_pagination',
                        kwargs={
                            'forum_id': forum_id,
                            'slug': forum.get_slug(),
                            'page': page
                        }))
        else:
            return HttpResponseRedirect(
                reverse('djangobb:forum',
                        kwargs={
                            'forum_id': forum_id,
                            'slug': forum.get_slug()
                        }))
    topics = forum.topics.order_by('-sticky', '-updated').select_related()
    moderator = request.user.is_superuser or\
        request.user in forum.moderators.all()

    categories = []
    for category in Category.objects.all():
        if category.has_access(request.user):
            categories.append(category)

    to_return = {
        'categories':
        categories,
        'forum':
        forum,
        'posts':
        forum.post_count,
        'topics_page':
        get_page(topics, request, forum_settings.FORUM_PAGE_SIZE, page=page),
        'moderator':
        moderator,
    }
    if full:
        return render(request, 'djangobb_forum/forum.html', to_return)
    else:
        return render(request, 'djangobb_forum/lofi/forum.html', to_return)
コード例 #9
0
ファイル: views.py プロジェクト: predatell/djangobb
def delete_posts(request, topic_id):

    topic = Topic.objects.select_related().get(pk=topic_id)

    if forum_moderated_by(topic, request.user):
        deleted = False
        post_list = request.POST.getlist('post')
        for post_id in post_list:
            if not deleted:
                deleted = True
            delete_post(request, post_id)
        if deleted:
            messages.success(request, _("Post deleted."))
            return HttpResponseRedirect(topic.get_absolute_url())

    last_post = topic.posts.latest()

    if request.user.is_authenticated:
        topic.update_read(request.user)

    posts = topic.posts.all().select_related()

    initial = {}
    if request.user.is_authenticated:
        initial = {'markup': request.user.forum_profile.markup}
    form = AddPostForm(topic=topic, initial=initial)

    moderator = request.user.is_superuser or\
        request.user in topic.forum.moderators.all()
    if request.user.is_authenticated and request.user in topic.subscribers.all(
    ):
        subscribed = True
    else:
        subscribed = False
    return render(
        request, 'djangobb_forum/delete_posts.html', {
            'topic': topic,
            'last_post': last_post,
            'form': form,
            'moderator': moderator,
            'subscribed': subscribed,
            'posts_page': get_page(posts, request,
                                   forum_settings.TOPIC_PAGE_SIZE),
        })
コード例 #10
0
ファイル: views.py プロジェクト: mjrulesamrat/djangobb
def review_content(request):
    """
    :param request:
    :return: render to review page or 404
    """
    posts = Post.objects.filter(is_moderated=False).values_list(
        'topic', flat=True).distinct()
    topics = Topic.objects.filter(pk__in=posts)
    try:
        if request.user.is_superuser or request.user in user.groups.filter(
                name='topic_moderator').exists():
            return render(
                request, 'djangobb_forum/review.html', {
                    'topics_page':
                    get_page(topics, request, forum_settings.FORUM_PAGE_SIZE)
                })
        else:
            raise Http404
    except Exception as e:
        raise Http404
コード例 #11
0
ファイル: views.py プロジェクト: Azelphur/DjangoBB
def delete_posts(request, topic_id):

    topic = Topic.objects.select_related().get(pk=topic_id)

    if forum_moderated_by(topic, request.user):
        deleted = False
        post_list = request.POST.getlist('post')
        for post_id in post_list:
            if not deleted:
                deleted = True
            delete_post(request, post_id)
        if deleted:
            messages.success(request, _("Post deleted."))
            return HttpResponseRedirect(topic.get_absolute_url())

    last_post = topic.posts.latest()

    if request.user.is_authenticated():
        topic.update_read(request.user)

    posts = topic.posts.all().select_related()

    initial = {}
    if request.user.is_authenticated():
        initial = {'markup': request.user.forum_profile.markup}
    form = AddPostForm(topic=topic, initial=initial)

    moderator = request.user.is_superuser or\
        request.user in topic.forum.moderators.all()
    if request.user.is_authenticated() and request.user in topic.subscribers.all():
        subscribed = True
    else:
        subscribed = False
    return render(request, 'djangobb_forum/delete_posts.html', {
        'topic': topic,
        'last_post': last_post,
        'form': form,
        'moderator': moderator,
        'subscribed': subscribed,
        'posts_page': get_page(posts, request, forum_settings.TOPIC_PAGE_SIZE),
    })
コード例 #12
0
ファイル: views.py プロジェクト: predatell/djangobb
def moderate(request, forum_id):
    forum = get_object_or_404(Forum, pk=forum_id)
    topics = forum.topics.order_by('-sticky', '-updated').select_related()
    if request.user.is_superuser or request.user in forum.moderators.all():
        topic_ids = request.POST.getlist('topic_id')
        if 'move_topics' in request.POST:
            return render(
                request, 'djangobb_forum/move_topic.html', {
                    'categories': Category.objects.all(),
                    'topic_ids': topic_ids,
                    'exclude_forum': forum,
                })
        elif 'delete_topics' in request.POST:
            for topic_id in topic_ids:
                topic = get_object_or_404(Topic, pk=topic_id)
                topic.delete()
            messages.success(request, _("Topics deleted"))
            return HttpResponseRedirect(reverse('djangobb:index'))
        elif 'open_topics' in request.POST:
            for topic_id in topic_ids:
                open_close_topic(request, topic_id, 'o')
            messages.success(request, _("Topics opened"))
            return HttpResponseRedirect(reverse('djangobb:index'))
        elif 'close_topics' in request.POST:
            for topic_id in topic_ids:
                open_close_topic(request, topic_id, 'c')
            messages.success(request, _("Topics closed"))
            return HttpResponseRedirect(reverse('djangobb:index'))

        return render(
            request, 'djangobb_forum/moderate.html', {
                'forum':
                forum,
                'topics_page':
                get_page(topics, request, forum_settings.FORUM_PAGE_SIZE),
                'posts':
                forum.posts.count(),
            })
    else:
        raise Http404
コード例 #13
0
ファイル: views.py プロジェクト: Azelphur/DjangoBB
def show_forum(request, forum_id, full=True):
    forum = get_object_or_404(Forum, pk=forum_id)
    if not forum.category.has_access(request.user):
        raise PermissionDenied
    topics = forum.topics.order_by('-sticky', '-updated').select_related()
    moderator = request.user.is_superuser or\
        request.user in forum.moderators.all()

    categories = []
    for category in Category.objects.all():
        if category.has_access(request.user):
            categories.append(category)

    to_return = {
        'categories': categories,
        'forum': forum,
        'posts': forum.post_count,
        'topics_page': get_page(topics, request, forum_settings.FORUM_PAGE_SIZE),
        'moderator': moderator,
    }
    if full:
        return render(request, 'djangobb_forum/forum.html', to_return)
    else:
        return render(request, 'djangobb_forum/lofi/forum.html', to_return)
コード例 #14
0
ファイル: views.py プロジェクト: Azelphur/DjangoBB
def show_topic(request, topic_id, full=True):
    """
    * Display a topic
    * save a reply
    * save a poll vote

    TODO: Add reply in lofi mode
    """
    post_request = request.method == "POST"
    user_is_authenticated = request.user.is_authenticated()
    if post_request and not user_is_authenticated:
        # Info: only user that are logged in should get forms in the page.
        raise PermissionDenied

    topic = get_object_or_404(Topic.objects.select_related(), pk=topic_id)
    if not topic.forum.category.has_access(request.user):
        raise PermissionDenied
    Topic.objects.filter(pk=topic.id).update(views=F('views') + 1)

    last_post = topic.last_post

    if request.user.is_authenticated():
        topic.update_read(request.user)
    posts = topic.posts.all().select_related()

    moderator = request.user.is_superuser or request.user in topic.forum.moderators.all()
    if user_is_authenticated and request.user in topic.subscribers.all():
        subscribed = True
    else:
        subscribed = False

    # reply form
    reply_form = None
    form_url = None
    back_url = None
    if user_is_authenticated and not topic.closed:
        form_url = request.path + "#reply" # if form validation failed: browser should scroll down to reply form ;)
        back_url = request.path
        ip = request.META.get('REMOTE_ADDR', None)
        post_form_kwargs = {"topic":topic, "user":request.user, "ip":ip}
        if post_request and AddPostForm.FORM_NAME in request.POST:
            reply_form = AddPostForm(request.POST, request.FILES, **post_form_kwargs)
            if reply_form.is_valid():
                post = reply_form.save()
                messages.success(request, _("Your reply saved."))
                return HttpResponseRedirect(post.get_absolute_url())
        else:
            reply_form = AddPostForm(
                initial={
                    'markup': request.user.forum_profile.markup,
                    'subscribe': request.user.forum_profile.auto_subscribe,
                },
                **post_form_kwargs
            )

    # handle poll, if exists
    poll_form = None
    polls = topic.poll_set.all()
    if not polls:
        poll = None
    else:
        poll = polls[0]
        if user_is_authenticated: # Only logged in users can vote
            poll.deactivate_if_expired()
            has_voted = request.user in poll.users.all()
            if not post_request or not VotePollForm.FORM_NAME in request.POST:
                # It's not a POST request or: The reply form was send and not a poll vote
                if poll.active and not has_voted:
                    poll_form = VotePollForm(poll)
            else:
                if not poll.active:
                    messages.error(request, _("This poll is not active!"))
                    return HttpResponseRedirect(topic.get_absolute_url())
                elif has_voted:
                    messages.error(request, _("You have already vote to this poll in the past!"))
                    return HttpResponseRedirect(topic.get_absolute_url())

                poll_form = VotePollForm(poll, request.POST)
                if poll_form.is_valid():
                    ids = poll_form.cleaned_data["choice"]
                    queryset = poll.choices.filter(id__in=ids)
                    queryset.update(votes=F('votes') + 1)
                    poll.users.add(request.user) # save that this user has vote
                    messages.success(request, _("Your votes are saved."))
                    return HttpResponseRedirect(topic.get_absolute_url())

    highlight_word = request.GET.get('hl', '')
    view_data = {
        'categories': Category.objects.all(),
        'topic': topic,
        'posts_page': get_page(posts, request, forum_settings.TOPIC_PAGE_SIZE),
        'poll': poll,
        'poll_form': poll_form,
    }
    if full:
        view_data.update({
            'last_post': last_post,
            'form_url': form_url,
            'reply_form': reply_form,
            'back_url': back_url,
            'moderator': moderator,
            'subscribed': subscribed,
            'highlight_word': highlight_word,
        })
        return render(request, 'djangobb_forum/topic.html', view_data)
    else:
        return render(request, 'djangobb_forum/lofi/topic.html', view_data)
コード例 #15
0
ファイル: views.py プロジェクト: Azelphur/DjangoBB
def search(request):
    # TODO: used forms in every search type

    def _render_search_form(form=None):
        return render(request, 'djangobb_forum/search_form.html', {'categories': Category.objects.all(),
                'form': form,
                })

    if not 'action' in request.GET:
        return _render_search_form(form=PostSearchForm())

    if request.GET.get("show_as") == "posts":
        show_as_posts = True
        template_name = 'djangobb_forum/search_posts.html'
    else:
        show_as_posts = False
        template_name = 'djangobb_forum/search_topics.html'

    context = {}

    # Create 'user viewable' pre-filtered topics/posts querysets
    viewable_category = Category.objects.all()
    topics = Topic.objects.all().order_by("-last_post__created")
    posts = Post.objects.all().order_by('-created')
    user = request.user
    if not user.is_superuser:
        user_groups = user.groups.all() or [] # need 'or []' for anonymous user otherwise: 'EmptyManager' object is not iterable
        viewable_category = viewable_category.filter(Q(groups__in=user_groups) | Q(groups__isnull=True))

        topics = Topic.objects.filter(forum__category__in=viewable_category)
        posts = Post.objects.filter(topic__forum__category__in=viewable_category)

    base_url = None
    _generic_context = True

    action = request.GET['action']
    if action == 'show_24h':
        date = timezone.now() - timedelta(days=1)
        if show_as_posts:
            context["posts"] = posts.filter(Q(created__gte=date) | Q(updated__gte=date))
        else:
            context["topics"] = topics.filter(Q(last_post__created__gte=date) | Q(last_post__updated__gte=date))
        _generic_context = False
    elif action == 'show_new':
        if not user.is_authenticated():
            raise Http404("Search 'show_new' not available for anonymous user.")
        try:
            last_read = PostTracking.objects.get(user=user).last_read
        except PostTracking.DoesNotExist:
            last_read = None

        if last_read:
            if show_as_posts:
                context["posts"] = posts.filter(Q(created__gte=last_read) | Q(updated__gte=last_read))
            else:
                context["topics"] = topics.filter(Q(last_post__created__gte=last_read) | Q(last_post__updated__gte=last_read))
            _generic_context = False
        else:
            #searching more than forum_settings.SEARCH_PAGE_SIZE in this way - not good idea :]
            topics_id = [topic.id for topic in topics[:forum_settings.SEARCH_PAGE_SIZE] if forum_extras.has_unreads(topic, user)]
            topics = Topic.objects.filter(id__in=topics_id) # to create QuerySet

    elif action == 'show_unanswered':
        topics = topics.filter(post_count=1)
    elif action == 'show_subscriptions':
        topics = topics.filter(subscribers__id=user.id)
    elif action == 'show_user':
        # Show all posts from user or topics started by user
        if not user.is_authenticated():
            raise Http404("Search 'show_user' not available for anonymous user.")

        user_id = request.GET.get("user_id", user.id)
        try:
            user_id = int(user_id)
        except ValueError:
            raise SuspiciousOperation()

        if user_id != user.id:
            try:
                search_user = User.objects.get(id=user_id)
            except User.DoesNotExist:
                messages.error(request, _("Error: User unknown!"))
                return HttpResponseRedirect(request.path)
            messages.info(request, _("Filter by user '%(username)s'.") % {'username': search_user.username})

        if show_as_posts:
            posts = posts.filter(user__id=user_id)
        else:
            # show as topic
            topics = topics.filter(posts__user__id=user_id).order_by("-last_post__created").distinct()

        base_url = "?action=show_user&user_id=%s&show_as=" % user_id
    elif action == 'search':
        form = PostSearchForm(request.GET)
        if not form.is_valid():
            return _render_search_form(form)

        keywords = form.cleaned_data['keywords']
        author = form.cleaned_data['author']
        forum = form.cleaned_data['forum']
        search_in = form.cleaned_data['search_in']
        sort_by = form.cleaned_data['sort_by']
        sort_dir = form.cleaned_data['sort_dir']

        query = SearchQuerySet().models(Post)

        if author:
            query = query.filter(author__username=author)

        if forum != '0':
            query = query.filter(forum__id=forum)

        if keywords:
            if search_in == 'all':
                query = query.filter(SQ(topic=keywords) | SQ(text=keywords))
            elif search_in == 'message':
                query = query.filter(text=keywords)
            elif search_in == 'topic':
                query = query.filter(topic=keywords)

        order = {'0': 'created',
                 '1': 'author',
                 '2': 'topic',
                 '3': 'forum'}.get(sort_by, 'created')
        if sort_dir == 'DESC':
            order = '-' + order

        post_pks = query.values_list("pk", flat=True)

        if not show_as_posts:
            # TODO: We have here a problem to get a list of topics without double entries.
            # Maybe we must add a search index over topics?

            # Info: If whoosh backend used, setup HAYSTACK_ITERATOR_LOAD_PER_QUERY
            #    to a higher number to speed up
            context["topics"] = topics.filter(posts__in=post_pks).distinct()
        else:
            # FIXME: How to use the pre-filtered query from above?
            posts = posts.filter(pk__in=post_pks).order_by(order)
            context["posts"] = posts

        get_query_dict = request.GET.copy()
        get_query_dict.pop("show_as")
        base_url = "?%s&show_as=" % get_query_dict.urlencode()
        _generic_context = False

    if _generic_context:
        if show_as_posts:
            context["posts"] = posts.filter(topic__in=topics).order_by('-created')
        else:
            context["topics"] = topics

    if base_url is None:
        base_url = "?action=%s&show_as=" % action

    if show_as_posts:
        context['posts_page'] = get_page(context['posts'], request, forum_settings.SEARCH_PAGE_SIZE)
        context["as_topic_url"] = base_url + "topics"
        post_count = context["posts"].count()
        messages.success(request, _("Found %i posts.") % post_count)
    else:
        context['topics_page'] = get_page(context['topics'], request, forum_settings.SEARCH_PAGE_SIZE)
        context["as_post_url"] = base_url + "posts"
        topic_count = context["topics"].count()
        messages.success(request, _("Found %i topics.") % topic_count)

    return render(request, template_name, context)
コード例 #16
0
ファイル: views.py プロジェクト: predatell/djangobb
def search(request):
    # TODO: used forms in every search type

    def _render_search_form(form=None):
        return render(request, 'djangobb_forum/search_form.html', {
            'categories': Category.objects.all(),
            'form': form,
        })

    if not 'action' in request.GET:
        return _render_search_form(form=PostSearchForm())

    if request.GET.get("show_as") == "posts":
        show_as_posts = True
        template_name = 'djangobb_forum/search_posts.html'
    else:
        show_as_posts = False
        template_name = 'djangobb_forum/search_topics.html'

    context = {}

    # Create 'user viewable' pre-filtered topics/posts querysets
    viewable_category = Category.objects.all()
    topics = Topic.objects.all().order_by("-last_post__created")
    posts = Post.objects.all().order_by('-created')
    user = request.user
    if not user.is_superuser:
        user_groups = user.groups.all() or [
        ]  # need 'or []' for anonymous user otherwise: 'EmptyManager' object is not iterable
        viewable_category = viewable_category.filter(
            Q(groups__in=user_groups) | Q(groups__isnull=True))

        topics = Topic.objects.filter(forum__category__in=viewable_category)
        posts = Post.objects.filter(
            topic__forum__category__in=viewable_category)

    base_url = None
    _generic_context = True

    action = request.GET['action']
    if action == 'show_24h':
        date = timezone.now() - timedelta(days=1)
        if show_as_posts:
            context["posts"] = posts.filter(
                Q(created__gte=date) | Q(updated__gte=date))
        else:
            context["topics"] = topics.filter(
                Q(last_post__created__gte=date)
                | Q(last_post__updated__gte=date))
        _generic_context = False
    elif action == 'show_new':
        if not user.is_authenticated:
            raise Http404(
                "Search 'show_new' not available for anonymous user.")
        try:
            last_read = PostTracking.objects.get(user=user).last_read
        except PostTracking.DoesNotExist:
            last_read = None

        if last_read:
            if show_as_posts:
                context["posts"] = posts.filter(
                    Q(created__gte=last_read) | Q(updated__gte=last_read))
            else:
                context["topics"] = topics.filter(
                    Q(last_post__created__gte=last_read)
                    | Q(last_post__updated__gte=last_read))
            _generic_context = False
        else:
            #searching more than forum_settings.SEARCH_PAGE_SIZE in this way - not good idea :]
            topics_id = [
                topic.id for topic in topics[:forum_settings.SEARCH_PAGE_SIZE]
                if forum_extras.has_unreads(topic, user)
            ]
            topics = Topic.objects.filter(
                id__in=topics_id)  # to create QuerySet

    elif action == 'show_unanswered':
        topics = topics.filter(post_count=1)
    elif action == 'show_subscriptions':
        topics = topics.filter(subscribers__id=user.id)
    elif action == 'show_user':
        # Show all posts from user or topics started by user
        if not user.is_authenticated:
            raise Http404(
                "Search 'show_user' not available for anonymous user.")

        user_id = request.GET.get("user_id", user.id)
        try:
            user_id = int(user_id)
        except ValueError:
            raise SuspiciousOperation()

        if user_id != user.id:
            try:
                search_user = User.objects.get(id=user_id)
            except User.DoesNotExist:
                messages.error(request, _("Error: User unknown!"))
                return HttpResponseRedirect(request.path)
            messages.info(
                request,
                _("Filter by user '%(username)s'.") %
                {'username': search_user.username})

        if show_as_posts:
            posts = posts.filter(user__id=user_id)
        else:
            # show as topic
            topics = topics.filter(posts__user__id=user_id).order_by(
                "-last_post__created").distinct()

        base_url = "?action=show_user&user_id=%s&show_as=" % user_id
    elif action == 'search':
        form = PostSearchForm(request.GET)
        if not form.is_valid():
            return _render_search_form(form)

        keywords = form.cleaned_data['keywords']
        author = form.cleaned_data['author']
        forum = form.cleaned_data['forum']
        search_in = form.cleaned_data['search_in']
        sort_by = form.cleaned_data['sort_by']
        sort_dir = form.cleaned_data['sort_dir']

        query = SearchQuerySet().models(Post)

        if author:
            query = query.filter(author__username=author)

        if forum != '0':
            query = query.filter(forum__id=forum)

        if keywords:
            if search_in == 'all':
                query = query.filter(SQ(topic=keywords) | SQ(text=keywords))
            elif search_in == 'message':
                query = query.filter(text=keywords)
            elif search_in == 'topic':
                query = query.filter(topic=keywords)

        order = {
            '0': 'created',
            '1': 'author',
            '2': 'topic',
            '3': 'forum'
        }.get(sort_by, 'created')
        if sort_dir == 'DESC':
            order = '-' + order

        post_pks = query.values_list("pk", flat=True)

        if not show_as_posts:
            # TODO: We have here a problem to get a list of topics without double entries.
            # Maybe we must add a search index over topics?

            # Info: If whoosh backend used, setup HAYSTACK_ITERATOR_LOAD_PER_QUERY
            #    to a higher number to speed up
            context["topics"] = topics.filter(posts__in=post_pks).distinct()
        else:
            # FIXME: How to use the pre-filtered query from above?
            posts = posts.filter(pk__in=post_pks).order_by(order)
            context["posts"] = posts

        get_query_dict = request.GET.copy()
        get_query_dict.pop("show_as")
        base_url = "?%s&show_as=" % get_query_dict.urlencode()
        _generic_context = False

    if _generic_context:
        if show_as_posts:
            context["posts"] = posts.filter(
                topic__in=topics).order_by('-created')
        else:
            context["topics"] = topics

    if base_url is None:
        base_url = "?action=%s&show_as=" % action

    if show_as_posts:
        context['posts_page'] = get_page(context['posts'], request,
                                         forum_settings.SEARCH_PAGE_SIZE)
        context["as_topic_url"] = base_url + "topics"
        post_count = context["posts"].count()
        messages.success(request, _("Found %i posts.") % post_count)
    else:
        context['topics_page'] = get_page(context['topics'], request,
                                          forum_settings.SEARCH_PAGE_SIZE)
        context["as_post_url"] = base_url + "posts"
        topic_count = context["topics"].count()
        messages.success(request, _("Found %i topics.") % topic_count)

    return render(request, template_name, context)
コード例 #17
0
ファイル: views.py プロジェクト: predatell/djangobb
def show_topic(request, topic_id, full=True):
    """
    * Display a topic
    * save a reply
    * save a poll vote

    TODO: Add reply in lofi mode
    """
    post_request = request.method == "POST"
    user_is_authenticated = request.user.is_authenticated
    if post_request and not user_is_authenticated:
        # Info: only user that are logged in should get forms in the page.
        raise PermissionDenied

    topic = get_object_or_404(Topic.objects.select_related(), pk=topic_id)
    if not topic.forum.category.has_access(request.user):
        raise PermissionDenied
    Topic.objects.filter(pk=topic.id).update(views=F('views') + 1)

    last_post = topic.last_post

    if request.user.is_authenticated:
        topic.update_read(request.user)
    posts = topic.posts.all().select_related()

    moderator = request.user.is_superuser or request.user in topic.forum.moderators.all(
    )
    if user_is_authenticated and request.user in topic.subscribers.all():
        subscribed = True
    else:
        subscribed = False

    # reply form
    reply_form = None
    form_url = None
    back_url = None
    if user_is_authenticated and not topic.closed:
        form_url = request.path + "#reply"  # if form validation failed: browser should scroll down to reply form ;)
        back_url = request.path
        ip = request.META.get('REMOTE_ADDR', None)
        post_form_kwargs = {"topic": topic, "user": request.user, "ip": ip}
        if post_request and AddPostForm.FORM_NAME in request.POST:
            reply_form = AddPostForm(request.POST, request.FILES,
                                     **post_form_kwargs)
            if reply_form.is_valid():
                post = reply_form.save()
                messages.success(request, _("Your reply saved."))
                return HttpResponseRedirect(post.get_absolute_url())
        else:
            reply_form = AddPostForm(initial={
                'markup':
                request.user.forum_profile.markup,
                'subscribe':
                request.user.forum_profile.auto_subscribe,
            },
                                     **post_form_kwargs)

    # handle poll, if exists
    poll_form = None
    polls = topic.poll_set.all()
    if not polls:
        poll = None
    else:
        poll = polls[0]
        if user_is_authenticated:  # Only logged in users can vote
            poll.deactivate_if_expired()
            has_voted = request.user in poll.users.all()
            if not post_request or not VotePollForm.FORM_NAME in request.POST:
                # It's not a POST request or: The reply form was send and not a poll vote
                if poll.active and not has_voted:
                    poll_form = VotePollForm(poll)
            else:
                if not poll.active:
                    messages.error(request, _("This poll is not active!"))
                    return HttpResponseRedirect(topic.get_absolute_url())
                elif has_voted:
                    messages.error(
                        request,
                        _("You have already vote to this poll in the past!"))
                    return HttpResponseRedirect(topic.get_absolute_url())

                poll_form = VotePollForm(poll, request.POST)
                if poll_form.is_valid():
                    ids = poll_form.cleaned_data["choice"]
                    queryset = poll.choices.filter(id__in=ids)
                    queryset.update(votes=F('votes') + 1)
                    poll.users.add(
                        request.user)  # save that this user has vote
                    messages.success(request, _("Your votes are saved."))
                    return HttpResponseRedirect(topic.get_absolute_url())

    highlight_word = request.GET.get('hl', '')
    view_data = {
        'categories': Category.objects.all(),
        'topic': topic,
        'posts_page': get_page(posts, request, forum_settings.TOPIC_PAGE_SIZE),
        'poll': poll,
        'poll_form': poll_form,
    }
    if full:
        view_data.update({
            'last_post': last_post,
            'form_url': form_url,
            'reply_form': reply_form,
            'back_url': back_url,
            'moderator': moderator,
            'subscribed': subscribed,
            'highlight_word': highlight_word,
        })
        return render(request, 'djangobb_forum/topic.html', view_data)
    else:
        return render(request, 'djangobb_forum/lofi/topic.html', view_data)