123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- """
- Module with basic views for use by inheriting actions
- """
- from django.db.transaction import atomic
- from django.shortcuts import redirect, render
- from django.views.generic import View
- from misago.acl import add_acl
- from misago.core.shortcuts import get_object_or_404, paginate, validate_slug
- from misago.forums.lists import get_forums_list, get_forum_path
- from misago.forums.models import Forum
- from misago.forums.permissions import allow_see_forum, allow_browse_forum
- from misago.threads.forms.posting import EditorFormset, START, REPLY, EDIT
- from misago.threads.models import Thread, Post
- from misago.threads.permissions import allow_see_thread, allow_start_thread
- class ForumMixin(object):
- """
- Mixin for getting forums
- """
- def get_forum(self, request, lock=False, **kwargs):
- forum = self.fetch_forum(request, lock, **kwargs)
- self.check_forum_permissions(request, forum)
- if kwargs.get('forum_slug'):
- validate_slug(forum, kwargs.get('forum_slug'))
- return forum
- def fetch_forum(self, request, lock=False, **kwargs):
- queryset = Forum.objects
- if lock:
- queryset = queryset.select_for_update()
- return get_object_or_404(
- queryset, id=kwargs.get('forum_id'), role='forum')
- def check_forum_permissions(self, request, forum):
- add_acl(request.user, forum)
- allow_see_forum(request.user, forum)
- allow_browse_forum(request.user, forum)
- class ThreadMixin(object):
- """
- Mixin for getting thread
- """
- def get_thread(self, request, lock=False, **kwargs):
- thread = self.fetch_thread(request, lock, **kwargs)
- self.check_thread_permissions(request, thread)
- if kwargs.get('thread_slug'):
- validate_slug(thread, kwargs.get('thread_slug'))
- return thread
- def fetch_thread(self, request, lock=False, **kwargs):
- queryset = Thread.objects
- if lock:
- queryset = queryset.select_for_update()
- return get_object_or_404(queryset, id=kwargs.get('thread_id'))
- def check_thread_permissions(self, request, thread):
- add_acl(request.user, thread)
- allow_see_thread(request.user, thread)
- class ViewBase(ForumMixin, View):
- templates_dir = ''
- template = ''
- def final_template(self):
- return '%s/%s' % (self.templates_dir, self.template)
- def process_context(self, request, context):
- """
- Simple hook for extending and manipulating template context.
- """
- return context
- def render(self, request, context=None, template=None):
- context = self.process_context(request, context or {})
- template = template or self.final_template()
- return render(request, template, context)
- class ForumView(ViewBase):
- """
- Basic view for threads lists
- """
- template = 'list.html'
- def get_threads(self, request, forum, **kwargs):
- return forum.thread_set
- def dispatch(self, request, *args, **kwargs):
- forum = self.get_forum(request, **kwargs)
- forum.subforums = get_forums_list(request.user, forum)
- threads = self.get_threads(request, forum, **kwargs)
- return self.render(request, {
- 'forum': forum,
- 'path': get_forum_path(forum),
- })
- class ThreadView(ViewBase):
- """
- Basic view for threads
- """
- def fetch_thread(self, request, **kwargs):
- pass
- def dispatch(self, request, *args, **kwargs):
- thread = self.fetch_thread(request, **kwargs)
- class PostView(ViewBase):
- """
- Basic view for posts
- """
- def fetch_post(self, request, **kwargs):
- pass
- def dispatch(self, request, *args, **kwargs):
- post = self.fetch_post(request, **kwargs)
- class EditorView(ViewBase):
- """
- Basic view for starting/replying/editing
- """
- template = 'editor.html'
- def find_mode(self, request, *args, **kwargs):
- """
- First step: guess from request what kind of view we are
- """
- is_post = request.method == 'POST'
- if 'forum_id' in kwargs:
- mode = START
- user = request.user
- forum = self.get_forum(request, lock=is_post, **kwargs)
- thread = Thread(forum=forum, starter=user, last_poster=user)
- post = Post(forum=forum, thread=thread, poster=user)
- quote = Post(0)
- elif 'thread_id' in kwargs:
- thread = self.get_thread(request, lock=is_post, **kwargs)
- forum = thread.forum
- return mode, forum, thread, post, quote
- def allow_mode(self, user, mode, forum, thread, post, quote):
- """
- Second step: check start/reply/edit permissions
- """
- if mode == START:
- self.allow_start(user, forum)
- if mode == REPLY:
- self.allow_reply(user, forum, thread, quote)
- if mode == EDIT:
- self.allow_edit(user, forum, thread, post)
- def allow_start(self, user, forum):
- allow_start_thread(user, forum)
- def allow_reply(self, user, forum, thread, quote):
- raise NotImplementedError()
- def allow_edit(self, user, forum, thread, post):
- raise NotImplementedError()
- def dispatch(self, request, *args, **kwargs):
- if request.method == 'POST':
- with atomic():
- return self.real_dispatch(request, *args, **kwargs)
- else:
- return self.real_dispatch(request, *args, **kwargs)
- def real_dispatch(self, request, *args, **kwargs):
- mode_context = self.find_mode(request, *args, **kwargs)
- self.allow_mode(request.user, *mode_context)
- mode, forum, thread, post, quote = mode_context
- formset = EditorFormset(request=request,
- mode=mode,
- user=request.user,
- forum=forum,
- thread=thread,
- post=post,
- quote=quote)
- if request.method == 'POST':
- if 'submit' in request.POST and formset.is_valid():
- formset.save()
- return redirect('misago:index')
- else:
- formset.update()
- return self.render(request, {
- 'mode': mode,
- 'formset': formset,
- 'forms': formset.get_forms_list(),
- 'main_forms': formset.get_main_forms(),
- 'supporting_forms': formset.get_supporting_forms(),
- 'forum': forum,
- 'path': get_forum_path(forum),
- 'thread': thread,
- 'post': post,
- 'quote': quote
- })
|