from django.core.exceptions import ObjectDoesNotExist from django.http import Http404 from django.shortcuts import get_object_or_404, render, redirect from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect from django.views.generic.edit import FormMixin from boards import utils from boards.abstracts.settingsmanager import get_settings_manager from boards.forms import PostForm, PlainErrorList from boards.models import Post from boards.views.base import BaseBoardView, CONTEXT_FORM from boards.views.mixins import DispatcherMixin, PARAMETER_METHOD from boards.views.posting_mixin import PostMixin REQ_POST_ID = 'post_id' CONTEXT_LASTUPDATE = "last_update" CONTEXT_THREAD = 'thread' CONTEXT_MODE = 'mode' CONTEXT_OP = 'opening_post' CONTEXT_FAVORITE = 'is_favorite' CONTEXT_RSS_URL = 'rss_url' FORM_TITLE = 'title' FORM_TEXT = 'text' FORM_IMAGE = 'image' FORM_THREADS = 'threads' class ThreadView(BaseBoardView, PostMixin, FormMixin, DispatcherMixin): @method_decorator(csrf_protect) def get(self, request, post_id, form: PostForm=None): try: opening_post = Post.objects.get(id=post_id) except ObjectDoesNotExist: raise Http404 # If the tag is favorite, update the counter settings_manager = get_settings_manager(request) favorite = settings_manager.thread_is_fav(opening_post) if favorite: settings_manager.add_or_read_fav_thread(opening_post) # If this is not OP, don't show it as it is if not opening_post.is_opening(): return redirect('{}#{}'.format(opening_post.get_thread().get_opening_post() .get_absolute_url(), opening_post.id)) if not form: form = PostForm(error_class=PlainErrorList) thread_to_show = opening_post.get_thread() params = dict() params[CONTEXT_FORM] = form params[CONTEXT_LASTUPDATE] = str(thread_to_show.last_edit_time) params[CONTEXT_THREAD] = thread_to_show params[CONTEXT_MODE] = self.get_mode() params[CONTEXT_OP] = opening_post params[CONTEXT_FAVORITE] = favorite params[CONTEXT_RSS_URL] = self.get_rss_url(post_id) params.update(self.get_data(thread_to_show)) return render(request, self.get_template(), params) @method_decorator(csrf_protect) def post(self, request, post_id): opening_post = get_object_or_404(Post, id=post_id) # If this is not OP, don't show it as it is if not opening_post.is_opening(): raise Http404 if PARAMETER_METHOD in request.POST: self.dispatch_method(request, opening_post) return redirect('thread', post_id) # FIXME Different for different modes if not opening_post.get_thread().is_archived(): form = PostForm(request.POST, request.FILES, error_class=PlainErrorList) form.session = request.session if form.is_valid(): return self.new_post(request, form, opening_post) if form.need_to_ban: # Ban user because he is suspected to be a bot self._ban_current_user(request) return self.get(request, post_id, form) def new_post(self, request, form: PostForm, opening_post: Post=None, html_response=True): """ Adds a new post (in thread or as a reply). """ ip = utils.get_client_ip(request) 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) post_thread = opening_post.get_thread() post = Post.objects.create_post(title=title, text=text, files=files, thread=post_thread, ip=ip, tripcode=form.get_tripcode(), images=images, file_urls=file_urls) if form.is_subscribe(): settings_manager = get_settings_manager(request) settings_manager.add_or_read_fav_thread( post_thread.get_opening_post()) if html_response: if opening_post: return redirect(post.get_absolute_url()) else: return post def get_data(self, thread) -> dict: """ Returns context params for the view. """ return dict() def get_template(self) -> str: """ Gets template to show the thread mode on. """ pass def get_mode(self) -> str: pass def subscribe(self, request, opening_post): settings_manager = get_settings_manager(request) settings_manager.add_or_read_fav_thread(opening_post) def unsubscribe(self, request, opening_post): settings_manager = get_settings_manager(request) settings_manager.del_fav_thread(opening_post) def get_rss_url(self, opening_id): return reverse('thread', kwargs={'post_id': opening_id}) + 'rss/'