thread.py
150 lines
| 5.0 KiB
| text/x-python
|
PythonLexer
|
r542 | 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 | ||||
|
r633 | from django.views.generic.edit import FormMixin | ||
|
r690 | |||
|
r716 | from boards import utils, settings | ||
|
r542 | from boards.forms import PostForm, PlainErrorList | ||
|
r690 | from boards.models import Post, Ban | ||
|
r542 | from boards.views.banned import BannedView | ||
|
r722 | from boards.views.base import BaseBoardView, CONTEXT_FORM | ||
|
r542 | from boards.views.posting_mixin import PostMixin | ||
|
r853 | import neboard | ||
|
r542 | |||
|
r722 | 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' | ||||
|
r853 | CONTEXT_WS_TOKEN = 'ws_token' | ||
CONTEXT_WS_PROJECT = 'ws_project' | ||||
CONTEXT_WS_HOST = 'ws_host' | ||||
CONTEXT_WS_PORT = 'ws_port' | ||||
|
r722 | |||
FORM_TITLE = 'title' | ||||
FORM_TEXT = 'text' | ||||
FORM_IMAGE = 'image' | ||||
|
r690 | |||
|
r542 | MODE_GALLERY = 'gallery' | ||
MODE_NORMAL = 'normal' | ||||
|
r633 | |||
class ThreadView(BaseBoardView, PostMixin, FormMixin): | ||||
|
r542 | |||
|
r544 | def get(self, request, post_id, mode=MODE_NORMAL, form=None): | ||
|
r689 | try: | ||
opening_post = Post.objects.filter(id=post_id).only('thread_new')[0] | ||||
except IndexError: | ||||
raise Http404 | ||||
|
r542 | |||
# If this is not OP, don't show it as it is | ||||
|
r659 | if not opening_post or not opening_post.is_opening(): | ||
|
r542 | raise Http404 | ||
|
r544 | if not form: | ||
form = PostForm(error_class=PlainErrorList) | ||||
|
r542 | |||
|
r617 | thread_to_show = opening_post.get_thread() | ||
|
r542 | |||
context = self.get_context_data(request=request) | ||||
|
r722 | context[CONTEXT_FORM] = form | ||
|
r853 | context[CONTEXT_LASTUPDATE] = str(utils.datetime_to_epoch( | ||
thread_to_show.last_edit_time)) | ||||
|
r722 | context[CONTEXT_THREAD] = thread_to_show | ||
context[CONTEXT_MAX_REPLIES] = settings.MAX_POSTS_PER_THREAD | ||||
|
r542 | |||
|
r853 | 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 | ||||
|
r859 | # TODO Move this to subclasses: NormalThreadView, GalleryThreadView etc | ||
|
r542 | if MODE_NORMAL == mode: | ||
|
r722 | 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) | ||||
|
r542 | |||
|
r722 | context[CONTEXT_OP] = opening_post | ||
|
r542 | |||
|
r722 | document = TEMPLATE_NORMAL | ||
|
r542 | elif MODE_GALLERY == mode: | ||
|
r722 | context[CONTEXT_POSTS] = thread_to_show.get_replies_with_images( | ||
|
r693 | view_fields_only=True) | ||
|
r542 | |||
|
r722 | document = TEMPLATE_GALLERY | ||
|
r542 | else: | ||
raise Http404 | ||||
|
r872 | # TODO Use dict here | ||
return render(request, document, context_instance=context) | ||||
|
r542 | |||
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 | ||||
|
r617 | if not opening_post.get_thread().archived: | ||
|
r542 | 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) | ||||
|
r544 | return self.get(request, post_id, mode, form) | ||
|
r542 | |||
@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) | ||||
data = form.cleaned_data | ||||
|
r722 | title = data[FORM_TITLE] | ||
text = data[FORM_TEXT] | ||||
|
r542 | |||
text = self._remove_invalid_links(text) | ||||
|
r771 | if FORM_IMAGE in list(data.keys()): | ||
|
r722 | image = data[FORM_IMAGE] | ||
|
r542 | else: | ||
image = None | ||||
tags = [] | ||||
|
r617 | post_thread = opening_post.get_thread() | ||
|
r542 | |||
|
r728 | post = Post.objects.create_post(title=title, text=text, image=image, | ||
thread=post_thread, ip=ip, tags=tags) | ||||
|
r895 | post.send_to_websocket(request, recursive=False) | ||
|
r542 | |||
thread_to_show = (opening_post.id if opening_post else post.id) | ||||
if html_response: | ||||
if opening_post: | ||||
|
r722 | return redirect( | ||
reverse('thread', kwargs={'post_id': thread_to_show}) | ||||
+ '#' + str(post.id)) | ||||
|
r638 | else: | ||
|
r640 | return post | ||