views.py 28.5 KB
Newer Older
1 2 3 4
# -*- coding:utf-8 -*
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
Sli's avatar
Sli committed
5
# - Sli <antoine@bartuccio.fr>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#
# 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.
#
#

Krophil's avatar
Krophil committed
26
from django.shortcuts import redirect, get_object_or_404
Skia's avatar
Skia committed
27
from django.http import HttpResponseRedirect
Sli's avatar
Sli committed
28
from django.views.generic import ListView, DetailView, View
Skia's avatar
Skia committed
29
from django.views.generic.edit import UpdateView, CreateView, DeleteView
Skia's avatar
Skia committed
30
from django.views.generic.detail import SingleObjectMixin
Skia's avatar
Skia committed
31
from django.utils.translation import ugettext_lazy as _
32
from django.core.urlresolvers import reverse, reverse_lazy
33 34
from django.core.exceptions import ValidationError
from django.utils import timezone
Skia's avatar
Skia committed
35
from django.conf import settings
Skia's avatar
Skia committed
36
from django.db.models import Max
Skia's avatar
Skia committed
37
from django.forms.models import modelform_factory
Sli's avatar
Sli committed
38
from django.core.exceptions import PermissionDenied
39
from django import forms
40

41 42
from datetime import timedelta

43
from com.models import Sith, News, NewsDate, Weekmail, WeekmailArticle, Screen, Poster
Sli's avatar
Sli committed
44 45 46 47 48 49 50 51
from core.views import (
    CanViewMixin,
    CanEditMixin,
    CanEditPropMixin,
    TabedViewMixin,
    CanCreateMixin,
    QuickNotifMixin,
)
Sli's avatar
Sli committed
52
from core.views.forms import SelectDateTime, MarkdownInput
Skia's avatar
Skia committed
53
from core.models import Notification, RealGroup, User
Sli's avatar
Sli committed
54
from club.models import Club, Mailing
55

56

57
# Sith object
58 59 60

sith = Sith.objects.first

Krophil's avatar
Krophil committed
61

Nicolas Ballet's avatar
Nicolas Ballet committed
62 63 64
class PosterForm(forms.ModelForm):
    class Meta:
        model = Poster
Sli's avatar
Sli committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
        fields = [
            "name",
            "file",
            "club",
            "screens",
            "date_begin",
            "date_end",
            "display_time",
        ]
        widgets = {"screens": forms.CheckboxSelectMultiple}

    date_begin = forms.DateTimeField(
        ["%Y-%m-%d %H:%M:%S"],
        label=_("Start date"),
        widget=SelectDateTime,
        required=True,
        initial=timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
    )
    date_end = forms.DateTimeField(
        ["%Y-%m-%d %H:%M:%S"],
        label=_("End date"),
        widget=SelectDateTime,
        required=False,
    )
Sli's avatar
Sli committed
89

Nicolas Ballet's avatar
Nicolas Ballet committed
90
    def __init__(self, *args, **kwargs):
Sli's avatar
Sli committed
91
        self.user = kwargs.pop("user", None)
Nicolas Ballet's avatar
Nicolas Ballet committed
92
        super(PosterForm, self).__init__(*args, **kwargs)
Nicolas Ballet's avatar
Nicolas Ballet committed
93 94
        if self.user:
            if not self.user.is_com_admin:
Sli's avatar
Sli committed
95 96 97 98
                self.fields["club"].queryset = Club.objects.filter(
                    id__in=self.user.clubs_with_rights
                )
                self.fields.pop("display_time")
Nicolas Ballet's avatar
Nicolas Ballet committed
99 100


101 102 103 104 105 106
class ComTabsMixin(TabedViewMixin):
    def get_tabs_title(self):
        return _("Communication administration")

    def get_list_of_tabs(self):
        tab_list = []
Sli's avatar
Sli committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
        tab_list.append(
            {"url": reverse("com:weekmail"), "slug": "weekmail", "name": _("Weekmail")}
        )
        tab_list.append(
            {
                "url": reverse("com:weekmail_destinations"),
                "slug": "weekmail_destinations",
                "name": _("Weekmail destinations"),
            }
        )
        tab_list.append(
            {"url": reverse("com:info_edit"), "slug": "info", "name": _("Info message")}
        )
        tab_list.append(
            {
                "url": reverse("com:alert_edit"),
                "slug": "alert",
                "name": _("Alert message"),
            }
        )
        tab_list.append(
            {
                "url": reverse("com:mailing_admin"),
                "slug": "mailings",
                "name": _("Mailing lists administration"),
            }
        )
        tab_list.append(
            {
                "url": reverse("com:poster_list"),
                "slug": "posters",
                "name": _("Posters list"),
            }
        )
        tab_list.append(
            {
                "url": reverse("com:screen_list"),
                "slug": "screens",
                "name": _("Screens list"),
            }
        )
148 149
        return tab_list

Krophil's avatar
Krophil committed
150

151 152
class IsComAdminMixin(View):
    def dispatch(self, request, *args, **kwargs):
153
        if not (request.user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)):
154 155 156 157
            raise PermissionDenied
        return super(IsComAdminMixin, self).dispatch(request, *args, **kwargs)


158 159
class ComEditView(ComTabsMixin, CanEditPropMixin, UpdateView):
    model = Sith
Sli's avatar
Sli committed
160
    template_name = "core/edit.jinja"
161 162 163 164

    def get_object(self, queryset=None):
        return Sith.objects.first()

Krophil's avatar
Krophil committed
165

166
class AlertMsgEditView(ComEditView):
167 168 169
    form_class = modelform_factory(
        Sith, fields=["alert_msg"], widgets={"alert_msg": MarkdownInput}
    )
170
    current_tab = "alert"
Sli's avatar
Sli committed
171
    success_url = reverse_lazy("com:alert_edit")
172

Krophil's avatar
Krophil committed
173

174
class InfoMsgEditView(ComEditView):
175 176 177
    form_class = modelform_factory(
        Sith, fields=["info_msg"], widgets={"info_msg": MarkdownInput}
    )
178
    current_tab = "info"
Sli's avatar
Sli committed
179
    success_url = reverse_lazy("com:info_edit")
180

Krophil's avatar
Krophil committed
181

Skia's avatar
Skia committed
182
class WeekmailDestinationEditView(ComEditView):
Sli's avatar
Sli committed
183
    fields = ["weekmail_destinations"]
Skia's avatar
Skia committed
184
    current_tab = "weekmail_destinations"
Sli's avatar
Sli committed
185 186
    success_url = reverse_lazy("com:weekmail_destinations")

Skia's avatar
Skia committed
187

188 189
# News

Krophil's avatar
Krophil committed
190

191 192 193
class NewsForm(forms.ModelForm):
    class Meta:
        model = News
Sli's avatar
Sli committed
194
        fields = ["type", "title", "club", "summary", "content", "author"]
Sli's avatar
Sli committed
195 196 197 198 199 200
        widgets = {
            "author": forms.HiddenInput,
            "type": forms.RadioSelect,
            "summary": MarkdownInput,
            "content": MarkdownInput,
        }
Sli's avatar
Sli committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

    start_date = forms.DateTimeField(
        ["%Y-%m-%d %H:%M:%S"],
        label=_("Start date"),
        widget=SelectDateTime,
        required=False,
    )
    end_date = forms.DateTimeField(
        ["%Y-%m-%d %H:%M:%S"],
        label=_("End date"),
        widget=SelectDateTime,
        required=False,
    )
    until = forms.DateTimeField(
        ["%Y-%m-%d %H:%M:%S"], label=_("Until"), widget=SelectDateTime, required=False
    )
Skia's avatar
Skia committed
217
    automoderation = forms.BooleanField(label=_("Automoderation"), required=False)
218 219 220

    def clean(self):
        self.cleaned_data = super(NewsForm, self).clean()
Sli's avatar
Sli committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
        if self.cleaned_data["type"] != "NOTICE":
            if not self.cleaned_data["start_date"]:
                self.add_error(
                    "start_date", ValidationError(_("This field is required."))
                )
            if not self.cleaned_data["end_date"]:
                self.add_error(
                    "end_date", ValidationError(_("This field is required."))
                )
            if self.cleaned_data["start_date"] > self.cleaned_data["end_date"]:
                self.add_error(
                    "end_date",
                    ValidationError(
                        _("You crazy? You can not finish an event before starting it.")
                    ),
                )
            if self.cleaned_data["type"] == "WEEKLY" and not self.cleaned_data["until"]:
                self.add_error("until", ValidationError(_("This field is required.")))
239 240 241 242 243 244
        return self.cleaned_data

    def save(self):
        ret = super(NewsForm, self).save()
        self.instance.dates.all().delete()
        if self.instance.type == "EVENT" or self.instance.type == "CALL":
Sli's avatar
Sli committed
245 246 247 248 249
            NewsDate(
                start_date=self.cleaned_data["start_date"],
                end_date=self.cleaned_data["end_date"],
                news=self.instance,
            ).save()
250
        elif self.instance.type == "WEEKLY":
Sli's avatar
Sli committed
251 252 253 254 255 256
            start_date = self.cleaned_data["start_date"]
            end_date = self.cleaned_data["end_date"]
            while start_date <= self.cleaned_data["until"]:
                NewsDate(
                    start_date=start_date, end_date=end_date, news=self.instance
                ).save()
257 258 259 260
                start_date += timedelta(days=7)
                end_date += timedelta(days=7)
        return ret

Krophil's avatar
Krophil committed
261

Skia's avatar
Skia committed
262
class NewsEditView(CanEditMixin, UpdateView):
263 264
    model = News
    form_class = NewsForm
Sli's avatar
Sli committed
265 266
    template_name = "com/news_edit.jinja"
    pk_url_kwarg = "news_id"
267 268 269 270

    def get_initial(self):
        init = {}
        try:
Sli's avatar
Sli committed
271 272 273 274 275
            init["start_date"] = (
                self.object.dates.order_by("id")
                .first()
                .start_date.strftime("%Y-%m-%d %H:%M:%S")
            )
Krophil's avatar
Krophil committed
276 277
        except:
            pass
278
        try:
Sli's avatar
Sli committed
279 280 281 282 283
            init["end_date"] = (
                self.object.dates.order_by("id")
                .first()
                .end_date.strftime("%Y-%m-%d %H:%M:%S")
            )
Krophil's avatar
Krophil committed
284 285
        except:
            pass
286 287
        return init

Skia's avatar
Skia committed
288 289
    def post(self, request, *args, **kwargs):
        form = self.get_form()
Sli's avatar
Sli committed
290
        if form.is_valid() and "preview" not in request.POST.keys():
Skia's avatar
Skia committed
291 292 293 294
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

Skia's avatar
Skia committed
295 296
    def form_valid(self, form):
        self.object = form.save()
Sli's avatar
Sli committed
297 298 299
        if form.cleaned_data["automoderation"] and self.request.user.is_in_group(
            settings.SITH_GROUP_COM_ADMIN_ID
        ):
Skia's avatar
Skia committed
300 301 302 303 304 305
            self.object.moderator = self.request.user
            self.object.is_moderated = True
            self.object.save()
        else:
            self.object.is_moderated = False
            self.object.save()
Sli's avatar
Sli committed
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
            for u in (
                RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID)
                .first()
                .users.all()
            ):
                if not u.notifications.filter(
                    type="NEWS_MODERATION", viewed=False
                ).exists():
                    Notification(
                        user=u,
                        url=reverse(
                            "com:news_detail", kwargs={"news_id": self.object.id}
                        ),
                        type="NEWS_MODERATION",
                    ).save()
Skia's avatar
Skia committed
321 322
        return super(NewsEditView, self).form_valid(form)

Krophil's avatar
Krophil committed
323

Skia's avatar
Skia committed
324
class NewsCreateView(CanCreateMixin, CreateView):
325 326
    model = News
    form_class = NewsForm
Sli's avatar
Sli committed
327
    template_name = "com/news_edit.jinja"
328 329

    def get_initial(self):
Sli's avatar
Sli committed
330
        init = {"author": self.request.user}
331
        try:
Sli's avatar
Sli committed
332
            init["club"] = Club.objects.filter(id=self.request.GET["club"]).first()
Krophil's avatar
Krophil committed
333 334
        except:
            pass
335 336
        return init

Skia's avatar
Skia committed
337 338
    def post(self, request, *args, **kwargs):
        form = self.get_form()
Sli's avatar
Sli committed
339
        if form.is_valid() and "preview" not in request.POST.keys():
Skia's avatar
Skia committed
340 341 342 343 344
            return self.form_valid(form)
        else:
            self.object = form.instance
            return self.form_invalid(form)

Skia's avatar
Skia committed
345 346
    def form_valid(self, form):
        self.object = form.save()
Sli's avatar
Sli committed
347 348 349
        if form.cleaned_data["automoderation"] and self.request.user.is_in_group(
            settings.SITH_GROUP_COM_ADMIN_ID
        ):
Skia's avatar
Skia committed
350 351 352
            self.object.moderator = self.request.user
            self.object.is_moderated = True
            self.object.save()
Skia's avatar
Skia committed
353
        else:
Sli's avatar
Sli committed
354 355 356 357 358 359 360 361 362 363 364 365 366
            for u in (
                RealGroup.objects.filter(id=settings.SITH_GROUP_COM_ADMIN_ID)
                .first()
                .users.all()
            ):
                if not u.notifications.filter(
                    type="NEWS_MODERATION", viewed=False
                ).exists():
                    Notification(
                        user=u,
                        url=reverse("com:news_admin_list"),
                        type="NEWS_MODERATION",
                    ).save()
Skia's avatar
Skia committed
367 368
        return super(NewsCreateView, self).form_valid(form)

Krophil's avatar
Krophil committed
369

Skia's avatar
Skia committed
370 371
class NewsDeleteView(CanEditMixin, DeleteView):
    model = News
Sli's avatar
Sli committed
372 373 374
    pk_url_kwarg = "news_id"
    template_name = "core/delete_confirm.jinja"
    success_url = reverse_lazy("com:news_admin_list")
Krophil's avatar
Krophil committed
375

Skia's avatar
Skia committed
376

Skia's avatar
Skia committed
377 378
class NewsModerateView(CanEditMixin, SingleObjectMixin):
    model = News
Sli's avatar
Sli committed
379
    pk_url_kwarg = "news_id"
Skia's avatar
Skia committed
380 381 382

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
Sli's avatar
Sli committed
383
        if "remove" in request.GET.keys():
Skia's avatar
Skia committed
384 385 386
            self.object.is_moderated = False
        else:
            self.object.is_moderated = True
Skia's avatar
Skia committed
387 388
        self.object.moderator = request.user
        self.object.save()
Sli's avatar
Sli committed
389 390 391
        if "next" in self.request.GET.keys():
            return redirect(self.request.GET["next"])
        return redirect("com:news_admin_list")
Skia's avatar
Skia committed
392

Krophil's avatar
Krophil committed
393

Skia's avatar
Skia committed
394
class NewsAdminListView(CanEditMixin, ListView):
395
    model = News
Sli's avatar
Sli committed
396
    template_name = "com/news_admin_list.jinja"
Skia's avatar
Skia committed
397
    queryset = News.objects.all()
398

Krophil's avatar
Krophil committed
399

Skia's avatar
Skia committed
400
class NewsListView(CanViewMixin, ListView):
401
    model = News
Sli's avatar
Sli committed
402
    template_name = "com/news_list.jinja"
Skia's avatar
Skia committed
403
    queryset = News.objects.filter(is_moderated=True)
404

Skia's avatar
Skia committed
405 406
    def get_context_data(self, **kwargs):
        kwargs = super(NewsListView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
407 408 409 410 411 412 413 414 415 416
        kwargs["NewsDate"] = NewsDate
        kwargs["timedelta"] = timedelta
        kwargs["birthdays"] = (
            User.objects.filter(
                date_of_birth__month=timezone.now().month,
                date_of_birth__day=timezone.now().day,
            )
            .filter(role__in=["STUDENT", "FORMER STUDENT"])
            .order_by("-date_of_birth")
        )
Skia's avatar
Skia committed
417 418
        return kwargs

Krophil's avatar
Krophil committed
419

Skia's avatar
Skia committed
420
class NewsDetailView(CanViewMixin, DetailView):
421
    model = News
Sli's avatar
Sli committed
422 423 424
    template_name = "com/news_detail.jinja"
    pk_url_kwarg = "news_id"

Skia's avatar
Skia committed
425

Skia's avatar
Skia committed
426 427
# Weekmail

Krophil's avatar
Krophil committed
428

Skia's avatar
Skia committed
429
class WeekmailPreviewView(ComTabsMixin, CanEditPropMixin, DetailView):
Skia's avatar
Skia committed
430
    model = Weekmail
Sli's avatar
Sli committed
431 432
    template_name = "com/weekmail_preview.jinja"
    success_url = reverse_lazy("com:weekmail")
Skia's avatar
Skia committed
433 434 435 436 437
    current_tab = "weekmail"

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        try:
Sli's avatar
Sli committed
438
            if request.POST["send"] == "validate":
Skia's avatar
Skia committed
439
                self.object.send()
Sli's avatar
Sli committed
440 441 442
                return HttpResponseRedirect(
                    reverse("com:weekmail") + "?qn_weekmail_send_success"
                )
Krophil's avatar
Krophil committed
443 444
        except:
            pass
Skia's avatar
Skia committed
445
        return super(WeekmailEditView, self).get(request, *args, **kwargs)
Skia's avatar
Skia committed
446 447

    def get_object(self, queryset=None):
Sli's avatar
Sli committed
448
        return self.model.objects.filter(sent=False).order_by("-id").first()
Skia's avatar
Skia committed
449 450 451 452

    def get_context_data(self, **kwargs):
        """Add rendered weekmail"""
        kwargs = super(WeekmailPreviewView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
453
        kwargs["weekmail_rendered"] = self.object.render_html()
Skia's avatar
Skia committed
454 455
        return kwargs

Krophil's avatar
Krophil committed
456

Skia's avatar
Skia committed
457
class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateView):
Skia's avatar
Skia committed
458
    model = Weekmail
Sli's avatar
Sli committed
459 460 461 462 463
    template_name = "com/weekmail.jinja"
    form_class = modelform_factory(
        Weekmail,
        fields=["title", "intro", "joke", "protip", "conclusion"],
        help_texts={"title": _("Delete and save to regenerate")},
Sli's avatar
Sli committed
464 465 466 467 468 469
        widgets={
            "intro": MarkdownInput,
            "joke": MarkdownInput,
            "protip": MarkdownInput,
            "conclusion": MarkdownInput,
        },
Sli's avatar
Sli committed
470 471
    )
    success_url = reverse_lazy("com:weekmail")
Skia's avatar
Skia committed
472
    current_tab = "weekmail"
Skia's avatar
Skia committed
473 474

    def get_object(self, queryset=None):
Sli's avatar
Sli committed
475
        weekmail = self.model.objects.filter(sent=False).order_by("-id").first()
Skia's avatar
Skia committed
476 477
        if not weekmail.title:
            now = timezone.now()
Sli's avatar
Sli committed
478 479 480
            weekmail.title = _("Weekmail of the ") + (
                now + timedelta(days=6 - now.weekday())
            ).strftime("%d/%m/%Y")
Skia's avatar
Skia committed
481
            weekmail.save()
Skia's avatar
Skia committed
482
        return weekmail
Skia's avatar
Skia committed
483

Skia's avatar
Skia committed
484 485
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
Sli's avatar
Sli committed
486 487 488 489 490 491 492
        if "up_article" in request.GET.keys():
            art = get_object_or_404(
                WeekmailArticle, id=request.GET["up_article"], weekmail=self.object
            )
            prev_art = (
                self.object.articles.order_by("rank").filter(rank__lt=art.rank).last()
            )
Skia's avatar
Skia committed
493 494 495 496
            if prev_art:
                art.rank, prev_art.rank = prev_art.rank, art.rank
                art.save()
                prev_art.save()
Sli's avatar
Sli committed
497 498 499 500 501 502 503 504
                self.quick_notif_list += ["qn_success"]
        if "down_article" in request.GET.keys():
            art = get_object_or_404(
                WeekmailArticle, id=request.GET["down_article"], weekmail=self.object
            )
            next_art = (
                self.object.articles.order_by("rank").filter(rank__gt=art.rank).first()
            )
Skia's avatar
Skia committed
505 506 507 508
            if next_art:
                art.rank, next_art.rank = next_art.rank, art.rank
                art.save()
                next_art.save()
Sli's avatar
Sli committed
509 510 511 512 513
                self.quick_notif_list += ["qn_success"]
        if "add_article" in request.GET.keys():
            art = get_object_or_404(
                WeekmailArticle, id=request.GET["add_article"], weekmail=None
            )
Skia's avatar
Skia committed
514
            art.weekmail = self.object
Sli's avatar
Sli committed
515
            art.rank = self.object.articles.aggregate(Max("rank"))["rank__max"] or 0
Skia's avatar
Skia committed
516 517
            art.rank += 1
            art.save()
Sli's avatar
Sli committed
518 519 520 521 522
            self.quick_notif_list += ["qn_success"]
        if "del_article" in request.GET.keys():
            art = get_object_or_404(
                WeekmailArticle, id=request.GET["del_article"], weekmail=self.object
            )
Skia's avatar
Skia committed
523 524 525
            art.weekmail = None
            art.rank = -1
            art.save()
Sli's avatar
Sli committed
526
            self.quick_notif_list += ["qn_success"]
Skia's avatar
Skia committed
527 528 529 530 531
        return super(WeekmailEditView, self).get(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        """Add orphan articles """
        kwargs = super(WeekmailEditView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
532
        kwargs["orphans"] = WeekmailArticle.objects.filter(weekmail=None)
Skia's avatar
Skia committed
533 534
        return kwargs

Krophil's avatar
Krophil committed
535

Sli's avatar
Sli committed
536 537 538
class WeekmailArticleEditView(
    ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateView
):
Skia's avatar
Skia committed
539
    """Edit an article"""
Sli's avatar
Sli committed
540

Skia's avatar
Skia committed
541
    model = WeekmailArticle
Sli's avatar
Sli committed
542 543 544 545 546
    form_class = modelform_factory(
        WeekmailArticle,
        fields=["title", "club", "content"],
        widgets={"content": MarkdownInput},
    )
Skia's avatar
Skia committed
547
    pk_url_kwarg = "article_id"
Sli's avatar
Sli committed
548 549
    template_name = "core/edit.jinja"
    success_url = reverse_lazy("com:weekmail")
Skia's avatar
Skia committed
550
    quick_notif_url_arg = "qn_weekmail_article_edit"
Skia's avatar
Skia committed
551
    current_tab = "weekmail"
Skia's avatar
Skia committed
552

Krophil's avatar
Krophil committed
553

554
class WeekmailArticleCreateView(QuickNotifMixin, CreateView):
Skia's avatar
Skia committed
555
    """Post an article"""
Sli's avatar
Sli committed
556

Skia's avatar
Skia committed
557
    model = WeekmailArticle
Sli's avatar
Sli committed
558 559 560 561 562
    form_class = modelform_factory(
        WeekmailArticle,
        fields=["title", "club", "content"],
        widgets={"content": MarkdownInput},
    )
Sli's avatar
Sli committed
563 564
    template_name = "core/create.jinja"
    success_url = reverse_lazy("core:user_tools")
Skia's avatar
Skia committed
565 566
    quick_notif_url_arg = "qn_weekmail_new_article"

567 568 569
    def get_initial(self):
        init = {}
        try:
Sli's avatar
Sli committed
570
            init["club"] = Club.objects.filter(id=self.request.GET["club"]).first()
Krophil's avatar
Krophil committed
571 572
        except:
            pass
573 574
        return init

575 576 577
    def post(self, request, *args, **kwargs):
        form = self.get_form()
        self.object = form.instance
Krophil's avatar
Krophil committed
578
        form.is_valid()  #  Valid a first time to populate club field
579 580 581 582 583
        try:
            m = form.instance.club.get_membership_for(request.user)
            if m.role <= settings.SITH_MAXIMUM_FREE_ROLE:
                raise
        except:
Sli's avatar
Sli committed
584 585 586 587 588 589 590 591 592
            form.add_error(
                "club",
                ValidationError(
                    _(
                        "You must be a board member of the selected club to post in the Weekmail."
                    )
                ),
            )
        if form.is_valid() and not "preview" in request.POST.keys():
593 594 595 596
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

Skia's avatar
Skia committed
597 598 599 600
    def form_valid(self, form):
        form.instance.author = self.request.user
        return super(WeekmailArticleCreateView, self).form_valid(form)

Krophil's avatar
Krophil committed
601

Skia's avatar
Skia committed
602
class WeekmailArticleDeleteView(CanEditPropMixin, DeleteView):
Skia's avatar
Skia committed
603
    """Delete an article"""
Sli's avatar
Sli committed
604

Skia's avatar
Skia committed
605
    model = WeekmailArticle
Sli's avatar
Sli committed
606 607
    template_name = "core/delete_confirm.jinja"
    success_url = reverse_lazy("com:weekmail")
608
    pk_url_kwarg = "article_id"
Sli's avatar
Sli committed
609 610 611 612 613 614 615 616


class MailingListAdminView(ComTabsMixin, ListView):
    template_name = "com/mailing_admin.jinja"
    model = Mailing
    current_tab = "mailings"

    def dispatch(self, request, *args, **kwargs):
Sli's avatar
Sli committed
617 618 619 620
        if not (
            request.user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
            or request.user.is_root
        ):
Sli's avatar
Sli committed
621 622 623 624 625
            raise PermissionDenied
        return super(MailingListAdminView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        kwargs = super(MailingListAdminView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
626 627 628 629
        kwargs["moderated"] = self.get_queryset().filter(is_moderated=True).all()
        kwargs["unmoderated"] = self.get_queryset().filter(is_moderated=False).all()
        kwargs["has_moderated"] = len(kwargs["moderated"]) > 0
        kwargs["has_unmoderated"] = len(kwargs["unmoderated"]) > 0
Sli's avatar
Sli committed
630
        return kwargs
Sli's avatar
Sli committed
631 632 633 634


class MailingModerateView(View):
    def get(self, request, *args, **kwargs):
Sli's avatar
Sli committed
635
        mailing = get_object_or_404(Mailing, pk=kwargs["mailing_id"])
Sli's avatar
Sli committed
636 637 638 639
        if mailing.can_moderate(request.user):
            mailing.is_moderated = True
            mailing.moderator = request.user
            mailing.save()
Sli's avatar
Sli committed
640
            return redirect("com:mailing_admin")
Sli's avatar
Sli committed
641 642

        raise PermissionDenied
643 644


Nicolas Ballet's avatar
Nicolas Ballet committed
645
class PosterListBaseView(ListView):
646
    """List communication posters"""
Sli's avatar
Sli committed
647

648 649
    current_tab = "posters"
    model = Poster
Sli's avatar
Sli committed
650
    template_name = "com/poster_list.jinja"
Nicolas Ballet's avatar
Nicolas Ballet committed
651 652

    def dispatch(self, request, *args, **kwargs):
Sli's avatar
Sli committed
653
        club_id = kwargs.pop("club_id", None)
Sli's avatar
Sli committed
654
        self.club = None
Nicolas Ballet's avatar
Nicolas Ballet committed
655 656
        if club_id:
            self.club = get_object_or_404(Club, pk=club_id)
Nicolas Ballet's avatar
Nicolas Ballet committed
657 658 659
        return super(PosterListBaseView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
Nicolas Ballet's avatar
Nicolas Ballet committed
660
        if self.request.user.is_com_admin:
Sli's avatar
Sli committed
661
            return Poster.objects.all().order_by("-date_begin")
Nicolas Ballet's avatar
Nicolas Ballet committed
662 663
        else:
            return Poster.objects.filter(club=self.club.id)
664 665

    def get_context_data(self, **kwargs):
Nicolas Ballet's avatar
Nicolas Ballet committed
666
        kwargs = super(PosterListBaseView, self).get_context_data(**kwargs)
Nicolas Ballet's avatar
Nicolas Ballet committed
667
        if not self.request.user.is_com_admin:
Sli's avatar
Sli committed
668
            kwargs["club"] = self.club
669 670 671
        return kwargs


Nicolas Ballet's avatar
Nicolas Ballet committed
672
class PosterCreateBaseView(CreateView):
673
    """Create communication poster"""
Sli's avatar
Sli committed
674

675
    current_tab = "posters"
676
    form_class = PosterForm
Sli's avatar
Sli committed
677
    template_name = "core/create.jinja"
Nicolas Ballet's avatar
Nicolas Ballet committed
678 679 680 681 682

    def get_queryset(self):
        return Poster.objects.all()

    def dispatch(self, request, *args, **kwargs):
Sli's avatar
Sli committed
683 684
        if "club_id" in kwargs:
            self.club = get_object_or_404(Club, pk=kwargs["club_id"])
Nicolas Ballet's avatar
Nicolas Ballet committed
685
        return super(PosterCreateBaseView, self).dispatch(request, *args, **kwargs)
686

Nicolas Ballet's avatar
Nicolas Ballet committed
687 688
    def get_form_kwargs(self):
        kwargs = super(PosterCreateBaseView, self).get_form_kwargs()
Sli's avatar
Sli committed
689
        kwargs.update({"user": self.request.user})
Nicolas Ballet's avatar
Nicolas Ballet committed
690 691
        return kwargs

692
    def get_context_data(self, **kwargs):
Nicolas Ballet's avatar
Nicolas Ballet committed
693
        kwargs = super(PosterCreateBaseView, self).get_context_data(**kwargs)
Nicolas Ballet's avatar
Nicolas Ballet committed
694
        if not self.request.user.is_com_admin:
Sli's avatar
Sli committed
695
            kwargs["club"] = self.club
696 697
        return kwargs

Nicolas Ballet's avatar
Nicolas Ballet committed
698
    def form_valid(self, form):
Nicolas Ballet's avatar
Nicolas Ballet committed
699
        if self.request.user.is_com_admin:
Nicolas Ballet's avatar
Nicolas Ballet committed
700 701 702
            form.instance.is_moderated = True
        return super(PosterCreateBaseView, self).form_valid(form)

703

Nicolas Ballet's avatar
Nicolas Ballet committed
704
class PosterEditBaseView(UpdateView):
705
    """Edit communication poster"""
Sli's avatar
Sli committed
706

707 708
    pk_url_kwarg = "poster_id"
    current_tab = "posters"
709
    form_class = PosterForm
Sli's avatar
Sli committed
710
    template_name = "com/poster_edit.jinja"
Nicolas Ballet's avatar
Nicolas Ballet committed
711

Sli's avatar
Sli committed
712 713 714
    def get_initial(self):
        init = {}
        try:
Sli's avatar
Sli committed
715
            init["date_begin"] = self.object.date_begin.strftime("%Y-%m-%d %H:%M:%S")
Sli's avatar
Sli committed
716 717 718
        except Exception:
            pass
        try:
Sli's avatar
Sli committed
719
            init["date_end"] = self.object.date_end.strftime("%Y-%m-%d %H:%M:%S")
Sli's avatar
Sli committed
720 721 722 723
        except Exception:
            pass
        return init

Nicolas Ballet's avatar
Nicolas Ballet committed
724
    def dispatch(self, request, *args, **kwargs):
Sli's avatar
Sli committed
725
        if "club_id" in kwargs and kwargs["club_id"]:
Nicolas Ballet's avatar
Nicolas Ballet committed
726
            try:
Sli's avatar
Sli committed
727
                self.club = Club.objects.get(pk=kwargs["club_id"])
Nicolas Ballet's avatar
Nicolas Ballet committed
728
            except Club.DoesNotExist:
Nicolas Ballet's avatar
Nicolas Ballet committed
729
                raise PermissionDenied
Nicolas Ballet's avatar
Nicolas Ballet committed
730 731 732 733 734
        return super(PosterEditBaseView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        return Poster.objects.all()

Nicolas Ballet's avatar
Nicolas Ballet committed
735 736
    def get_form_kwargs(self):
        kwargs = super(PosterEditBaseView, self).get_form_kwargs()
Sli's avatar
Sli committed
737
        kwargs.update({"user": self.request.user})
Nicolas Ballet's avatar
Nicolas Ballet committed
738 739
        return kwargs

Nicolas Ballet's avatar
Nicolas Ballet committed
740 741
    def get_context_data(self, **kwargs):
        kwargs = super(PosterEditBaseView, self).get_context_data(**kwargs)
742 743
        if hasattr(self, "club"):
            kwargs["club"] = self.club
Nicolas Ballet's avatar
Nicolas Ballet committed
744 745 746
        return kwargs

    def form_valid(self, form):
747
        if self.request.user.is_com_admin:
Nicolas Ballet's avatar
Nicolas Ballet committed
748 749 750 751
            form.instance.is_moderated = False
        return super(PosterEditBaseView, self).form_valid(form)


Nicolas Ballet's avatar
Nicolas Ballet committed
752 753
class PosterDeleteBaseView(DeleteView):
    """Edit communication poster"""
Sli's avatar
Sli committed
754

Nicolas Ballet's avatar
Nicolas Ballet committed
755
    pk_url_kwarg = "poster_id"
Nicolas Ballet's avatar
Nicolas Ballet committed
756 757
    current_tab = "posters"
    model = Poster
Sli's avatar
Sli committed
758
    template_name = "core/delete_confirm.jinja"
Nicolas Ballet's avatar
Nicolas Ballet committed
759 760

    def dispatch(self, request, *args, **kwargs):
Sli's avatar
Sli committed
761
        if "club_id" in kwargs and kwargs["club_id"]:
Nicolas Ballet's avatar
Nicolas Ballet committed
762
            try:
Sli's avatar
Sli committed
763
                self.club = Club.objects.get(pk=kwargs["club_id"])
Nicolas Ballet's avatar
Nicolas Ballet committed
764 765 766 767 768 769 770
            except Club.DoesNotExist:
                raise PermissionDenied
        return super(PosterDeleteBaseView, self).dispatch(request, *args, **kwargs)


class PosterListView(IsComAdminMixin, ComTabsMixin, PosterListBaseView):
    """List communication posters"""
Nicolas Ballet's avatar
Nicolas Ballet committed
771 772 773

    def get_context_data(self, **kwargs):
        kwargs = super(PosterListView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
774
        kwargs["app"] = "com"
Nicolas Ballet's avatar
Nicolas Ballet committed
775 776 777 778 779
        return kwargs


class PosterCreateView(IsComAdminMixin, ComTabsMixin, PosterCreateBaseView):
    """Create communication poster"""
Sli's avatar
Sli committed
780 781

    success_url = reverse_lazy("com:poster_list")
Nicolas Ballet's avatar
Nicolas Ballet committed
782 783 784

    def get_context_data(self, **kwargs):
        kwargs = super(PosterCreateView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
785
        kwargs["app"] = "com"
Nicolas Ballet's avatar
Nicolas Ballet committed
786 787 788 789 790
        return kwargs


class PosterEditView(IsComAdminMixin, ComTabsMixin, PosterEditBaseView):
    """Edit communication poster"""
Sli's avatar
Sli committed
791 792

    success_url = reverse_lazy("com:poster_list")
793

794 795
    def get_context_data(self, **kwargs):
        kwargs = super(PosterEditView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
796
        kwargs["app"] = "com"
797 798
        return kwargs

799

Nicolas Ballet's avatar
Nicolas Ballet committed
800
class PosterDeleteView(IsComAdminMixin, ComTabsMixin, PosterDeleteBaseView):
801
    """Delete communication poster"""
Sli's avatar
Sli committed
802 803

    success_url = reverse_lazy("com:poster_list")
804 805 806 807


class PosterModerateListView(IsComAdminMixin, ComTabsMixin, ListView):
    """Moderate list communication poster"""
Sli's avatar
Sli committed
808

809 810
    current_tab = "posters"
    model = Poster
Sli's avatar
Sli committed
811
    template_name = "com/poster_moderate.jinja"
Nicolas Ballet's avatar
Nicolas Ballet committed
812
    queryset = Poster.objects.filter(is_moderated=False).all()
813

814 815
    def get_context_data(self, **kwargs):
        kwargs = super(PosterModerateListView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
816
        kwargs["app"] = "com"
817 818 819
        return kwargs


820
class PosterModerateView(IsComAdminMixin, ComTabsMixin, View):
821
    """Moderate communication poster"""
Sli's avatar
Sli committed
822

823
    def get(self, request, *args, **kwargs):
Sli's avatar
Sli committed
824
        obj = get_object_or_404(Poster, pk=kwargs["object_id"])
825
        if obj.can_be_moderated_by(request.user):
826 827 828
            obj.is_moderated = True
            obj.moderator = request.user
            obj.save()
Sli's avatar
Sli committed
829
            return redirect("com:poster_moderate_list")
830 831
        raise PermissionDenied

832 833
    def get_context_data(self, **kwargs):
        kwargs = super(PosterModerateListView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
834
        kwargs["app"] = "com"
835 836
        return kwargs

837 838 839

class ScreenListView(IsComAdminMixin, ComTabsMixin, ListView):
    """List communication screens"""
Sli's avatar
Sli committed
840

841 842
    current_tab = "screens"
    model = Screen
Sli's avatar
Sli committed
843
    template_name = "com/screen_list.jinja"
844 845 846 847


class ScreenSlideshowView(DetailView):
    """Slideshow of actives posters"""
Sli's avatar
Sli committed
848

849 850
    pk_url_kwarg = "screen_id"
    model = Screen
Sli's avatar
Sli committed
851
    template_name = "com/screen_slideshow.jinja"
852 853 854

    def get_context_data(self, **kwargs):
        kwargs = super(ScreenSlideshowView, self).get_context_data(**kwargs)
Sli's avatar
Sli committed
855
        kwargs["posters"] = self.object.active_posters()
856 857 858 859 860
        return kwargs


class ScreenCreateView(IsComAdminMixin, ComTabsMixin, CreateView):
    """Create communication screen"""
Sli's avatar
Sli committed
861

862 863
    current_tab = "screens"
    model = Screen
Sli's avatar
Sli committed
864 865 866
    fields = ["name"]
    template_name = "core/create.jinja"
    success_url = reverse_lazy("com:screen_list")
867 868 869 870


class ScreenEditView(IsComAdminMixin, ComTabsMixin, UpdateView):
    """Edit communication screen"""
Sli's avatar
Sli committed
871

872 873 874
    pk_url_kwarg = "screen_id"
    current_tab = "screens"
    model = Screen
Sli's avatar
Sli committed
875 876 877
    fields = ["name"]
    template_name = "com/screen_edit.jinja"
    success_url = reverse_lazy("com:screen_list")
878 879 880 881


class ScreenDeleteView(IsComAdminMixin, ComTabsMixin, DeleteView):
    """Delete communication screen"""
Sli's avatar
Sli committed
882

883 884 885
    pk_url_kwarg = "screen_id"
    current_tab = "screens"
    model = Screen
Sli's avatar
Sli committed
886 887
    template_name = "core/delete_confirm.jinja"
    success_url = reverse_lazy("com:screen_list")