from django.db import transaction from django.shortcuts import render, redirect from boards import utils, settings from boards.abstracts.paginator import get_paginator from boards.abstracts.settingsmanager import get_settings_manager from boards.forms import ThreadForm, PlainErrorList from boards.models import Post, Thread, Ban, Tag from boards.views.banned import BannedView from boards.views.base import BaseBoardView, CONTEXT_FORM from boards.views.posting_mixin import PostMixin FORM_TAGS = 'tags' FORM_TEXT = 'text' FORM_TITLE = 'title' FORM_IMAGE = 'image' TAG_DELIMITER = ' ' PARAMETER_CURRENT_PAGE = 'current_page' PARAMETER_PAGINATOR = 'paginator' PARAMETER_THREADS = 'threads' TEMPLATE = 'boards/posting_general.html' DEFAULT_PAGE = 1 class AllThreadsView(PostMixin, BaseBoardView): def __init__(self): self.settings_manager = None super(AllThreadsView, self).__init__() def get(self, request, page=DEFAULT_PAGE, form=None): params = self.get_context_data(request=request) if not form: form = ThreadForm(error_class=PlainErrorList) self.settings_manager = get_settings_manager(request) paginator = get_paginator(self.get_threads(), settings.THREADS_PER_PAGE) paginator.current_page = int(page) threads = paginator.page(page).object_list params[PARAMETER_THREADS] = threads params[CONTEXT_FORM] = form self._get_page_context(paginator, params, page) return render(request, TEMPLATE, params) def post(self, request, page=DEFAULT_PAGE): 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, page, form) def _get_page_context(self, paginator, params, page): """ Get pagination context variables """ params[PARAMETER_PAGINATOR] = paginator params[PARAMETER_CURRENT_PAGE] = paginator.page(int(page)) @staticmethod def parse_tags_string(tag_strings): """ Parses tag list string and returns tag object list. """ tags = [] if tag_strings: tag_strings = tag_strings.split(TAG_DELIMITER) for tag_name in tag_strings: tag_name = tag_name.strip().lower() if len(tag_name) > 0: tag, created = Tag.objects.get_or_create(name=tag_name) tags.append(tag) return tags @transaction.atomic def create_thread(self, request, form, 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 = data[FORM_TITLE] text = data[FORM_TEXT] image = data.get(FORM_IMAGE) text = self._remove_invalid_links(text) tag_strings = data[FORM_TAGS] tags = self.parse_tags_string(tag_strings) post = Post.objects.create_post(title=title, text=text, image=image, ip=ip, tags=tags) # This is required to update the threads to which posts we have replied # when creating this one post.send_to_websocket(request) if html_response: return redirect(post.get_url()) def get_threads(self): """ Gets list of threads that will be shown on a page. """ return Thread.objects.order_by('-bump_time')\ .exclude(tags__in=self.settings_manager.get_hidden_tags())