from django.core.paginator import EmptyPage from django.http import Http404 from django.shortcuts import render from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect from boards import settings from boards.abstracts.constants import PARAM_PAGE from boards.abstracts.paginator import get_paginator from boards.abstracts.settingsmanager import get_settings_manager, \ SETTING_ONLY_FAVORITES from boards.forms import ThreadForm, PlainErrorList from boards.models import Post, Thread from boards.settings import SECTION_VIEW from boards.views.base import BaseBoardView, CONTEXT_FORM from boards.views.mixins import PaginatedMixin, \ DispatcherMixin, PARAMETER_METHOD ORDER_BUMP = 'bump' PARAM_ORDER = 'order' FORM_TAGS = 'tags' FORM_TEXT = 'text' FORM_TITLE = 'title' FORM_IMAGE = 'image' FORM_THREADS = 'threads' TAG_DELIMITER = ' ' PARAMETER_CURRENT_PAGE = 'current_page' PARAMETER_PAGINATOR = 'paginator' PARAMETER_THREADS = 'threads' PARAMETER_ADDITIONAL = 'additional_params' PARAMETER_RSS_URL = 'rss_url' TEMPLATE = 'boards/all_threads.html' DEFAULT_PAGE = 1 class AllThreadsView(BaseBoardView, PaginatedMixin, DispatcherMixin): tag_name = '' def __init__(self): self.settings_manager = None super(AllThreadsView, self).__init__() @method_decorator(csrf_protect) def get(self, request, form: ThreadForm=None): page = request.GET.get(PARAM_PAGE, DEFAULT_PAGE) params = self.get_context_data(request=request) if not form: form = ThreadForm(error_class=PlainErrorList, initial={FORM_TAGS: self.tag_name}) self.settings_manager = get_settings_manager(request) threads = self.get_threads() order = request.GET.get(PARAM_ORDER, ORDER_BUMP) if order == ORDER_BUMP: threads = threads.order_by('-bump_time') else: threads = threads.filter(replies__opening=True)\ .order_by('-replies__pub_time') threads = threads.distinct() paginator = get_paginator(threads, settings.get_int( SECTION_VIEW, 'ThreadsPerPage')) paginator.current_page = int(page) try: threads = paginator.page(page).object_list except EmptyPage: raise Http404() params[PARAMETER_THREADS] = threads params[CONTEXT_FORM] = form params[PARAMETER_RSS_URL] = self.get_rss_url() paginator.set_url(self.get_reverse_url(), request.GET.dict()) params.update(self.get_page_context(paginator, page)) return render(request, TEMPLATE, params) @method_decorator(csrf_protect) def post(self, request): if PARAMETER_METHOD in request.POST: self.dispatch_method(request) return self.get_reverse_url() form = ThreadForm(request.POST, request.FILES, error_class=PlainErrorList) form.session = request.session if form.is_valid(): return Post.objects.create_from_form(request, form, None) if form.need_to_ban: # Ban user because he is suspected to be a bot self._ban_current_user(request) return self.get(request, form) def get_reverse_url(self): return reverse('index') def get_threads(self): """ Gets list of threads that will be shown on a page. """ threads = Thread.objects\ .exclude(tags__in=self.settings_manager.get_hidden_tags()) if self.settings_manager.get_setting(SETTING_ONLY_FAVORITES): fav_tags = self.settings_manager.get_fav_tags() if len(fav_tags) > 0: threads = threads.filter(tags__in=fav_tags) return threads def get_rss_url(self): return self.get_reverse_url() + 'rss/' def toggle_fav(self, request): settings_manager = get_settings_manager(request) settings_manager.set_setting(SETTING_ONLY_FAVORITES, not settings_manager.get_setting(SETTING_ONLY_FAVORITES, False))