from collections import defaultdict from datetime import date, datetime from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.sites.shortcuts import get_current_site from django.db.models import Count from django.utils.safestring import mark_safe from django.views.generic import UpdateView, DeleteView from django.urls import reverse, reverse_lazy from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator from django.core.mail import send_mail from django.http import Http404 from gestion.models import ErnestoUser from calendrier.calend import EventCalendar from calendar import monthrange from calendrier.forms import ModifEventForm, EventForm, ParticipantsForm, \ SendMail, ChangeDoodleName from calendrier.models import Event, Participants from partitions.decorators import chef_required from propositions.utils import generer def named_month(pMonthNumber): return date(1900, pMonthNumber, 1).strftime('%B') def home(request): lToday = datetime.now() return calendar(request, lToday.year, lToday.month) def calendar(request, pYear, pMonth): lYear = int(pYear) lMonth = int(pMonth) lCalendarFromMonth = datetime(lYear, lMonth, 1) lCalendarToMonth = datetime(lYear, lMonth, monthrange(lYear, lMonth)[1]) lEvents = Event.objects.filter(date__gte=lCalendarFromMonth, date__lte=lCalendarToMonth, calendrier=True) if request.user.is_authenticated: lEvents = Event.objects.filter(date__gte=lCalendarFromMonth, date__lte=lCalendarToMonth) lCalendar = EventCalendar(lEvents).formatmonth(lYear, lMonth) lPreviousYear = lYear lPreviousMonth = lMonth - 1 if lPreviousMonth == 0: lPreviousMonth = 12 lPreviousYear -= 1 lNextYear = lYear lNextMonth = lMonth + 1 if lNextMonth == 13: lNextMonth = 1 lNextYear = lYear + 1 lYearAfterThis = lYear + 1 lYearBeforeThis = lYear - 1 return render(request, 'calendrier/home.html', { 'Calendar': mark_safe(lCalendar), 'Month': lMonth, 'MonthName': named_month(lMonth), 'Year': lYear, 'PreviousMonth': lPreviousMonth, 'PreviousMonthName': named_month(lPreviousMonth), 'PreviousYear': lPreviousYear, 'NextMonth': lNextMonth, 'NextMonthName': named_month(lNextMonth), 'NextYear': lNextYear, 'YearBeforeThis': lYearBeforeThis, 'YearAfterThis': lYearAfterThis, }) def view_event(request, id): event = get_object_or_404(Event, id=id) participants = event.participants_set.all() # Restricted event, only erneso users can see it if not request.user.is_authenticated and not event.calendrier: return redirect(reverse('calendrier:home')) # Count the number of occurences of each instrument instrument_count = defaultdict(lambda: (0, 0)) for participant in participants: instrument = participant.participant.instru sure, maybe = instrument_count[instrument] if participant.reponse == "oui": instrument_count[instrument] = (sure + 1, maybe) elif participant.reponse == "pe": instrument_count[instrument] = (sure, maybe + 1) instrument_count = [ (instrument, sure, maybe) for instrument, (sure, maybe) in instrument_count.items() ] context = { "event": event, "instrument_count": instrument_count, "participants": participants, "nboui": len(participants.filter(reponse="oui")), "nbpe": len(participants.filter(reponse="pe")), "nbnon": len(participants.filter(reponse="non")), } return render(request, 'calendrier/view_event.html', context=context) # XXX: Horrible nasty code duplication. Go to hell RikM @chef_required def resend(request, id): if request.method == "POST": form = SendMail(request.POST) if form.is_valid(): ev = get_object_or_404(Event, id=id) users = ErnestoUser.objects.filter(is_ernesto=True) message = form.cleaned_data["message"] for user in users: if user.mails: Subject = "[Pouet-Pouet] %s, le %s" % ( ev.nom, ev.date.strftime('%d/%m/%Y')) sender = 'fanfare@ens.fr' receivers = [user.user.email] if message != '': text = "%s\n\n" % message else: text = "Bonjour, un évémenent a été créé.\n" domain = get_current_site(request).domain text += ( 'Pour voir l\'événement, allez sur %s%s\n' 'Pour répondre oui allez sur %s%s\n' 'Pour répondre non, allez sur %s%s\n' 'Pour répondre peut-être, allez sur %s%s\n') \ % (domain, reverse_lazy('calendrier:view-event', args=[ev.id]), domain, reverse_lazy('calendrier.reponse_event', args=[user.slug, ev.slug, "oui"]), domain, reverse_lazy('calendrier.reponse_event', args=[user.slug, ev.slug, "non"]), domain, reverse_lazy('calendrier.reponse_event', args=[user.slug, ev.slug, "pe"])) try: send_mail(Subject, text, sender, receivers) except: erreur = "Une erreur est survenue, le mail n'a pas pu être envoyé." return redirect("calendrier:view-event", id) else: form = SendMail() return render(request, "calendrier/resend.html", locals()) @login_required def changename(request): if request.method == 'POST': requbis = request.POST.copy() form = ChangeDoodleName(requbis, instance=request.user) if form.is_valid(): form.save() success = True else: form = ChangeDoodleName(instance=request.user) return render(request, 'calendrier/changename.html', locals()) @chef_required def create_event(request): if request.method == "POST": form = EventForm(request.POST) if form.is_valid(): temp = True while temp: code = generer() try: Event.objects.get(slug=code) except: temp = False sendmail = form.cleaned_data["sendmail"] nom = form.cleaned_data["nom"] date = form.cleaned_data["date"] date = date.strftime('%d/%m/%Y') debut = form.cleaned_data["debut"] message = form.cleaned_data["message"] obj = form.save(commit=False) obj.slug = code obj.save() id = obj.id envoi = True if sendmail: users = ErnestoUser.objects.filter(is_ernesto=True) for user in users: if user.mails: Subject = "[Pouet-Pouet] %s, le %s" % (nom, date) sender = 'fanfare@ens.fr' receivers = [user.user.email] if message != '': text = "%s\n\n" % message else: text = "Bonjour, un évémenent a été créé.\n" domain = get_current_site(request).domain text += ( "Pour voir l'événement, allez sur %s%s" '\nPour répondre oui allez sur %s%s\n' 'Pour répondre non, allez sur %s%s\n' 'Pour répondre peut-être, allez sur %s%s\n') \ % (domain, reverse('calendrier:view-event', args=[obj.id]), domain, reverse('calendrier.reponse_event', args=[user.slug, obj.slug, "oui"]), domain, reverse('calendrier.reponse_event', args=[user.slug, obj.slug, "non"]), domain, reverse('calendrier.reponse_event', args=[user.slug, obj.slug, "pe"])) try: send_mail(Subject, text, sender, receivers) except: erreur = "Une erreur est survenue, le mail n'a pas pu être envoyé." else: form = EventForm() return render(request, "calendrier/create.html", locals()) @login_required def reponse(request, id): part = request.user.profile ev = get_object_or_404(Event, id=id) if request.method == "POST": form = ParticipantsForm(request.POST) if form.is_valid(): try: p = Participants.objects.get(event=ev, participant=part) p.delete() except Participants.DoesNotExist: pass obj = form.save(commit=False) obj.event = ev obj.participant = part obj.save() envoi = True else: form = ParticipantsForm() return render(request, "calendrier/reponse.html", locals()) # XXX: UNSAFE! def reponse_event(request, codeus, codeev, coderep): """ Inscriptions aux événements via les liens envoyés par mail. """ # On vérifie qu'on a reçu une réponse valide if coderep not in ['oui', 'non', 'pe']: raise Http404 part = get_object_or_404(ErnestoUser, slug=codeus) ev = get_object_or_404(Event, slug=codeev) # On supprime la précédente réponse si elle existe Participants.objects.filter(event=ev, participant=part).delete() # Et on écrit la nouvelle inscription Participants.objects.create(participant=part, event=ev, reponse=coderep) return redirect(reverse('calendrier:home')) class EventUpdate(UpdateView): model = Event template_name = "calendrier/update.html" form_class = ModifEventForm success_url = reverse_lazy("home") @method_decorator(chef_required) def dispatch(self, *args, **kwargs): return super(EventUpdate, self).dispatch(*args, **kwargs) class EventDelete(DeleteView): model = Event template_name = "calendrier/delete.html" success_url = reverse_lazy("home") @method_decorator(chef_required) def dispatch(self, *args, **kwargs): return super(EventDelete, self).dispatch(*args, **kwargs)