views.py 13.8 KB
Newer Older
Skia's avatar
Skia committed
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 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
from django.http import Http404
Krophil's avatar
Krophil committed
26
from django.shortcuts import get_object_or_404, redirect
27
from django.core.urlresolvers import reverse_lazy, reverse
Krophil's avatar
Krophil committed
28
from django.views.generic import DetailView, RedirectView, TemplateView
Krophil's avatar
Krophil committed
29
from django.views.generic.edit import UpdateView, CreateView, DeleteView
Skia's avatar
Skia committed
30
31
from django.utils.translation import ugettext_lazy as _
from django import forms
Skia's avatar
Skia committed
32
from django.conf import settings
33
from django.forms.models import modelform_factory
Skia's avatar
Skia committed
34

Skia's avatar
Skia committed
35
36
from datetime import date

Skia's avatar
Skia committed
37
from trombi.models import Trombi, TrombiUser, TrombiComment, TrombiClubMembership
Krophil's avatar
Krophil committed
38
from core.views.forms import SelectDate
Krophil's avatar
Krophil committed
39
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin, CanCreateMixin, QuickNotifMixin
Skia's avatar
Skia committed
40
41
42
from core.models import User
from club.models import Club

Krophil's avatar
Krophil committed
43

Skia's avatar
Skia committed
44
45
46
47
48
49
50
class TrombiTabsMixin(TabedViewMixin):
    def get_tabs_title(self):
        return _("Trombi")

    def get_list_of_tabs(self):
        tab_list = []
        tab_list.append({
Krophil's avatar
Krophil committed
51
52
            'url': reverse('trombi:user_tools'),
            'slug': 'tools',
Skia's avatar
Skia committed
53
                    'name': _("Tools"),
Krophil's avatar
Krophil committed
54
        })
Skia's avatar
Skia committed
55
        tab_list.append({
Krophil's avatar
Krophil committed
56
57
            'url': reverse('trombi:profile'),
            'slug': 'profile',
Skia's avatar
Skia committed
58
                    'name': _("My profile"),
Krophil's avatar
Krophil committed
59
        })
Skia's avatar
Skia committed
60
        tab_list.append({
Krophil's avatar
Krophil committed
61
62
            'url': reverse('trombi:pictures'),
            'slug': 'pictures',
Skia's avatar
Skia committed
63
                    'name': _("My pictures"),
Krophil's avatar
Krophil committed
64
        })
Skia's avatar
Skia committed
65
66
67
68
        try:
            trombi = self.request.user.trombi_user.trombi
            if self.request.user.is_owner(trombi):
                tab_list.append({
Krophil's avatar
Krophil committed
69
70
71
72
73
74
                    'url': reverse('trombi:detail', kwargs={'trombi_id': trombi.id}),
                    'slug': 'admin_tools',
                    'name': _("Admin tools"),
                })
        except:
            pass
Skia's avatar
Skia committed
75
76
        return tab_list

Krophil's avatar
Krophil committed
77

Skia's avatar
Skia committed
78
class TrombiForm(forms.ModelForm):
Skia's avatar
Skia committed
79
    class Meta:
Skia's avatar
Skia committed
80
        model = Trombi
Skia's avatar
Skia committed
81
        fields = ['subscription_deadline', 'comments_deadline', 'max_chars', 'show_profiles']
Skia's avatar
Skia committed
82
        widgets = {
Krophil's avatar
Krophil committed
83
84
85
86
            'subscription_deadline': SelectDate,
            'comments_deadline': SelectDate,
        }

Skia's avatar
Skia committed
87

Krophil's avatar
Krophil committed
88
class TrombiCreateView(CanCreateMixin, CreateView):
Skia's avatar
Skia committed
89
    """
Skia's avatar
Skia committed
90
    Create a trombi for a club
Skia's avatar
Skia committed
91
    """
Skia's avatar
Skia committed
92
93
    model = Trombi
    form_class = TrombiForm
Skia's avatar
Skia committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    template_name = 'core/create.jinja'

    def post(self, request, *args, **kwargs):
        """
        Affect club
        """
        form = self.get_form()
        if form.is_valid():
            club = get_object_or_404(Club, id=self.kwargs['club_id'])
            form.instance.club = club
            ret = self.form_valid(form)
            return ret
        else:
            return self.form_invalid(form)

Krophil's avatar
Krophil committed
109

Skia's avatar
Skia committed
110
class TrombiEditView(CanEditPropMixin, TrombiTabsMixin, UpdateView):
Skia's avatar
Skia committed
111
112
    model = Trombi
    form_class = TrombiForm
Skia's avatar
Skia committed
113
    template_name = 'core/edit.jinja'
Skia's avatar
Skia committed
114
    pk_url_kwarg = 'trombi_id'
Skia's avatar
Skia committed
115
    current_tab = "admin_tools"
Skia's avatar
Skia committed
116

Skia's avatar
Skia committed
117
    def get_success_url(self):
Krophil's avatar
Krophil committed
118
119
        return super(TrombiEditView, self).get_success_url() + "?qn_success"

Skia's avatar
Skia committed
120

Skia's avatar
Skia committed
121
class TrombiDetailView(CanEditMixin, QuickNotifMixin, TrombiTabsMixin, DetailView):
Skia's avatar
Skia committed
122
123
124
    model = Trombi
    template_name = 'trombi/detail.jinja'
    pk_url_kwarg = 'trombi_id'
Skia's avatar
Skia committed
125
    current_tab = "admin_tools"
Skia's avatar
Skia committed
126

Krophil's avatar
Krophil committed
127

Skia's avatar
Skia committed
128
129
130
131
132
class TrombiDeleteUserView(CanEditPropMixin, TrombiTabsMixin, DeleteView):
    model = TrombiUser
    pk_url_kwarg = 'user_id'
    template_name = 'core/delete_confirm.jinja'
    current_tab = "admin_tools"
Skia's avatar
Skia committed
133

Skia's avatar
Skia committed
134
135
    def get_success_url(self):
        return reverse('trombi:detail', kwargs={'trombi_id': self.object.trombi.id}) + "?qn_success"
Skia's avatar
Skia committed
136

Krophil's avatar
Krophil committed
137

Skia's avatar
Skia committed
138
class TrombiModerateCommentsView(CanEditPropMixin, QuickNotifMixin, TrombiTabsMixin, DetailView):
Skia's avatar
Skia committed
139
140
141
    model = Trombi
    template_name = 'trombi/comment_moderation.jinja'
    pk_url_kwarg = 'trombi_id'
Skia's avatar
Skia committed
142
    current_tab = "admin_tools"
Skia's avatar
Skia committed
143
144
145
146

    def get_context_data(self, **kwargs):
        kwargs = super(TrombiModerateCommentsView, self).get_context_data(**kwargs)
        kwargs['comments'] = TrombiComment.objects.filter(is_moderated=False,
Krophil's avatar
Krophil committed
147
                                                          author__trombi__id=self.object.id).exclude(target__user__id=self.request.user.id)
Skia's avatar
Skia committed
148
149
        return kwargs

Krophil's avatar
Krophil committed
150

Skia's avatar
Skia committed
151
152
153
154
class TrombiModerateForm(forms.Form):
    reason = forms.CharField(help_text=_("Explain why you rejected the comment"))
    action = forms.CharField(initial="delete", widget=forms.widgets.HiddenInput)

Krophil's avatar
Krophil committed
155

Skia's avatar
Skia committed
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
class TrombiModerateCommentView(DetailView):
    model = TrombiComment
    template_name = 'core/edit.jinja'
    pk_url_kwarg = 'comment_id'

    def dispatch(self, request, *args, **kwargs):
        self.object = self.get_object()
        if not request.user.is_owner(self.object.author.trombi):
            raise Http404()
        return super(TrombiModerateCommentView, self).dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        if "action" in request.POST:
            if request.POST['action'] == "accept":
                self.object.is_moderated = True
                self.object.save()
Krophil's avatar
Krophil committed
172
                return redirect(reverse('trombi:moderate_comments', kwargs={'trombi_id': self.object.author.trombi.id}) + "?qn_success")
Skia's avatar
Skia committed
173
174
175
176
            elif request.POST['action'] == "reject":
                return super(TrombiModerateCommentView, self).get(request, *args, **kwargs)
            elif request.POST['action'] == "delete" and "reason" in request.POST.keys():
                self.object.author.user.email_user(
Krophil's avatar
Krophil committed
177
178
179
180
181
182
183
184
185
186
187
                    subject="[%s] %s" % (settings.SITH_NAME, _("Rejected comment")),
                    message=_("Your comment to %(target)s on the Trombi \"%(trombi)s\" was rejected for the following "
                              "reason: %(reason)s\n\n"
                              "Your comment was:\n\n%(content)s"
                              ) % {
                        'target': self.object.target.user.get_display_name(),
                        'trombi': self.object.author.trombi,
                        'reason': request.POST["reason"],
                        'content': self.object.content,
                    },
                )
Skia's avatar
Skia committed
188
                self.object.delete()
Krophil's avatar
Krophil committed
189
                return redirect(reverse('trombi:moderate_comments', kwargs={'trombi_id': self.object.author.trombi.id}) + "?qn_success")
Skia's avatar
Skia committed
190
191
192
193
194
195
196
        raise Http404

    def get_context_data(self, **kwargs):
        kwargs = super(TrombiModerateCommentView, self).get_context_data(**kwargs)
        kwargs['form'] = TrombiModerateForm()
        return kwargs

Skia's avatar
Skia committed
197
# User side
Krophil's avatar
Krophil committed
198
199


Skia's avatar
Skia committed
200
201
202
203
class TrombiModelChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        return _("%(name)s (deadline: %(date)s)") % {'name': str(obj), 'date': str(obj.subscription_deadline)}

Krophil's avatar
Krophil committed
204

Skia's avatar
Skia committed
205
class UserTrombiForm(forms.Form):
Skia's avatar
Skia committed
206
    trombi = TrombiModelChoiceField(Trombi.availables.all(), required=False, label=_("Select trombi"),
Krophil's avatar
Krophil committed
207
208
209
210
                                    help_text=_("This allows you to subscribe to a Trombi. "
                                                "Be aware that you can subscribe only once, so don't play with that, "
                                                "or you will expose yourself to the admins' wrath!"))

Skia's avatar
Skia committed
211

Skia's avatar
Skia committed
212
class UserTrombiToolsView(QuickNotifMixin, TrombiTabsMixin, TemplateView):
Skia's avatar
Skia committed
213
    """
Skia's avatar
Skia committed
214
    Display a user's trombi tools
Skia's avatar
Skia committed
215
    """
Skia's avatar
Skia committed
216
    template_name = "trombi/user_tools.jinja"
Skia's avatar
Skia committed
217
    current_tab = "tools"
Skia's avatar
Skia committed
218
219

    def post(self, request, *args, **kwargs):
Skia's avatar
Skia committed
220
        self.form = UserTrombiForm(request.POST)
Skia's avatar
Skia committed
221
        if self.form.is_valid():
Skia's avatar
Skia committed
222
            trombi_user = TrombiUser(user=request.user,
Krophil's avatar
Krophil committed
223
                                     trombi=self.form.cleaned_data['trombi'])
Skia's avatar
Skia committed
224
            trombi_user.save()
Skia's avatar
Skia committed
225
            self.quick_notif_list += ['qn_success']
Skia's avatar
Skia committed
226
        return super(UserTrombiToolsView, self).get(request, *args, **kwargs)
Skia's avatar
Skia committed
227
228

    def get_context_data(self, **kwargs):
Skia's avatar
Skia committed
229
        kwargs = super(UserTrombiToolsView, self).get_context_data(**kwargs)
Skia's avatar
Skia committed
230
        kwargs['user'] = self.request.user
Skia's avatar
Skia committed
231
232
        if not hasattr(self.request.user, 'trombi_user'):
            kwargs['subscribe_form'] = UserTrombiForm()
Skia's avatar
Skia committed
233
234
235
        else:
            kwargs['trombi'] = self.request.user.trombi_user.trombi
            kwargs['date'] = date
Skia's avatar
Skia committed
236
237
        return kwargs

Krophil's avatar
Krophil committed
238

Skia's avatar
Skia committed
239
class UserTrombiEditPicturesView(TrombiTabsMixin, UpdateView):
240
241
242
    model = TrombiUser
    fields = ['profile_pict', 'scrub_pict']
    template_name = "core/edit.jinja"
Skia's avatar
Skia committed
243
    current_tab = "pictures"
244
245
246
247
248

    def get_object(self):
        return self.request.user.trombi_user

    def get_success_url(self):
Krophil's avatar
Krophil committed
249
250
        return reverse('trombi:user_tools') + "?qn_success"

251

Skia's avatar
Skia committed
252
class UserTrombiEditProfileView(QuickNotifMixin, TrombiTabsMixin, UpdateView):
Skia's avatar
Skia committed
253
254
    model = User
    form_class = modelform_factory(User,
Krophil's avatar
Krophil committed
255
256
                                   fields=['second_email', 'phone', 'department', 'dpt_option',
                                           'quote', 'parent_address'],
Krophil's avatar
Krophil committed
257
258
259
260
261
                                   labels={
                                       'second_email': _("Personal email (not UTBM)"),
                                       'phone': _("Phone"),
                                       'parent_address': _("Native town"),
                                   })
Skia's avatar
Skia committed
262
    template_name = "trombi/edit_profile.jinja"
Skia's avatar
Skia committed
263
    current_tab = "profile"
Skia's avatar
Skia committed
264
265
266
267

    def get_object(self):
        return self.request.user

268
    def get_success_url(self):
Krophil's avatar
Krophil committed
269
270
        return reverse('trombi:user_tools') + "?qn_success"

271

Skia's avatar
Skia committed
272
273
274
275
276
277
278
279
280
class UserTrombiResetClubMembershipsView(RedirectView):
    permanent = False

    def get(self, request, *args, **kwargs):
        user = self.request.user.trombi_user
        user.make_memberships()
        return redirect(self.get_success_url())

    def get_success_url(self):
Krophil's avatar
Krophil committed
281
282
        return reverse('trombi:profile') + "?qn_success"

Skia's avatar
Skia committed
283

Skia's avatar
Skia committed
284
class UserTrombiDeleteMembershipView(TrombiTabsMixin, CanEditMixin, DeleteView):
Skia's avatar
Skia committed
285
286
287
288
    model = TrombiClubMembership
    pk_url_kwarg = "membership_id"
    template_name = "core/delete_confirm.jinja"
    success_url = reverse_lazy('trombi:profile')
Skia's avatar
Skia committed
289
290
291
292
    current_tab = "profile"

    def get_success_url(self):
        return super(UserTrombiDeleteMembershipView, self).get_success_url() + "?qn_success"
Skia's avatar
Skia committed
293

Krophil's avatar
Krophil committed
294

Skia's avatar
Skia committed
295
class UserTrombiEditMembershipView(CanEditMixin, TrombiTabsMixin, UpdateView):
Skia's avatar
Skia committed
296
297
298
299
    model = TrombiClubMembership
    pk_url_kwarg = "membership_id"
    fields = ['role', 'start', 'end']
    template_name = "core/edit.jinja"
Skia's avatar
Skia committed
300
301
302
303
304
    current_tab = "profile"

    def get_success_url(self):
        return super(UserTrombiEditMembershipView, self).get_success_url() + "?qn_success"

Skia's avatar
Skia committed
305

Skia's avatar
Skia committed
306
class UserTrombiProfileView(TrombiTabsMixin, DetailView):
Skia's avatar
Skia committed
307
308
309
310
    model = TrombiUser
    pk_url_kwarg = "user_id"
    template_name = "trombi/user_profile.jinja"
    context_object_name = "trombi_user"
Skia's avatar
Skia committed
311
    current_tab = "tools"
Skia's avatar
Skia committed
312
313
314
315
316
317
318
319
320

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        if (self.object.trombi.id != request.user.trombi_user.trombi.id or
                self.object.user.id == request.user.id or
                not self.object.trombi.show_profiles):
            raise Http404()
        return super(UserTrombiProfileView, self).get(request, *args, **kwargs)

Krophil's avatar
Krophil committed
321

Skia's avatar
Skia committed
322
class TrombiCommentFormView():
323
    """
Skia's avatar
Skia committed
324
    Create/edit a trombi comment
325
    """
Skia's avatar
Skia committed
326
    model = TrombiComment
327
    fields = ['content']
328
    template_name = 'trombi/comment.jinja'
329
330

    def get_form_class(self):
Skia's avatar
Skia committed
331
        self.trombi = self.request.user.trombi_user.trombi
Skia's avatar
Skia committed
332
333
        if date.today() <= self.trombi.subscription_deadline:
            raise Http404(_("You can not yet write comment, you must wait for "
Krophil's avatar
Krophil committed
334
                            "the subscription deadline to be passed."))
Skia's avatar
Skia committed
335
336
        if self.trombi.comments_deadline < date.today():
            raise Http404(_("You can not write comment anymore, the deadline is "
Krophil's avatar
Krophil committed
337
                            "already passed."))
338
        return modelform_factory(self.model, fields=self.fields,
Krophil's avatar
Krophil committed
339
340
341
342
343
344
                                 widgets={
                                     'content': forms.widgets.Textarea(attrs={'maxlength': self.trombi.max_chars})
                                 },
                                 help_texts={
                                     'content': _("Maximum characters: %(max_length)s") % {'max_length': self.trombi.max_chars}
                                 })
345
346

    def get_success_url(self):
Krophil's avatar
Krophil committed
347
        return reverse('trombi:user_tools') + "?qn_success"
348

349
350
351
352
353
354
355
    def get_context_data(self, **kwargs):
        kwargs = super(TrombiCommentFormView, self).get_context_data(**kwargs)
        if 'user_id' in self.kwargs.keys():
            kwargs['target'] = get_object_or_404(TrombiUser, id=self.kwargs['user_id'])
        else:
            kwargs['target'] = self.object.target
        return kwargs
356

Krophil's avatar
Krophil committed
357

358
class TrombiCommentCreateView(TrombiCommentFormView, CreateView):
359
    def form_valid(self, form):
Skia's avatar
Skia committed
360
361
        target = get_object_or_404(TrombiUser, id=self.kwargs['user_id'])
        form.instance.author = self.request.user.trombi_user
362
        form.instance.target = target
Skia's avatar
Skia committed
363
        return super(TrombiCommentCreateView, self).form_valid(form)
364

Krophil's avatar
Krophil committed
365

Skia's avatar
Skia committed
366
class TrombiCommentEditView(TrombiCommentFormView, CanViewMixin, UpdateView):
367
368
    pk_url_kwarg = "comment_id"

Skia's avatar
Skia committed
369
370
371
    def form_valid(self, form):
        form.instance.is_moderated = False
        return super(TrombiCommentEditView, self).form_valid(form)