from django.core.urlresolvers import reverse from django.db import transaction from django.http import Http404 from django.shortcuts import get_object_or_404, render, redirect from django.views.decorators.cache import never_cache, cache_control from django.views.generic.edit import FormMixin from boards import utils, settings from boards.forms import PostForm, PlainErrorList from boards.models import Post, Ban from boards.views.banned import BannedView from boards.views.base import BaseBoardView, CONTEXT_FORM from boards.views.posting_mixin import PostMixin import neboard TEMPLATE_GALLERY = 'boards/thread_gallery.html' TEMPLATE_NORMAL = 'boards/thread.html' CONTEXT_POSTS = 'posts' CONTEXT_OP = 'opening_post' CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress' CONTEXT_POSTS_LEFT = 'posts_left' CONTEXT_LASTUPDATE = "last_update" CONTEXT_MAX_REPLIES = 'max_replies' CONTEXT_THREAD = 'thread' CONTEXT_BUMPABLE = 'bumpable' CONTEXT_WS_TOKEN = 'ws_token' CONTEXT_WS_PROJECT = 'ws_project' CONTEXT_WS_HOST = 'ws_host' CONTEXT_WS_PORT = 'ws_port' FORM_TITLE = 'title' FORM_TEXT = 'text' FORM_IMAGE = 'image' MODE_GALLERY = 'gallery' MODE_NORMAL = 'normal' class ThreadView(BaseBoardView, PostMixin, FormMixin): @cache_control(no_cache=True) def get(self, request, post_id, mode=MODE_NORMAL, form=None): try: opening_post = Post.objects.filter(id=post_id).only('thread_new')[0] except IndexError: raise Http404 # If this is not OP, don't show it as it is if not opening_post or not opening_post.is_opening(): raise Http404 if not form: form = PostForm(error_class=PlainErrorList) thread_to_show = opening_post.get_thread() context = self.get_context_data(request=request) context[CONTEXT_FORM] = form context[CONTEXT_LASTUPDATE] = str(utils.datetime_to_epoch( thread_to_show.last_edit_time)) context[CONTEXT_THREAD] = thread_to_show context[CONTEXT_MAX_REPLIES] = settings.MAX_POSTS_PER_THREAD if settings.WEBSOCKETS_ENABLED: context[CONTEXT_WS_TOKEN] = utils.get_websocket_token( timestamp=context[CONTEXT_LASTUPDATE]) context[CONTEXT_WS_PROJECT] = neboard.settings.CENTRIFUGE_PROJECT_ID context[CONTEXT_WS_HOST] = request.get_host().split(':')[0] context[CONTEXT_WS_PORT] = neboard.settings.CENTRIFUGE_PORT # TODO Move this to subclasses: NormalThreadView, GalleryThreadView etc if MODE_NORMAL == mode: bumpable = thread_to_show.can_bump() context[CONTEXT_BUMPABLE] = bumpable if bumpable: left_posts = settings.MAX_POSTS_PER_THREAD \ - thread_to_show.get_reply_count() context[CONTEXT_POSTS_LEFT] = left_posts context[CONTEXT_BUMPLIMIT_PRG] = str( float(left_posts) / settings.MAX_POSTS_PER_THREAD * 100) context[CONTEXT_OP] = opening_post document = TEMPLATE_NORMAL elif MODE_GALLERY == mode: context[CONTEXT_POSTS] = thread_to_show.get_replies_with_images( view_fields_only=True) document = TEMPLATE_GALLERY else: raise Http404 # TODO Use dict here return render(request, document, context_instance=context) def post(self, request, post_id, mode=MODE_NORMAL): 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 not opening_post.get_thread().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, mode, form) @transaction.atomic def new_post(self, request, form, opening_post=None, html_response=True): """Add a new post (in thread or as a reply).""" 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 None data = form.cleaned_data title = data[FORM_TITLE] text = data[FORM_TEXT] text = self._remove_invalid_links(text) if FORM_IMAGE in list(data.keys()): image = data[FORM_IMAGE] else: image = None tags = [] post_thread = opening_post.get_thread() post = Post.objects.create_post(title=title, text=text, image=image, thread=post_thread, ip=ip, tags=tags) post.send_to_websocket(request) thread_to_show = (opening_post.id if opening_post else post.id) if html_response: if opening_post: return redirect( reverse('thread', kwargs={'post_id': thread_to_show}) + '#' + str(post.id)) else: return post