From c7a3656dedfe29e3ee2624261d01ee898594f661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sat, 9 Jul 2016 20:19:37 +0100 Subject: [PATCH] =?UTF-8?q?PEP8:=20fixed=20'=20=3D=20'=20=E2=86=92=20'=3D'?= =?UTF-8?q?=20on=20parameters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'unexpected spaces around keyword / parameter equals' --- bda/admin.py | 16 +- bda/algorithm.py | 17 +- bda/forms.py | 6 +- bda/models.py | 29 ++-- bda/urls.py | 6 +- bda/views.py | 65 +++++--- cof/urls.py | 16 +- gestioncof/admin.py | 34 +++- gestioncof/autocomplete.py | 21 +-- gestioncof/csv_views.py | 4 +- gestioncof/decorators.py | 4 +- gestioncof/forms.py | 131 ++++++++-------- gestioncof/models.py | 145 +++++++++-------- gestioncof/petits_cours_views.py | 88 ++++++----- gestioncof/shared.py | 29 ++-- gestioncof/views.py | 260 +++++++++++++++++-------------- sync_clipper.py | 2 +- tirage_bda.py | 2 +- 18 files changed, 496 insertions(+), 379 deletions(-) diff --git a/bda/admin.py b/bda/admin.py index 604ac883..a86a9766 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -19,23 +19,25 @@ class AttributionInline(admin.TabularInline): class ParticipantAdmin(admin.ModelAdmin): inlines = [AttributionInline] def get_queryset(self, request): - return Participant.objects.annotate(nb_places = Count('attributions'), - total = Sum('attributions__price')) + 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 €" + 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", "tirage") list_filter = ("paid", "tirage") search_fields = ('user__username', 'user__first_name', 'user__last_name') - actions = ['send_attribs',] + actions = ['send_attribs', ] actions_on_bottom = True list_per_page = 400 readonly_fields = ("total",) @@ -97,7 +99,7 @@ Le Bureau des Arts mail = mail % (name, attribs_text, deadline.strftime('%d %b %Y')) send_mail ("Résultats du tirage au sort", mail, "bda@ens.fr", [member.user.email], - fail_silently = True) + fail_silently=True) count = len(queryset.all()) if count == 1: message_bit = u"1 membre a" @@ -110,7 +112,7 @@ Le Bureau des Arts class AttributionAdminForm(forms.ModelForm): def clean(self): - cleaned_data=super(AttributionAdminForm, self).clean() + cleaned_data = super(AttributionAdminForm, self).clean() participant = cleaned_data.get("participant") spectacle = cleaned_data.get("spectacle") if participant and spectacle: diff --git a/bda/algorithm.py b/bda/algorithm.py index 77770377..21825369 100644 --- a/bda/algorithm.py +++ b/bda/algorithm.py @@ -39,8 +39,10 @@ class Algorithm(object): 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 + 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] @@ -49,7 +51,7 @@ class Algorithm(object): for member in members: self.origranks[member] = dict(self.ranks[member]) - def IncrementRanks(self, member, currank, increment = 1): + def IncrementRanks(self, member, currank, increment=1): for show in self.ranks[member]: if self.ranks[member][show] > currank: self.ranks[member][show] -= increment @@ -63,7 +65,7 @@ class Algorithm(object): def __call__(self, seed): random.seed(seed) results = [] - shows = sorted(self.shows, key = lambda x: x.nrequests / x.slots, reverse = True) + shows = sorted(self.shows, key=lambda x: 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)]) @@ -78,7 +80,7 @@ class Algorithm(object): group = list(groups[i]) random.shuffle(group) for member in group: - if self.choices[member][show].double: # double + if self.choices[member][show].double: # double if len(winners) + 1 < show.slots: self.appendResult(winners, member, show) self.appendResult(winners, member, show) @@ -89,12 +91,11 @@ class Algorithm(object): self.appendResult(losers, member, show) self.appendResult(losers, member, show) self.IncrementRanks(member, i, 2) - else: # simple + 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)) + results.append((show, winners, losers)) return results - diff --git a/bda/forms.py b/bda/forms.py index acc2d4b5..cfc48266 100644 --- a/bda/forms.py +++ b/bda/forms.py @@ -9,7 +9,8 @@ class BaseBdaFormSet(BaseInlineFormSet): """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 + # 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()): @@ -32,10 +33,9 @@ class SpectacleModelChoiceField(forms.ModelChoiceField): obj.location, obj.price) class ResellForm(forms.Form): - count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) + 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() - diff --git a/bda/models.py b/bda/models.py index 16ea4818..1f160bbe 100644 --- a/bda/models.py +++ b/bda/models.py @@ -18,12 +18,12 @@ class Tirage(models.Model): def __unicode__(self): return u"%s - %s" % (self.title, self.date_no_seconds()) - + class Salle(models.Model): - name = models.CharField("Nom", max_length = 300) + name = models.CharField("Nom", max_length=300) address = models.TextField("Adresse") - def __unicode__ (self): + def __unicode__(self): return self.name class Spectacle(models.Model): @@ -39,9 +39,9 @@ class Spectacle(models.Model): class Meta: verbose_name = "Spectacle" - ordering = ("priority", "date","title",) + ordering = ("priority", "date", "title",) - def __repr__ (self): + def __repr__(self): return u"[%s]" % self.__unicode__() def timestamp(self): @@ -50,15 +50,15 @@ class Spectacle(models.Model): def date_no_seconds(self): return self.date.strftime('%d %b %Y %H:%M') - def __unicode__ (self): + 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"), + ("cash", u"Cash"), + ("cb", "CB"), + ("cheque", u"Chèque"), + ("autre", u"Autre"), ) class Participant(models.Model): @@ -69,12 +69,12 @@ class Participant(models.Model): attributions = models.ManyToManyField(Spectacle, through="Attribution", related_name="attributed_to") - paid = models.BooleanField (u"A payé", default=False) + paid = models.BooleanField(u"A payé", default=False) paymenttype = models.CharField(u"Moyen de paiement", max_length=6, choices=PAYMENT_TYPES, blank=True) tirage = models.ForeignKey(Tirage) - - def __unicode__ (self): + + def __unicode__(self): return u"%s" % (self.user) DOUBLE_CHOICES = ( @@ -109,6 +109,5 @@ class Attribution(models.Model): spectacle = models.ForeignKey(Spectacle, related_name="attribues") given = models.BooleanField(u"Donnée", default=False) - def __unicode__ (self): + def __unicode__(self): return u"%s -- %s" % (self.participant, self.spectacle) - diff --git a/bda/urls.py b/bda/urls.py index d3f4fe2f..f8e385b8 100644 --- a/bda/urls.py +++ b/bda/urls.py @@ -21,14 +21,14 @@ urlpatterns = patterns('', name='bda-etat-places'), url(r'tirage/(?P\d+)$', 'bda.views.tirage'), url(r'spectacles/(?P\d+)$', - SpectacleListView.as_view() , - name ="bda-liste-spectacles"), + SpectacleListView.as_view(), + name="bda-liste-spectacles"), url(r'spectacles/(?P\d+)/(?P\d+)$', "bda.views.spectacle", name="bda-spectacle"), url(r'spectacles-ics/(?P\d+)$', 'bda.views.liste_spectacles_ics', - name ="bda-liste-spectacles-ics"), + name="bda-liste-spectacles-ics"), url(r'spectacles/unpaid/(?P\d+)$', "bda.views.unpaid", name="bda-unpaid"), diff --git a/bda/views.py b/bda/views.py index 1eab066d..3167ec16 100644 --- a/bda/views.py +++ b/bda/views.py @@ -10,7 +10,7 @@ from django.core import serializers from django.forms.models import inlineformset_factory import hashlib -from django.core.mail import send_mail +from django.core.mail import send_mail from django.utils import timezone from django.views.generic.list import ListView @@ -23,6 +23,7 @@ from bda.algorithm import Algorithm from bda.forms import BaseBdaFormSet, TokenForm, ResellForm + @cof_required def etat_places(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) @@ -30,13 +31,13 @@ def etat_places(request, tirage_id): .filter(spectacle__tirage=tirage) \ .filter(double_choice="1") \ .all() \ - .values('spectacle','spectacle__title') \ + .values('spectacle', 'spectacle__title') \ .annotate(total=models.Count('spectacle')) spectacles2 = ChoixSpectacle.objects \ .filter(spectacle__tirage=tirage) \ .exclude(double_choice="1") \ .all() \ - .values('spectacle','spectacle__title') \ + .values('spectacle', 'spectacle__title') \ .annotate(total=models.Count('spectacle')) spectacles = tirage.spectacle_set.all() spectacles_dict = {} @@ -50,22 +51,24 @@ def etat_places(request, tirage_id): spectacles_dict[spectacle["spectacle"]].ratio = \ spectacles_dict[spectacle["spectacle"]].total / \ spectacles_dict[spectacle["spectacle"]].slots - total += spectacle["total"] + total += spectacle["total"] for spectacle in spectacles2: spectacles_dict[spectacle["spectacle"]].total += 2*spectacle["total"] spectacles_dict[spectacle["spectacle"]].ratio = \ spectacles_dict[spectacle["spectacle"]].total / \ spectacles_dict[spectacle["spectacle"]].slots - total += spectacle["total"] + total += spectacle["total"] return render(request, "etat-places.html", {"spectacles": spectacles, "total": total, 'tirage': tirage}) + def _hash_queryset(queryset): data = serializers.serialize("json", queryset) hasher = hashlib.sha256() hasher.update(data) return hasher.hexdigest() + @cof_required def places(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) @@ -99,7 +102,8 @@ def places(request, tirage_id): "total": total, "warning": warning}) -@cof_required + +@cof_required def places_ics(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) participant, created = Participant.objects.get_or_create( @@ -114,7 +118,8 @@ def places_ics(request, tirage_id): places_dict[place.spectacle].double = True else: place.double = False - place.spectacle.dtend = place.spectacle.date + timedelta(seconds=7200) + place.spectacle.dtend = place.spectacle.date + \ + timedelta(seconds=7200) places_dict[place.spectacle] = place spectacles.append(place.spectacle) filtered_places.append(place) @@ -122,6 +127,7 @@ def places_ics(request, tirage_id): {"participant": participant, "places": filtered_places}, content_type="text/calendar") + @cof_required def inscription(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) @@ -130,7 +136,7 @@ def inscription(request, tirage_id): tirage.ouverture.strftime('%d %b %Y à %H:%M')) return render(request, 'resume_inscription.html', { "error_title": "Le tirage n'est pas encore ouvert !", - "error_description": error_desc }) + "error_description": error_desc}) if timezone.now() > tirage.fermeture: participant, created = Participant.objects.get_or_create( user=request.user, tirage=tirage) @@ -146,7 +152,7 @@ def inscription(request, tirage_id): BdaFormSet = inlineformset_factory( Participant, ChoixSpectacle, - fields=("spectacle","double_choice","priority"), + fields=("spectacle", "double_choice", "priority"), formset=BaseBdaFormSet, formfield_callback=formfield_callback) participant, created = Participant.objects.get_or_create( @@ -170,7 +176,8 @@ def inscription(request, tirage_id): total_price = 0 for choice in participant.choixspectacle_set.all(): total_price += choice.spectacle.price - if choice.double: total_price += choice.spectacle.price + if choice.double: + total_price += choice.spectacle.price return render(request, "inscription-bda.html", { "formset": formset, "success": success, @@ -179,6 +186,7 @@ def inscription(request, tirage_id): 'tirage': tirage, "stateerror": stateerror}) + def do_tirage(request, tirage_id): tirage_elt = get_object_or_404(Tirage, id=tirage_id) form = TokenForm(request.POST) @@ -221,8 +229,9 @@ def do_tirage(request, tirage_id): 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 + # Participant objects are not shared accross spectacle results, + # so assign a single object for each Participant id + members_uniq = {} for (show, members, _) in results: for (member, _, _, _) in members: if member.id not in members_uniq: @@ -249,6 +258,7 @@ def do_tirage(request, tirage_id): else: return render(request, "bda-attrib.html", data) + @buro_required def tirage(request, tirage_id): if request.POST: @@ -259,6 +269,7 @@ def tirage(request, tirage_id): form = TokenForm() return render(request, "bda-token.html", {"form": form}) + def do_resell(request, form): spectacle = form.cleaned_data["spectacle"] count = form.cleaned_data["count"] @@ -273,9 +284,10 @@ Contactez moi par email si vous êtes intéressé·e·s ! request.user.email) send_mail("%s" % spectacle, mail, request.user.email, ["bda-revente@lists.ens.fr"], - fail_silently = False) + fail_silently=False) return render(request, "bda-success.html", {"show": spectacle, "places": places}) + @login_required def revente(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) @@ -291,6 +303,7 @@ def revente(request, tirage_id): form = ResellForm(participant) return render(request, "bda-revente.html", {"form": form, 'tirage': tirage}) + @buro_required def spectacle(request, tirage_id, spectacle_id): tirage = get_object_or_404(Tirage, id=tirage_id) @@ -299,37 +312,41 @@ def spectacle(request, tirage_id, spectacle_id): participants = {} for attrib in attributions: participant = attrib.participant - participant_info = {'lastname': participant.user.last_name, - 'name': participant.user.get_full_name, - 'username': participant.user.username, - 'email': participant.user.email, - 'given': int(attrib.given), - 'paid': participant.paid, + participant_info = {'lastname': participant.user.last_name, + 'name': participant.user.get_full_name, + 'username': participant.user.username, + 'email': participant.user.email, + 'given': int(attrib.given), + 'paid': participant.paid, 'nb_places': 1} if participant.id in participants: - participants[participant.id]['nb_places'] += 1 + participants[participant.id]['nb_places'] += 1 participants[participant.id]['given'] += attrib.given else: participants[participant.id] = participant_info - participants_info = sorted(participants.values(), + participants_info = sorted(participants.values(), key=lambda part: part['lastname']) - return render(request, "bda-participants.html", + return render(request, "bda-participants.html", {"spectacle": spectacle, "participants": participants_info}) + class SpectacleListView(ListView): model = Spectacle template_name = 'spectacle_list.html' + def get_queryset(self): self.tirage = get_object_or_404(Tirage, id=self.kwargs['tirage_id']) categories = self.tirage.spectacle_set.all() return categories + def get_context_data(self, **kwargs): context = super(SpectacleListView, self).get_context_data(**kwargs) context['tirage_id'] = self.tirage.id context['tirage_name'] = self.tirage.title return context + @buro_required def unpaid(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) @@ -338,7 +355,8 @@ def unpaid(request, tirage_id): .filter(paid=False, nb_attributions__gt=0).all() return render(request, "bda-unpaid.html", {"unpaid": unpaid}) -@buro_required + +@buro_required def liste_spectacles_ics(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) spectacles = tirage.spectacle_set.order_by("date").all() @@ -347,4 +365,3 @@ def liste_spectacles_ics(request, tirage_id): return render(request, "liste_spectacles.ics", {"spectacles": spectacles, "tirage": tirage}, content_type="text/calendar") - diff --git a/cof/urls.py b/cof/urls.py index f0b3c207..817db2dc 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -1,22 +1,23 @@ from django.conf.urls import patterns, include, url import autocomplete_light -autocomplete_light.autodiscover() from django.contrib import admin -admin.autodiscover() from django.views.generic.base import TemplateView from gestioncof.urls import export_patterns, petitcours_patterns, \ surveys_patterns, events_patterns +autocomplete_light.autodiscover() +admin.autodiscover() + urlpatterns = patterns('', # Page d'accueil - url(r'^$', 'gestioncof.views.home', name = 'home'), + url(r'^$', 'gestioncof.views.home', name='home'), # Le BdA url(r'^bda/', include('bda.urls')), - # Les exports + # Les exports url(r'^export/', include(export_patterns)), # Les petits cours url(r'^petitcours/', include(petitcours_patterns)), @@ -24,7 +25,7 @@ urlpatterns = patterns('', url(r'^survey/', include(surveys_patterns)), # Evenements url(r'^event/', include(events_patterns)), - # Authentification + # Authentification url(r'^cof/denied$', TemplateView.as_view(template_name='cof-denied.html'), name="cof-denied"), url(r'^cas/login$', 'django_cas_ng.views.login', name="cas_login_view"), @@ -34,7 +35,7 @@ urlpatterns = patterns('', {'next_page': 'home'}), url(r'^login$', 'gestioncof.views.login'), url(r'^logout$', 'gestioncof.views.logout'), - # Infos persos + # Infos persos url(r'^profile$', 'gestioncof.views.profile'), url(r'^outsider/password-change$', 'django.contrib.auth.views.password_change'), @@ -57,7 +58,7 @@ urlpatterns = patterns('', url(r'^admin/doc/', include('django.contrib.admindocs.urls')), url(r'^admin/(?P[\d\w]+)/(?P[\d\w]+)/csv/', 'gestioncof.csv_views.admin_list_export', - {'fields': ['username',]}), + {'fields': ['username', ]}), url(r'^admin/', include(admin.site.urls)), url(r'^grappelli/', include('grappelli.urls')), # Liens utiles du COF et du BdA @@ -67,4 +68,3 @@ urlpatterns = patterns('', url(r'^utile_cof/diff_cof$', 'gestioncof.views.liste_diffcof'), url(r'^utile_bda/bda_revente$', 'gestioncof.views.liste_bdarevente'), ) - diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 09ac61fd..2c149ed0 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -9,16 +9,18 @@ from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ + def add_link_field(target_model='', field='', link_text=unicode, desc_text=unicode): def add_link(cls): reverse_name = target_model or cls.model.__name__.lower() + def link(self, instance): app_name = instance._meta.app_label reverse_path = "admin:%s_%s_change" % (app_name, reverse_name) link_obj = getattr(instance, field, None) or instance if not link_obj.id: return "" - url = reverse(reverse_path, args = (link_obj.id,)) + url = reverse(reverse_path, args=(link_obj.id,)) return mark_safe("%s" % (url, link_text(link_obj))) link.allow_tags = True link.short_description = desc_text(reverse_name + ' link') @@ -27,58 +29,69 @@ def add_link_field(target_model='', field='', link_text=unicode, desc_text=unico return cls return add_link + class SurveyQuestionAnswerInline(admin.TabularInline): model = SurveyQuestionAnswer + @add_link_field(desc_text=lambda x: "Réponses", - link_text=lambda x: "Éditer les réponses") + link_text=lambda x: "Éditer les réponses") class SurveyQuestionInline(admin.TabularInline): model = SurveyQuestion + class SurveyQuestionAdmin(admin.ModelAdmin): inlines = [ SurveyQuestionAnswerInline, ] + class SurveyAdmin(admin.ModelAdmin): inlines = [ SurveyQuestionInline, ] + class EventOptionChoiceInline(admin.TabularInline): model = EventOptionChoice + @add_link_field(desc_text=lambda x: "Choix", - link_text=lambda x: "Éditer les choix") + link_text=lambda x: "Éditer les choix") class EventOptionInline(admin.TabularInline): model = EventOption + class EventCommentFieldInline(admin.TabularInline): model = EventCommentField + class EventOptionAdmin(admin.ModelAdmin): inlines = [ EventOptionChoiceInline, ] + class EventAdmin(admin.ModelAdmin): inlines = [ EventOptionInline, EventCommentFieldInline, ] + class CofProfileInline(admin.StackedInline): model = CofProfile inline_classes = ("collapse open",) + class FkeyLookup(object): def __init__(self, fkeydecl, short_description=None, admin_order_field=None): self.fk, fkattrs = fkeydecl.split('__', 1) self.fkattrs = fkattrs.split('__') - + self.short_description = short_description or self.fkattrs[-1] self.admin_order_field = admin_order_field or fkeydecl - + def __get__(self, obj, klass): if obj is None: return self # hack required to make Django validate (if obj is @@ -89,6 +102,7 @@ class FkeyLookup(object): item = getattr(item, attr) return item + def ProfileInfo(field, short_description, boolean=False): def getter(self): try: @@ -108,6 +122,7 @@ User.profile_mailing_cof = ProfileInfo("mailing_cof", "ML COF", True) User.profile_mailing_bda = ProfileInfo("mailing_bda", "ML BDA", True) User.profile_mailing_bda_revente = ProfileInfo("mailing_bda_revente", "ML BDA-R", True) + class UserProfileAdmin(UserAdmin): def is_buro(self, obj): try: @@ -137,12 +152,15 @@ class UserProfileAdmin(UserAdmin): ] import autocomplete_light + def user_unicode(self): if self.first_name and self.last_name: return u"%s %s (%s)" % (self.first_name, self.last_name, self.username) else: return self.username User.__unicode__ = user_unicode + + class EventRegistrationAdmin(admin.ModelAdmin): form = autocomplete_light.modelform_factory(EventRegistration, exclude=[]) list_display = ('__unicode__','event','user','paid') @@ -150,15 +168,18 @@ class EventRegistrationAdmin(admin.ModelAdmin): search_fields = ('user__username', 'user__first_name', 'user__last_name', 'user__email', 'event__title') + class PetitCoursAbilityAdmin(admin.ModelAdmin): list_display = ('user','matiere','niveau','agrege') search_fields = ('user__username', 'user__first_name', 'user__last_name', 'user__email', 'matiere__name', 'niveau') list_filter = ('matiere','niveau','agrege') + class PetitCoursAttributionAdmin(admin.ModelAdmin): list_display = ('user','demande','matiere','rank',) + class PetitCoursAttributionCounterAdmin(admin.ModelAdmin): list_display = ('user','matiere','count',) list_filter = ('matiere',) @@ -166,11 +187,12 @@ class PetitCoursAttributionCounterAdmin(admin.ModelAdmin): 'user__email', 'matiere__name') actions = ['reset',] actions_on_bottom = True - + def reset(self, request, queryset): queryset.update(count=0) reset.short_description = u"Remise à zéro du compteur" + class PetitCoursDemandeAdmin(admin.ModelAdmin): list_display = ('name','email','agrege_requis','niveau','created', 'traitee','processed') diff --git a/gestioncof/autocomplete.py b/gestioncof/autocomplete.py index c431a5cc..e381bed4 100644 --- a/gestioncof/autocomplete.py +++ b/gestioncof/autocomplete.py @@ -5,6 +5,7 @@ from django.db.models import Q from django.contrib.auth.models import User from gestioncof.models import CofProfile, Clipper + def autocomplete(request): if "q" not in request.GET: raise Http404 @@ -22,25 +23,25 @@ def autocomplete(request): for bit in bits: queries['members'] = queries['members'].filter( Q(user__first_name__icontains=bit) - |Q(user__last_name__icontains=bit) - |Q(user__username__icontains=bit) - |Q(login_clipper__icontains=bit)) + | Q(user__last_name__icontains=bit) + | Q(user__username__icontains=bit) + | Q(login_clipper__icontains=bit)) queries['users'] = queries['users'].filter( Q(first_name__icontains=bit) - |Q(last_name__icontains=bit) - |Q(username__icontains=bit)) + | Q(last_name__icontains=bit) + | Q(username__icontains=bit)) queries['clippers'] = queries['clippers'].filter( Q(fullname__icontains=bit) - |Q(username__icontains=bit)) + | Q(username__icontains=bit)) queries['members'] = queries['members'].distinct() queries['users'] = queries['users'].distinct() - usernames = list(queries['members'].values_list('login_clipper', flat = 'True')) \ - + list(queries['users'].values_list('profile__login_clipper', flat = 'True')) - queries['clippers'] = queries['clippers'].exclude(username__in = usernames).distinct() + usernames = list(queries['members'].values_list('login_clipper', flat='True')) \ + + list(queries['users'].values_list('profile__login_clipper', flat='True')) + queries['clippers'] = queries['clippers'].exclude(username__in=usernames).distinct() # add clippers data.update(queries) - + options = 0 for query in queries.values(): options += len(query) diff --git a/gestioncof/csv_views.py b/gestioncof/csv_views.py index f921953f..43c028e0 100644 --- a/gestioncof/csv_views.py +++ b/gestioncof/csv_views.py @@ -3,6 +3,7 @@ from django.http import HttpResponse, HttpResponseForbidden from django.template.defaultfilters import slugify from django.apps import apps + def export(qs, fields=None): model = qs.model response = HttpResponse(content_type='text/csv') @@ -29,6 +30,7 @@ def export(qs, fields=None): # Return CSV file to browser as download return response + def admin_list_export(request, model_name, app_label, queryset=None, fields=None, list_display=True): """ Put the following line in your urls.py BEFORE your admin include @@ -39,7 +41,7 @@ def admin_list_export(request, model_name, app_label, queryset=None, fields=None if not queryset: model = apps.get_model(app_label, model_name) queryset = model.objects.all() - queryset = queryset.filter(profile__is_cof = True) + queryset = queryset.filter(profile__is_cof=True) if not fields: if list_display and len(queryset.model._meta.admin.list_display) > 1: fields = queryset.model._meta.admin.list_display diff --git a/gestioncof/decorators.py b/gestioncof/decorators.py index 1a3d60c5..f442e68e 100644 --- a/gestioncof/decorators.py +++ b/gestioncof/decorators.py @@ -1,5 +1,6 @@ from django_cas_ng.decorators import user_passes_test + def is_cof(user): try: profile = user.profile @@ -8,7 +9,8 @@ def is_cof(user): return False cof_required = user_passes_test(lambda u: is_cof(u)) -cof_required_customdenied = user_passes_test(lambda u: is_cof(u), login_url = "cof-denied") +cof_required_customdenied = user_passes_test(lambda u: is_cof(u), login_url="cof-denied") + def is_buro(user): try: diff --git a/gestioncof/forms.py b/gestioncof/forms.py index a470face..cfe1aa62 100644 --- a/gestioncof/forms.py +++ b/gestioncof/forms.py @@ -10,6 +10,7 @@ from gestioncof.models import CofProfile, EventCommentValue from gestioncof.widgets import TriStateCheckbox from gestioncof.shared import lock_table, unlock_table + class EventForm(forms.Form): def __init__(self, *args, **kwargs): event = kwargs.pop("event") @@ -28,18 +29,18 @@ class EventForm(forms.Form): choices = [(choice.id, choice.value) for choice in option.choices.all()] if option.multi_choices: initial = [] if option.id not in all_choices else all_choices[option.id] - field = forms.MultipleChoiceField(label = option.name, - choices = choices, - widget = CheckboxSelectMultiple, - required = False, - initial = initial) + field = forms.MultipleChoiceField(label=option.name, + choices=choices, + widget=CheckboxSelectMultiple, + required=False, + initial=initial) else: initial = None if option.id not in all_choices else all_choices[option.id][0] - field = forms.ChoiceField(label = option.name, - choices = choices, - widget = RadioSelect, - required = False, - initial = initial) + field = forms.ChoiceField(label=option.name, + choices=choices, + widget=RadioSelect, + required=False, + initial=initial) field.option_id = option.id self.fields["option_%d" % option.id] = field @@ -48,6 +49,7 @@ class EventForm(forms.Form): if name.startswith('option_'): yield (self.fields[name].option_id, value) + class SurveyForm(forms.Form): def __init__(self, *args, **kwargs): survey = kwargs.pop("survey") @@ -64,18 +66,18 @@ class SurveyForm(forms.Form): choices = [(answer.id, answer.answer) for answer in question.answers.all()] if question.multi_answers: initial = [] if question.id not in answers else answers[question.id] - field = forms.MultipleChoiceField(label = question.question, - choices = choices, - widget = CheckboxSelectMultiple, - required = False, - initial = initial) + field = forms.MultipleChoiceField(label=question.question, + choices=choices, + widget=CheckboxSelectMultiple, + required=False, + initial=initial) else: initial = None if question.id not in answers else answers[question.id][0] - field = forms.ChoiceField(label = question.question, - choices = choices, - widget = RadioSelect, - required = False, - initial = initial) + field = forms.ChoiceField(label=question.question, + choices=choices, + widget=RadioSelect, + required=False, + initial=initial) field.question_id = question.id self.fields["question_%d" % question.id] = field @@ -83,7 +85,8 @@ class SurveyForm(forms.Form): for name, value in self.cleaned_data.items(): if name.startswith('question_'): yield (self.fields[name].question_id, value) - + + class SurveyStatusFilterForm(forms.Form): def __init__(self, *args, **kwargs): survey = kwargs.pop("survey") @@ -95,11 +98,11 @@ class SurveyStatusFilterForm(forms.Form): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" - field = forms.ChoiceField(label = "%s : %s" % (question.question, answer.answer), - choices = [("yes", "yes"),("no","no"),("none","none")], - widget = TriStateCheckbox, - required = False, - initial = initial) + field = forms.ChoiceField(label="%s : %s" % (question.question, answer.answer), + choices=[("yes", "yes"), ("no", "no"), ("none", "none")], + widget=TriStateCheckbox, + required=False, + initial=initial) field.question_id = question.id field.answer_id = answer.id self.fields[name] = field @@ -109,6 +112,7 @@ class SurveyStatusFilterForm(forms.Form): if name.startswith('question_'): yield (self.fields[name].question_id, self.fields[name].answer_id, value) + class EventStatusFilterForm(forms.Form): def __init__(self, *args, **kwargs): event = kwargs.pop("event") @@ -120,11 +124,11 @@ class EventStatusFilterForm(forms.Form): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" - field = forms.ChoiceField(label = "%s : %s" % (option.name, choice.value), - choices = [("yes", "yes"),("no","no"),("none","none")], - widget = TriStateCheckbox, - required = False, - initial = initial) + field = forms.ChoiceField(label="%s : %s" % (option.name, choice.value), + choices=[("yes", "yes"), ("no", "no"), ("none", "none")], + widget=TriStateCheckbox, + required=False, + initial=initial) field.option_id = option.id field.choice_id = choice.id self.fields[name] = field @@ -134,11 +138,11 @@ class EventStatusFilterForm(forms.Form): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" - field = forms.ChoiceField(label = "Événement payé", - choices = [("yes", "yes"),("no","no"),("none","none")], - widget = TriStateCheckbox, - required = False, - initial = initial) + field = forms.ChoiceField(label="Événement payé", + choices=[("yes", "yes"), ("no", "no"), ("none", "none")], + widget=TriStateCheckbox, + required=False, + initial=initial) self.fields[name] = field def filters(self): @@ -148,6 +152,7 @@ class EventStatusFilterForm(forms.Form): elif name == "event_has_paid": yield ("has_paid", None, value) + class UserProfileForm(forms.ModelForm): first_name = forms.CharField(label=_(u'Prénom'), max_length=30) last_name = forms.CharField(label=_(u'Nom'), max_length=30) @@ -174,7 +179,8 @@ class UserProfileForm(forms.ModelForm): class Meta: model = CofProfile - fields = ("phone", "mailing_cof", "mailing_bda", "mailing_bda_revente",) + fields = ("phone", "mailing_cof", "mailing_bda", "mailing_bda_revente", ) + class RegistrationUserForm(forms.ModelForm): def __init__(self, *args, **kw): @@ -185,6 +191,7 @@ class RegistrationUserForm(forms.ModelForm): model = User fields = ("username", "first_name", "last_name", "email") + class RegistrationProfileForm(forms.ModelForm): def __init__(self, *args, **kw): super(RegistrationProfileForm, self).__init__(*args, **kw) @@ -226,12 +233,13 @@ class RegistrationProfileForm(forms.ModelForm): model = CofProfile fields = ("login_clipper", "num", "phone", "occupation", "departement", "is_cof", "type_cotiz", "mailing_cof", "mailing_bda", "mailing_bda_revente", "comments") -STATUS_CHOICES = (('no','Non'), - ('wait','Oui mais attente paiement'), - ('paid','Oui payé'),) +STATUS_CHOICES = (('no', 'Non'), + ('wait', 'Oui mais attente paiement'), + ('paid', 'Oui payé'),) + class AdminEventForm(forms.Form): - status = forms.ChoiceField(label = "Inscription", choices = STATUS_CHOICES, widget = RadioSelect) + status = forms.ChoiceField(label="Inscription", choices=STATUS_CHOICES, widget=RadioSelect) def __init__(self, *args, **kwargs): event = kwargs.pop("event") @@ -239,12 +247,12 @@ class AdminEventForm(forms.Form): registration = kwargs.pop("current_registration", None) current_choices = registration.options.all() if registration is not None else [] paid = kwargs.pop("paid", None) - if paid == True: - kwargs["initial"] = {"status":"paid"} - elif paid == False: - kwargs["initial"] = {"status":"wait"} + if paid is True: + kwargs["initial"] = {"status": "paid"} + elif paid is False: + kwargs["initial"] = {"status": "wait"} else: - kwargs["initial"] = {"status":"no"} + kwargs["initial"] = {"status": "no"} super(AdminEventForm, self).__init__(*args, **kwargs) choices = {} for choice in current_choices: @@ -257,32 +265,32 @@ class AdminEventForm(forms.Form): choices = [(choice.id, choice.value) for choice in option.choices.all()] if option.multi_choices: initial = [] if option.id not in all_choices else all_choices[option.id] - field = forms.MultipleChoiceField(label = option.name, - choices = choices, - widget = CheckboxSelectMultiple, - required = False, - initial = initial) + field = forms.MultipleChoiceField(label=option.name, + choices=choices, + widget=CheckboxSelectMultiple, + required=False, + initial=initial) else: initial = None if option.id not in all_choices else all_choices[option.id][0] - field = forms.ChoiceField(label = option.name, - choices = choices, - widget = RadioSelect, - required = False, - initial = initial) + field = forms.ChoiceField(label=option.name, + choices=choices, + widget=RadioSelect, + required=False, + initial=initial) field.option_id = option.id self.fields["option_%d" % option.id] = field for commentfield in event.commentfields.all(): initial = commentfield.default if registration is not None: try: - initial = registration.comments.get(commentfield = commentfield).content + initial = registration.comments.get(commentfield=commentfield).content except EventCommentValue.DoesNotExist: pass widget = forms.Textarea if commentfield.fieldtype == "text" else forms.TextInput - field = forms.CharField(label = commentfield.name, - widget = widget, - required = False, - initial = initial) + field = forms.CharField(label=commentfield.name, + widget=widget, + required=False, + initial=initial) field.comment_id = commentfield.id self.fields["comment_%d" % commentfield.id] = field @@ -295,4 +303,3 @@ class AdminEventForm(forms.Form): for name, value in self.cleaned_data.items(): if name.startswith('comment_'): yield (self.fields[name].comment_id, value) - diff --git a/gestioncof/models.py b/gestioncof/models.py index 2086557e..bac5ad62 100644 --- a/gestioncof/models.py +++ b/gestioncof/models.py @@ -29,32 +29,33 @@ TYPE_COMMENT_FIELD = ( ('char', _(u"Texte court")), ) -def choices_length (choices): - return reduce (lambda m, choice: max (m, len (choice[0])), choices, 0) + +def choices_length(choices): + return reduce(lambda m, choice: max(m, len(choice[0])), choices, 0) + class CofProfile(models.Model): - user = models.OneToOneField(User, related_name = "profile") - login_clipper = models.CharField("Login clipper", max_length = 8, blank = True) - is_cof = models.BooleanField("Membre du COF", default = False) - num = models.IntegerField ("Numéro d'adhérent", blank = True, default = 0) - phone = models.CharField("Téléphone", max_length = 20, blank = True) - occupation = models.CharField (_(u"Occupation"), - default = "1A", - choices = OCCUPATION_CHOICES, - max_length = choices_length (OCCUPATION_CHOICES)) - departement = models.CharField (_(u"Département"), max_length = 50, blank = True) - type_cotiz = models.CharField (_(u"Type de cotisation"), - default = "normalien", - choices = TYPE_COTIZ_CHOICES, - max_length = choices_length (TYPE_COTIZ_CHOICES)) - mailing_cof = models.BooleanField("Recevoir les mails COF", default = False) - mailing_bda = models.BooleanField("Recevoir les mails BdA", default = False) - mailing_bda_revente = models.BooleanField("Recevoir les mails de revente de places BdA", default = False) - comments = models.TextField("Commentaires visibles uniquement par le Buro", blank = True) - is_buro = models.BooleanField("Membre du Burô", default = False) - petits_cours_accept = models.BooleanField("Recevoir des petits cours", default = False) + user = models.OneToOneField(User, related_name="profile") + login_clipper = models.CharField("Login clipper", max_length=8, blank=True) + is_cof = models.BooleanField("Membre du COF", default=False) + num = models.IntegerField("Numéro d'adhérent", blank=True, default=0) + phone = models.CharField("Téléphone", max_length=20, blank=True) + occupation = models.CharField(_(u"Occupation"), + default="1A", + choices=OCCUPATION_CHOICES, + max_length=choices_length(OCCUPATION_CHOICES)) + departement = models.CharField(_(u"Département"), max_length=50, blank=True) + type_cotiz = models.CharField(_(u"Type de cotisation"), + default="normalien", + max_length=choices_length(TYPE_COTIZ_CHOICES)) + mailing_cof = models.BooleanField("Recevoir les mails COF", default=False) + mailing_bda = models.BooleanField("Recevoir les mails BdA", default=False) + mailing_bda_revente = models.BooleanField("Recevoir les mails de revente de places BdA", default=False) + comments = models.TextField("Commentaires visibles uniquement par le Buro", blank=True) + is_buro = models.BooleanField("Membre du Burô", default=False) + petits_cours_accept = models.BooleanField("Recevoir des petits cours", default=False) petits_cours_remarques = models.TextField(_(u"Remarques et précisions pour les petits cours"), - blank = True, default = "") + blank=True, default="") class Meta: verbose_name = "Profil COF" @@ -63,22 +64,25 @@ class CofProfile(models.Model): def __unicode__(self): return unicode(self.user.username) + def create_user_profile(sender, instance, created, **kwargs): if created: - CofProfile.objects.get_or_create(user = instance) -post_save.connect(create_user_profile, sender = User) + CofProfile.objects.get_or_create(user=instance) +post_save.connect(create_user_profile, sender=User) + class Club(models.Model): - name = models.CharField("Nom", max_length = 200) + name = models.CharField("Nom", max_length=200) description = models.TextField("Description") - respos = models.ManyToManyField(User, related_name = "clubs_geres") - membres = models.ManyToManyField(User, related_name = "clubs") + respos = models.ManyToManyField(User, related_name="clubs_geres") + membres = models.ManyToManyField(User, related_name="clubs") + class CustomMail(models.Model): - shortname = models.SlugField(max_length = 50, blank = False) - title = models.CharField("Titre", max_length = 200, blank = False) - content = models.TextField("Contenu", blank = False) - comments = models.TextField("Informations contextuelles sur le mail", blank = True) + shortname = models.SlugField(max_length=50, blank=False) + title = models.CharField("Titre", max_length=200, blank=False) + content = models.TextField("Contenu", blank=False) + comments = models.TextField("Informations contextuelles sur le mail", blank=True) class Meta: verbose_name = "Mails personnalisables" @@ -86,14 +90,15 @@ class CustomMail(models.Model): def __unicode__(self): return u"%s: %s" % (self.shortname, self.title) + class Event(models.Model): - title = models.CharField("Titre", max_length = 200) - location = models.CharField("Lieu", max_length = 200) - start_date = models.DateField("Date de début", blank = True, null = True) - end_date = models.DateField("Date de fin", blank = True, null = True) - description = models.TextField("Description", blank = True) - registration_open = models.BooleanField("Inscriptions ouvertes", default = True) - old = models.BooleanField("Archiver (événement fini)", default = False) + title = models.CharField("Titre", max_length=200) + location = models.CharField("Lieu", max_length=200) + start_date = models.DateField("Date de début", blank=True, null=True) + end_date = models.DateField("Date de fin", blank=True, null=True) + description = models.TextField("Description", blank=True) + registration_open = models.BooleanField("Inscriptions ouvertes", default=True) + old = models.BooleanField("Archiver (événement fini)", default=False) class Meta: verbose_name = "Événement" @@ -101,11 +106,12 @@ class Event(models.Model): def __unicode__(self): return unicode(self.title) + class EventCommentField(models.Model): - event = models.ForeignKey(Event, related_name = "commentfields") - name = models.CharField("Champ", max_length = 200) - fieldtype = models.CharField("Type", max_length = 10, choices = TYPE_COMMENT_FIELD, default = "text") - default = models.TextField("Valeur par défaut", blank = True) + event = models.ForeignKey(Event, related_name="commentfields") + name = models.CharField("Champ", max_length=200) + fieldtype = models.CharField("Type", max_length=10, choices=TYPE_COMMENT_FIELD, default="text") + default = models.TextField("Valeur par défaut", blank=True) class Meta: verbose_name = "Champ" @@ -113,15 +119,17 @@ class EventCommentField(models.Model): def __unicode__(self): return unicode(self.name) + class EventCommentValue(models.Model): - commentfield = models.ForeignKey(EventCommentField, related_name = "values") - registration = models.ForeignKey("EventRegistration", related_name = "comments") - content = models.TextField("Contenu", blank = True, null = True) + commentfield = models.ForeignKey(EventCommentField, related_name="values") + registration = models.ForeignKey("EventRegistration", related_name="comments") + content = models.TextField("Contenu", blank=True, null=True) + class EventOption(models.Model): - event = models.ForeignKey(Event, related_name = "options") - name = models.CharField("Option", max_length = 200) - multi_choices = models.BooleanField("Choix multiples", default = False) + event = models.ForeignKey(Event, related_name="options") + name = models.CharField("Option", max_length=200) + multi_choices = models.BooleanField("Choix multiples", default=False) class Meta: verbose_name = "Option" @@ -129,9 +137,10 @@ class EventOption(models.Model): def __unicode__(self): return unicode(self.name) + class EventOptionChoice(models.Model): - event_option = models.ForeignKey(EventOption, related_name = "choices") - value = models.CharField("Valeur", max_length = 200) + event_option = models.ForeignKey(EventOption, related_name="choices") + value = models.CharField("Valeur", max_length=200) class Meta: verbose_name = "Choix" @@ -139,12 +148,13 @@ class EventOptionChoice(models.Model): def __unicode__(self): return unicode(self.value) + class EventRegistration(models.Model): user = models.ForeignKey(User) event = models.ForeignKey(Event) options = models.ManyToManyField(EventOptionChoice) - filledcomments = models.ManyToManyField(EventCommentField, through = EventCommentValue) - paid = models.BooleanField("A payé", default = False) + filledcomments = models.ManyToManyField(EventCommentField, through=EventCommentValue) + paid = models.BooleanField("A payé", default=False) class Meta: verbose_name = "Inscription" @@ -153,11 +163,12 @@ class EventRegistration(models.Model): def __unicode__(self): return u"Inscription de %s à %s" % (unicode(self.user), unicode(self.event.title)) + class Survey(models.Model): - title = models.CharField("Titre", max_length = 200) - details = models.TextField("Détails", blank = True) - survey_open = models.BooleanField("Sondage ouvert", default = True) - old = models.BooleanField("Archiver (sondage fini)", default = False) + title = models.CharField("Titre", max_length=200) + details = models.TextField("Détails", blank=True) + survey_open = models.BooleanField("Sondage ouvert", default=True) + old = models.BooleanField("Archiver (sondage fini)", default=False) class Meta: verbose_name = "Sondage" @@ -165,10 +176,11 @@ class Survey(models.Model): def __unicode__(self): return unicode(self.title) + class SurveyQuestion(models.Model): - survey = models.ForeignKey(Survey, related_name = "questions") - question = models.CharField("Question", max_length = 200) - multi_answers = models.BooleanField("Choix multiples", default = False) + survey = models.ForeignKey(Survey, related_name="questions") + question = models.CharField("Question", max_length=200) + multi_answers = models.BooleanField("Choix multiples", default=False) class Meta: verbose_name = "Question" @@ -176,9 +188,10 @@ class SurveyQuestion(models.Model): def __unicode__(self): return unicode(self.question) + class SurveyQuestionAnswer(models.Model): - survey_question = models.ForeignKey(SurveyQuestion, related_name = "answers") - answer = models.CharField("Réponse", max_length = 200) + survey_question = models.ForeignKey(SurveyQuestion, related_name="answers") + answer = models.CharField("Réponse", max_length=200) class Meta: verbose_name = "Réponse" @@ -186,15 +199,17 @@ class SurveyQuestionAnswer(models.Model): def __unicode__(self): return unicode(self.answer) + class SurveyAnswer(models.Model): user = models.ForeignKey(User) survey = models.ForeignKey(Survey) - answers = models.ManyToManyField(SurveyQuestionAnswer, related_name = "selected_by") + answers = models.ManyToManyField(SurveyQuestionAnswer, related_name="selected_by") class Meta: verbose_name = "Réponses" unique_together = ("user", "survey") + class Clipper(models.Model): - username = models.CharField("Identifiant", max_length = 20) - fullname = models.CharField("Nom complet", max_length = 200) + username = models.CharField("Identifiant", max_length=20) + fullname = models.CharField("Nom complet", max_length=200) diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index a5347948..534632af 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -26,58 +26,64 @@ from datetime import datetime import base64 import simplejson + def render_template(template_path, data): tmpl = loader.get_template(template_path) context = Context(data) return tmpl.render(context) + class DemandeListView(ListView): model = PetitCoursDemande template_name = "petits_cours_demandes_list.html" paginate_by = 20 def get_queryset(self): - return PetitCoursDemande.objects.order_by('traitee','-id').all() + return PetitCoursDemande.objects.order_by('traitee', '-id').all() @method_decorator(buro_required) def dispatch(self, *args, **kwargs): return super(DemandeListView, self).dispatch(*args, **kwargs) + @buro_required def details(request, demande_id): - demande = get_object_or_404(PetitCoursDemande, id = demande_id) - attributions = PetitCoursAttribution.objects.filter(demande = demande).all() + demande = get_object_or_404(PetitCoursDemande, id=demande_id) + attributions = PetitCoursAttribution.objects.filter(demande=demande).all() return render(request, "details_demande_petit_cours.html", {"demande": demande, "attributions": attributions}) + def _get_attrib_counter(user, matiere): - counter, created = PetitCoursAttributionCounter.objects.get_or_create(user = user, - matiere = matiere) + counter, created = PetitCoursAttributionCounter.objects.get_or_create(user=user, + matiere=matiere) if created: - mincount = PetitCoursAttributionCounter.objects.filter(matiere = matiere).exclude(user = user).all().aggregate(Min('count')) + mincount = PetitCoursAttributionCounter.objects.filter(matiere=matiere).exclude(user=user).all().aggregate(Min('count')) counter.count = mincount['count__min'] counter.save() return counter -def _get_demande_candidates(demande, redo = False): + +def _get_demande_candidates(demande, redo=False): for matiere in demande.matieres.all(): - candidates = PetitCoursAbility.objects.filter(matiere = matiere, niveau = demande.niveau) - candidates = candidates.filter(user__profile__is_cof = True, - user__profile__petits_cours_accept = True) + candidates = PetitCoursAbility.objects.filter(matiere=matiere, niveau=demande.niveau) + candidates = candidates.filter(user__profile__is_cof=True, + user__profile__petits_cours_accept=True) if demande.agrege_requis: - candidates = candidates.filter(agrege = True) + candidates = candidates.filter(agrege=True) if redo: - attributions = PetitCoursAttribution.objects.filter(demande = demande, - matiere = matiere).all() + attributions = PetitCoursAttribution.objects.filter(demande=demande, + matiere=matiere).all() for attrib in attributions: - candidates = candidates.exclude(user = attrib.user) + candidates = candidates.exclude(user=attrib.user) candidates = candidates.order_by('?').select_related().all() yield (matiere, candidates) + @buro_required -def traitement(request, demande_id, redo = False): - demande = get_object_or_404(PetitCoursDemande, id = demande_id) +def traitement(request, demande_id, redo=False): + demande = get_object_or_404(PetitCoursDemande, id=demande_id) if demande.niveau == "other": return _traitement_other(request, demande, redo) if request.method == "POST": @@ -92,7 +98,7 @@ def traitement(request, demande_id, redo = False): for candidate in candidates: user = candidate.user tuples.append((candidate, _get_attrib_counter(user, matiere))) - tuples = sorted(tuples, key = lambda c: c[1].count) + tuples = sorted(tuples, key=lambda c: c[1].count) candidates, _ = zip(*tuples) candidates = candidates[0:min(3, len(candidates))] attribdata[matiere.id] = [] @@ -110,12 +116,14 @@ def traitement(request, demande_id, redo = False): return _finalize_traitement(request, demande, proposals, proposed_for, unsatisfied, attribdata, redo) + @buro_required def retraitement(request, demande_id): - return traitement(request, demande_id, redo = True) + return traitement(request, demande_id, redo=True) + def _finalize_traitement(request, demande, proposals, proposed_for, - unsatisfied, attribdata, redo = False, errors = None): + unsatisfied, attribdata, redo=False, errors=None): proposals = proposals.items() proposed_for = proposed_for.items() attribdata = attribdata.items() @@ -136,6 +144,7 @@ def _finalize_traitement(request, demande, proposals, proposed_for, "errors": errors, }) + def _generate_eleve_email(demande, proposed_for): proposed_mails = [] for user, matieres in proposed_for: @@ -143,6 +152,7 @@ def _generate_eleve_email(demande, proposed_for): proposed_mails.append((user, msg)) return proposed_mails + def _traitement_other_preparing(request, demande): redo = "redo" in request.POST unsatisfied = [] @@ -179,7 +189,8 @@ def _traitement_other_preparing(request, demande): errors.append(u"Seulement %d proposition%s pour %s" % (len(proposals[matiere]), "s" if len(proposals[matiere]) > 1 else "", matiere)) else: unsatisfied.append(matiere) - return _finalize_traitement(request, demande, proposals, proposed_for, unsatisfied, attribdata, errors = errors) + return _finalize_traitement(request, demande, proposals, proposed_for, unsatisfied, attribdata, errors=errors) + def _traitement_other(request, demande, redo): if request.method == "POST": @@ -197,7 +208,7 @@ def _traitement_other(request, demande, redo): for candidate in candidates: user = candidate.user tuples.append((candidate, _get_attrib_counter(user, matiere))) - tuples = sorted(tuples, key = lambda c: c[1].count) + tuples = sorted(tuples, key=lambda c: c[1].count) candidates, _ = zip(*tuples) attribdata[matiere.id] = [] proposals[matiere] = [] @@ -220,6 +231,7 @@ def _traitement_other(request, demande, redo): "proposed_for": proposed_for, }) + def _traitement_post(request, demande): proposals = {} proposed_for = {} @@ -234,7 +246,7 @@ def _traitement_post(request, demande): else: proposals[matiere] = [] for user_id in attribdata[matiere.id]: - user = User.objects.get(pk = user_id) + user = User.objects.get(pk=user_id) proposals[matiere].append(user) if user not in proposed_for: proposed_for[user] = [matiere] @@ -254,21 +266,21 @@ def _traitement_post(request, demande): for (user, msg) in proposed_mails: msg = EmailMessage("Petits cours ENS par le COF", msg, frommail, [user.email], - [bccaddress], headers = {'Reply-To': replyto}) + [bccaddress], headers={'Reply-To': replyto}) mails_to_send.append(msg) mails_to_send.append(EmailMessage("Cours particuliers ENS", mainmail, frommail, [demande.email], - [bccaddress], headers = {'Reply-To': replyto})) - connection = mail.get_connection(fail_silently = True) + [bccaddress], headers={'Reply-To': replyto})) + connection = mail.get_connection(fail_silently=True) connection.send_messages(mails_to_send) lock_table(PetitCoursAttributionCounter, PetitCoursAttribution, User) for matiere in proposals: for rank, user in enumerate(proposals[matiere]): - counter = PetitCoursAttributionCounter.objects.get(user = user, matiere = matiere) + counter = PetitCoursAttributionCounter.objects.get(user=user, matiere=matiere) counter.count += 1 counter.save() - attrib = PetitCoursAttribution(user = user, matiere = matiere, - demande = demande, rank = rank + 1) + attrib = PetitCoursAttribution(user=user, matiere=matiere, + demande=demande, rank=rank + 1) attrib.save() unlock_tables() demande.traitee = True @@ -280,6 +292,7 @@ def _traitement_post(request, demande): "redo": redo, }) + class BaseMatieresFormSet(BaseInlineFormSet): def clean(self): super(BaseMatieresFormSet, self).clean() @@ -298,35 +311,36 @@ class BaseMatieresFormSet(BaseInlineFormSet): raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour la même matiere avec le même niveau.") matieres.append((matiere, niveau)) + @login_required def inscription(request): - profile, created = CofProfile.objects.get_or_create(user = request.user) + profile, created = CofProfile.objects.get_or_create(user=request.user) if not profile.is_cof: return redirect("cof-denied") MatieresFormSet = inlineformset_factory(User, PetitCoursAbility, - fields = ("matiere", "niveau", "agrege",), - formset = BaseMatieresFormSet) + fields=("matiere", "niveau", "agrege",), + formset=BaseMatieresFormSet) success = False if request.method == "POST": - formset = MatieresFormSet(request.POST, instance = request.user) + formset = MatieresFormSet(request.POST, instance=request.user) if formset.is_valid(): formset.save() profile.petits_cours_accept = "receive_proposals" in request.POST profile.petits_cours_remarques = request.POST["remarques"] profile.save() lock_table(PetitCoursAttributionCounter, PetitCoursAbility, User, PetitCoursSubject) - abilities = PetitCoursAbility.objects.filter(user = request.user).all() + abilities = PetitCoursAbility.objects.filter(user=request.user).all() for ability in abilities: counter = _get_attrib_counter(ability.user, ability.matiere) unlock_tables() success = True - formset = MatieresFormSet(instance = request.user) + formset = MatieresFormSet(instance=request.user) else: - formset = MatieresFormSet(instance = request.user) + formset = MatieresFormSet(instance=request.user) return render(request, "inscription-petit-cours.html", {"formset": formset, "success": success, "receive_proposals": profile.petits_cours_accept, "remarques": profile.petits_cours_remarques}) class DemandeForm(ModelForm): - captcha = ReCaptchaField(attrs = {'theme': 'clean', 'lang': 'fr'}) + captcha = ReCaptchaField(attrs={'theme': 'clean', 'lang': 'fr'}) def __init__(self, *args, **kwargs): super(DemandeForm, self).__init__(*args, **kwargs) @@ -337,6 +351,7 @@ class DemandeForm(ModelForm): fields = ('name', 'email', 'phone', 'quand', 'freq', 'lieu', 'matieres', 'agrege_requis', 'niveau', 'remarques') widgets = {'matieres': forms.CheckboxSelectMultiple} + @csrf_exempt def demande(request): success = False @@ -349,6 +364,7 @@ def demande(request): form = DemandeForm() return render(request, "demande-petit-cours.html", {"form": form, "success": success}) + @csrf_exempt def demande_raw(request): success = False diff --git a/gestioncof/shared.py b/gestioncof/shared.py index 4bdd9aa5..4fb2e4bc 100644 --- a/gestioncof/shared.py +++ b/gestioncof/shared.py @@ -12,17 +12,18 @@ from gestioncof.models import CofProfile, CustomMail User = get_user_model() + class COFCASBackend(CASBackend): def authenticate_cas(self, ticket, service, request): """Verifies CAS ticket and gets or creates User object""" client = get_cas_client(service_url=service) - username, attributes, _= client.verify_ticket(ticket) + username, attributes, _ = client.verify_ticket(ticket) if attributes: request.session['attributes'] = attributes if not username: return None - profiles = CofProfile.objects.filter(login_clipper = username) + profiles = CofProfile.objects.filter(login_clipper=username) if len(profiles) > 0: profile = profiles.order_by('-is_cof')[0] user = profile.user @@ -43,7 +44,7 @@ class COFCASBackend(CASBackend): try: profile = user.profile except CofProfile.DoesNotExist: - profile, created = CofProfile.objects.get_or_create(user = user) + profile, created = CofProfile.objects.get_or_create(user=user) profile.save() if not profile.login_clipper: profile.login_clipper = user.username @@ -57,7 +58,8 @@ class COFCASBackend(CASBackend): user.save() return user -def context_processor (request): + +def context_processor(request): '''Append extra data to the context of the given request''' data = { "user": request.user, @@ -65,17 +67,20 @@ def context_processor (request): } return data + def lock_table(*models): query = "LOCK TABLES " for i, model in enumerate(models): table = model._meta.db_table - if i > 0: query += ", " + if i > 0: + query += ", " query += "%s WRITE" % table cursor = connection.cursor() cursor.execute(query) row = cursor.fetchone() return row + def unlock_tables(*models): cursor = connection.cursor() cursor.execute("UNLOCK TABLES") @@ -84,15 +89,17 @@ def unlock_tables(*models): unlock_table = unlock_tables -def send_custom_mail(to, shortname, context = None, from_email = "cof@ens.fr"): - if context is None: context = {} + +def send_custom_mail(to, shortname, context=None, from_email="cof@ens.fr"): + if context is None: + context = {} if isinstance(to, DjangoUser): context["nom"] = to.get_full_name() context["prenom"] = to.first_name to = to.email - mail = CustomMail.objects.get(shortname = shortname) + mail = CustomMail.objects.get(shortname=shortname) template = Template(mail.content) message = template.render(Context(context)) - send_mail (mail.title, message, - from_email, [to], - fail_silently = True) + send_mail(mail.title, message, + from_email, [to], + fail_silently=True) diff --git a/gestioncof/views.py b/gestioncof/views.py index a862c773..cdf758b2 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -20,6 +20,7 @@ from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \ from bda.models import Tirage + @login_required def home(request): data = {"surveys": Survey.objects.filter(old=False).all(), @@ -29,61 +30,65 @@ def home(request): "open_tirages": Tirage.objects.filter(active=True).all()} return render(request, "home.html", data) + def login(request): if request.user.is_authenticated(): return redirect("gestioncof.views.home") return render(request, "login_switch.html", {}) + def login_ext(request): if request.method == "POST" and "username" in request.POST: try: - user = User.objects.get(username = request.POST["username"]) - if not user.has_usable_password() or user.password in ("","!"): - profile, created = CofProfile.objects.get_or_create(user = user) + user = User.objects.get(username=request.POST["username"]) + if not user.has_usable_password() or user.password in ("", "!"): + profile, created = CofProfile.objects.get_or_create(user=user) if profile.login_clipper: return render(request, "error.html", {"error_type": "use_clipper_login"}) else: return render(request, "error.html", {"error_type": "no_password"}) except User.DoesNotExist: pass - return django_login_view(request, template_name = 'login.html') + return django_login_view(request, template_name='login.html') + @login_required def logout(request): try: profile = request.user.profile except CofProfile.DoesNotExist: - profile, created = CofProfile.objects.get_or_create(user = request.user) + profile, created = CofProfile.objects.get_or_create(user=request.user) if profile.login_clipper: return redirect("django_cas_ng.views.logout") else: return redirect("django.contrib.auth.views.logout") + @login_required def survey(request, survey_id): - survey = get_object_or_404(Survey, id = survey_id) + survey = get_object_or_404(Survey, id=survey_id) if not survey.survey_open: raise Http404 success = False deleted = False if request.method == "POST": - form = SurveyForm(request.POST, survey = survey) + form = SurveyForm(request.POST, survey=survey) if request.POST.get('delete'): try: - current_answer = SurveyAnswer.objects.get(user = request.user, survey = survey) + current_answer = SurveyAnswer.objects.get(user=request.user, survey=survey) current_answer.delete() current_answer = None except SurveyAnswer.DoesNotExist: current_answer = None - form = SurveyForm(survey = survey) + form = SurveyForm(survey=survey) success = True deleted = True else: if form.is_valid(): all_answers = [] for question_id, answers_ids in form.answers(): - question = get_object_or_404(SurveyQuestion, id = question_id, - survey = survey) + question = get_object_or_404(SurveyQuestion, id=question_id, + survey=survey) if type(answers_ids) != list: answers_ids = [answers_ids] if not question.multi_answers and len(answers_ids) > 1: @@ -93,31 +98,32 @@ def survey(request, survey_id): continue answer_id = int(answer_id) answer = SurveyQuestionAnswer.objects.get( - id = answer_id, - survey_question = question) + id=answer_id, + survey_question=question) all_answers.append(answer) try: - current_answer = SurveyAnswer.objects.get(user = request.user, survey = survey) + current_answer = SurveyAnswer.objects.get(user=request.user, survey=survey) except SurveyAnswer.DoesNotExist: - current_answer = SurveyAnswer(user = request.user, survey = survey) + current_answer = SurveyAnswer(user=request.user, survey=survey) current_answer.save() current_answer.answers = all_answers current_answer.save() success = True else: try: - current_answer = SurveyAnswer.objects.get(user = request.user, survey = survey) - form = SurveyForm(survey = survey, current_answers = current_answer.answers) + current_answer = SurveyAnswer.objects.get(user=request.user, survey=survey) + form = SurveyForm(survey=survey, current_answers=current_answer.answers) except SurveyAnswer.DoesNotExist: current_answer = None - form = SurveyForm(survey = survey) + form = SurveyForm(survey=survey) return render(request, "survey.html", {"survey": survey, "form": form, "success": success, "deleted": deleted, "current_answer": current_answer}) + def get_event_form_choices(event, form): all_choices = [] for option_id, choices_ids in form.choices(): - option = get_object_or_404(EventOption, id = option_id, - event = event) + option = get_object_or_404(EventOption, id=option_id, + event=event) if type(choices_ids) != list: choices_ids = [choices_ids] if not option.multi_choices and len(choices_ids) > 1: @@ -127,42 +133,43 @@ def get_event_form_choices(event, form): continue choice_id = int(choice_id) choice = EventOptionChoice.objects.get( - id = choice_id, - event_option = option) + id=choice_id, + event_option=option) all_choices.append(choice) return all_choices def update_event_form_comments(event, form, registration): for commentfield_id, value in form.comments(): - field = get_object_or_404(EventCommentField, id = commentfield_id, - event = event) + field = get_object_or_404(EventCommentField, id=commentfield_id, + event=event) if value == field.default: continue - (storage, _) = EventCommentValue.objects.get_or_create(commentfield = field, - registration = registration) + (storage, _) = EventCommentValue.objects.get_or_create(commentfield=field, + registration=registration) storage.content = value storage.save() + @login_required def event(request, event_id): - event = get_object_or_404(Event, id = event_id) + event = get_object_or_404(Event, id=event_id) if not event.registration_open: raise Http404 success = False if request.method == "POST": - form = EventForm(request.POST, event = event) + form = EventForm(request.POST, event=event) if form.is_valid(): all_choices = get_event_form_choices(event, form) - (current_registration, _) = EventRegistration.objects.get_or_create(user = request.user, event = event) + (current_registration, _) = EventRegistration.objects.get_or_create(user=request.user, event=event) current_registration.options = all_choices current_registration.save() success = True else: try: - current_registration = EventRegistration.objects.get(user = request.user, event = event) - form = EventForm(event = event, current_choices = current_registration.options) + current_registration = EventRegistration.objects.get(user=request.user, event=event) + form = EventForm(event=event, current_choices=current_registration.options) except EventRegistration.DoesNotExist: - form = EventForm(event = event) + form = EventForm(event=event) return render(request, "event.html", {"event": event, "form": form, "success": success}) def clean_post_for_status(initial): @@ -175,27 +182,27 @@ def clean_post_for_status(initial): @buro_required def event_status(request, event_id): - event = get_object_or_404(Event, id = event_id) - registrations_query = EventRegistration.objects.filter(event = event) + event = get_object_or_404(Event, id=event_id) + registrations_query = EventRegistration.objects.filter(event=event) post_data = clean_post_for_status(request.POST) - form = EventStatusFilterForm(post_data or None, event = event) + form = EventStatusFilterForm(post_data or None, event=event) if form.is_valid(): for option_id, choice_id, value in form.filters(): if option_id == "has_paid": if value == "yes": - registrations_query = registrations_query.filter(paid = True) + registrations_query = registrations_query.filter(paid=True) elif value == "no": - registrations_query = registrations_query.filter(paid = False) + registrations_query = registrations_query.filter(paid=False) continue - choice = get_object_or_404(EventOptionChoice, id = choice_id, event_option__id = option_id) + choice = get_object_or_404(EventOptionChoice, id=choice_id, event_option__id=option_id) if value == "none": continue if value == "yes": - registrations_query = registrations_query.filter(options__id__exact = choice.id) + registrations_query = registrations_query.filter(options__id__exact=choice.id) elif value == "no": - registrations_query = registrations_query.exclude(options__id__exact = choice.id) + registrations_query = registrations_query.exclude(options__id__exact=choice.id) user_choices = registrations_query.prefetch_related("user").all() - options = EventOption.objects.filter(event = event).all() + options = EventOption.objects.filter(event=event).all() choices_count = {} for option in options: for choice in option.choices.all(): @@ -205,23 +212,24 @@ def event_status(request, event_id): choices_count[choice.id] += 1 return render(request, "event_status.html", {"event": event, "user_choices": user_choices, "options": options, "choices_count": choices_count, "form": form}) + @buro_required def survey_status(request, survey_id): - survey = get_object_or_404(Survey, id = survey_id) - answers_query = SurveyAnswer.objects.filter(survey = survey) + survey = get_object_or_404(Survey, id=survey_id) + answers_query = SurveyAnswer.objects.filter(survey=survey) post_data = clean_post_for_status(request.POST) - form = SurveyStatusFilterForm(post_data or None, survey = survey) + form = SurveyStatusFilterForm(post_data or None, survey=survey) if form.is_valid(): for question_id, answer_id, value in form.filters(): - answer = get_object_or_404(SurveyQuestionAnswer, id = answer_id, survey_question__id = question_id) + answer = get_object_or_404(SurveyQuestionAnswer, id=answer_id, survey_question__id=question_id) if value == "none": continue if value == "yes": - answers_query = answers_query.filter(answers__id__exact = answer.id) + answers_query = answers_query.filter(answers__id__exact=answer.id) elif value == "no": - answers_query = answers_query.exclude(answers__id__exact = answer.id) + answers_query = answers_query.exclude(answers__id__exact=answer.id) user_answers = answers_query.prefetch_related("user").all() - questions = SurveyQuestion.objects.filter(survey = survey).all() + questions = SurveyQuestion.objects.filter(survey=survey).all() answers_count = {} for question in questions: for answer in question.answers.all(): @@ -231,29 +239,32 @@ def survey_status(request, survey_id): answers_count[answer.id] += 1 return render(request, "survey_status.html", {"survey": survey, "user_answers": user_answers, "questions": questions, "answers_count": answers_count, "form": form}) + @login_required def profile(request): success = False if request.method == "POST": - form = UserProfileForm(request.POST, instance = request.user.profile) + form = UserProfileForm(request.POST, instance=request.user.profile) if form.is_valid(): form.save() success = True else: - form = UserProfileForm(instance = request.user.profile) + form = UserProfileForm(instance=request.user.profile) return render(request, "profile.html", {"form": form, "success": success}) + def registration_set_ro_fields(user_form, profile_form): user_form.fields['username'].widget.attrs['readonly'] = True profile_form.fields['login_clipper'].widget.attrs['readonly'] = True + @buro_required -def registration_form(request, login_clipper = None, username = None): +def registration_form(request, login_clipper=None, username=None): member = None if login_clipper: - clipper = get_object_or_404(Clipper, username = login_clipper) - try: # check if the given user is already registered - member = User.objects.filter(username = login_clipper).get() + clipper = get_object_or_404(Clipper, username=login_clipper) + try: # check if the given user is already registered + member = User.objects.filter(username=login_clipper).get() username = member.username login_clipper = None except User.DoesNotExist: @@ -270,11 +281,11 @@ def registration_form(request, login_clipper = None, username = None): user_form.fields['last_name'].initial = " ".join(bits[1:]) registration_set_ro_fields(user_form, profile_form) if username: - member = get_object_or_404(User, username = username) - (profile, _) = CofProfile.objects.get_or_create(user = member) + member = get_object_or_404(User, username=username) + (profile, _) = CofProfile.objects.get_or_create(user=member) # already existing, prefill - user_form = RegistrationUserForm(instance = member) - profile_form = RegistrationProfileForm(instance = profile) + user_form = RegistrationUserForm(instance=member) + profile_form = RegistrationProfileForm(instance=profile) registration_set_ro_fields(user_form, profile_form) elif not login_clipper: # new user @@ -283,20 +294,20 @@ def registration_form(request, login_clipper = None, username = None): return render(request, "registration_form.html", {"user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper}) @buro_required -def registration_form2(request, login_clipper = None, username = None): - events = Event.objects.filter(old = False).all() +def registration_form2(request, login_clipper=None, username=None): + events = Event.objects.filter(old=False).all() member = None if login_clipper: - clipper = get_object_or_404(Clipper, username = login_clipper) - try: # check if the given user is already registered - member = User.objects.filter(username = login_clipper).get() + clipper = get_object_or_404(Clipper, username=login_clipper) + try: # check if the given user is already registered + member = User.objects.filter(username=login_clipper).get() username = member.username login_clipper = None except User.DoesNotExist: # new user, but prefill user_form = RegistrationUserForm() profile_form = RegistrationProfileForm() - event_forms = [AdminEventForm(event = event) for event in events] + event_forms = [AdminEventForm(event=event) for event in events] user_form.fields['username'].initial = login_clipper user_form.fields['email'].initial = login_clipper + "@clipper.ens.fr" profile_form.fields['login_clipper'].initial = login_clipper @@ -307,27 +318,28 @@ def registration_form2(request, login_clipper = None, username = None): user_form.fields['last_name'].initial = " ".join(bits[1:]) registration_set_ro_fields(user_form, profile_form) if username: - member = get_object_or_404(User, username = username) - (profile, _) = CofProfile.objects.get_or_create(user = member) + member = get_object_or_404(User, username=username) + (profile, _) = CofProfile.objects.get_or_create(user=member) # already existing, prefill - user_form = RegistrationUserForm(instance = member) - profile_form = RegistrationProfileForm(instance = profile) + user_form = RegistrationUserForm(instance=member) + profile_form = RegistrationProfileForm(instance=profile) registration_set_ro_fields(user_form, profile_form) event_forms = [] for event in events: try: - current_registration = EventRegistration.objects.get(user = member, event = event) - form = AdminEventForm(event = event, current_registration = current_registration, paid = current_registration.paid) + current_registration = EventRegistration.objects.get(user=member, event=event) + form = AdminEventForm(event=event, current_registration=current_registration, paid=current_registration.paid) except EventRegistration.DoesNotExist: - form = AdminEventForm(event = event) + form = AdminEventForm(event=event) event_forms.append(form) elif not login_clipper: # new user user_form = RegistrationUserForm() profile_form = RegistrationProfileForm() - event_forms = [AdminEventForm(event = event) for event in events] + event_forms = [AdminEventForm(event=event) for event in events] return render(request, "registration_form.html", {"user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper, "event_forms": event_forms}) + @buro_required def registration(request): if request.POST: @@ -337,59 +349,62 @@ def registration(request): success = False user_form = RegistrationUserForm(request_dict) profile_form = RegistrationProfileForm(request_dict) - events = Event.objects.filter(old = False).all() - event_forms = [AdminEventForm(request_dict, event = event) for event in events] + events = Event.objects.filter(old=False).all() + event_forms = [AdminEventForm(request_dict, event=event) for event in events] user_form.is_valid() profile_form.is_valid() - for event_form in event_forms: event_form.is_valid() + for event_form in event_forms: + event_form.is_valid() member = None login_clipper = None if "user_exists" in request_dict and request_dict["user_exists"]: username = request_dict["username"] try: - member = User.objects.filter(username = username).get() - (profile, _) = CofProfile.objects.get_or_create(user = member) - user_form = RegistrationUserForm(request_dict, instance = member) - profile_form = RegistrationProfileForm(request_dict, instance = profile) + member = User.objects.filter(username=username).get() + (profile, _) = CofProfile.objects.get_or_create(user=member) + user_form = RegistrationUserForm(request_dict, instance=member) + profile_form = RegistrationProfileForm(request_dict, instance=profile) except User.DoesNotExist: try: - clipper = Clipper.objects.filter(username = username).get() + clipper = Clipper.objects.filter(username=username).get() login_clipper = clipper.username except Clipper.DoesNotExist: pass for form in event_forms: - if not form.is_valid(): break - if form.cleaned_data['status'] == 'no': continue + if not form.is_valid(): + break + if form.cleaned_data['status'] == 'no': + continue all_choices = get_event_form_choices(form.event, form) if user_form.is_valid() and profile_form.is_valid() and not any([not form.is_valid() for form in event_forms]): member = user_form.save() - (profile, _) = CofProfile.objects.get_or_create(user = member) + (profile, _) = CofProfile.objects.get_or_create(user=member) was_cof = profile.is_cof request_dict["num"] = profile.num - profile_form = RegistrationProfileForm(request_dict, instance = profile) + profile_form = RegistrationProfileForm(request_dict, instance=profile) profile_form.is_valid() profile_form.save() - (profile, _) = CofProfile.objects.get_or_create(user = member) + (profile, _) = CofProfile.objects.get_or_create(user=member) if profile.is_cof and not was_cof: send_custom_mail(member, "bienvenue") for form in event_forms: if form.cleaned_data['status'] == 'no': try: - current_registration = EventRegistration.objects.get(user = member, event = form.event) + current_registration = EventRegistration.objects.get(user=member, event=form.event) current_registration.delete() except EventRegistration.DoesNotExist: pass continue all_choices = get_event_form_choices(form.event, form) - (current_registration, created_reg) = EventRegistration.objects.get_or_create(user = member, event = form.event) + (current_registration, created_reg) = EventRegistration.objects.get_or_create(user=member, event=form.event) update_event_form_comments(event, form, current_registration) current_registration.options = all_choices current_registration.paid = (form.cleaned_data['status'] == 'paid') current_registration.save() if event.title == "Mega 15" and created_reg: - field = EventCommentField.objects.get(event = event, name = "Commentaires") + field = EventCommentField.objects.get(event=event, name="Commentaires") try: - comments = EventCommentValue.objects.get(commentfield = field, registration = current_registration).content + comments = EventCommentValue.objects.get(commentfield=field, registration=current_registration).content except EventCommentValue.DoesNotExist: comments = field.default send_custom_mail(member, "mega", {"remarques": comments}) @@ -398,22 +413,24 @@ def registration(request): else: return render(request, "registration.html") + @buro_required def export_members(request): - response = HttpResponse(content_type = 'text/csv') + response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=membres_cof.csv' writer = unicodecsv.writer(response) - for profile in CofProfile.objects.filter(is_cof = True).all(): + for profile in CofProfile.objects.filter(is_cof=True).all(): user = profile.user bits = [profile.num, user.username, user.first_name, user.last_name, user.email, profile.phone, profile.occupation, profile.departement, profile.type_cotiz] writer.writerow([unicode(bit) for bit in bits]) return response + @buro_required def csv_export_mega(filename, qs): - response = HttpResponse(content_type = 'text/csv') + response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=' + filename writer = unicodecsv.writer(response) @@ -426,15 +443,16 @@ def csv_export_mega(filename, qs): return response + @buro_required def export_mega_remarksonly(request): filename = 'remarques_mega_2015.csv' - response = HttpResponse(content_type = 'text/csv') + response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=' + filename writer = unicodecsv.writer(response) - event = Event.objects.get(title = "Mega 15") - commentfield = event.commentfields.get(name = "Commentaires") + event = Event.objects.get(title="Mega 15") + commentfield = event.commentfields.get(name="Commentaires") for val in commentfield.values.all(): reg = val.registration user = reg.user @@ -444,6 +462,7 @@ def export_mega_remarksonly(request): return response + @buro_required def export_mega_bytype(request, type): types = {"orga-actif": "Orga élève", @@ -454,60 +473,67 @@ def export_mega_bytype(request, type): if type not in types: raise Http404 - event = Event.objects.get(title = "Mega 15") - type_option = event.options.get(name = "Type") - participant_type = type_option.choices.get(value = types[type]).id - qs = EventRegistration.objects.filter(event = event).filter(options__id__exact = participant_type) + event = Event.objects.get(title="Mega 15") + type_option = event.options.get(name="Type") + participant_type = type_option.choices.get(value=types[type]).id + qs = EventRegistration.objects.filter(event=event).filter(options__id__exact=participant_type) return csv_export_mega(type + '_mega_2015.csv', qs) + @buro_required def export_mega_orgas(request): - event = Event.objects.get(title = "Mega 15") - type_option = event.options.get(name = "Type") - participant_type_a = type_option.choices.get(value = "Conscrit étudiant").id - participant_type_b = type_option.choices.get(value = "Conscrit élève").id - qs = EventRegistration.objects.filter(event = event).exclude(options__id__in = (participant_type_a, participant_type_b)) + event = Event.objects.get(title="Mega 15") + type_option = event.options.get(name="Type") + participant_type_a = type_option.choices.get(value="Conscrit étudiant").id + participant_type_b = type_option.choices.get(value="Conscrit élève").id + qs = EventRegistration.objects.filter(event=event).exclude(options__id__in=(participant_type_a, participant_type_b)) return csv_export_mega('orgas_mega_15.csv', qs) + @buro_required def export_mega_participants(request): - event = Event.objects.get(title = "Mega 15") - type_option = event.options.get(name = "Type") - participant_type_a = type_option.choices.get(value = "Conscrit étudiant").id - participant_type_b = type_option.choices.get(value = "Conscrit élève").id - qs = EventRegistration.objects.filter(event = event).filter(options__id__in = (participant_type_a, participant_type_b)) + event = Event.objects.get(title="Mega 15") + type_option = event.options.get(name="Type") + participant_type_a = type_option.choices.get(value="Conscrit étudiant").id + participant_type_b = type_option.choices.get(value="Conscrit élève").id + qs = EventRegistration.objects.filter(event=event).filter(options__id__in=(participant_type_a, participant_type_b)) return csv_export_mega('participants_mega_15.csv', qs) + @buro_required def export_mega(request): - event = Event.objects.filter(title = "Mega 15") - qs = EventRegistration.objects.filter(event = event).order_by("user__username") + event = Event.objects.filter(title="Mega 15") + qs = EventRegistration.objects.filter(event=event).order_by("user__username") return csv_export_mega('all_mega_2015.csv', qs) + @buro_required def utile_cof(request): - return render(request, "utile_cof.html", {}) + return render(request, "utile_cof.html", {}) + @buro_required def utile_bda(request): tirages = Tirage.objects.all() return render(request, "utile_bda.html", {'tirages': tirages}) + @buro_required def liste_bdadiff(request): titre = "BdA diffusion" - personnes = CofProfile.objects.filter(mailing_bda = True, is_cof = True).all() + personnes = CofProfile.objects.filter(mailing_bda=True, is_cof=True).all() return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) - + + @buro_required def liste_bdarevente(request): titre = "BdA revente" - personnes = CofProfile.objects.filter(mailing_bda_revente = True, is_cof = True).all() + personnes = CofProfile.objects.filter(mailing_bda_revente=True, is_cof=True).all() return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) + @buro_required def liste_diffcof(request): titre = "Diffusion COF" - personnes = CofProfile.objects.filter(mailing_cof = True, is_cof = True).all() + personnes = CofProfile.objects.filter(mailing_cof=True, is_cof=True).all() return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) - diff --git a/sync_clipper.py b/sync_clipper.py index 4b698995..4dac6447 100644 --- a/sync_clipper.py +++ b/sync_clipper.py @@ -22,7 +22,7 @@ if __name__ == "__main__": clipper.save() print "Updated", username else: - clipper = Clipper(username = username, fullname = fullname) + clipper = Clipper(username=username, fullname=fullname) clipper.save() print "Created", username print "[ DONE ]" diff --git a/tirage_bda.py b/tirage_bda.py index cedf48d7..bd021784 100644 --- a/tirage_bda.py +++ b/tirage_bda.py @@ -24,7 +24,7 @@ if __name__ == "__main__": print "%d places" % available_slots print "%d participants" % len(members) print "%d demandes" % len(choices) - print "%d places demandées" % (len(choices) + len(choices.filter(double = True).all())) + print "%d places demandées" % (len(choices) + len(choices.filter(double=True).all())) print "%.02f€ à brasser" % total_price print "Récupération: %.2fs" % (time.time() - start) start_init = time.time()