views.py 10.4 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):
44
    queryset = Forum.objects.filter(parent=None).select_related("_last_message__author", "_last_message__topic___title")
Skia's avatar
Skia committed
45 46
    template_name = "forum/main.jinja"

Skia's avatar
Skia committed
47 48 49 50 51 52 53 54 55
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()
56 57
            for m in request.user.read_messages.filter(date__lt=fi.last_read_date):
                m.readers.remove(request.user) # Clean up to keep table low in data
Skia's avatar
Skia committed
58 59 60 61 62 63
        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
64
    paginate_by = settings.SITH_FORUM_PAGE_LENGTH / 2
Skia's avatar
Skia committed
65 66

    def get_queryset(self):
67 68 69 70 71
        topic_list = self.model.objects.filter(_last_message__date__gt=self.request.user.forum_infos.last_read_date)\
                .exclude(_last_message__readers=self.request.user)\
                .order_by('-_last_message__date')\
                .select_related('_last_message__author__avatar_pict')
        return topic_list
Skia's avatar
Skia committed
72

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

80
class ForumCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
81
    model = Forum
82
    form_class = ForumForm
Skia's avatar
Skia committed
83 84 85 86
    template_name = "core/create.jinja"

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

96
class ForumEditForm(ForumForm):
97 98
    recursive = forms.BooleanField(label=_("Apply rights and club owner recursively"), required=False)

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

106 107 108 109 110 111 112 113 114 115 116 117
    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')

118
class ForumDetailView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
119 120 121 122
    model = Forum
    template_name = "forum/forum.jinja"
    pk_url_kwarg = "forum_id"

Skia's avatar
Skia committed
123 124
    def get_context_data(self, **kwargs):
        kwargs = super(ForumDetailView, self).get_context_data(**kwargs)
Skia's avatar
Skia committed
125 126 127 128 129 130 131 132 133 134
        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
135 136
        return kwargs

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

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

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

Skia's avatar
Skia committed
161
class ForumTopicEditView(CanEditMixin, UpdateView):
Skia's avatar
Skia committed
162
    model = ForumTopic
Skia's avatar
Skia committed
163
    fields = ['forum']
Skia's avatar
Skia committed
164 165 166
    pk_url_kwarg = "topic_id"
    template_name = "core/edit.jinja"

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

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

192 193 194 195 196 197 198 199 200
class ForumMessageView(SingleObjectMixin, RedirectView):
    model = ForumMessage
    pk_url_kwarg = "message_id"
    permanent = False

    def get_redirect_url(self, *args, **kwargs):
        self.object = self.get_object()
        return self.object.get_url()

Skia's avatar
Skia committed
201 202 203
class ForumMessageEditView(CanEditMixin, UpdateView):
    model = ForumMessage
    fields = ['title', 'message']
204
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
205 206
    pk_url_kwarg = "message_id"

Skia's avatar
Skia committed
207 208 209 210
    def form_valid(self, form):
        ForumMessageMeta(message=self.object, user=self.request.user, action="EDIT").save()
        return super(ForumMessageEditView, self).form_valid(form)

211 212 213 214 215
    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
216 217 218 219 220 221
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
222
        self.object = self.get_object()
Skia's avatar
Skia committed
223 224 225 226 227 228 229 230 231 232
        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
233
        self.object = self.get_object()
Skia's avatar
Skia committed
234 235 236 237
        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()

238
class ForumMessageCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
239 240
    model = ForumMessage
    fields = ['title', 'message']
Skia's avatar
Skia committed
241
    template_name = "forum/reply.jinja"
Skia's avatar
Skia committed
242 243 244 245 246 247 248 249 250 251

    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
252 253 254 255
            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
256
                ])
Skia's avatar
Skia committed
257 258 259
            init['message'] += "\n\n"
        except Exception as e:
            print(repr(e))
Skia's avatar
Skia committed
260 261 262 263 264 265 266
        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
267 268 269 270
    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
271