views.py 9.91 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# -*- coding:utf-8 -*
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
#
#

Skia's avatar
Skia committed
25 26 27
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
28
from django.views.generic.detail import SingleObjectMixin
Skia's avatar
Skia committed
29 30 31 32 33
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
34
from django.db import models
Skia's avatar
Skia committed
35
from django.core.exceptions import PermissionDenied
36
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
Skia's avatar
Skia committed
37

38
from ajax_select import make_ajax_form, make_ajax_field
Skia's avatar
Skia committed
39

40
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
Skia's avatar
Skia committed
41
from forum.models import Forum, ForumMessage, ForumTopic, ForumMessageMeta
Skia's avatar
Skia committed
42

Skia's avatar
Skia committed
43
class ForumMainView(ListView):
Skia's avatar
Skia committed
44 45 46
    queryset = Forum.objects.filter(parent=None)
    template_name = "forum/main.jinja"

Skia's avatar
Skia committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
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"
Skia's avatar
Skia committed
62
    paginate_by = settings.SITH_FORUM_PAGE_LENGTH / 2
Skia's avatar
Skia committed
63 64 65 66

    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
67
        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
68

69 70 71
class ForumForm(forms.ModelForm):
    class Meta:
        model = Forum
Skia's avatar
Skia committed
72
        fields = ['name', 'parent', 'number', 'owner_club', 'is_category', 'edit_groups', 'view_groups']
73 74 75
    edit_groups = make_ajax_field(Forum, 'edit_groups', 'groups', help_text="")
    view_groups = make_ajax_field(Forum, 'view_groups', 'groups', help_text="")

76
class ForumCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
77
    model = Forum
78
    form_class = ForumForm
Skia's avatar
Skia committed
79 80 81 82
    template_name = "core/create.jinja"

    def get_initial(self):
        init = super(ForumCreateView, self).get_initial()
Skia's avatar
Skia committed
83 84 85
        try:
            parent = Forum.objects.filter(id=self.request.GET['parent']).first()
            init['parent'] = parent
86
            init['owner_club'] = parent.owner_club
87 88
            init['edit_groups'] = parent.edit_groups.all()
            init['view_groups'] = parent.view_groups.all()
Skia's avatar
Skia committed
89
        except: pass
Skia's avatar
Skia committed
90 91
        return init

92
class ForumEditForm(ForumForm):
93 94
    recursive = forms.BooleanField(label=_("Apply rights and club owner recursively"), required=False)

95
class ForumEditView(CanEditPropMixin, UpdateView):
Skia's avatar
Skia committed
96 97
    model = Forum
    pk_url_kwarg = "forum_id"
98
    form_class = ForumEditForm
Skia's avatar
Skia committed
99 100 101
    template_name = "core/edit.jinja"
    success_url = reverse_lazy('forum:main')

102 103 104 105 106 107 108 109 110 111 112 113
    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')

114
class ForumDetailView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
115 116 117 118
    model = Forum
    template_name = "forum/forum.jinja"
    pk_url_kwarg = "forum_id"

Skia's avatar
Skia committed
119 120
    def get_context_data(self, **kwargs):
        kwargs = super(ForumDetailView, self).get_context_data(**kwargs)
Skia's avatar
Skia committed
121 122 123 124 125 126 127 128 129 130
        qs = self.object.topics.order_by('-_last_message__date').select_related('_last_message')
        paginator = Paginator(qs,
                settings.SITH_FORUM_PAGE_LENGTH)
        page = self.request.GET.get('topic_page')
        try:
            kwargs["topics"] = paginator.page(page)
        except PageNotAnInteger:
            kwargs["topics"] = paginator.page(1)
        except EmptyPage:
            kwargs["topics"] = paginator.page(paginator.num_pages)
Skia's avatar
Skia committed
131 132
        return kwargs

133 134 135 136
class TopicForm(forms.ModelForm):
    class Meta:
        model = ForumMessage
        fields = ['title', 'message']
Skia's avatar
Skia committed
137
    title = forms.CharField(required=True, label=_("Title"))
138

139
class ForumTopicCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
140
    model = ForumMessage
141
    form_class = TopicForm
Skia's avatar
Skia committed
142
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
143 144 145 146 147 148 149 150

    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
151 152 153
        topic = ForumTopic(title=form.instance.title, author=self.request.user, forum=self.forum)
        topic.save()
        form.instance.topic = topic
Skia's avatar
Skia committed
154 155 156
        form.instance.author = self.request.user
        return super(ForumTopicCreateView, self).form_valid(form)

Skia's avatar
Skia committed
157
class ForumTopicEditView(CanEditMixin, UpdateView):
Skia's avatar
Skia committed
158
    model = ForumTopic
Skia's avatar
Skia committed
159
    fields = ['forum']
Skia's avatar
Skia committed
160 161 162
    pk_url_kwarg = "topic_id"
    template_name = "core/edit.jinja"

163
class ForumTopicDetailView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
164 165 166 167
    model = ForumTopic
    pk_url_kwarg = "topic_id"
    template_name = "forum/topic.jinja"
    context_object_name = "topic"
Skia's avatar
Skia committed
168
    queryset = ForumTopic.objects.select_related('forum__parent')
Skia's avatar
Skia committed
169

Skia's avatar
Skia committed
170 171 172
    def get_context_data(self, **kwargs):
        kwargs = super(ForumTopicDetailView, self).get_context_data(**kwargs)
        try:
Skia's avatar
Skia committed
173
            msg = self.object.get_first_unread_message(user)
Skia's avatar
Skia committed
174 175
            kwargs['first_unread_message_id'] = msg.id
        except:
176
            kwargs['first_unread_message_id'] = float("inf")
Skia's avatar
Skia committed
177
        paginator = Paginator(self.object.messages.select_related('author__avatar_pict').order_by('date'),
178 179
                settings.SITH_FORUM_PAGE_LENGTH)
        page = self.request.GET.get('page')
Skia's avatar
Skia committed
180
        try:
181 182 183 184 185
            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
186 187
        return kwargs

Skia's avatar
Skia committed
188 189 190
class ForumMessageEditView(CanEditMixin, UpdateView):
    model = ForumMessage
    fields = ['title', 'message']
191
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
192 193
    pk_url_kwarg = "message_id"

Skia's avatar
Skia committed
194 195 196 197
    def form_valid(self, form):
        ForumMessageMeta(message=self.object, user=self.request.user, action="EDIT").save()
        return super(ForumMessageEditView, self).form_valid(form)

198 199 200 201 202
    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
203 204 205 206 207 208
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
209
        self.object = self.get_object()
Skia's avatar
Skia committed
210 211 212 213 214 215 216 217 218 219
        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
220
        self.object = self.get_object()
Skia's avatar
Skia committed
221 222 223 224
        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()

225
class ForumMessageCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
226 227
    model = ForumMessage
    fields = ['title', 'message']
Skia's avatar
Skia committed
228
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
229 230 231 232 233 234 235 236 237 238

    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
239 240 241 242
            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
243
                ])
Skia's avatar
Skia committed
244 245 246
            init['message'] += "\n\n"
        except Exception as e:
            print(repr(e))
Skia's avatar
Skia committed
247 248 249 250 251 252 253
        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
254 255 256 257
    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
258