diff --git a/bda2/__init__.py b/bda2/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/bda2/admin.py b/bda2/admin.py
deleted file mode 100644
index 84eebfa3..00000000
--- a/bda2/admin.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# coding: utf-8
-
-from django.core.mail import send_mail
-from django.contrib.contenttypes.models import ContentType
-
-from django.contrib import admin
-from django.db.models import Sum, Count
-from bda2.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution
-
-class ChoixSpectacleInline(admin.TabularInline):
- model = ChoixSpectacle
- sortable_field_name = "priority"
-
-class AttributionInline(admin.TabularInline):
- model = Attribution
-
-class ParticipantAdmin(admin.ModelAdmin):
- #inlines = [ChoixSpectacleInline]
- inlines = [AttributionInline]
- def get_queryset(self, request):
- return Participant.objects.annotate(nb_places = Count('attributions'),
- total = Sum('attributions__price'))
- def nb_places(self, obj):
- return obj.nb_places
- nb_places.admin_order_field = "nb_places"
- nb_places.short_description = "Nombre de places"
- def total(self, obj):
- tot = obj.total
- if tot: return u"%.02f €" % tot
- else: return u"0 €"
- total.admin_order_field = "total"
- total.short_description = "Total à payer"
- list_display = ("user", "nb_places", "total", "paid", "paymenttype")
- list_filter = ("paid",)
- search_fields = ('user__username', 'user__first_name', 'user__last_name')
- actions = ['send_attribs',]
- actions_on_bottom = True
- list_per_page = 400
-
- def send_choices(self, request, queryset):
- for member in queryset.all():
- choices = member.choixspectacle_set.order_by('priority').all()
- if len(choices) == 0:
- continue
- mail = u"""Cher(e) %s,
-Voici tes choix de spectacles tels que notre système les a enregistrés :\n\n""" % member.user.get_full_name()
- next_rank = 1
- member_shows = {}
- for choice in choices:
- if choice.spectacle in member_shows: continue
- else: member_shows[choice.spectacle] = True
- extra = ""
- if choice.double:
- extra += u" ; deux places"
- if choice.autoquit:
- extra += u" ; désistement automatique"
- mail += u"- Choix %d : %s%s\n" % (next_rank, choice.spectacle, extra)
- next_rank += 1
- mail += u"""\nSi cette liste est incorrecte, merci de nous contacter au plus vite (avant samedi 6 octobre 18h).
-
-Artistiquement,
-Le BdA"""
- send_mail ("Choix de spectacles (BdA du COF)", mail,
- "bda@ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
- message_bit = u"1 membre a"
- plural = ""
- else:
- message_bit = u"%d membres ont" % count
- plural = "s"
- self.message_user(request, u"%s été informé%s avec succès." % (message_bit, plural))
- send_choices.short_description = u"Envoyer les choix par mail"
-
- def send_attribs(self, request, queryset):
- for member in queryset.all():
- attribs = member.attributions.all()
- if len(attribs) == 0:
- mail = u"""Cher-e %s,
-
-Tu t'es inscrit-e pour le tirage au sort du BdA. Malheureusement, tu n'as
-obtenu aucune place.
-
-Nous sommes conscients que le nombre de places proposées lors de ce tirage
-au sort est très restreint, mais nous sommes limités par les quotas que
-nous imposent les théâtres.
-
-Nous proposons cependant de nombreuses offres hors-tirage tout au long de
-l'année, et nous t'invitons à nous contacter si l'une d'entre elles t'intéresse !
---
-Le (nouveau) Bureau des Arts
-(Thomas, Caroline, Antonin, Cécile, Hugo)
-
-"""
- name = member.user.get_full_name()
- mail = mail % name
- else:
- mail = u"""Cher-e %s,
-
-Tu t'es inscrit-e pour le tirage au sort du BdA. Tu as été sélectionné-e
-pour les spectacles suivants :
-
-%s
-
-Nous sommes conscients que le nombre de places proposées lors de ce tirage
-au sort est très restreint, mais nous sommes limités par les quotas que
-nous imposent les théâtres.
-
-*Paiement*
-L'intégralité de ces places de spectacles est à régler à partir du lundi
-18 janvier et AVANT le vendredi 22 janvier, au bureau du COF pendant les
-heures de permanences (du lundi au vendredi entre 12h et 14h, et entre 18h
-et 20h). Des facilités de paiement sont bien évidemment possibles : nous
-pouvons ne pas encaisser le chèque immédiatement, ou bien découper votre
-paiement en deux fois. Il est possible de payer par carte, chèque ou en espèces.
-
-*Mode de retrait des places*
-Lors du paiement, nous vous donnerons les places physiques que nous possédons, et vous indiquerons
-quelles places sont sur listing, à retirer le soir même de la représentation. Nous vous enverrons un mail de rappel quelques jours avant les spectacles.
-
-Nous vous rappelons que l'obtention de places du BdA vous engage à
-respecter les règles de fonctionnement :
-http://www.cof.ens.fr/bda/?page_id=1370
-Le système de revente des places via les mails BdA-revente est accessible
-directement sur votre compte GestioCOF.
-
-En vous souhaitant de belles représentations,
---
-Le (nouveau) Bureau des Arts
-(Thomas, Caroline, Antonin, Cécile, Hugo)
-"""
- attribs_text = ""
- name = member.user.get_full_name()
- for attrib in attribs:
- attribs_text += u"- 1 place pour %s\n" % attrib
- mail = mail % (name, attribs_text)
-
- send_mail ("[BdA] Résultats du tirage au sort", mail,
- "bda@ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
- message_bit = u"1 membre a"
- plural = ""
- else:
- message_bit = u"%d membres ont" % count
- plural = "s"
- self.message_user(request, u"%s été informé%s avec succès." % (message_bit, plural))
- send_attribs.short_description = u"Envoyer les résultats par mail"
-
-class AttributionAdmin(admin.ModelAdmin):
- def paid(self, obj):
- return obj.participant.paid
- paid.short_description = 'A payé'
- paid.boolean = True
- list_display = ("id", "spectacle", "participant", "given", "paid")
- search_fields = ('spectacle__title', 'participant__user__username', 'participant__user__first_name', 'participant__user__last_name')
-
-import autocomplete_light
-class ChoixSpectacleAdmin(admin.ModelAdmin):
- form = autocomplete_light.modelform_factory(ChoixSpectacle, exclude=[])
- list_display = ("participant", "spectacle", "priority", "double", "autoquit")
- list_filter = ("double", "autoquit")
- search_fields = ('participant__user__username', 'participant__user__first_name', 'participant__user__last_name')
-
-class SpectacleAdmin(admin.ModelAdmin):
- model = Spectacle
- list_display = ("title", "date", "location", "slots", "price")
- list_filter = ("location",)
- search_fields = ("title", "location__name")
-
-admin.site.register(Spectacle, SpectacleAdmin)
-admin.site.register(Salle)
-admin.site.register(Participant, ParticipantAdmin)
-admin.site.register(Attribution, AttributionAdmin)
-admin.site.register(ChoixSpectacle, ChoixSpectacleAdmin)
diff --git a/bda2/algorithm.py b/bda2/algorithm.py
deleted file mode 100644
index 623f9756..00000000
--- a/bda2/algorithm.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# coding: utf-8
-
-from django.conf import settings
-from django.db.models import Max
-
-import random
-
-class Algorithm(object):
-
- shows = None
- ranks = None
- origranks = None
- double = None
-
- def __init__(self, shows, members, choices):
- """Initialisation :
- - on aggrège toutes les demandes pour chaque spectacle dans
- show.requests
- - on crée des tables de demandes pour chaque personne, afin de
- pouvoir modifier les rankings"""
- self.max_group = 2 * choices.aggregate(Max('priority'))['priority__max']
- self.shows = []
- showdict = {}
- for show in shows:
- show.nrequests = 0
- showdict[show] = show
- show.requests = []
- self.shows.append(show)
- self.ranks = {}
- self.origranks = {}
- self.choices = {}
- next_rank = {}
- member_shows = {}
- for member in members:
- self.ranks[member] = {}
- self.choices[member] = {}
- next_rank[member] = 1
- member_shows[member] = {}
- for choice in choices:
- member = choice.participant
- if choice.spectacle in member_shows[member]: continue
- else: member_shows[member][choice.spectacle] = True
- showdict[choice.spectacle].requests.append(member)
- showdict[choice.spectacle].nrequests += 2 if choice.double else 1
- self.ranks[member][choice.spectacle] = next_rank[member]
- next_rank[member] += 2 if choice.double else 1
- self.choices[member][choice.spectacle] = choice
- for member in members:
- self.origranks[member] = dict(self.ranks[member])
-
- def IncrementRanks(self, member, currank, increment = 1):
- for show in self.ranks[member]:
- if self.ranks[member][show] > currank:
- self.ranks[member][show] -= increment
-
- def appendResult(self, l, member, show):
- l.append((member,
- self.ranks[member][show],
- self.origranks[member][show],
- self.choices[member][show].double))
-
- """
- Pour les 2 Walkyries: c'est Sandefer
-
- Pour les 4 places pour l'Oratorio c'est Maxence Arutkin
- """
-
- def __call__(self, seed):
- random.seed(seed)
- results = []
- shows = sorted(self.shows, key = lambda x: float(x.nrequests) / x.slots, reverse = True)
- for show in shows:
- # On regroupe tous les gens ayant le même rang
- groups = dict([(i, []) for i in range(1, self.max_group + 1)])
- for member in show.requests:
- if self.ranks[member][show] == 0:
- raise RuntimeError, (member, show.title)
- groups[self.ranks[member][show]].append(member)
- # On passe à l'attribution
- winners = []
- losers = []
- for i in range(1, self.max_group + 1):
- group = list(groups[i])
- random.shuffle(group)
- for member in group:
- if self.choices[member][show].double: # double
- if len(winners) + 1 < show.slots:
- self.appendResult(winners, member, show)
- self.appendResult(winners, member, show)
- elif not self.choices[member][show].autoquit and len(winners) < show.slots:
- self.appendResult(winners, member, show)
- self.appendResult(losers, member, show)
- else:
- self.appendResult(losers, member, show)
- self.appendResult(losers, member, show)
- self.IncrementRanks(member, i, 2)
- else: # simple
- if len(winners) < show.slots:
- self.appendResult(winners, member, show)
- else:
- self.appendResult(losers, member, show)
- self.IncrementRanks(member, i)
- results.append((show,winners,losers))
- return results
diff --git a/bda2/autocomplete_light_registry.py b/bda2/autocomplete_light_registry.py
deleted file mode 100644
index 3254b3c8..00000000
--- a/bda2/autocomplete_light_registry.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import autocomplete_light
-
-from bda.models import Participant, Spectacle
-
-autocomplete_light.register(Participant, search_fields=('user__username','user__first_name','user__last_name'),
- autocomplete_js_attributes={'placeholder': 'participant...'})
-
-autocomplete_light.register(Spectacle, search_fields=('title',),
- autocomplete_js_attributes={'placeholder': 'spectacle...'})
diff --git a/bda2/difftobda b/bda2/difftobda
deleted file mode 100644
index 3e6686e5..00000000
--- a/bda2/difftobda
+++ /dev/null
@@ -1,421 +0,0 @@
-Only in .: .admin.py.swp
-Binary files ../bda/__init__.pyc and ./__init__.pyc differ
-diff -p -u -r ../bda/admin.py ./admin.py
---- ../bda/admin.py 2013-12-17 10:19:56.000000000 +0100
-+++ ./admin.py 2012-12-08 22:31:46.000000000 +0100
-@@ -4,8 +4,8 @@ from django.core.mail import send_mail
- from django.contrib.contenttypes.models import ContentType
-
- from django.contrib import admin
--from django.db.models import Sum, Count
--from bda.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution
-+from django.db.models import Sum
-+from bda2.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution
-
- class ChoixSpectacleInline(admin.TabularInline):
- model = ChoixSpectacle
-@@ -17,18 +17,13 @@ class AttributionInline(admin.TabularInl
- class ParticipantAdmin(admin.ModelAdmin):
- #inlines = [ChoixSpectacleInline]
- inlines = [AttributionInline]
-- def queryset(self, request):
-- return Participant.objects.annotate(nb_places = Count('attributions'),
-- total = Sum('attributions__price'))
- def nb_places(self, obj):
-- return obj.nb_places
-- nb_places.admin_order_field = "nb_places"
-+ return len(obj.attribution_set.all())
- nb_places.short_description = "Nombre de places"
- def total(self, obj):
-- tot = obj.total
-+ tot = obj.attributions.aggregate(total = Sum('price'))['total']
- if tot: return u"%.02f €" % tot
- else: return u"0 €"
-- total.admin_order_field = "total"
- total.short_description = "Total à payer"
- list_display = ("user", "nb_places", "total", "paid", "paymenttype")
- list_filter = ("paid",)
-@@ -61,7 +56,7 @@ Voici tes choix de spectacles tels que n
- Artistiquement,
- Le BdA"""
- send_mail ("Choix de spectacles (BdA du COF)", mail,
-- "bda@ens.fr", [member.user.email],
-+ "bda@clipper.ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
-@@ -86,48 +81,41 @@ pour les spectacles suivants :
- %s
-
- *Paiement*
--L'intégralité de ces places de spectacles est à régler à partir du jeudi
--10 octobre et AVANT le mercredi 23 octobre, au bureau du COF pendant les
--heures de permanences (du lundi au vendredi entre 12h et 14h, et entre 18h
--et 20h). Des facilités de paiement sont bien évidemment possibles : nous
--pouvons ne pas encaisser le chèque immédiatement, ou bien découper votre
--paiement en deux fois.
-+Ces spectacles sont à régler avant le lundi 17 décembre, pendant les
-+heures de permanences du COF (tous les jours de la semaine entre 12h et
-+14h, et entre 18h et 20h). Des facilités de paiement sont bien évidemment
-+possibles (encaissement échelonné des chèques).
-
- *Mode de retrait des places*
--Au moment du paiement, une enveloppe vous sera remise, contenant les
--places pour l'Opéra de Paris, pour les premiers spectacles de la Comédie
--française, certains spectacles du Châtelet et du Théâtre de la Ville.
--
--Pour les concerts Radio France, le Théâtre des Champs-Élysées, le théâtre
--du Rond-Point, le théâtre de la Colline, le théâtre de l'Athénée, l'IRCAM,
--la Cité de la musique et le 104, le Studio-Théâtre de la Comédie
--française, les places seront nominatives et à retirer au théâtre le soir
--de la représentation au moins une demi-heure avant le début du spectacle.
--
--Pour le théâtre de l'Odéon, la salle Richelieu le théâtre du Vieux
--colombier de la Comédie française, certains spectacles du théâtre de la
--Ville et du théâtre de Châtelet ainsi que pour le théâtre de Chaillot, les
--places seront distribuées environ une semaine avant la représentation (un
--mail vous en avertira).
--
--Nous vous rappelons que l'obtention de places du BdA vous engage à
--respecter les règles de fonctionnement :
--http://www.cof.ens.fr/bda/?page_id=1370
--Le système de revente des places via les mails BdA-revente sera très
--prochainement disponible, directement sur votre compte GestioCOF.
-+Pour l'Opéra de Paris, le théâtre de la Colline et le théâtre du Châtelet,
-+les places sont à retirer au COF le jour du paiement.
-+
-+Pour les concerts Radio France, le théâtre des Champs-Élysées, l'IRCAM
-+et le 104, les places seront nominatives et à retirer à la salle le soir de
-+la représentation au moins une demi-heure avant le début du spectacle.
-+
-+Pour le théâtre de l'Odéon, la Comédie Française, le théâtre de la Ville,
-+le théâtre de Chaillot, les places seront distribuées dans vos
-+casiers environ une semaine avant la représentation (un mail vous en
-+avertira).
-+
-+Dans tous les cas, n'hésitez pas à nous contacter si vous avez un doute !
-+
-+Nous profitons aussi de ce message pour vous annoncer qu'un festival de
-+courts métrages aura lieu le 21 décembre dans l'école.
-+Plus d'informations : http://www.cof.ens.fr/bda/courts.
-+
-+Culturellement vôtre,
-
--En vous souhaitant de très beaux spectacles tout au long de l'année,
- --
--Le Bureau des Arts
--(Chloé, Emilie, Jaime, Maxime, Olivier)
--"""
-+Le BdA"""
- attribs_text = ""
- name = member.user.get_full_name()
- for attrib in attribs:
- attribs_text += u"- 1 place pour %s\n" % attrib
- mail = mail % (name, attribs_text)
-- send_mail ("Résultats du tirage au sort", mail,
-- "bda@ens.fr", [member.user.email],
-+ send_mail ("Places de spectacle (BdA du COF)", mail,
-+ "bda@clipper.ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
-@@ -154,13 +142,7 @@ class ChoixSpectacleAdmin(admin.ModelAdm
- list_filter = ("double", "autoquit")
- search_fields = ('participant__user__username', 'participant__user__first_name', 'participant__user__last_name')
-
--class SpectacleAdmin(admin.ModelAdmin):
-- model = Spectacle
-- list_display = ("title", "date", "location", "slots", "price")
-- list_filter = ("location",)
-- search_fields = ("title", "location__name")
--
--admin.site.register(Spectacle, SpectacleAdmin)
-+admin.site.register(Spectacle)
- admin.site.register(Salle)
- admin.site.register(Participant, ParticipantAdmin)
- admin.site.register(Attribution, AttributionAdmin)
-diff -p -u -r ../bda/algorithm.py ./algorithm.py
---- ../bda/algorithm.py 2013-10-07 14:08:44.000000000 +0200
-+++ ./algorithm.py 2012-10-31 23:01:48.000000000 +0100
-@@ -29,24 +29,25 @@ class Algorithm(object):
- self.ranks = {}
- self.origranks = {}
- self.choices = {}
-- next_rank = {}
-- member_shows = {}
- for member in members:
-- self.ranks[member] = {}
-- self.choices[member] = {}
-- next_rank[member] = 1
-- member_shows[member] = {}
-- for choice in choices:
-- member = choice.participant
-- if choice.spectacle in member_shows[member]: continue
-- else: member_shows[member][choice.spectacle] = True
-- showdict[choice.spectacle].requests.append(member)
-- showdict[choice.spectacle].nrequests += 2 if choice.double else 1
-- self.ranks[member][choice.spectacle] = next_rank[member]
-- next_rank[member] += 2 if choice.double else 1
-- self.choices[member][choice.spectacle] = choice
-- for member in members:
-- self.origranks[member] = dict(self.ranks[member])
-+ ranks = {}
-+ member_choices = {}
-+ member_shows = {}
-+ #next_priority = 1
-+ next_rank = 1
-+ for choice in member.choixspectacle_set.order_by('priority').all():
-+ if choice.spectacle in member_shows: continue
-+ else: member_shows[choice.spectacle] = True
-+ #assert choice.priority == next_priority
-+ #next_priority += 1
-+ showdict[choice.spectacle].requests.append(member)
-+ showdict[choice.spectacle].nrequests += 2 if choice.double else 1
-+ ranks[choice.spectacle] = next_rank
-+ next_rank += 2 if choice.double else 1
-+ member_choices[choice.spectacle] = choice
-+ self.ranks[member] = ranks
-+ self.choices[member] = member_choices
-+ self.origranks[member] = dict(ranks)
-
- def IncrementRanks(self, member, currank, increment = 1):
- for show in self.ranks[member]:
-Only in ../bda: algorithm.pyc
-Only in .: difftobda
-diff -p -u -r ../bda/models.py ./models.py
---- ../bda/models.py 2013-10-10 10:44:43.000000000 +0200
-+++ ./models.py 2012-10-31 23:12:56.000000000 +0100
-@@ -1,7 +1,5 @@
- # coding: utf-8
-
--import calendar
--
- from django.db import models
- from django.contrib.auth.models import User
- from django.utils.translation import ugettext_lazy as _
-@@ -19,7 +17,7 @@ class Spectacle (models.Model):
- date = models.DateTimeField ("Date & heure")
- location = models.ForeignKey(Salle)
- description = models.TextField ("Description", blank = True)
-- slots_description = models.TextField ("Description des places", blank = True)
-+ #slots_description = models.TextField ("Description des places", blank = True)
- price = models.FloatField("Prix d'une place", blank = True)
- slots = models.IntegerField ("Places")
- priority = models.IntegerField ("Priorité", default = 1000)
-@@ -31,14 +29,11 @@ class Spectacle (models.Model):
- def __repr__ (self):
- return u"[%s]" % self.__unicode__()
-
-- def timestamp(self):
-- return "%d" % calendar.timegm(self.date.utctimetuple())
--
- def date_no_seconds(self):
- return self.date.strftime('%d %b %Y %H:%M')
-
- def __unicode__ (self):
-- return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price)
-+ return u"%s - %s @ %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price)
-
- PAYMENT_TYPES = (
- ("cash",u"Cash"),
-@@ -48,7 +43,7 @@ PAYMENT_TYPES = (
- )
-
- class Participant (models.Model):
-- user = models.ForeignKey(User, unique = True)
-+ user = models.ForeignKey(User, unique = True, related_name = "participants2")
- choices = models.ManyToManyField(Spectacle, through = "ChoixSpectacle", related_name = "chosen_by")
- attributions = models.ManyToManyField(Spectacle, through = "Attribution", related_name = "attributed_to")
- paid = models.BooleanField (u"A payé", default = False)
-Binary files ../bda/models.pyc and ./models.pyc differ
-diff -p -u -r ../bda/views.py ./views.py
---- ../bda/views.py 2014-01-04 21:37:15.000000000 +0100
-+++ ./views.py 2013-02-12 22:03:38.000000000 +0100
-@@ -1,23 +1,19 @@
- # coding: utf-8
-
--from django.contrib.auth.models import User
- from django.shortcuts import render, get_object_or_404
- from django.contrib.auth.decorators import login_required
- from django.db import models
- from django.http import Http404
- from django import forms
- from django.forms.models import inlineformset_factory, BaseInlineFormSet
--from django.core import serializers
--import hashlib
-
- from django.core.mail import send_mail
-
--from datetime import datetime
- import time
-
- from gestioncof.decorators import cof_required, buro_required
--from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution
--from bda.algorithm import Algorithm
-+from bda2.models import Spectacle, Participant, ChoixSpectacle, Attribution
-+from bda2.algorithm import Algorithm
-
- class BaseBdaFormSet(BaseInlineFormSet):
- def clean(self):
-@@ -37,7 +33,7 @@ class BaseBdaFormSet(BaseInlineFormSet):
- raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.")
- spectacles.append(spectacle)
-
--@cof_required
-+@buro_required
- def etat_places(request):
- spectacles1 = ChoixSpectacle.objects.all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
- spectacles2 = ChoixSpectacle.objects.filter(double = True).all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
-@@ -46,93 +42,47 @@ def etat_places(request):
- total = 0
- for spectacle in spectacles:
- spectacle.total = 0
-- spectacle.ratio = -1.0
- spectacles_dict[spectacle.id] = spectacle
- for spectacle in spectacles1:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
-- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- for spectacle in spectacles2:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
-- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- return render(request, "etat-places.html", {"spectacles": spectacles, "total": total})
-
--def _hash_queryset(queryset):
-- data = serializers.serialize("json", queryset)
-- hasher = hashlib.sha256()
-- hasher.update(data)
-- return hasher.hexdigest()
--
--@cof_required
--def places(request):
-- participant, created = Participant.objects.get_or_create(user = request.user)
-- places = participant.attribution_set.order_by("spectacle__date", "spectacle").all()
-- total = sum([place.spectacle.price for place in places])
-- filtered_places = []
-- places_dict = {}
-- spectacles = []
-- dates = []
-- warning = False
-- for place in places:
-- if place.spectacle in spectacles:
-- places_dict[place.spectacle].double = True
-- else:
-- place.double = False
-- places_dict[place.spectacle] = place
-- spectacles.append(place.spectacle)
-- filtered_places.append(place)
-- date = place.spectacle.date.date()
-- if date in dates:
-- warning = True
-- else:
-- dates.append(date)
-- return render(request, "resume_places.html",
-- {"participant": participant,
-- "places": filtered_places,
-- "total": total,
-- "warning": warning})
--
- @cof_required
- def inscription(request):
-- if datetime.now() > datetime(2013, 10, 6, 23, 59):
-- participant, created = Participant.objects.get_or_create(user = request.user)
-- choices = participant.choixspectacle_set.order_by("priority").all()
-- return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 7 octobre !", "choices": choices})
-+ if time.time() > 1354921200:
-+ return render(request, "error.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 6 octobre dans la soirée "})
- BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet)
- participant, created = Participant.objects.get_or_create(user = request.user)
- success = False
-- stateerror = False
- if request.method == "POST":
-- dbstate = _hash_queryset(participant.choixspectacle_set.all())
-- if "dbstate" in request.POST and dbstate != request.POST["dbstate"]:
-- stateerror = True
-+ formset = BdaFormSet(request.POST, instance = participant)
-+ if formset.is_valid():
-+ #ChoixSpectacle.objects.filter(participant = participant).delete()
-+ formset.save()
-+ success = True
- formset = BdaFormSet(instance = participant)
-- else:
-- formset = BdaFormSet(request.POST, instance = participant)
-- if formset.is_valid():
-- #ChoixSpectacle.objects.filter(participant = participant).delete()
-- formset.save()
-- success = True
-- formset = BdaFormSet(instance = participant)
- else:
- formset = BdaFormSet(instance = participant)
-- dbstate = _hash_queryset(participant.choixspectacle_set.all())
- total_price = 0
- for choice in participant.choixspectacle_set.all():
- total_price += choice.spectacle.price
- if choice.double: total_price += choice.spectacle.price
-- return render(request, "inscription-bda.html", {"formset": formset, "success": success, "total_price": total_price, "dbstate": dbstate, "stateerror": stateerror})
-+ return render(request, "inscription-bda.html", {"formset": formset, "success": success, "total_price": total_price})
-+
-+Spectacle.deficit = lambda x: (x.slots-x.nrequests)*x.price
-
- def do_tirage(request):
- form = TokenForm(request.POST)
- if not form.is_valid():
- return tirage(request)
-- start = time.time()
- data = {}
-- shows = Spectacle.objects.select_related().all()
-+ shows = Spectacle.objects.all()
- members = Participant.objects.all()
-- choices = ChoixSpectacle.objects.order_by('participant', 'priority').select_related().all()
-+ choices = ChoixSpectacle.objects.all()
- algo = Algorithm(shows, members, choices)
- results = algo(form.cleaned_data["token"])
- total_slots = 0
-@@ -149,8 +99,8 @@ def do_tirage(request):
- total_sold = 0
- total_deficit = 0
- opera_deficit = 0
-- for (show, members, _) in results:
-- deficit = (show.slots - len(members)) * show.price
-+ for show in shows:
-+ deficit = show.deficit()
- total_sold += show.slots * show.price
- if deficit >= 0:
- if u"Opéra" in show.location.name:
-@@ -159,23 +109,18 @@ def do_tirage(request):
- data["total_sold"] = total_sold - total_deficit
- data["total_deficit"] = total_deficit
- data["opera_deficit"] = opera_deficit
-- data["duration"] = time.time() - start
- if request.user.is_authenticated():
- members2 = {}
-- members_uniq = {} # Participant objects are not shared accross spectacle results,
-- # So assign a single object for each Participant id
- for (show, members, _) in results:
- for (member, _, _, _) in members:
-- if member.id not in members_uniq:
-- members_uniq[member.id] = member
-+ if member not in members2:
- members2[member] = []
- member.total = 0
-- member = members_uniq[member.id]
- members2[member].append(show)
- member.total += show.price
- members2 = members2.items()
- data["members2"] = sorted(members2, key = lambda m: m[0].user.last_name)
-- if False and request.user.username in ["seguin", "harazi"]:
-+ if False and request.user.username == "seguin":
- Attribution.objects.all().delete()
- for (show, members, _) in results:
- for (member, _, _, _) in members:
-@@ -220,7 +165,7 @@ Je souhaite revendre %s pour %s le %s (%
- Contactez moi par email si vous êtes intéressés !
-
- %s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), spectacle.location, spectacle.price, request.user.get_full_name(), request.user.email)
-- send_mail("%s" % spectacle, mail,
-+ send_mail("Revente de place: %s" % spectacle, mail,
- request.user.email, ["bda-revente@lists.ens.fr"],
- fail_silently = True)
- return render(request, "bda-success.html", {"show": spectacle, "places": places})
-Only in .: views.py~
diff --git a/bda2/migrations/0001_initial.py b/bda2/migrations/0001_initial.py
deleted file mode 100644
index 450e1607..00000000
--- a/bda2/migrations/0001_initial.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-from django.conf import settings
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Attribution',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('given', models.BooleanField(default=False, verbose_name='Donn\xe9e')),
- ],
- ),
- migrations.CreateModel(
- name='ChoixSpectacle',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('priority', models.PositiveIntegerField(verbose_name=b'Priorit\xc3\xa9')),
- ('double', models.BooleanField(default=False, verbose_name=b'Deux places1 ')),
- ('autoquit', models.BooleanField(default=False, verbose_name=b'Abandon2 ')),
- ],
- options={
- 'ordering': ('priority',),
- 'verbose_name': 'voeu',
- 'verbose_name_plural': 'voeux',
- },
- ),
- migrations.CreateModel(
- name='Participant',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('paid', models.BooleanField(default=False, verbose_name='A pay\xe9')),
- ('paymenttype', models.CharField(blank=True, max_length=6, verbose_name='Moyen de paiement', choices=[(b'cash', 'Cash'), (b'cb', b'CB'), (b'cheque', 'Ch\xe8que'), (b'autre', 'Autre')])),
- ],
- ),
- migrations.CreateModel(
- name='Salle',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=300, verbose_name=b'Nom')),
- ('address', models.TextField(verbose_name=b'Adresse')),
- ],
- ),
- migrations.CreateModel(
- name='Spectacle',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('title', models.CharField(max_length=300, verbose_name=b'Titre')),
- ('date', models.DateTimeField(verbose_name=b'Date & heure')),
- ('description', models.TextField(verbose_name=b'Description', blank=True)),
- ('slots_description', models.TextField(verbose_name=b'Description des places', blank=True)),
- ('price', models.FloatField(verbose_name=b"Prix d'une place", blank=True)),
- ('slots', models.IntegerField(verbose_name=b'Places')),
- ('priority', models.IntegerField(default=1000, verbose_name=b'Priorit\xc3\xa9')),
- ('location', models.ForeignKey(to='bda2.Salle')),
- ],
- options={
- 'ordering': ('priority', 'date', 'title'),
- 'verbose_name': 'Spectacle',
- },
- ),
- migrations.AddField(
- model_name='participant',
- name='attributions',
- field=models.ManyToManyField(related_name='attributed_to', through='bda2.Attribution', to='bda2.Spectacle'),
- ),
- migrations.AddField(
- model_name='participant',
- name='choices',
- field=models.ManyToManyField(related_name='chosen_by', through='bda2.ChoixSpectacle', to='bda2.Spectacle'),
- ),
- migrations.AddField(
- model_name='participant',
- name='user',
- field=models.OneToOneField(related_name='participants2', to=settings.AUTH_USER_MODEL),
- ),
- migrations.AddField(
- model_name='choixspectacle',
- name='participant',
- field=models.ForeignKey(to='bda2.Participant'),
- ),
- migrations.AddField(
- model_name='choixspectacle',
- name='spectacle',
- field=models.ForeignKey(related_name='participants', to='bda2.Spectacle'),
- ),
- migrations.AddField(
- model_name='attribution',
- name='participant',
- field=models.ForeignKey(to='bda2.Participant'),
- ),
- migrations.AddField(
- model_name='attribution',
- name='spectacle',
- field=models.ForeignKey(related_name='attribues', to='bda2.Spectacle'),
- ),
- migrations.AlterUniqueTogether(
- name='choixspectacle',
- unique_together=set([('participant', 'spectacle')]),
- ),
- ]
diff --git a/bda2/migrations/__init__.py b/bda2/migrations/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/bda2/models.py b/bda2/models.py
deleted file mode 100644
index c9fefe6e..00000000
--- a/bda2/models.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# coding: utf-8
-
-import calendar
-
-from django.db import models
-from django.contrib.auth.models import User
-from django.utils.translation import ugettext_lazy as _
-from django.db.models.signals import post_save
-
-class Salle (models.Model):
- name = models.CharField ("Nom", max_length = 300)
- address = models.TextField ("Adresse")
-
- def __unicode__ (self):
- return self.name
-
-class Spectacle (models.Model):
- title = models.CharField ("Titre", max_length = 300)
- date = models.DateTimeField ("Date & heure")
- location = models.ForeignKey(Salle)
- description = models.TextField ("Description", blank = True)
- slots_description = models.TextField ("Description des places", blank = True)
- price = models.FloatField("Prix d'une place", blank = True)
- slots = models.IntegerField ("Places")
- priority = models.IntegerField ("Priorité", default = 1000)
-
- class Meta:
- verbose_name = "Spectacle"
- ordering = ("priority", "date","title",)
-
- def __repr__ (self):
- return u"[%s]" % self.__unicode__()
-
- def timestamp(self):
- return "%d" % calendar.timegm(self.date.utctimetuple())
-
- def date_no_seconds(self):
- return self.date.strftime('%d %b %Y %H:%M')
-
- def __unicode__ (self):
- return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price)
-
-PAYMENT_TYPES = (
-("cash",u"Cash"),
-("cb","CB"),
-("cheque",u"Chèque"),
-("autre",u"Autre"),
-)
-
-class Participant (models.Model):
- user = models.OneToOneField(User, related_name = "participants2")
- choices = models.ManyToManyField(Spectacle, through = "ChoixSpectacle", related_name = "chosen_by")
- attributions = models.ManyToManyField(Spectacle, through = "Attribution", related_name = "attributed_to")
- paid = models.BooleanField (u"A payé", default = False)
- paymenttype = models.CharField(u"Moyen de paiement", max_length = 6, choices = PAYMENT_TYPES, blank = True)
-
- def __unicode__ (self):
- return u"%s" % (self.user)
-
-class ChoixSpectacle (models.Model):
- participant = models.ForeignKey(Participant)
- spectacle = models.ForeignKey(Spectacle, related_name = "participants")
- priority = models.PositiveIntegerField("Priorité")
- double = models.BooleanField("Deux places1 ",default=False)
- autoquit = models.BooleanField("Abandon2 ",default=False)
- class Meta:
- ordering = ("priority",)
- unique_together = (("participant", "spectacle",),)
- verbose_name = "voeu"
- verbose_name_plural = "voeux"
-
-class Attribution (models.Model):
- participant = models.ForeignKey(Participant)
- spectacle = models.ForeignKey(Spectacle, related_name = "attribues")
- given = models.BooleanField(u"Donnée", default = False)
-
- def __unicode__ (self):
- return u"%s -- %s" % (self.participant, self.spectacle)
diff --git a/bda2/static/css/bda.css b/bda2/static/css/bda.css
deleted file mode 100644
index 8851eeee..00000000
--- a/bda2/static/css/bda.css
+++ /dev/null
@@ -1,10 +0,0 @@
-form#tokenform {text-align: center; font-size: 2em;}
-label {margin-right: 10px; vertical-align: top;}
-form#tokenform textarea {font-size: 2em; width: 350px; height: 200px; font-family: 'Droif Serif', serif;}
-input {width: 400px; font-size: 2em;}
-ul.losers {display: inline; margin: 0; padding: 0;}
-ul.losers li {display: inline;}
-span.details {font-size: 0.7em;}
-table {border: 1px solid black; border-collapse: collapse;}
-td {border: 1px solid black; padding: 2px;}
-.attribresult {margin: 10px 0px;}
diff --git a/bda2/templates/bda-attrib-extra.html b/bda2/templates/bda-attrib-extra.html
deleted file mode 100644
index c2c266d2..00000000
--- a/bda2/templates/bda-attrib-extra.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "bda-attrib.html" %}
-
-{% block extracontent %}
-
-
Attribution (détails)
-Token : {{ token }}
-Placés : {{ total_slots }} ; Déçus : {{ total_losers }}
-
-
-{% for member, shows in members2 %}
-
- {{ member.user.get_full_name }}
- {{ member.user.email }}
- Total: {{ member.total }}€
-
-
-{% for show in shows %}
-
-
-
- {{ show }}
-
-
-{% endfor %}
-{% endfor %}
-
-{% endblock %}
diff --git a/bda2/templates/bda-attrib.html b/bda2/templates/bda-attrib.html
deleted file mode 100644
index 8390bd03..00000000
--- a/bda2/templates/bda-attrib.html
+++ /dev/null
@@ -1,41 +0,0 @@
-{% extends "base_title.html" %}
-{% load staticfiles %}
-
-{% block extra_head %}
-
-{% endblock %}
-
-{% block realcontent %}
-
-Attribution
-Token : {{ token }}
-Placés : {{ total_slots }} ; Déçus : {{ total_losers }}
-{% if user.profile.is_buro %}Déficit total: {{ total_deficit }} €, Opéra: {{ opera_deficit }} €, Attribué: {{ total_sold }} € {% endif %}
-
-{% for show, members, losers in results %}
-
-
{{ show.title }} - {{ show.date_no_seconds }} @ {{ show.location }}
-
-{{ show.nrequests }} demandes pour {{ show.slots }} places
-{{ show.price }}€ par place{% if user.profile.is_buro and show.nrequests < show.slots %}, {{ show.deficit }}€ de déficit{% endif %}
-
-Places :
-
-{% for member, rank, origrank, double in members %}
- {{ member.user.get_full_name }} (souhait {{ origrank }} — rang {{ rank }})
-{% endfor %}
-
-Déçus :
-{% if not losers %}/{% else %}
-
-{% for member, rank, origrank, double in losers %}
-{% if not forloop.first %} ; {% endif %}
- {{ member.user.get_full_name }} (souhait {{ origrank }} — rang {{ rank }})
-{% endfor %}
-
-{% endif %}
-
-{% endfor %}
-{% block extracontent %}
-{% endblock %}
-{% endblock %}
diff --git a/bda2/templates/bda-emails.html b/bda2/templates/bda-emails.html
deleted file mode 100644
index 39744ae1..00000000
--- a/bda2/templates/bda-emails.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
- {{ spectacle }}
-
-{% endblock %}
diff --git a/bda2/templates/bda-notpaid.html b/bda2/templates/bda-notpaid.html
deleted file mode 100644
index 10b272d8..00000000
--- a/bda2/templates/bda-notpaid.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
- Nope
- Avant de revendre des places, il faut aller les payer !
-{% endblock %}
diff --git a/bda2/templates/bda-revente.html b/bda2/templates/bda-revente.html
deleted file mode 100644
index 82ed80fe..00000000
--- a/bda2/templates/bda-revente.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "base_title.html" %}
-{% load staticfiles %}
-
-{% block extra_head %}
-
-{% endblock %}
-
-{% block realcontent %}
-
-Revente de place
-
-{% endblock %}
diff --git a/bda2/templates/bda-success.html b/bda2/templates/bda-success.html
deleted file mode 100644
index ebcc87a7..00000000
--- a/bda2/templates/bda-success.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends "base_title.html" %}
-{% load staticfiles %}
-
-{% block extra_head %}
-
-{% endblock %}
-
-{% block realcontent %}
-
-Revente de place
-Votre offre de revente de {{ places }} pour {{ show.title }} le {{ show.date_no_seconds }} ({{ show.location }}) à {{ show.price }}€ a bien été envoyée.
-{% endblock %}
diff --git a/bda2/templates/bda-token.html b/bda2/templates/bda-token.html
deleted file mode 100644
index cbe72a76..00000000
--- a/bda2/templates/bda-token.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
-Tirage au sort du BdA
-
-{% endblock %}
diff --git a/bda2/templates/bda-unpaid.html b/bda2/templates/bda-unpaid.html
deleted file mode 100644
index 5596dd82..00000000
--- a/bda2/templates/bda-unpaid.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
- Impayés
-
-{% endblock %}
diff --git a/bda2/templates/etat-places.html b/bda2/templates/etat-places.html
deleted file mode 100644
index 086ca648..00000000
--- a/bda2/templates/etat-places.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
- Etat des inscriptions BDA
-
- {% for spectacle in spectacles %}
- {{ spectacle.title }} ({{ spectacle.date_no_seconds }}, {{ spectacle.location }} , {{ spectacle.slots }} places) : {{ spectacle.total }} demandes
- {% endfor %}
-
- Total : {{ total }} demandes
-{% endblock %}
diff --git a/bda2/templates/inscription-bda.html b/bda2/templates/inscription-bda.html
deleted file mode 100644
index 933f087a..00000000
--- a/bda2/templates/inscription-bda.html
+++ /dev/null
@@ -1,116 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block extra_head %}
-
-
-
-
-
-{% endblock %}
-
-{% block realcontent %}
-
-
- Inscription au tirage au sort du BDA
- {% if success %}
- Votre inscription a été mise à jour avec succès !
- {% endif %}
-
-{% endblock %}
diff --git a/bda2/templates/inscription-formset.html b/bda2/templates/inscription-formset.html
deleted file mode 100644
index 04b68a6b..00000000
--- a/bda2/templates/inscription-formset.html
+++ /dev/null
@@ -1,40 +0,0 @@
-{{ formset.non_form_errors.as_ul }}
-
diff --git a/bda2/templates/spectacle_list.html b/bda2/templates/spectacle_list.html
deleted file mode 100644
index 956037f8..00000000
--- a/bda2/templates/spectacle_list.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
- Spectacles
-
-{% endblock %}
diff --git a/bda2/tests.py b/bda2/tests.py
deleted file mode 100644
index 501deb77..00000000
--- a/bda2/tests.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-This file demonstrates writing tests using the unittest module. These will pass
-when you run "manage.py test".
-
-Replace this with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-
-class SimpleTest(TestCase):
- def test_basic_addition(self):
- """
- Tests that 1 + 1 always equals 2.
- """
- self.assertEqual(1 + 1, 2)
diff --git a/bda2/views.py b/bda2/views.py
deleted file mode 100644
index 93d54f62..00000000
--- a/bda2/views.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# coding: utf-8
-
-from django.contrib.auth.models import User
-from django.shortcuts import render, get_object_or_404
-from django.contrib.auth.decorators import login_required
-from django.db import models
-from django.http import Http404
-from django import forms
-from django.forms.models import inlineformset_factory, BaseInlineFormSet
-from django.core import serializers
-import hashlib
-
-from django.core.mail import send_mail
-
-from datetime import datetime
-import time
-
-from gestioncof.decorators import cof_required, buro_required
-from bda2.models import Spectacle, Participant, ChoixSpectacle, Attribution
-from bda2.algorithm import Algorithm
-
-class BaseBdaFormSet(BaseInlineFormSet):
- def clean(self):
- """Checks that no two articles have the same title."""
- super(BaseBdaFormSet, self).clean()
- if any(self.errors):
- # Don't bother validating the formset unless each form is valid on its own
- return
- spectacles = []
- for i in range(0, self.total_form_count()):
- form = self.forms[i]
- if not form.cleaned_data:
- continue
- spectacle = form.cleaned_data['spectacle']
- delete = form.cleaned_data['DELETE']
- if not delete and spectacle in spectacles:
- raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.")
- spectacles.append(spectacle)
-
-@cof_required
-def etat_places(request):
- spectacles1 = ChoixSpectacle.objects.all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
- spectacles2 = ChoixSpectacle.objects.filter(double = True).all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
- spectacles = Spectacle.objects.all()
- spectacles_dict = {}
- total = 0
- for spectacle in spectacles:
- spectacle.total = 0
- spectacle.ratio = 0.0
- spectacles_dict[spectacle.id] = spectacle
- for spectacle in spectacles1:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- for spectacle in spectacles2:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- return render(request, "etat-places.html", {"spectacles": spectacles, "total": total})
-
-def _hash_queryset(queryset):
- data = serializers.serialize("json", queryset)
- hasher = hashlib.sha256()
- hasher.update(data)
- return hasher.hexdigest()
-
-@cof_required
-def places(request):
- participant, created = Participant.objects.get_or_create(user = request.user)
- places = participant.attribution_set.order_by("spectacle__date", "spectacle").all()
- total = sum([place.spectacle.price for place in places])
- filtered_places = []
- places_dict = {}
- spectacles = []
- dates = []
- warning = False
- for place in places:
- if place.spectacle in spectacles:
- places_dict[place.spectacle].double = True
- else:
- place.double = False
- places_dict[place.spectacle] = place
- spectacles.append(place.spectacle)
- filtered_places.append(place)
- date = place.spectacle.date.date()
- if date in dates:
- warning = True
- else:
- dates.append(date)
- return render(request, "resume_places.html",
- {"participant": participant,
- "places": filtered_places,
- "total": total,
- "warning": warning})
-
-@cof_required
-def inscription(request):
- if datetime.now() > datetime(2016, 1, 17, 12, 00):
- participant, created = Participant.objects.get_or_create(user = request.user)
- choices = participant.choixspectacle_set.order_by("priority").all()
- return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 17 janvier !", "choices": choices})
- BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet)
- participant, created = Participant.objects.get_or_create(user = request.user)
- success = False
- stateerror = False
- if request.method == "POST":
- dbstate = _hash_queryset(participant.choixspectacle_set.all())
- if "dbstate" in request.POST and dbstate != request.POST["dbstate"]:
- stateerror = True
- formset = BdaFormSet(instance = participant)
- else:
- formset = BdaFormSet(request.POST, instance = participant)
- if formset.is_valid():
- #ChoixSpectacle.objects.filter(participant = participant).delete()
- formset.save()
- success = True
- formset = BdaFormSet(instance = participant)
- else:
- formset = BdaFormSet(instance = participant)
- dbstate = _hash_queryset(participant.choixspectacle_set.all())
- total_price = 0
- for choice in participant.choixspectacle_set.all():
- total_price += choice.spectacle.price
- if choice.double: total_price += choice.spectacle.price
- return render(request, "inscription-bda2.html", {"formset": formset, "success": success, "total_price": total_price, "dbstate": dbstate, "stateerror": stateerror})
-
-def do_tirage(request):
- form = TokenForm(request.POST)
- if not form.is_valid():
- return tirage(request)
- start = time.time()
- data = {}
- shows = Spectacle.objects.select_related().all()
- members = Participant.objects.all()
- choices = ChoixSpectacle.objects.order_by('participant', 'priority').select_related().all()
- algo = Algorithm(shows, members, choices)
- results = algo(form.cleaned_data["token"])
- total_slots = 0
- total_losers = 0
- for (_, members, losers) in results:
- total_slots += len(members)
- total_losers += len(losers)
- data["total_slots"] = total_slots
- data["total_losers"] = total_losers
- data["shows"] = shows
- data["token"] = form.cleaned_data["token"]
- data["members"] = members
- data["results"] = results
- total_sold = 0
- total_deficit = 0
- opera_deficit = 0
- for (show, members, _) in results:
- deficit = (show.slots - len(members)) * show.price
- total_sold += show.slots * show.price
- if deficit >= 0:
- if u"Opéra" in show.location.name:
- opera_deficit += deficit
- total_deficit += deficit
- data["total_sold"] = total_sold - total_deficit
- data["total_deficit"] = total_deficit
- data["opera_deficit"] = opera_deficit
- data["duration"] = time.time() - start
- if request.user.is_authenticated():
- members2 = {}
- members_uniq = {} # Participant objects are not shared accross spectacle results,
- # So assign a single object for each Participant id
- for (show, members, _) in results:
- for (member, _, _, _) in members:
- if member.id not in members_uniq:
- members_uniq[member.id] = member
- members2[member] = []
- member.total = 0
- member = members_uniq[member.id]
- members2[member].append(show)
- member.total += show.price
- members2 = members2.items()
- data["members2"] = sorted(members2, key = lambda m: m[0].user.last_name)
- if False and request.user.username in ["seguin", "harazi", "fromherz", "mpepin"]:
- Attribution.objects.all().delete()
- for (show, members, _) in results:
- for (member, _, _, _) in members:
- attrib = Attribution(spectacle = show, participant = member)
- attrib.save()
- return render(request, "bda-attrib-extra.html", data)
- else:
- return render(request, "bda-attrib.html", data)
-
-class TokenForm(forms.Form):
- token = forms.CharField(widget = forms.widgets.Textarea())
-
-@login_required
-def tirage(request):
- if request.POST:
- form = TokenForm(request.POST)
- if form.is_valid():
- return do_tirage(request)
- else:
- form = TokenForm()
- return render(request, "bda-token.html", {"form": form})
-
-class SpectacleModelChoiceField(forms.ModelChoiceField):
- def label_from_instance(self, obj):
- return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price)
-
-class ResellForm(forms.Form):
- count = forms.ChoiceField(choices = (("1","1"),("2","2"),))
- spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none())
-
- def __init__(self, participant, *args, **kwargs):
- super(ResellForm, self).__init__(*args, **kwargs)
- self.fields['spectacle'].queryset = participant.attributions.all().distinct()
-
-def do_resell(request, form):
- spectacle = form.cleaned_data["spectacle"]
- count = form.cleaned_data["count"]
- places = "2 places" if count == "2" else "une place"
- mail = u"""Bonjour,
-
-Je souhaite revendre %s pour %s le %s (%s) à %.02f€.
-Contactez moi par email si vous êtes intéressés !
-
-%s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), spectacle.location, spectacle.price, request.user.get_full_name(), request.user.email)
- send_mail("%s" % spectacle, mail,
- request.user.email, ["bda-revente@lists.ens.fr"],
- fail_silently = True)
- return render(request, "bda-success.html", {"show": spectacle, "places": places})
-
-@login_required
-def revente(request):
- participant, created = Participant.objects.get_or_create(user = request.user)
- if not participant.paid:
- return render(request, "bda-notpaid.html", {})
- if request.POST:
- form = ResellForm(participant, request.POST)
- if form.is_valid():
- return do_resell(request, form)
- else:
- form = ResellForm(participant)
- return render(request, "bda-revente.html", {"form": form})
-
-@buro_required
-def spectacle(request, spectacle_id):
- spectacle = get_object_or_404(Spectacle, id = spectacle_id)
- return render(request, "bda-emails.html", {"spectacle": spectacle})
-
-@buro_required
-def unpaid(request):
- return render(request, "bda-unpaid.html", {"unpaid": Participant.objects.filter(paid = False).all()})
diff --git a/bda3/__init__.py b/bda3/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/bda3/admin.py b/bda3/admin.py
deleted file mode 100644
index 26b0beed..00000000
--- a/bda3/admin.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# coding: utf-8
-
-from django.core.mail import send_mail
-from django.contrib.contenttypes.models import ContentType
-
-from django.contrib import admin
-from django.db.models import Sum, Count
-from bda3.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution
-
-class ChoixSpectacleInline(admin.TabularInline):
- model = ChoixSpectacle
- sortable_field_name = "priority"
-
-class AttributionInline(admin.TabularInline):
- model = Attribution
-
-class ParticipantAdmin(admin.ModelAdmin):
- #inlines = [ChoixSpectacleInline]
- inlines = [AttributionInline]
- def get_queryset(self, request):
- return Participant.objects.annotate(nb_places = Count('attributions'),
- total = Sum('attributions__price'))
- def nb_places(self, obj):
- return obj.nb_places
- nb_places.admin_order_field = "nb_places"
- nb_places.short_description = "Nombre de places"
- def total(self, obj):
- tot = obj.total
- if tot: return u"%.02f €" % tot
- else: return u"0 €"
- total.admin_order_field = "total"
- total.short_description = "Total à payer"
- list_display = ("user", "nb_places", "total", "paid", "paymenttype")
- list_filter = ("paid",)
- search_fields = ('user__username', 'user__first_name', 'user__last_name')
- actions = ['send_attribs',]
- actions_on_bottom = True
- list_per_page = 400
-
- def send_choices(self, request, queryset):
- for member in queryset.all():
- choices = member.choixspectacle_set.order_by('priority').all()
- if len(choices) == 0:
- continue
- mail = u"""Cher(e) %s,
-Voici tes choix de spectacles tels que notre système les a enregistrés :\n\n""" % member.user.get_full_name()
- next_rank = 1
- member_shows = {}
- for choice in choices:
- if choice.spectacle in member_shows: continue
- else: member_shows[choice.spectacle] = True
- extra = ""
- if choice.double:
- extra += u" ; deux places"
- if choice.autoquit:
- extra += u" ; désistement automatique"
- mail += u"- Choix %d : %s%s\n" % (next_rank, choice.spectacle, extra)
- next_rank += 1
- mail += u"""\nSi cette liste est incorrecte, merci de nous contacter au plus vite (avant samedi 6 octobre 18h).
-
-Artistiquement,
-Le BdA"""
- send_mail ("Choix de spectacles (BdA du COF)", mail,
- "bda@ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
- message_bit = u"1 membre a"
- plural = ""
- else:
- message_bit = u"%d membres ont" % count
- plural = "s"
- self.message_user(request, u"%s été informé%s avec succès." % (message_bit, plural))
- send_choices.short_description = u"Envoyer les choix par mail"
-
- def send_attribs(self, request, queryset):
- for member in queryset.all():
- attribs = member.attributions.all()
- if len(attribs) == 0:
- mail = u"""Cher-e %s,
-
-Tu t'es inscrit-e pour le troisième tirage au sort du BdA. Nous avons le regret
-de t'annoncer que tu n'as pas obtenu de place.
-
-Nous sommes bien conscients que le nombre de places mises en jeu était
-très restreint, mais les premier et deuxième tirages au sort comprenaient
-déjà un nombre exceptionnel de places, et nous dépendons des limites
-fixées par les théâtres partenaires pour l'obtention de places à tarif réduit.
-
-Le système de revente des places via les mails BdA-revente reste disponible,
-alors surveille tes mails.
-
-En vous souhaitant une bonne fin de journée,
---
-Le Bureau des Arts
-
-"""
- name = member.user.get_full_name()
- mail = mail % name
- else:
- mail = u"""Cher-e %s,
-
-Tu t'es inscrit-e pour le troisième tirage au sort du BdA. Tu as été
-sélectionné-e pour les spectacles suivants :
-
-%s
-
-Nous sommes bien conscients que le nombre de places mises en jeu était
-très restreint, mais les premier et deuxième tirages au sort comprenaient
-déjà un nombre exceptionnel de places, et nous dépendons des limites fixées
-par les théâtres partenaires pour l'obtention de places à tarif réduit.
-
-*Paiement*
-L'intégralité de ces places de spectacles est à régler à partir du lundi
-11 avril et AVANT le 16 avril, au bureau du COF pendant les
-heures de permanences (du lundi au vendredi entre 12h et 14h, et entre 18h
-et 20h). Si vous n'êtes pas disponible cette semaine, prévenez-nous par mail.
-Attention : au-delà de cette date, les places pourront être remises en jeu.
-
-*Mode de retrait des places*
-Au moment du paiement, les places pour les spectacles de la Comédie-Française
-et pour la Philarmonie vous seront remises.
-
-Nous vous rappelons que l'obtention de places du BdA vous engage à
-respecter les règles de fonctionnement :
-http://www.cof.ens.fr/bda/?page_id=1370
-
-Le système de revente des places via les mails BdA-revente reste disponible,
-directement sur votre compte GestioCOF.
-
-En vous souhaitant de très beaux spectacles,
---
-Le Bureau des Arts
-
-"""
- attribs_text = ""
- name = member.user.get_full_name()
- for attrib in attribs:
- attribs_text += u"- 1 place pour %s\n" % attrib
- mail = mail % (name, attribs_text)
-
- send_mail ("[BdA] Résultats du tirage au sort", mail,
- "bda@ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
- message_bit = u"1 membre a"
- plural = ""
- else:
- message_bit = u"%d membres ont" % count
- plural = "s"
- self.message_user(request, u"%s été informé%s avec succès." % (message_bit, plural))
- send_attribs.short_description = u"Envoyer les résultats par mail"
-
-class AttributionAdmin(admin.ModelAdmin):
- def paid(self, obj):
- return obj.participant.paid
- paid.short_description = 'A payé'
- paid.boolean = True
- list_display = ("id", "spectacle", "participant", "given", "paid")
- search_fields = ('spectacle__title', 'participant__user__username', 'participant__user__first_name', 'participant__user__last_name')
-
-import autocomplete_light
-class ChoixSpectacleAdmin(admin.ModelAdmin):
- form = autocomplete_light.modelform_factory(ChoixSpectacle, exclude=[])
- list_display = ("participant", "spectacle", "priority", "double", "autoquit")
- list_filter = ("double", "autoquit")
- search_fields = ('participant__user__username', 'participant__user__first_name', 'participant__user__last_name')
-
-class SpectacleAdmin(admin.ModelAdmin):
- model = Spectacle
- list_display = ("title", "date", "location", "slots", "price")
- list_filter = ("location",)
- search_fields = ("title", "location__name")
-
-admin.site.register(Spectacle, SpectacleAdmin)
-admin.site.register(Salle)
-admin.site.register(Participant, ParticipantAdmin)
-admin.site.register(Attribution, AttributionAdmin)
-admin.site.register(ChoixSpectacle, ChoixSpectacleAdmin)
diff --git a/bda3/algorithm.py b/bda3/algorithm.py
deleted file mode 100644
index 623f9756..00000000
--- a/bda3/algorithm.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# coding: utf-8
-
-from django.conf import settings
-from django.db.models import Max
-
-import random
-
-class Algorithm(object):
-
- shows = None
- ranks = None
- origranks = None
- double = None
-
- def __init__(self, shows, members, choices):
- """Initialisation :
- - on aggrège toutes les demandes pour chaque spectacle dans
- show.requests
- - on crée des tables de demandes pour chaque personne, afin de
- pouvoir modifier les rankings"""
- self.max_group = 2 * choices.aggregate(Max('priority'))['priority__max']
- self.shows = []
- showdict = {}
- for show in shows:
- show.nrequests = 0
- showdict[show] = show
- show.requests = []
- self.shows.append(show)
- self.ranks = {}
- self.origranks = {}
- self.choices = {}
- next_rank = {}
- member_shows = {}
- for member in members:
- self.ranks[member] = {}
- self.choices[member] = {}
- next_rank[member] = 1
- member_shows[member] = {}
- for choice in choices:
- member = choice.participant
- if choice.spectacle in member_shows[member]: continue
- else: member_shows[member][choice.spectacle] = True
- showdict[choice.spectacle].requests.append(member)
- showdict[choice.spectacle].nrequests += 2 if choice.double else 1
- self.ranks[member][choice.spectacle] = next_rank[member]
- next_rank[member] += 2 if choice.double else 1
- self.choices[member][choice.spectacle] = choice
- for member in members:
- self.origranks[member] = dict(self.ranks[member])
-
- def IncrementRanks(self, member, currank, increment = 1):
- for show in self.ranks[member]:
- if self.ranks[member][show] > currank:
- self.ranks[member][show] -= increment
-
- def appendResult(self, l, member, show):
- l.append((member,
- self.ranks[member][show],
- self.origranks[member][show],
- self.choices[member][show].double))
-
- """
- Pour les 2 Walkyries: c'est Sandefer
-
- Pour les 4 places pour l'Oratorio c'est Maxence Arutkin
- """
-
- def __call__(self, seed):
- random.seed(seed)
- results = []
- shows = sorted(self.shows, key = lambda x: float(x.nrequests) / x.slots, reverse = True)
- for show in shows:
- # On regroupe tous les gens ayant le même rang
- groups = dict([(i, []) for i in range(1, self.max_group + 1)])
- for member in show.requests:
- if self.ranks[member][show] == 0:
- raise RuntimeError, (member, show.title)
- groups[self.ranks[member][show]].append(member)
- # On passe à l'attribution
- winners = []
- losers = []
- for i in range(1, self.max_group + 1):
- group = list(groups[i])
- random.shuffle(group)
- for member in group:
- if self.choices[member][show].double: # double
- if len(winners) + 1 < show.slots:
- self.appendResult(winners, member, show)
- self.appendResult(winners, member, show)
- elif not self.choices[member][show].autoquit and len(winners) < show.slots:
- self.appendResult(winners, member, show)
- self.appendResult(losers, member, show)
- else:
- self.appendResult(losers, member, show)
- self.appendResult(losers, member, show)
- self.IncrementRanks(member, i, 2)
- else: # simple
- if len(winners) < show.slots:
- self.appendResult(winners, member, show)
- else:
- self.appendResult(losers, member, show)
- self.IncrementRanks(member, i)
- results.append((show,winners,losers))
- return results
diff --git a/bda3/autocomplete_light_registry.py b/bda3/autocomplete_light_registry.py
deleted file mode 100644
index 3254b3c8..00000000
--- a/bda3/autocomplete_light_registry.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import autocomplete_light
-
-from bda.models import Participant, Spectacle
-
-autocomplete_light.register(Participant, search_fields=('user__username','user__first_name','user__last_name'),
- autocomplete_js_attributes={'placeholder': 'participant...'})
-
-autocomplete_light.register(Spectacle, search_fields=('title',),
- autocomplete_js_attributes={'placeholder': 'spectacle...'})
diff --git a/bda3/difftobda b/bda3/difftobda
deleted file mode 100644
index 70c81735..00000000
--- a/bda3/difftobda
+++ /dev/null
@@ -1,421 +0,0 @@
-Only in .: .admin.py.swp
-Binary files ../bda/__init__.pyc and ./__init__.pyc differ
-diff -p -u -r ../bda/admin.py ./admin.py
---- ../bda/admin.py 2013-12-17 10:19:56.000000000 +0100
-+++ ./admin.py 2012-12-08 22:31:46.000000000 +0100
-@@ -4,8 +4,8 @@ from django.core.mail import send_mail
- from django.contrib.contenttypes.models import ContentType
-
- from django.contrib import admin
--from django.db.models import Sum, Count
--from bda.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution
-+from django.db.models import Sum
-+from bda3.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution
-
- class ChoixSpectacleInline(admin.TabularInline):
- model = ChoixSpectacle
-@@ -17,18 +17,13 @@ class AttributionInline(admin.TabularInl
- class ParticipantAdmin(admin.ModelAdmin):
- #inlines = [ChoixSpectacleInline]
- inlines = [AttributionInline]
-- def queryset(self, request):
-- return Participant.objects.annotate(nb_places = Count('attributions'),
-- total = Sum('attributions__price'))
- def nb_places(self, obj):
-- return obj.nb_places
-- nb_places.admin_order_field = "nb_places"
-+ return len(obj.attribution_set.all())
- nb_places.short_description = "Nombre de places"
- def total(self, obj):
-- tot = obj.total
-+ tot = obj.attributions.aggregate(total = Sum('price'))['total']
- if tot: return u"%.02f €" % tot
- else: return u"0 €"
-- total.admin_order_field = "total"
- total.short_description = "Total à payer"
- list_display = ("user", "nb_places", "total", "paid", "paymenttype")
- list_filter = ("paid",)
-@@ -61,7 +56,7 @@ Voici tes choix de spectacles tels que n
- Artistiquement,
- Le BdA"""
- send_mail ("Choix de spectacles (BdA du COF)", mail,
-- "bda@ens.fr", [member.user.email],
-+ "bda@clipper.ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
-@@ -86,48 +81,41 @@ pour les spectacles suivants :
- %s
-
- *Paiement*
--L'intégralité de ces places de spectacles est à régler à partir du jeudi
--10 octobre et AVANT le mercredi 23 octobre, au bureau du COF pendant les
--heures de permanences (du lundi au vendredi entre 12h et 14h, et entre 18h
--et 20h). Des facilités de paiement sont bien évidemment possibles : nous
--pouvons ne pas encaisser le chèque immédiatement, ou bien découper votre
--paiement en deux fois.
-+Ces spectacles sont à régler avant le lundi 17 décembre, pendant les
-+heures de permanences du COF (tous les jours de la semaine entre 12h et
-+14h, et entre 18h et 20h). Des facilités de paiement sont bien évidemment
-+possibles (encaissement échelonné des chèques).
-
- *Mode de retrait des places*
--Au moment du paiement, une enveloppe vous sera remise, contenant les
--places pour l'Opéra de Paris, pour les premiers spectacles de la Comédie
--française, certains spectacles du Châtelet et du Théâtre de la Ville.
--
--Pour les concerts Radio France, le Théâtre des Champs-Élysées, le théâtre
--du Rond-Point, le théâtre de la Colline, le théâtre de l'Athénée, l'IRCAM,
--la Cité de la musique et le 104, le Studio-Théâtre de la Comédie
--française, les places seront nominatives et à retirer au théâtre le soir
--de la représentation au moins une demi-heure avant le début du spectacle.
--
--Pour le théâtre de l'Odéon, la salle Richelieu le théâtre du Vieux
--colombier de la Comédie française, certains spectacles du théâtre de la
--Ville et du théâtre de Châtelet ainsi que pour le théâtre de Chaillot, les
--places seront distribuées environ une semaine avant la représentation (un
--mail vous en avertira).
--
--Nous vous rappelons que l'obtention de places du BdA vous engage à
--respecter les règles de fonctionnement :
--http://www.cof.ens.fr/bda/?page_id=1370
--Le système de revente des places via les mails BdA-revente sera très
--prochainement disponible, directement sur votre compte GestioCOF.
-+Pour l'Opéra de Paris, le théâtre de la Colline et le théâtre du Châtelet,
-+les places sont à retirer au COF le jour du paiement.
-+
-+Pour les concerts Radio France, le théâtre des Champs-Élysées, l'IRCAM
-+et le 104, les places seront nominatives et à retirer à la salle le soir de
-+la représentation au moins une demi-heure avant le début du spectacle.
-+
-+Pour le théâtre de l'Odéon, la Comédie Française, le théâtre de la Ville,
-+le théâtre de Chaillot, les places seront distribuées dans vos
-+casiers environ une semaine avant la représentation (un mail vous en
-+avertira).
-+
-+Dans tous les cas, n'hésitez pas à nous contacter si vous avez un doute !
-+
-+Nous profitons aussi de ce message pour vous annoncer qu'un festival de
-+courts métrages aura lieu le 21 décembre dans l'école.
-+Plus d'informations : http://www.cof.ens.fr/bda/courts.
-+
-+Culturellement vôtre,
-
--En vous souhaitant de très beaux spectacles tout au long de l'année,
- --
--Le Bureau des Arts
--(Chloé, Emilie, Jaime, Maxime, Olivier)
--"""
-+Le BdA"""
- attribs_text = ""
- name = member.user.get_full_name()
- for attrib in attribs:
- attribs_text += u"- 1 place pour %s\n" % attrib
- mail = mail % (name, attribs_text)
-- send_mail ("Résultats du tirage au sort", mail,
-- "bda@ens.fr", [member.user.email],
-+ send_mail ("Places de spectacle (BdA du COF)", mail,
-+ "bda@clipper.ens.fr", [member.user.email],
- fail_silently = True)
- count = len(queryset.all())
- if count == 1:
-@@ -154,13 +142,7 @@ class ChoixSpectacleAdmin(admin.ModelAdm
- list_filter = ("double", "autoquit")
- search_fields = ('participant__user__username', 'participant__user__first_name', 'participant__user__last_name')
-
--class SpectacleAdmin(admin.ModelAdmin):
-- model = Spectacle
-- list_display = ("title", "date", "location", "slots", "price")
-- list_filter = ("location",)
-- search_fields = ("title", "location__name")
--
--admin.site.register(Spectacle, SpectacleAdmin)
-+admin.site.register(Spectacle)
- admin.site.register(Salle)
- admin.site.register(Participant, ParticipantAdmin)
- admin.site.register(Attribution, AttributionAdmin)
-diff -p -u -r ../bda/algorithm.py ./algorithm.py
---- ../bda/algorithm.py 2013-10-07 14:08:44.000000000 +0200
-+++ ./algorithm.py 2012-10-31 23:01:48.000000000 +0100
-@@ -29,24 +29,25 @@ class Algorithm(object):
- self.ranks = {}
- self.origranks = {}
- self.choices = {}
-- next_rank = {}
-- member_shows = {}
- for member in members:
-- self.ranks[member] = {}
-- self.choices[member] = {}
-- next_rank[member] = 1
-- member_shows[member] = {}
-- for choice in choices:
-- member = choice.participant
-- if choice.spectacle in member_shows[member]: continue
-- else: member_shows[member][choice.spectacle] = True
-- showdict[choice.spectacle].requests.append(member)
-- showdict[choice.spectacle].nrequests += 2 if choice.double else 1
-- self.ranks[member][choice.spectacle] = next_rank[member]
-- next_rank[member] += 2 if choice.double else 1
-- self.choices[member][choice.spectacle] = choice
-- for member in members:
-- self.origranks[member] = dict(self.ranks[member])
-+ ranks = {}
-+ member_choices = {}
-+ member_shows = {}
-+ #next_priority = 1
-+ next_rank = 1
-+ for choice in member.choixspectacle_set.order_by('priority').all():
-+ if choice.spectacle in member_shows: continue
-+ else: member_shows[choice.spectacle] = True
-+ #assert choice.priority == next_priority
-+ #next_priority += 1
-+ showdict[choice.spectacle].requests.append(member)
-+ showdict[choice.spectacle].nrequests += 2 if choice.double else 1
-+ ranks[choice.spectacle] = next_rank
-+ next_rank += 2 if choice.double else 1
-+ member_choices[choice.spectacle] = choice
-+ self.ranks[member] = ranks
-+ self.choices[member] = member_choices
-+ self.origranks[member] = dict(ranks)
-
- def IncrementRanks(self, member, currank, increment = 1):
- for show in self.ranks[member]:
-Only in ../bda: algorithm.pyc
-Only in .: difftobda
-diff -p -u -r ../bda/models.py ./models.py
---- ../bda/models.py 2013-10-10 10:44:43.000000000 +0200
-+++ ./models.py 2012-10-31 23:12:56.000000000 +0100
-@@ -1,7 +1,5 @@
- # coding: utf-8
-
--import calendar
--
- from django.db import models
- from django.contrib.auth.models import User
- from django.utils.translation import ugettext_lazy as _
-@@ -19,7 +17,7 @@ class Spectacle (models.Model):
- date = models.DateTimeField ("Date & heure")
- location = models.ForeignKey(Salle)
- description = models.TextField ("Description", blank = True)
-- slots_description = models.TextField ("Description des places", blank = True)
-+ #slots_description = models.TextField ("Description des places", blank = True)
- price = models.FloatField("Prix d'une place", blank = True)
- slots = models.IntegerField ("Places")
- priority = models.IntegerField ("Priorité", default = 1000)
-@@ -31,14 +29,11 @@ class Spectacle (models.Model):
- def __repr__ (self):
- return u"[%s]" % self.__unicode__()
-
-- def timestamp(self):
-- return "%d" % calendar.timegm(self.date.utctimetuple())
--
- def date_no_seconds(self):
- return self.date.strftime('%d %b %Y %H:%M')
-
- def __unicode__ (self):
-- return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price)
-+ return u"%s - %s @ %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price)
-
- PAYMENT_TYPES = (
- ("cash",u"Cash"),
-@@ -48,7 +43,7 @@ PAYMENT_TYPES = (
- )
-
- class Participant (models.Model):
-- user = models.ForeignKey(User, unique = True)
-+ user = models.ForeignKey(User, unique = True, related_name = "participants2")
- choices = models.ManyToManyField(Spectacle, through = "ChoixSpectacle", related_name = "chosen_by")
- attributions = models.ManyToManyField(Spectacle, through = "Attribution", related_name = "attributed_to")
- paid = models.BooleanField (u"A payé", default = False)
-Binary files ../bda/models.pyc and ./models.pyc differ
-diff -p -u -r ../bda/views.py ./views.py
---- ../bda/views.py 2014-01-04 21:37:15.000000000 +0100
-+++ ./views.py 2013-02-12 22:03:38.000000000 +0100
-@@ -1,23 +1,19 @@
- # coding: utf-8
-
--from django.contrib.auth.models import User
- from django.shortcuts import render, get_object_or_404
- from django.contrib.auth.decorators import login_required
- from django.db import models
- from django.http import Http404
- from django import forms
- from django.forms.models import inlineformset_factory, BaseInlineFormSet
--from django.core import serializers
--import hashlib
-
- from django.core.mail import send_mail
-
--from datetime import datetime
- import time
-
- from gestioncof.decorators import cof_required, buro_required
--from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution
--from bda.algorithm import Algorithm
-+from bda3.models import Spectacle, Participant, ChoixSpectacle, Attribution
-+from bda3.algorithm import Algorithm
-
- class BaseBdaFormSet(BaseInlineFormSet):
- def clean(self):
-@@ -37,7 +33,7 @@ class BaseBdaFormSet(BaseInlineFormSet):
- raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.")
- spectacles.append(spectacle)
-
--@cof_required
-+@buro_required
- def etat_places(request):
- spectacles1 = ChoixSpectacle.objects.all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
- spectacles2 = ChoixSpectacle.objects.filter(double = True).all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
-@@ -46,93 +42,47 @@ def etat_places(request):
- total = 0
- for spectacle in spectacles:
- spectacle.total = 0
-- spectacle.ratio = -1.0
- spectacles_dict[spectacle.id] = spectacle
- for spectacle in spectacles1:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
-- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- for spectacle in spectacles2:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
-- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- return render(request, "etat-places.html", {"spectacles": spectacles, "total": total})
-
--def _hash_queryset(queryset):
-- data = serializers.serialize("json", queryset)
-- hasher = hashlib.sha256()
-- hasher.update(data)
-- return hasher.hexdigest()
--
--@cof_required
--def places(request):
-- participant, created = Participant.objects.get_or_create(user = request.user)
-- places = participant.attribution_set.order_by("spectacle__date", "spectacle").all()
-- total = sum([place.spectacle.price for place in places])
-- filtered_places = []
-- places_dict = {}
-- spectacles = []
-- dates = []
-- warning = False
-- for place in places:
-- if place.spectacle in spectacles:
-- places_dict[place.spectacle].double = True
-- else:
-- place.double = False
-- places_dict[place.spectacle] = place
-- spectacles.append(place.spectacle)
-- filtered_places.append(place)
-- date = place.spectacle.date.date()
-- if date in dates:
-- warning = True
-- else:
-- dates.append(date)
-- return render(request, "resume_places.html",
-- {"participant": participant,
-- "places": filtered_places,
-- "total": total,
-- "warning": warning})
--
- @cof_required
- def inscription(request):
-- if datetime.now() > datetime(2013, 10, 6, 23, 59):
-- participant, created = Participant.objects.get_or_create(user = request.user)
-- choices = participant.choixspectacle_set.order_by("priority").all()
-- return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 7 octobre !", "choices": choices})
-+ if time.time() > 1354921200:
-+ return render(request, "error.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 6 octobre dans la soirée "})
- BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet)
- participant, created = Participant.objects.get_or_create(user = request.user)
- success = False
-- stateerror = False
- if request.method == "POST":
-- dbstate = _hash_queryset(participant.choixspectacle_set.all())
-- if "dbstate" in request.POST and dbstate != request.POST["dbstate"]:
-- stateerror = True
-+ formset = BdaFormSet(request.POST, instance = participant)
-+ if formset.is_valid():
-+ #ChoixSpectacle.objects.filter(participant = participant).delete()
-+ formset.save()
-+ success = True
- formset = BdaFormSet(instance = participant)
-- else:
-- formset = BdaFormSet(request.POST, instance = participant)
-- if formset.is_valid():
-- #ChoixSpectacle.objects.filter(participant = participant).delete()
-- formset.save()
-- success = True
-- formset = BdaFormSet(instance = participant)
- else:
- formset = BdaFormSet(instance = participant)
-- dbstate = _hash_queryset(participant.choixspectacle_set.all())
- total_price = 0
- for choice in participant.choixspectacle_set.all():
- total_price += choice.spectacle.price
- if choice.double: total_price += choice.spectacle.price
-- return render(request, "inscription-bda.html", {"formset": formset, "success": success, "total_price": total_price, "dbstate": dbstate, "stateerror": stateerror})
-+ return render(request, "inscription-bda.html", {"formset": formset, "success": success, "total_price": total_price})
-+
-+Spectacle.deficit = lambda x: (x.slots-x.nrequests)*x.price
-
- def do_tirage(request):
- form = TokenForm(request.POST)
- if not form.is_valid():
- return tirage(request)
-- start = time.time()
- data = {}
-- shows = Spectacle.objects.select_related().all()
-+ shows = Spectacle.objects.all()
- members = Participant.objects.all()
-- choices = ChoixSpectacle.objects.order_by('participant', 'priority').select_related().all()
-+ choices = ChoixSpectacle.objects.all()
- algo = Algorithm(shows, members, choices)
- results = algo(form.cleaned_data["token"])
- total_slots = 0
-@@ -149,8 +99,8 @@ def do_tirage(request):
- total_sold = 0
- total_deficit = 0
- opera_deficit = 0
-- for (show, members, _) in results:
-- deficit = (show.slots - len(members)) * show.price
-+ for show in shows:
-+ deficit = show.deficit()
- total_sold += show.slots * show.price
- if deficit >= 0:
- if u"Opéra" in show.location.name:
-@@ -159,23 +109,18 @@ def do_tirage(request):
- data["total_sold"] = total_sold - total_deficit
- data["total_deficit"] = total_deficit
- data["opera_deficit"] = opera_deficit
-- data["duration"] = time.time() - start
- if request.user.is_authenticated():
- members2 = {}
-- members_uniq = {} # Participant objects are not shared accross spectacle results,
-- # So assign a single object for each Participant id
- for (show, members, _) in results:
- for (member, _, _, _) in members:
-- if member.id not in members_uniq:
-- members_uniq[member.id] = member
-+ if member not in members2:
- members2[member] = []
- member.total = 0
-- member = members_uniq[member.id]
- members2[member].append(show)
- member.total += show.price
- members2 = members2.items()
- data["members2"] = sorted(members2, key = lambda m: m[0].user.last_name)
-- if False and request.user.username in ["seguin", "harazi"]:
-+ if False and request.user.username == "seguin":
- Attribution.objects.all().delete()
- for (show, members, _) in results:
- for (member, _, _, _) in members:
-@@ -220,7 +165,7 @@ Je souhaite revendre %s pour %s le %s (%
- Contactez moi par email si vous êtes intéressés !
-
- %s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), spectacle.location, spectacle.price, request.user.get_full_name(), request.user.email)
-- send_mail("%s" % spectacle, mail,
-+ send_mail("Revente de place: %s" % spectacle, mail,
- request.user.email, ["bda-revente@lists.ens.fr"],
- fail_silently = True)
- return render(request, "bda-success.html", {"show": spectacle, "places": places})
-Only in .: views.py~
diff --git a/bda3/migrations/0001_initial.py b/bda3/migrations/0001_initial.py
deleted file mode 100644
index 7a7e061b..00000000
--- a/bda3/migrations/0001_initial.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-from django.conf import settings
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Attribution',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('given', models.BooleanField(default=False, verbose_name='Donn\xe9e')),
- ],
- ),
- migrations.CreateModel(
- name='ChoixSpectacle',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('priority', models.PositiveIntegerField(verbose_name=b'Priorit\xc3\xa9')),
- ('double', models.BooleanField(default=False, verbose_name=b'Deux places1 ')),
- ('autoquit', models.BooleanField(default=False, verbose_name=b'Abandon2 ')),
- ],
- options={
- 'ordering': ('priority',),
- 'verbose_name': 'voeu',
- 'verbose_name_plural': 'voeux',
- },
- ),
- migrations.CreateModel(
- name='Participant',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('paid', models.BooleanField(default=False, verbose_name='A pay\xe9')),
- ('paymenttype', models.CharField(blank=True, max_length=6, verbose_name='Moyen de paiement', choices=[(b'cash', 'Cash'), (b'cb', b'CB'), (b'cheque', 'Ch\xe8que'), (b'autre', 'Autre')])),
- ],
- ),
- migrations.CreateModel(
- name='Salle',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=300, verbose_name=b'Nom')),
- ('address', models.TextField(verbose_name=b'Adresse')),
- ],
- ),
- migrations.CreateModel(
- name='Spectacle',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('title', models.CharField(max_length=300, verbose_name=b'Titre')),
- ('date', models.DateTimeField(verbose_name=b'Date & heure')),
- ('description', models.TextField(verbose_name=b'Description', blank=True)),
- ('slots_description', models.TextField(verbose_name=b'Description des places', blank=True)),
- ('price', models.FloatField(verbose_name=b"Prix d'une place", blank=True)),
- ('slots', models.IntegerField(verbose_name=b'Places')),
- ('priority', models.IntegerField(default=1000, verbose_name=b'Priorit\xc3\xa9')),
- ('location', models.ForeignKey(to='bda3.Salle')),
- ],
- options={
- 'ordering': ('priority', 'date', 'title'),
- 'verbose_name': 'Spectacle',
- },
- ),
- migrations.AddField(
- model_name='participant',
- name='attributions',
- field=models.ManyToManyField(related_name='attributed_to', through='bda3.Attribution', to='bda3.Spectacle'),
- ),
- migrations.AddField(
- model_name='participant',
- name='choices',
- field=models.ManyToManyField(related_name='chosen_by', through='bda3.ChoixSpectacle', to='bda3.Spectacle'),
- ),
- migrations.AddField(
- model_name='participant',
- name='user',
- field=models.OneToOneField(related_name='participants3', to=settings.AUTH_USER_MODEL),
- ),
- migrations.AddField(
- model_name='choixspectacle',
- name='participant',
- field=models.ForeignKey(to='bda3.Participant'),
- ),
- migrations.AddField(
- model_name='choixspectacle',
- name='spectacle',
- field=models.ForeignKey(related_name='participants', to='bda3.Spectacle'),
- ),
- migrations.AddField(
- model_name='attribution',
- name='participant',
- field=models.ForeignKey(to='bda3.Participant'),
- ),
- migrations.AddField(
- model_name='attribution',
- name='spectacle',
- field=models.ForeignKey(related_name='attribues', to='bda3.Spectacle'),
- ),
- migrations.AlterUniqueTogether(
- name='choixspectacle',
- unique_together=set([('participant', 'spectacle')]),
- ),
- ]
diff --git a/bda3/migrations/__init__.py b/bda3/migrations/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/bda3/models.py b/bda3/models.py
deleted file mode 100644
index 6ada1be3..00000000
--- a/bda3/models.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# coding: utf-8
-
-import calendar
-
-from django.db import models
-from django.contrib.auth.models import User
-from django.utils.translation import ugettext_lazy as _
-from django.db.models.signals import post_save
-
-class Salle (models.Model):
- name = models.CharField ("Nom", max_length = 300)
- address = models.TextField ("Adresse")
-
- def __unicode__ (self):
- return self.name
-
-class Spectacle (models.Model):
- title = models.CharField ("Titre", max_length = 300)
- date = models.DateTimeField ("Date & heure")
- location = models.ForeignKey(Salle)
- description = models.TextField ("Description", blank = True)
- slots_description = models.TextField ("Description des places", blank = True)
- price = models.FloatField("Prix d'une place", blank = True)
- slots = models.IntegerField ("Places")
- priority = models.IntegerField ("Priorité", default = 1000)
-
- class Meta:
- verbose_name = "Spectacle"
- ordering = ("priority", "date","title",)
-
- def __repr__ (self):
- return u"[%s]" % self.__unicode__()
-
- def timestamp(self):
- return "%d" % calendar.timegm(self.date.utctimetuple())
-
- def date_no_seconds(self):
- return self.date.strftime('%d %b %Y %H:%M')
-
- def __unicode__ (self):
- return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), self.location, self.price)
-
-PAYMENT_TYPES = (
-("cash",u"Cash"),
-("cb","CB"),
-("cheque",u"Chèque"),
-("autre",u"Autre"),
-)
-
-class Participant (models.Model):
- user = models.OneToOneField(User, related_name = "participants3")
- choices = models.ManyToManyField(Spectacle, through = "ChoixSpectacle", related_name = "chosen_by")
- attributions = models.ManyToManyField(Spectacle, through = "Attribution", related_name = "attributed_to")
- paid = models.BooleanField (u"A payé", default = False)
- paymenttype = models.CharField(u"Moyen de paiement", max_length = 6, choices = PAYMENT_TYPES, blank = True)
-
- def __unicode__ (self):
- return u"%s" % (self.user)
-
-class ChoixSpectacle (models.Model):
- participant = models.ForeignKey(Participant)
- spectacle = models.ForeignKey(Spectacle, related_name = "participants")
- priority = models.PositiveIntegerField("Priorité")
- double = models.BooleanField("Deux places1 ",default=False)
- autoquit = models.BooleanField("Abandon2 ",default=False)
- class Meta:
- ordering = ("priority",)
- unique_together = (("participant", "spectacle",),)
- verbose_name = "voeu"
- verbose_name_plural = "voeux"
-
-class Attribution (models.Model):
- participant = models.ForeignKey(Participant)
- spectacle = models.ForeignKey(Spectacle, related_name = "attribues")
- given = models.BooleanField(u"Donnée", default = False)
-
- def __unicode__ (self):
- return u"%s -- %s" % (self.participant, self.spectacle)
diff --git a/bda3/static/css/bda.css b/bda3/static/css/bda.css
deleted file mode 100644
index 8851eeee..00000000
--- a/bda3/static/css/bda.css
+++ /dev/null
@@ -1,10 +0,0 @@
-form#tokenform {text-align: center; font-size: 2em;}
-label {margin-right: 10px; vertical-align: top;}
-form#tokenform textarea {font-size: 2em; width: 350px; height: 200px; font-family: 'Droif Serif', serif;}
-input {width: 400px; font-size: 2em;}
-ul.losers {display: inline; margin: 0; padding: 0;}
-ul.losers li {display: inline;}
-span.details {font-size: 0.7em;}
-table {border: 1px solid black; border-collapse: collapse;}
-td {border: 1px solid black; padding: 2px;}
-.attribresult {margin: 10px 0px;}
diff --git a/bda3/templates/spectacle_list.html b/bda3/templates/spectacle_list.html
deleted file mode 100644
index a4a67998..00000000
--- a/bda3/templates/spectacle_list.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base_title.html" %}
-
-{% block realcontent %}
- Spectacles
-
-{% endblock %}
diff --git a/bda3/tests.py b/bda3/tests.py
deleted file mode 100644
index 501deb77..00000000
--- a/bda3/tests.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-This file demonstrates writing tests using the unittest module. These will pass
-when you run "manage.py test".
-
-Replace this with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-
-class SimpleTest(TestCase):
- def test_basic_addition(self):
- """
- Tests that 1 + 1 always equals 2.
- """
- self.assertEqual(1 + 1, 2)
diff --git a/bda3/views.py b/bda3/views.py
deleted file mode 100644
index 620f1824..00000000
--- a/bda3/views.py
+++ /dev/null
@@ -1,249 +0,0 @@
-
-# coding: utf-8
-
-from django.contrib.auth.models import User
-from django.shortcuts import render, get_object_or_404
-from django.contrib.auth.decorators import login_required
-from django.db import models
-from django.http import Http404
-from django import forms
-from django.forms.models import inlineformset_factory, BaseInlineFormSet
-from django.core import serializers
-import hashlib
-
-from django.core.mail import send_mail
-
-from datetime import datetime
-import time
-
-from gestioncof.decorators import cof_required, buro_required
-from bda3.models import Spectacle, Participant, ChoixSpectacle, Attribution
-from bda3.algorithm import Algorithm
-
-class BaseBdaFormSet(BaseInlineFormSet):
- def clean(self):
- """Checks that no two articles have the same title."""
- super(BaseBdaFormSet, self).clean()
- if any(self.errors):
- # Don't bother validating the formset unless each form is valid on its own
- return
- spectacles = []
- for i in range(0, self.total_form_count()):
- form = self.forms[i]
- if not form.cleaned_data:
- continue
- spectacle = form.cleaned_data['spectacle']
- delete = form.cleaned_data['DELETE']
- if not delete and spectacle in spectacles:
- raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.")
- spectacles.append(spectacle)
-
-@cof_required
-def etat_places(request):
- spectacles1 = ChoixSpectacle.objects.all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
- spectacles2 = ChoixSpectacle.objects.filter(double = True).all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle'))
- spectacles = Spectacle.objects.all()
- spectacles_dict = {}
- total = 0
- for spectacle in spectacles:
- spectacle.total = 0
- spectacle.ratio = -1.0
- spectacles_dict[spectacle.id] = spectacle
- for spectacle in spectacles1:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- for spectacle in spectacles2:
- spectacles_dict[spectacle["spectacle"]].total += spectacle["total"]
- spectacles_dict[spectacle["spectacle"]].ratio = spectacles_dict[spectacle["spectacle"]].total/float(spectacles_dict[spectacle["spectacle"]].slots)
- total += spectacle["total"]
- return render(request, "etat-places.html", {"spectacles": spectacles, "total": total})
-
-def _hash_queryset(queryset):
- data = serializers.serialize("json", queryset)
- hasher = hashlib.sha256()
- hasher.update(data)
- return hasher.hexdigest()
-
-@cof_required
-def places(request):
- participant, created = Participant.objects.get_or_create(user = request.user)
- places = participant.attribution_set.order_by("spectacle__date", "spectacle").all()
- total = sum([place.spectacle.price for place in places])
- filtered_places = []
- places_dict = {}
- spectacles = []
- dates = []
- warning = False
- for place in places:
- if place.spectacle in spectacles:
- places_dict[place.spectacle].double = True
- else:
- place.double = False
- places_dict[place.spectacle] = place
- spectacles.append(place.spectacle)
- filtered_places.append(place)
- date = place.spectacle.date.date()
- if date in dates:
- warning = True
- else:
- dates.append(date)
- return render(request, "resume_places.html",
- {"participant": participant,
- "places": filtered_places,
- "total": total,
- "warning": warning})
-
-@cof_required
-def inscription(request):
- if datetime.now() > datetime(2016, 4, 10, 11, 59):
- participant, created = Participant.objects.get_or_create(user = request.user)
- choices = participant.choixspectacle_set.order_by("priority").all()
- return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort très bientôt !", "choices": choices})
- BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet)
- participant, created = Participant.objects.get_or_create(user = request.user)
- success = False
- stateerror = False
- if request.method == "POST":
- dbstate = _hash_queryset(participant.choixspectacle_set.all())
- if "dbstate" in request.POST and dbstate != request.POST["dbstate"]:
- stateerror = True
- formset = BdaFormSet(instance = participant)
- else:
- formset = BdaFormSet(request.POST, instance = participant)
- if formset.is_valid():
- #ChoixSpectacle.objects.filter(participant = participant).delete()
- formset.save()
- success = True
- formset = BdaFormSet(instance = participant)
- else:
- formset = BdaFormSet(instance = participant)
- dbstate = _hash_queryset(participant.choixspectacle_set.all())
- total_price = 0
- for choice in participant.choixspectacle_set.all():
- total_price += choice.spectacle.price
- if choice.double: total_price += choice.spectacle.price
- return render(request, "inscription-bda3.html", {"formset": formset, "success": success, "total_price": total_price, "dbstate": dbstate, "stateerror": stateerror})
-
-def do_tirage(request):
- form = TokenForm(request.POST)
- if not form.is_valid():
- return tirage(request)
- start = time.time()
- data = {}
- shows = Spectacle.objects.select_related().all()
- members = Participant.objects.all()
- choices = ChoixSpectacle.objects.order_by('participant', 'priority').select_related().all()
- algo = Algorithm(shows, members, choices)
- results = algo(form.cleaned_data["token"])
- total_slots = 0
- total_losers = 0
- for (_, members, losers) in results:
- total_slots += len(members)
- total_losers += len(losers)
- data["total_slots"] = total_slots
- data["total_losers"] = total_losers
- data["shows"] = shows
- data["token"] = form.cleaned_data["token"]
- data["members"] = members
- data["results"] = results
- total_sold = 0
- total_deficit = 0
- opera_deficit = 0
- for (show, members, _) in results:
- deficit = (show.slots - len(members)) * show.price
- total_sold += show.slots * show.price
- if deficit >= 0:
- if u"Opéra" in show.location.name:
- opera_deficit += deficit
- total_deficit += deficit
- data["total_sold"] = total_sold - total_deficit
- data["total_deficit"] = total_deficit
- data["opera_deficit"] = opera_deficit
- data["duration"] = time.time() - start
- if request.user.is_authenticated():
- members2 = {}
- members_uniq = {} # Participant objects are not shared accross spectacle results,
- # So assign a single object for each Participant id
- for (show, members, _) in results:
- for (member, _, _, _) in members:
- if member.id not in members_uniq:
- members_uniq[member.id] = member
- members2[member] = []
- member.total = 0
- member = members_uniq[member.id]
- members2[member].append(show)
- member.total += show.price
- members2 = members2.items()
- data["members2"] = sorted(members2, key = lambda m: m[0].user.last_name)
- if False and request.user.username in ["seguin", "harazi", "fromherz", "mpepin"]:
- Attribution.objects.all().delete()
- for (show, members, _) in results:
- for (member, _, _, _) in members:
- attrib = Attribution(spectacle = show, participant = member)
- attrib.save()
- return render(request, "bda-attrib-extra.html", data)
- else:
- return render(request, "bda-attrib.html", data)
-
-class TokenForm(forms.Form):
- token = forms.CharField(widget = forms.widgets.Textarea())
-
-@login_required
-def tirage(request):
- if request.POST:
- form = TokenForm(request.POST)
- if form.is_valid():
- return do_tirage(request)
- else:
- form = TokenForm()
- return render(request, "bda-token.html", {"form": form})
-
-class SpectacleModelChoiceField(forms.ModelChoiceField):
- def label_from_instance(self, obj):
- return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price)
-
-class ResellForm(forms.Form):
- count = forms.ChoiceField(choices = (("1","1"),("2","2"),))
- spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none())
-
- def __init__(self, participant, *args, **kwargs):
- super(ResellForm, self).__init__(*args, **kwargs)
- self.fields['spectacle'].queryset = participant.attributions.all().distinct()
-
-def do_resell(request, form):
- spectacle = form.cleaned_data["spectacle"]
- count = form.cleaned_data["count"]
- places = "2 places" if count == "2" else "une place"
- mail = u"""Bonjour,
-
-Je souhaite revendre %s pour %s le %s (%s) à %.02f€.
-Contactez moi par email si vous êtes intéressés !
-
-%s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), spectacle.location, spectacle.price, request.user.get_full_name(), request.user.email)
- send_mail("%s" % spectacle, mail,
- request.user.email, ["bda-revente@lists.ens.fr"],
- fail_silently = True)
- return render(request, "bda-success.html", {"show": spectacle, "places": places})
-
-@login_required
-def revente(request):
- participant, created = Participant.objects.get_or_create(user = request.user)
- if not participant.paid:
- return render(request, "bda-notpaid.html", {})
- if request.POST:
- form = ResellForm(participant, request.POST)
- if form.is_valid():
- return do_resell(request, form)
- else:
- form = ResellForm(participant)
- return render(request, "bda-revente.html", {"form": form})
-
-@buro_required
-def spectacle(request, spectacle_id):
- spectacle = get_object_or_404(Spectacle, id = spectacle_id)
- return render(request, "bda-emails.html", {"spectacle": spectacle})
-
-@buro_required
-def unpaid(request):
- return render(request, "bda-unpaid.html", {"unpaid": Participant.objects.filter(paid = False).all()})