from django.core.urlresolvers import reverse from django.core.files import File from django.core.files.temp import NamedTemporaryFile from django.core.paginator import EmptyPage from django.db import transaction from django.http import Http404 from django.shortcuts import render, redirect from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect from boards import utils, settings 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, Ban from boards.views.banned import BannedView from boards.views.base import BaseBoardView, CONTEXT_FORM from boards.views.posting_mixin import PostMixin from boards.views.mixins import FileUploadMixin, PaginatedMixin,\ DispatcherMixin, PARAMETER_METHOD 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_MAX_FILE_SIZE = 'max_file_size' PARAMETER_RSS_URL = 'rss_url' PARAMETER_MAX_FILES = 'max_files' TEMPLATE = 'boards/all_threads.html' DEFAULT_PAGE = 1 FORM_TAGS = 'tags' class AllThreadsView(PostMixin, FileUploadMixin, 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('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('order', 'bump') if order == 'bump': threads = threads.order_by('-bump_time') else: threads = threads.filter(replies__opening=True)\ .order_by('-replies__pub_time') filter = request.GET.get('filter') threads = threads.distinct() paginator = get_paginator(threads, settings.get_int('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_MAX_FILE_SIZE] = self.get_max_upload_size() params[PARAMETER_RSS_URL] = self.get_rss_url() params[PARAMETER_MAX_FILES] = settings.get_int('Forms', 'MaxFileCount') paginator.set_url(self.get_reverse_url(), request.GET.dict()) self.get_page_context(paginator, params, 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 redirect('index') # FIXME Different for different modes form = ThreadForm(request.POST, request.FILES, error_class=PlainErrorList) form.session = request.session if form.is_valid(): return self.create_thread(request, form) 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_page_context(self, paginator, params, page): """ Get pagination context variables """ params[PARAMETER_PAGINATOR] = paginator current_page = paginator.page(int(page)) params[PARAMETER_CURRENT_PAGE] = current_page self.set_page_urls(paginator, params) def get_reverse_url(self): return reverse('index') @transaction.atomic def create_thread(self, request, form: ThreadForm, html_response=True): """ Creates a new thread with an opening post. """ ip = utils.get_client_ip(request) is_banned = Ban.objects.filter(ip=ip).exists() if is_banned: if html_response: return redirect(BannedView().as_view()) else: return data = form.cleaned_data title = form.get_title() text = data[FORM_TEXT] files = form.get_files() file_urls = form.get_file_urls() images = form.get_images() text = self._remove_invalid_links(text) tags = data[FORM_TAGS] monochrome = form.is_monochrome() post = Post.objects.create_post(title=title, text=text, files=files, ip=ip, tags=tags, tripcode=form.get_tripcode(), monochrome=monochrome, images=images, file_urls=file_urls) if form.is_subscribe(): settings_manager = get_settings_manager(request) settings_manager.add_or_read_fav_thread(post) if html_response: return redirect(post.get_absolute_url()) 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))