views.py 8.65 KB
Newer Older
Skia's avatar
Skia committed
1 2 3
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, RedirectView
from django.views.generic.edit import UpdateView, CreateView, DeleteView
Skia's avatar
Skia committed
4
from django.views.generic.detail import SingleObjectMixin
Skia's avatar
Skia committed
5 6 7 8 9
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse, reverse_lazy
from django.utils import timezone
from django.conf import settings
from django import forms
Skia's avatar
Skia committed
10
from django.db import models
Skia's avatar
Skia committed
11
from django.core.exceptions import PermissionDenied
12
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
Skia's avatar
Skia committed
13

14
from ajax_select import make_ajax_form, make_ajax_field
Skia's avatar
Skia committed
15

16
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
Skia's avatar
Skia committed
17
from forum.models import Forum, ForumMessage, ForumTopic, ForumMessageMeta
Skia's avatar
Skia committed
18

Skia's avatar
Skia committed
19
class ForumMainView(ListView):
Skia's avatar
Skia committed
20 21 22
    queryset = Forum.objects.filter(parent=None)
    template_name = "forum/main.jinja"

Skia's avatar
Skia committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
class ForumMarkAllAsRead(RedirectView):
    permanent = False
    url = reverse_lazy('forum:last_unread')

    def get(self, request, *args, **kwargs):
        try:
            fi = request.user.forum_infos
            fi.last_read_date = timezone.now()
            fi.save()
        except: pass
        return super(ForumMarkAllAsRead, self).get(request, *args, **kwargs)

class ForumLastUnread(ListView):
    model = ForumTopic
    template_name = "forum/last_unread.jinja"

    def get_queryset(self):
        l = ForumMessage.objects.exclude(readers=self.request.user).filter(
                date__gt=self.request.user.forum_infos.last_read_date).values_list('topic') # TODO try to do better
Skia's avatar
Skia committed
42
        return self.model.objects.filter(id__in=l).annotate(models.Max('messages__date')).order_by('-messages__date__max').select_related('author')
Skia's avatar
Skia committed
43

44 45 46
class ForumForm(forms.ModelForm):
    class Meta:
        model = Forum
Skia's avatar
Skia committed
47
        fields = ['name', 'parent', 'number', 'owner_club', 'is_category', 'edit_groups', 'view_groups']
48 49 50
    edit_groups = make_ajax_field(Forum, 'edit_groups', 'groups', help_text="")
    view_groups = make_ajax_field(Forum, 'view_groups', 'groups', help_text="")

51
class ForumCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
52
    model = Forum
53
    form_class = ForumForm
Skia's avatar
Skia committed
54 55 56 57
    template_name = "core/create.jinja"

    def get_initial(self):
        init = super(ForumCreateView, self).get_initial()
Skia's avatar
Skia committed
58 59 60
        try:
            parent = Forum.objects.filter(id=self.request.GET['parent']).first()
            init['parent'] = parent
61
            init['owner_club'] = parent.owner_club
62 63
            init['edit_groups'] = parent.edit_groups.all()
            init['view_groups'] = parent.view_groups.all()
Skia's avatar
Skia committed
64
        except: pass
Skia's avatar
Skia committed
65 66
        return init

67
class ForumEditForm(ForumForm):
68 69
    recursive = forms.BooleanField(label=_("Apply rights and club owner recursively"), required=False)

70
class ForumEditView(CanEditPropMixin, UpdateView):
Skia's avatar
Skia committed
71 72
    model = Forum
    pk_url_kwarg = "forum_id"
73
    form_class = ForumEditForm
Skia's avatar
Skia committed
74 75 76
    template_name = "core/edit.jinja"
    success_url = reverse_lazy('forum:main')

77 78 79 80 81 82 83 84 85 86 87 88
    def form_valid(self, form):
        ret = super(ForumEditView, self).form_valid(form)
        if form.cleaned_data['recursive']:
            self.object.apply_rights_recursively()
        return ret

class ForumDeleteView(CanEditPropMixin, DeleteView):
    model = Forum
    pk_url_kwarg = "forum_id"
    template_name = "core/delete_confirm.jinja"
    success_url = reverse_lazy('forum:main')

89
class ForumDetailView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
90 91 92 93
    model = Forum
    template_name = "forum/forum.jinja"
    pk_url_kwarg = "forum_id"

Skia's avatar
Skia committed
94 95 96 97 98
    def get_context_data(self, **kwargs):
        kwargs = super(ForumDetailView, self).get_context_data(**kwargs)
        kwargs['topics'] = self.object.topics.annotate(models.Max('messages__date')).order_by('-messages__date__max')
        return kwargs

99 100 101 102
class TopicForm(forms.ModelForm):
    class Meta:
        model = ForumMessage
        fields = ['title', 'message']
Skia's avatar
Skia committed
103
    title = forms.CharField(required=True, label=_("Title"))
104

105
class ForumTopicCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
106
    model = ForumMessage
107
    form_class = TopicForm
Skia's avatar
Skia committed
108
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
109 110 111 112 113 114 115 116

    def dispatch(self, request, *args, **kwargs):
        self.forum = get_object_or_404(Forum, id=self.kwargs['forum_id'], is_category=False)
        if not request.user.can_view(self.forum):
            raise PermissionDenied
        return super(ForumTopicCreateView, self).dispatch(request, *args, **kwargs)

    def form_valid(self, form):
Skia's avatar
Skia committed
117 118 119
        topic = ForumTopic(title=form.instance.title, author=self.request.user, forum=self.forum)
        topic.save()
        form.instance.topic = topic
Skia's avatar
Skia committed
120 121 122
        form.instance.author = self.request.user
        return super(ForumTopicCreateView, self).form_valid(form)

Skia's avatar
Skia committed
123
class ForumTopicEditView(CanEditMixin, UpdateView):
Skia's avatar
Skia committed
124
    model = ForumTopic
Skia's avatar
Skia committed
125
    fields = ['forum']
Skia's avatar
Skia committed
126 127 128
    pk_url_kwarg = "topic_id"
    template_name = "core/edit.jinja"

129
class ForumTopicDetailView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
130 131 132 133
    model = ForumTopic
    pk_url_kwarg = "topic_id"
    template_name = "forum/topic.jinja"
    context_object_name = "topic"
Skia's avatar
Skia committed
134
    queryset = ForumTopic.objects.select_related('forum__parent')
Skia's avatar
Skia committed
135

Skia's avatar
Skia committed
136 137 138
    def get_context_data(self, **kwargs):
        kwargs = super(ForumTopicDetailView, self).get_context_data(**kwargs)
        try:
Skia's avatar
Skia committed
139
            msg = self.object.get_first_unread_message(user)
Skia's avatar
Skia committed
140 141
            kwargs['first_unread_message_id'] = msg.id
        except:
142
            kwargs['first_unread_message_id'] = float("inf")
143 144 145
        paginator = Paginator(self.object.messages.select_related('author__avatar_pict').all(),
                settings.SITH_FORUM_PAGE_LENGTH)
        page = self.request.GET.get('page')
Skia's avatar
Skia committed
146
        try:
147 148 149 150 151
            kwargs["msgs"] = paginator.page(page)
        except PageNotAnInteger:
            kwargs["msgs"] = paginator.page(1)
        except EmptyPage:
            kwargs["msgs"] = paginator.page(paginator.num_pages)
Skia's avatar
Skia committed
152 153
        return kwargs

Skia's avatar
Skia committed
154 155 156
class ForumMessageEditView(CanEditMixin, UpdateView):
    model = ForumMessage
    fields = ['title', 'message']
157
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
158 159
    pk_url_kwarg = "message_id"

Skia's avatar
Skia committed
160 161 162 163
    def form_valid(self, form):
        ForumMessageMeta(message=self.object, user=self.request.user, action="EDIT").save()
        return super(ForumMessageEditView, self).form_valid(form)

164 165 166 167 168
    def get_context_data(self, **kwargs):
        kwargs = super(ForumMessageEditView, self).get_context_data(**kwargs)
        kwargs['topic'] = self.object.topic
        return kwargs

Skia's avatar
Skia committed
169 170 171 172 173 174
class ForumMessageDeleteView(SingleObjectMixin, RedirectView):
    model = ForumMessage
    pk_url_kwarg = "message_id"
    permanent = False

    def get_redirect_url(self, *args, **kwargs):
Skia's avatar
Skia committed
175
        self.object = self.get_object()
Skia's avatar
Skia committed
176 177 178 179 180 181 182 183 184 185
        if self.object.can_be_moderated_by(self.request.user):
            ForumMessageMeta(message=self.object, user=self.request.user, action="DELETE").save()
        return self.object.get_absolute_url()

class ForumMessageUndeleteView(SingleObjectMixin, RedirectView):
    model = ForumMessage
    pk_url_kwarg = "message_id"
    permanent = False

    def get_redirect_url(self, *args, **kwargs):
Skia's avatar
Skia committed
186
        self.object = self.get_object()
Skia's avatar
Skia committed
187 188 189 190
        if self.object.can_be_moderated_by(self.request.user):
            ForumMessageMeta(message=self.object, user=self.request.user, action="UNDELETE").save()
        return self.object.get_absolute_url()

191
class ForumMessageCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
192 193
    model = ForumMessage
    fields = ['title', 'message']
Skia's avatar
Skia committed
194
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
195 196 197 198 199 200 201 202 203 204

    def dispatch(self, request, *args, **kwargs):
        self.topic = get_object_or_404(ForumTopic, id=self.kwargs['topic_id'])
        if not request.user.can_view(self.topic):
            raise PermissionDenied
        return super(ForumMessageCreateView, self).dispatch(request, *args, **kwargs)

    def get_initial(self):
        init = super(ForumMessageCreateView, self).get_initial()
        try:
Skia's avatar
Skia committed
205 206 207 208
            message = ForumMessage.objects.select_related('author').filter(id=self.request.GET['quote_id']).first()
            init['message'] = "> ##### %s\n" % (_("%(author)s said") % {'author': message.author.get_short_name()})
            init['message'] += "\n".join([
                "> " + line for line in message.message.split('\n')
Skia's avatar
Skia committed
209
                ])
Skia's avatar
Skia committed
210 211 212
            init['message'] += "\n\n"
        except Exception as e:
            print(repr(e))
Skia's avatar
Skia committed
213 214 215 216 217 218 219
        return init

    def form_valid(self, form):
        form.instance.topic = self.topic
        form.instance.author = self.request.user
        return super(ForumMessageCreateView, self).form_valid(form)

Skia's avatar
Skia committed
220 221 222 223
    def get_context_data(self, **kwargs):
        kwargs = super(ForumMessageCreateView, self).get_context_data(**kwargs)
        kwargs['topic'] = self.topic
        return kwargs
Skia's avatar
Skia committed
224