123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- from math import ceil
- from django.core.exceptions import PermissionDenied
- from django.shortcuts import get_object_or_404, redirect
- from django.utils.translation import ugettext as _
- from django.views.generic import View
- from misago.conf import settings
- from misago.threads.permissions import exclude_invisible_posts
- from misago.threads.viewmodels import ForumThread, PrivateThread
- class GotoView(View):
- thread = None
- read_aware=False
- def get(self, request, pk, slug, **kwargs):
- thread = self.get_thread(request, pk, slug).unwrap()
- self.test_permissions(request, thread)
- posts_queryset = exclude_invisible_posts(request.user, thread.category, thread.post_set)
- target_post = self.get_target_post(thread, posts_queryset.order_by('id'), **kwargs)
- target_page = self.compute_post_page(target_post, posts_queryset)
- return self.get_redirect(thread, target_post, target_page)
- def get_thread(self, request, pk, slug):
- return self.thread(request, pk, slug, read_aware=self.read_aware)
- def test_permissions(self, request, thread):
- pass
- def get_target_post(self, thread, posts_queryset):
- raise NotImplementedError("goto views should define their own get_target_post method")
- def compute_post_page(self, target_post, posts_queryset):
- # filter out events
- posts_queryset = posts_queryset.filter(is_event=False)
- thread_len = posts_queryset.count()
- if thread_len <= settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL:
- return 1 # no chance for post to be on other page than only page
- # compute total count of thread pages
- hits = max(1, thread_len - settings.MISAGO_POSTS_TAIL)
- hits += int(ceil(hits / float(settings.MISAGO_POSTS_PER_PAGE)))
- thread_pages = int(ceil(hits / float(settings.MISAGO_POSTS_PER_PAGE)))
- # is target an event?
- if target_post.is_event:
- target_event = target_post
- previous_posts = posts_queryset.filter(pk__lt=target_event.pk)
- target_post = previous_posts.order_by('id').last()
- # resolve post's page
- post_offset = posts_queryset.filter(pk__lte=target_post.pk).count()
- hits = max(1, post_offset)
- hits += int(ceil(hits / float(settings.MISAGO_POSTS_PER_PAGE)))
- post_page = int(ceil(hits / float(settings.MISAGO_POSTS_PER_PAGE)))
- if post_page > thread_pages:
- post_page = thread_pages
- return post_page
- def get_redirect(self, thread, target_post, target_page):
- thread_url = thread.thread_type.get_thread_absolute_url(thread, target_page)
- return redirect('%s#post-%s' % (thread_url, target_post.pk))
- class ThreadGotoPostView(GotoView):
- thread = ForumThread
- def get_target_post(self, thread, posts_queryset, **kwargs):
- return get_object_or_404(posts_queryset, pk=kwargs['post'])
- class ThreadGotoLastView(GotoView):
- thread = ForumThread
- def get_target_post(self, thread, posts_queryset, **kwargs):
- return posts_queryset.order_by('id').last()
- class ThreadGotoNewView(GotoView):
- thread = ForumThread
- read_aware = True
- def get_target_post(self, thread, posts_queryset, **kwargs):
- if thread.is_new:
- return posts_queryset.filter(posted_on__gt=thread.last_read_on).order_by('id').first()
- else:
- return posts_queryset.order_by('id').last()
- class ThreadGotoUnapprovedView(GotoView):
- thread = ForumThread
- def test_permissions(self, request, thread):
- if not thread.acl['can_approve']:
- raise PermissionDenied(
- _("You need permission to approve content to be able to go to first unapproved post."))
- def get_target_post(self, thread, posts_queryset, **kwargs):
- unapproved_post = posts_queryset.filter(is_unapproved=True).order_by('id').first()
- if unapproved_post:
- return unapproved_post
- else:
- return posts_queryset.order_by('id').last()
- class PrivateThreadGotoPostView(GotoView):
- thread = PrivateThread
- def get_target_post(self, thread, posts_queryset, **kwargs):
- return get_object_or_404(posts_queryset, pk=kwargs['post'])
- class PrivateThreadGotoLastView(GotoView):
- thread = PrivateThread
- def get_target_post(self, thread, posts_queryset, **kwargs):
- return posts_queryset.order_by('id').last()
- class PrivateThreadGotoNewView(GotoView):
- thread = PrivateThread
- read_aware = True
- def get_target_post(self, thread, posts_queryset, **kwargs):
- if thread.is_new:
- return posts_queryset.filter(posted_on__gt=thread.last_read_on).order_by('id').first()
- else:
- return posts_queryset.order_by('id').last()
|