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 1/4] =?UTF-8?q?PEP8:=20fixed=20'=20=3D=20'=20=E2=86=92=20'?= =?UTF-8?q?=3D'=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() From 88bccc0e60b1338205b85c7348a2f1ab0681a9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sat, 9 Jul 2016 21:31:56 +0100 Subject: [PATCH 2/4] PEP8: Enforced other rules, including 80 cols --- apache/wsgi.py | 4 +- bda/admin.py | 65 +++++--- bda/algorithm.py | 12 +- bda/autocomplete_light_registry.py | 7 +- bda/forms.py | 12 +- bda/models.py | 22 ++- bda/urls.py | 3 +- bda/views.py | 85 +++++----- cof/settings_dev.py | 11 +- cof/urls.py | 22 +-- gestioncof/admin.py | 86 +++++----- gestioncof/autocomplete.py | 9 +- gestioncof/autocomplete_light_registry.py | 3 +- gestioncof/csv_views.py | 20 ++- gestioncof/decorators.py | 3 +- gestioncof/forms.py | 118 ++++++++----- gestioncof/models.py | 50 ++++-- gestioncof/petits_cours_models.py | 61 ++++--- gestioncof/petits_cours_views.py | 87 ++++++---- gestioncof/urls.py | 5 +- gestioncof/views.py | 193 +++++++++++++++------- gestioncof/widgets.py | 5 +- tirage_bda.py | 12 +- 23 files changed, 571 insertions(+), 324 deletions(-) diff --git a/apache/wsgi.py b/apache/wsgi.py index 254e36f5..b7a1eb92 100644 --- a/apache/wsgi.py +++ b/apache/wsgi.py @@ -6,7 +6,7 @@ https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ """ import os -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") - from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings") application = get_wsgi_application() diff --git a/bda/admin.py b/bda/admin.py index a86a9766..bcbc6069 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -4,27 +4,36 @@ from django.core.mail import send_mail from django.contrib import admin from django.db.models import Sum, Count -from bda.models import Spectacle, Salle, Participant, ChoixSpectacle, Attribution, Tirage +from bda.models import Spectacle, Salle, Participant, ChoixSpectacle,\ + Attribution, Tirage from django import forms from datetime import timedelta +import autocomplete_light + + class ChoixSpectacleInline(admin.TabularInline): model = ChoixSpectacle sortable_field_name = "priority" + class AttributionInline(admin.TabularInline): model = Attribution + class ParticipantAdmin(admin.ModelAdmin): 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: @@ -51,8 +60,9 @@ class ParticipantAdmin(admin.ModelAdmin): Tu t'es inscrit-e pour le tirage au sort du BdA. Malheureusement, tu n'as obtenu aucune place. -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 ! +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 Bureau des Arts @@ -71,15 +81,16 @@ pour les spectacles suivants : L'intégralité de ces places de spectacles est à régler dès maintenant et AVANT le %s, 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. Pour ceux qui ne pourraient pas venir -payer au bureau, merci de nous contacter par mail. +évidemment possibles : nous pouvons ne pas encaisser le chèque immédiatement, +ou bien découper votre paiement en deux fois. Pour ceux qui ne pourraient pas +venir payer au bureau, merci de nous contacter par mail. *Mode de retrait des places* -Au moment du paiement, certaines places vous seront remises directement, d'autres -seront à récupérer au cours de l'année, d'autres encore seront nominatives et à retirer -le soir même dans les theâtres correspondants. Pour chaque spectacle, vous recevrez un mail -quelques jours avant la représentation vous indiquant le mode de retrait. +Au moment du paiement, certaines places vous seront remises directement, +d'autres seront à récupérer au cours de l'année, d'autres encore seront +nominatives et à retirer le soir même dans les theâtres correspondants. +Pour chaque spectacle, vous recevrez un mail quelques jours avant la +représentation vous indiquant le mode de retrait. Nous vous rappelons que l'obtention de places du BdA vous engage à respecter les règles de fonctionnement : @@ -96,10 +107,11 @@ Le Bureau des Arts for attrib in attribs: attribs_text += u"- 1 place pour %s\n" % attrib deadline = member.tirage.fermeture + timedelta(days=7) - 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) + 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) count = len(queryset.all()) if count == 1: message_bit = u"1 membre a" @@ -107,9 +119,11 @@ Le Bureau des Arts 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)) + 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 AttributionAdminForm(forms.ModelForm): def clean(self): cleaned_data = super(AttributionAdminForm, self).clean() @@ -117,26 +131,36 @@ class AttributionAdminForm(forms.ModelForm): spectacle = cleaned_data.get("spectacle") if participant and spectacle: if participant.tirage != spectacle.tirage: - raise forms.ValidationError(u"Erreur : le participant et le spectacle n'appartiennent pas au même tirage") + raise forms.ValidationError( + u"Erreur : le participant et le spectacle n'appartiennent" + u"pas au même tirage") return cleaned_data + 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') + search_fields = ('spectacle__title', 'participant__user__username', + 'participant__user__first_name', + 'participant__user__last_name') form = AttributionAdminForm -import autocomplete_light + class ChoixSpectacleAdmin(admin.ModelAdmin): form = autocomplete_light.modelform_factory(ChoixSpectacle, exclude=[]) + def tirage(self, obj): return obj.participant.tirage - list_display = ("participant", "tirage", "spectacle", "priority", "double_choice") + list_display = ("participant", "tirage", "spectacle", "priority", + "double_choice") list_filter = ("double_choice", "participant__tirage") - search_fields = ('participant__user__username', 'participant__user__first_name', 'participant__user__last_name') + search_fields = ('participant__user__username', + 'participant__user__first_name', + 'participant__user__last_name') + class SpectacleAdmin(admin.ModelAdmin): model = Spectacle @@ -144,6 +168,7 @@ class SpectacleAdmin(admin.ModelAdmin): list_filter = ("location", "tirage",) search_fields = ("title", "location__name") + class TirageAdmin(admin.ModelAdmin): model = Tirage list_display = ("title", "ouverture", "fermeture", "active") diff --git a/bda/algorithm.py b/bda/algorithm.py index 21825369..a948d288 100644 --- a/bda/algorithm.py +++ b/bda/algorithm.py @@ -6,6 +6,7 @@ from django.db.models import Max import random + class Algorithm(object): shows = None @@ -19,7 +20,8 @@ class Algorithm(object): 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.max_group = \ + 2 * choices.aggregate(Max('priority'))['priority__max'] self.shows = [] showdict = {} for show in shows: @@ -65,13 +67,14 @@ 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)]) for member in show.requests: if self.ranks[member][show] == 0: - raise RuntimeError, (member, show.title) + raise RuntimeError(member, show.title) groups[self.ranks[member][show]].append(member) # On passe à l'attribution winners = [] @@ -84,7 +87,8 @@ class Algorithm(object): 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: + elif not self.choices[member][show].autoquit and\ + len(winners) < show.slots: self.appendResult(winners, member, show) self.appendResult(losers, member, show) else: diff --git a/bda/autocomplete_light_registry.py b/bda/autocomplete_light_registry.py index 3254b3c8..7aa43b07 100644 --- a/bda/autocomplete_light_registry.py +++ b/bda/autocomplete_light_registry.py @@ -2,8 +2,11 @@ import autocomplete_light from bda.models import Participant, Spectacle -autocomplete_light.register(Participant, search_fields=('user__username','user__first_name','user__last_name'), +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_light.register( + Spectacle, search_fields=('title', ), autocomplete_js_attributes={'placeholder': 'spectacle...'}) diff --git a/bda/forms.py b/bda/forms.py index cfc48266..1b93c6ef 100644 --- a/bda/forms.py +++ b/bda/forms.py @@ -4,6 +4,7 @@ from django import forms from django.forms.models import BaseInlineFormSet from bda.models import Spectacle + class BaseBdaFormSet(BaseInlineFormSet): def clean(self): """Checks that no two articles have the same title.""" @@ -20,22 +21,27 @@ class BaseBdaFormSet(BaseInlineFormSet): 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.") + raise forms.ValidationError( + "Vous ne pouvez pas vous inscrire deux fois pour le " + "même spectacle.") spectacles.append(spectacle) + class TokenForm(forms.Form): token = forms.CharField(widget=forms.widgets.Textarea()) + 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() + self.fields['spectacle'].queryset = participant.attributions.all().\ + distinct() diff --git a/bda/models.py b/bda/models.py index 1f160bbe..fbb6e0ee 100644 --- a/bda/models.py +++ b/bda/models.py @@ -6,6 +6,7 @@ from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ + class Tirage(models.Model): title = models.CharField("Titre", max_length=300) ouverture = models.DateTimeField("Date et heure d'ouverture du tirage") @@ -19,6 +20,7 @@ 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) address = models.TextField("Adresse") @@ -26,6 +28,7 @@ class Salle(models.Model): def __unicode__(self): return self.name + class Spectacle(models.Model): title = models.CharField("Titre", max_length=300) date = models.DateTimeField("Date & heure") @@ -52,7 +55,7 @@ class Spectacle(models.Model): def __unicode__(self): return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), - self.location, self.price) + self.location, self.price) PAYMENT_TYPES = ( ("cash", u"Cash"), @@ -61,17 +64,19 @@ PAYMENT_TYPES = ( ("autre", u"Autre"), ) + class Participant(models.Model): user = models.ForeignKey(User) choices = models.ManyToManyField(Spectacle, - through="ChoixSpectacle", - related_name="chosen_by") + through="ChoixSpectacle", + related_name="chosen_by") attributions = models.ManyToManyField(Spectacle, - through="Attribution", - related_name="attributed_to") + 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) + max_length=6, choices=PAYMENT_TYPES, + blank=True) tirage = models.ForeignKey(Tirage) def __unicode__(self): @@ -83,12 +88,14 @@ DOUBLE_CHOICES = ( ("double", "2 places sinon rien"), ) + class ChoixSpectacle(models.Model): participant = models.ForeignKey(Participant) spectacle = models.ForeignKey(Spectacle, related_name="participants") priority = models.PositiveIntegerField("Priorité") double_choice = models.CharField("Nombre de places", - default="1", choices=DOUBLE_CHOICES, max_length=10) + default="1", choices=DOUBLE_CHOICES, + max_length=10) def get_double(self): return self.double_choice != "1" @@ -104,6 +111,7 @@ class ChoixSpectacle(models.Model): verbose_name = "voeu" verbose_name_plural = "voeux" + class Attribution(models.Model): participant = models.ForeignKey(Participant) spectacle = models.ForeignKey(Spectacle, related_name="attribues") diff --git a/bda/urls.py b/bda/urls.py index f8e385b8..4557ec86 100644 --- a/bda/urls.py +++ b/bda/urls.py @@ -3,7 +3,8 @@ from django.conf.urls import url, patterns from bda.views import SpectacleListView -urlpatterns = patterns('', +urlpatterns = patterns( + '', url(r'inscription/(?P\d+)$', 'bda.views.inscription', name='bda-tirage-inscription'), diff --git a/bda/views.py b/bda/views.py index 3167ec16..c09b5baa 100644 --- a/bda/views.py +++ b/bda/views.py @@ -18,7 +18,8 @@ from datetime import timedelta import time from gestioncof.decorators import cof_required, buro_required -from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution, Tirage +from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\ + Tirage from bda.algorithm import Algorithm from bda.forms import BaseBdaFormSet, TokenForm, ResellForm @@ -59,7 +60,7 @@ def etat_places(request, tirage_id): spectacles_dict[spectacle["spectacle"]].slots total += spectacle["total"] return render(request, "etat-places.html", - {"spectacles": spectacles, "total": total, 'tirage': tirage}) + {"spectacles": spectacles, "total": total, 'tirage': tirage}) def _hash_queryset(queryset): @@ -73,9 +74,9 @@ def _hash_queryset(queryset): def places(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) participant, created = Participant.objects.get_or_create( - user=request.user, tirage=tirage) + user=request.user, tirage=tirage) places = participant.attribution_set.order_by( - "spectacle__date", "spectacle").all() + "spectacle__date", "spectacle").all() total = sum([place.spectacle.price for place in places]) filtered_places = [] places_dict = {} @@ -107,9 +108,9 @@ def places(request, tirage_id): def places_ics(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) participant, created = Participant.objects.get_or_create( - user=request.user, tirage=tirage) + user=request.user, tirage=tirage) places = participant.attribution_set.order_by( - "spectacle__date", "spectacle").all() + "spectacle__date", "spectacle").all() filtered_places = [] places_dict = {} spectacles = [] @@ -133,30 +134,32 @@ def inscription(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) if timezone.now() < tirage.ouverture: error_desc = "Ouverture le %s" % ( - tirage.ouverture.strftime('%d %b %Y à %H:%M')) + 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_title": "Le tirage n'est pas encore ouvert !", + "error_description": error_desc}) if timezone.now() > tirage.fermeture: participant, created = Participant.objects.get_or_create( - user=request.user, tirage=tirage) + user=request.user, tirage=tirage) 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 dans la journée !", - "choices": choices}) + {"error_title": "C'est fini !", + "error_description": + u"Tirage au sort dans la journée !", + "choices": choices}) + def formfield_callback(f, **kwargs): if f.name == "spectacle": kwargs['queryset'] = tirage.spectacle_set return f.formfield(**kwargs) BdaFormSet = inlineformset_factory( - Participant, - ChoixSpectacle, - fields=("spectacle", "double_choice", "priority"), - formset=BaseBdaFormSet, - formfield_callback=formfield_callback) + Participant, + ChoixSpectacle, + fields=("spectacle", "double_choice", "priority"), + formset=BaseBdaFormSet, + formfield_callback=formfield_callback) participant, created = Participant.objects.get_or_create( - user=request.user, tirage=tirage) + user=request.user, tirage=tirage) success = False stateerror = False if request.method == "POST": @@ -179,12 +182,12 @@ def inscription(request, tirage_id): if choice.double: total_price += choice.spectacle.price return render(request, "inscription-bda.html", - { "formset": formset, - "success": success, - "total_price": total_price, - "dbstate": dbstate, - 'tirage': tirage, - "stateerror": stateerror}) + {"formset": formset, + "success": success, + "total_price": total_price, + "dbstate": dbstate, + 'tirage': tirage, + "stateerror": stateerror}) def do_tirage(request, tirage_id): @@ -198,8 +201,8 @@ def do_tirage(request, tirage_id): data = {} shows = tirage_elt.spectacle_set.select_related().all() members = tirage_elt.participant_set.all() - choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt).order_by( - 'participant', 'priority').select_related().all() + choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt).\ + order_by('participant', 'priority').select_related().all() algo = Algorithm(shows, members, choices) results = algo(form.cleaned_data["token"]) total_slots = 0 @@ -248,8 +251,8 @@ def do_tirage(request, tirage_id): # cf. issue #32 if False: Attribution.objects.filter( - spectacle__tirage=tirage_elt - ).delete() + spectacle__tirage=tirage_elt + ).delete() for (show, members, _) in results: for (member, _, _, _) in members: attrib = Attribution(spectacle=show, participant=member) @@ -280,19 +283,20 @@ Je souhaite revendre %s pour %s le %s (%s) à %.02f€. Contactez moi par email si vous êtes intéressé·e·s ! %s (%s)""" % (places, spectacle.title, spectacle.date_no_seconds(), - spectacle.location, spectacle.price, request.user.get_full_name(), - request.user.email) + 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=False) - return render(request, "bda-success.html", {"show": spectacle, "places": places}) + 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) participant, created = Participant.objects.get_or_create( - user=request.user, tirage=tirage) + user=request.user, tirage=tirage) if not participant.paid: return render(request, "bda-notpaid.html", {}) if request.POST: @@ -301,7 +305,8 @@ def revente(request, tirage_id): return do_resell(request, form) else: form = ResellForm(participant) - return render(request, "bda-revente.html", {"form": form, 'tirage': tirage}) + return render(request, "bda-revente.html", + {"form": form, 'tirage': tirage}) @buro_required @@ -326,9 +331,9 @@ def spectacle(request, tirage_id, spectacle_id): participants[participant.id] = participant_info participants_info = sorted(participants.values(), - key=lambda part: part['lastname']) + key=lambda part: part['lastname']) return render(request, "bda-participants.html", - {"spectacle": spectacle, "participants": participants_info}) + {"spectacle": spectacle, "participants": participants_info}) class SpectacleListView(ListView): @@ -351,8 +356,8 @@ class SpectacleListView(ListView): def unpaid(request, tirage_id): tirage = get_object_or_404(Tirage, id=tirage_id) unpaid = tirage.participant_set \ - .annotate(nb_attributions=Count('attribution')) \ - .filter(paid=False, nb_attributions__gt=0).all() + .annotate(nb_attributions=Count('attribution')) \ + .filter(paid=False, nb_attributions__gt=0).all() return render(request, "bda-unpaid.html", {"unpaid": unpaid}) @@ -363,5 +368,5 @@ def liste_spectacles_ics(request, tirage_id): for spectacle in spectacles: spectacle.dtend = spectacle.date + timedelta(seconds=7200) return render(request, "liste_spectacles.ics", - {"spectacles": spectacles, "tirage": tirage}, - content_type="text/calendar") + {"spectacles": spectacles, "tirage": tirage}, + content_type="text/calendar") diff --git a/cof/settings_dev.py b/cof/settings_dev.py index 75f67646..6f2f21ac 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -148,11 +148,14 @@ RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" RECAPTCHA_USE_SSL = True -# On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar car -# cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la -# machine physique n'est pas forcément connue, et peut difficilement être mise -# dans les INTERNAL_IPS. + def show_toolbar(request): + """ + On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar + car cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la + machine physique n'est pas forcément connue, et peut difficilement être + mise dans les INTERNAL_IPS. + """ if not DEBUG: return False if request.is_ajax(): diff --git a/cof/urls.py b/cof/urls.py index 817db2dc..e42af37c 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -12,7 +12,8 @@ from gestioncof.urls import export_patterns, petitcours_patterns, \ autocomplete_light.autodiscover() admin.autodiscover() -urlpatterns = patterns('', +urlpatterns = patterns( + '', # Page d'accueil url(r'^$', 'gestioncof.views.home', name='home'), # Le BdA @@ -27,38 +28,39 @@ urlpatterns = patterns('', url(r'^event/', include(events_patterns)), # Authentification url(r'^cof/denied$', TemplateView.as_view(template_name='cof-denied.html'), - name="cof-denied"), + name="cof-denied"), url(r'^cas/login$', 'django_cas_ng.views.login', name="cas_login_view"), url(r'^cas/logout$', 'django_cas_ng.views.logout'), url(r'^outsider/login$', 'gestioncof.views.login_ext'), url(r'^outsider/logout$', 'django.contrib.auth.views.logout', - {'next_page': 'home'}), + {'next_page': 'home'}), url(r'^login$', 'gestioncof.views.login'), url(r'^logout$', 'gestioncof.views.logout'), # Infos persos url(r'^profile$', 'gestioncof.views.profile'), url(r'^outsider/password-change$', - 'django.contrib.auth.views.password_change'), + 'django.contrib.auth.views.password_change'), url(r'^outsider/password-change-done$', 'django.contrib.auth.views.password_change_done', name='password_change_done'), # Inscription d'un nouveau membre url(r'^registration$', 'gestioncof.views.registration'), url(r'^registration/clipper/(?P[\w-]+)$', - 'gestioncof.views.registration_form2', name="clipper-registration"), + 'gestioncof.views.registration_form2', name="clipper-registration"), url(r'^registration/user/(?P.+)$', - 'gestioncof.views.registration_form2', name="user-registration"), + 'gestioncof.views.registration_form2', name="user-registration"), url(r'^registration/empty$', 'gestioncof.views.registration_form2', - name="empty-registration"), + name="empty-registration"), # Autocompletion - url(r'^autocomplete/registration$', 'gestioncof.autocomplete.autocomplete'), + url(r'^autocomplete/registration$', + 'gestioncof.autocomplete.autocomplete'), url(r'^autocomplete/', include('autocomplete_light.urls')), # Interface admin url(r'^admin/logout/', 'gestioncof.views.logout'), 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', ]}), + 'gestioncof.csv_views.admin_list_export', + {'fields': ['username', ]}), url(r'^admin/', include(admin.site.urls)), url(r'^grappelli/', include('grappelli.urls')), # Liens utiles du COF et du BdA diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 2c149ed0..3d5e8891 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -9,8 +9,11 @@ from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ +import autocomplete_light -def add_link_field(target_model='', field='', link_text=unicode, desc_text=unicode): + +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() @@ -21,11 +24,13 @@ def add_link_field(target_model='', field='', link_text=unicode, desc_text=unico if not link_obj.id: return "" url = reverse(reverse_path, args=(link_obj.id,)) - return mark_safe("%s" % (url, link_text(link_obj))) + return mark_safe("%s" % + (url, link_text(link_obj))) link.allow_tags = True link.short_description = desc_text(reverse_name + ' link') cls.link = link - cls.readonly_fields = list(getattr(cls, 'readonly_fields', [])) + ['link'] + cls.readonly_fields =\ + list(getattr(cls, 'readonly_fields', [])) + ['link'] return cls return add_link @@ -42,14 +47,14 @@ class SurveyQuestionInline(admin.TabularInline): class SurveyQuestionAdmin(admin.ModelAdmin): inlines = [ - SurveyQuestionAnswerInline, - ] + SurveyQuestionAnswerInline, + ] class SurveyAdmin(admin.ModelAdmin): inlines = [ - SurveyQuestionInline, - ] + SurveyQuestionInline, + ] class EventOptionChoiceInline(admin.TabularInline): @@ -68,15 +73,15 @@ class EventCommentFieldInline(admin.TabularInline): class EventOptionAdmin(admin.ModelAdmin): inlines = [ - EventOptionChoiceInline, - ] + EventOptionChoiceInline, + ] class EventAdmin(admin.ModelAdmin): inlines = [ - EventOptionInline, - EventCommentFieldInline, - ] + EventOptionInline, + EventCommentFieldInline, + ] class CofProfileInline(admin.StackedInline): @@ -85,7 +90,8 @@ class CofProfileInline(admin.StackedInline): class FkeyLookup(object): - def __init__(self, fkeydecl, short_description=None, admin_order_field=None): + def __init__(self, fkeydecl, short_description=None, + admin_order_field=None): self.fk, fkattrs = fkeydecl.split('__', 1) self.fkattrs = fkattrs.split('__') @@ -94,9 +100,12 @@ class FkeyLookup(object): def __get__(self, obj, klass): if obj is None: - return self # hack required to make Django validate (if obj is - # None, then we're a class, and classes are callable - # ) + """ + hack required to make Django validate (if obj is + None, then we're a class, and classes are callable + ) + """ + return self item = getattr(obj, self.fk) for attr in self.fkattrs: item = getattr(item, attr) @@ -113,14 +122,16 @@ def ProfileInfo(field, short_description, boolean=False): getter.boolean = boolean return getter -User.profile_login_clipper = FkeyLookup("profile__login_clipper", "Login clipper") +User.profile_login_clipper = FkeyLookup("profile__login_clipper", + "Login clipper") User.profile_num = FkeyLookup("profile__num", "Numéro") User.profile_phone = ProfileInfo("phone", "Téléphone") User.profile_occupation = ProfileInfo("occupation", "Occupation") User.profile_departement = ProfileInfo("departement", "Departement") 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) +User.profile_mailing_bda_revente = ProfileInfo("mailing_bda_revente", + "ML BDA-R", True) class UserProfileAdmin(UserAdmin): @@ -131,6 +142,7 @@ class UserProfileAdmin(UserAdmin): return False is_buro.short_description = 'Membre du Buro' is_buro.boolean = True + def is_cof(self, obj): try: return obj.profile.is_cof @@ -139,19 +151,18 @@ class UserProfileAdmin(UserAdmin): is_cof.short_description = 'Membre du COF' is_cof.boolean = True list_display = ('profile_num',) + UserAdmin.list_display \ - + ( 'profile_login_clipper','profile_phone','profile_occupation', - 'profile_mailing_cof','profile_mailing_bda', - 'profile_mailing_bda_revente','is_cof','is_buro',) - list_display_links = ('username','email','first_name','last_name') + + ('profile_login_clipper', 'profile_phone', 'profile_occupation', + 'profile_mailing_cof', 'profile_mailing_bda', + 'profile_mailing_bda_revente', 'is_cof', 'is_buro', ) + list_display_links = ('username', 'email', 'first_name', 'last_name') list_filter = UserAdmin.list_filter \ - + ( 'profile__is_cof', 'profile__is_buro', 'profile__mailing_cof', - 'profile__mailing_bda') + + ('profile__is_cof', 'profile__is_buro', 'profile__mailing_cof', + 'profile__mailing_bda') search_fields = UserAdmin.search_fields + ('profile__phone',) inlines = [ - CofProfileInline, - ] + CofProfileInline, + ] -import autocomplete_light def user_unicode(self): if self.first_name and self.last_name: @@ -163,29 +174,29 @@ User.__unicode__ = user_unicode class EventRegistrationAdmin(admin.ModelAdmin): form = autocomplete_light.modelform_factory(EventRegistration, exclude=[]) - list_display = ('__unicode__','event','user','paid') + list_display = ('__unicode__', 'event', 'user', 'paid') list_filter = ('paid',) search_fields = ('user__username', 'user__first_name', 'user__last_name', 'user__email', 'event__title') class PetitCoursAbilityAdmin(admin.ModelAdmin): - list_display = ('user','matiere','niveau','agrege') + 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') + list_filter = ('matiere', 'niveau', 'agrege') class PetitCoursAttributionAdmin(admin.ModelAdmin): - list_display = ('user','demande','matiere','rank',) + list_display = ('user', 'demande', 'matiere', 'rank', ) class PetitCoursAttributionCounterAdmin(admin.ModelAdmin): - list_display = ('user','matiere','count',) + list_display = ('user', 'matiere', 'count', ) list_filter = ('matiere',) search_fields = ('user__username', 'user__first_name', 'user__last_name', 'user__email', 'matiere__name') - actions = ['reset',] + actions = ['reset', ] actions_on_bottom = True def reset(self, request, queryset): @@ -194,9 +205,9 @@ class PetitCoursAttributionCounterAdmin(admin.ModelAdmin): class PetitCoursDemandeAdmin(admin.ModelAdmin): - list_display = ('name','email','agrege_requis','niveau','created', - 'traitee','processed') - list_filter = ('traitee','niveau') + list_display = ('name', 'email', 'agrege_requis', 'niveau', 'created', + 'traitee', 'processed') + list_filter = ('traitee', 'niveau') admin.site.register(Survey, SurveyAdmin) admin.site.register(SurveyQuestion, SurveyQuestionAdmin) @@ -210,6 +221,7 @@ admin.site.register(CustomMail) admin.site.register(PetitCoursSubject) admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin) admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin) -admin.site.register(PetitCoursAttributionCounter, PetitCoursAttributionCounterAdmin) +admin.site.register(PetitCoursAttributionCounter, + PetitCoursAttributionCounterAdmin) admin.site.register(PetitCoursDemande, PetitCoursDemandeAdmin) admin.site.register(EventRegistration, EventRegistrationAdmin) diff --git a/gestioncof/autocomplete.py b/gestioncof/autocomplete.py index e381bed4..4b222f06 100644 --- a/gestioncof/autocomplete.py +++ b/gestioncof/autocomplete.py @@ -35,9 +35,12 @@ def autocomplete(request): | 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) diff --git a/gestioncof/autocomplete_light_registry.py b/gestioncof/autocomplete_light_registry.py index f3283f8e..4a2737cb 100644 --- a/gestioncof/autocomplete_light_registry.py +++ b/gestioncof/autocomplete_light_registry.py @@ -2,5 +2,6 @@ import autocomplete_light from django.contrib.auth.models import User -autocomplete_light.register(User, search_fields=('username','first_name','last_name'), +autocomplete_light.register( + User, search_fields=('username', 'first_name', 'last_name'), autocomplete_js_attributes={'placeholder': 'membre...'}) diff --git a/gestioncof/csv_views.py b/gestioncof/csv_views.py index 43c028e0..6ba59d26 100644 --- a/gestioncof/csv_views.py +++ b/gestioncof/csv_views.py @@ -7,7 +7,8 @@ from django.apps import apps def export(qs, fields=None): model = qs.model response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename=%s.csv' % slugify(model.__name__) + response['Content-Disposition'] = 'attachment; filename=%s.csv' %\ + slugify(model.__name__) writer = csv.writer(response) # Write headers to CSV file if fields: @@ -31,10 +32,12 @@ def export(qs, fields=None): return response -def admin_list_export(request, model_name, app_label, queryset=None, fields=None, list_display=True): +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 - (r'^admin/(?P[\d\w]+)/(?P[\d\w]+)/csv/', 'util.csv_view.admin_list_export'), + (r'^admin/(?P[\d\w]+)/(?P[\d\w]+)/csv/', + 'util.csv_view.admin_list_export'), """ if not request.user.is_staff: return HttpResponseForbidden() @@ -49,12 +52,17 @@ def admin_list_export(request, model_name, app_label, queryset=None, fields=None fields = None return export(queryset, fields) """ - Create your own change_list.html for your admin view and put something like this in it: + Create your own change_list.html for your admin view and put something + like this in it: {% block object-tools %} {% endblock %} diff --git a/gestioncof/decorators.py b/gestioncof/decorators.py index f442e68e..62c527df 100644 --- a/gestioncof/decorators.py +++ b/gestioncof/decorators.py @@ -9,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): diff --git a/gestioncof/forms.py b/gestioncof/forms.py index cfe1aa62..8cfd6b9f 100644 --- a/gestioncof/forms.py +++ b/gestioncof/forms.py @@ -26,16 +26,20 @@ class EventForm(forms.Form): choices[choice.event_option.id].append(choice.id) all_choices = choices for option in event.options.all(): - choices = [(choice.id, choice.value) for choice in option.choices.all()] + 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) + 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) else: - initial = None if option.id not in all_choices else all_choices[option.id][0] + 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, @@ -63,16 +67,20 @@ class SurveyForm(forms.Form): else: answers[answer.survey_question.id].append(answer.id) for question in survey.questions.all(): - choices = [(answer.id, answer.answer) for answer in question.answers.all()] + 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) + 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) else: - initial = None if question.id not in answers else answers[question.id][0] + initial = None if question.id not in answers\ + else answers[question.id][0] field = forms.ChoiceField(label=question.question, choices=choices, widget=RadioSelect, @@ -94,15 +102,18 @@ class SurveyStatusFilterForm(forms.Form): for question in survey.questions.all(): for answer in question.answers.all(): name = "question_%d_answer_%d" % (question.id, answer.id) - if self.is_bound and self.data.get(self.add_prefix(name), None): + if self.is_bound and\ + self.data.get(self.add_prefix(name), None): 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 @@ -110,7 +121,8 @@ class SurveyStatusFilterForm(forms.Form): def filters(self): for name, value in self.cleaned_data.items(): if name.startswith('question_'): - yield (self.fields[name].question_id, self.fields[name].answer_id, value) + yield (self.fields[name].question_id, + self.fields[name].answer_id, value) class EventStatusFilterForm(forms.Form): @@ -120,15 +132,17 @@ class EventStatusFilterForm(forms.Form): for option in event.options.all(): for choice in option.choices.all(): name = "option_%d_choice_%d" % (option.id, choice.id) - if self.is_bound and self.data.get(self.add_prefix(name), None): + if self.is_bound and\ + self.data.get(self.add_prefix(name), None): 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 @@ -139,7 +153,8 @@ class EventStatusFilterForm(forms.Form): else: initial = "none" field = forms.ChoiceField(label="Événement payé", - choices=[("yes", "yes"), ("no", "no"), ("none", "none")], + choices=[("yes", "yes"), ("no", "no"), + ("none", "none")], widget=TriStateCheckbox, required=False, initial=initial) @@ -148,7 +163,8 @@ class EventStatusFilterForm(forms.Form): def filters(self): for name, value in self.cleaned_data.items(): if name.startswith('option_'): - yield (self.fields[name].option_id, self.fields[name].choice_id, value) + yield (self.fields[name].option_id, + self.fields[name].choice_id, value) elif name == "event_has_paid": yield ("has_paid", None, value) @@ -179,7 +195,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): @@ -231,7 +248,9 @@ class RegistrationProfileForm(forms.ModelForm): class Meta: model = CofProfile - fields = ("login_clipper", "num", "phone", "occupation", "departement", "is_cof", "type_cotiz", "mailing_cof", "mailing_bda", "mailing_bda_revente", "comments") + 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'), @@ -239,13 +258,16 @@ STATUS_CHOICES = (('no', 'Non'), 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") self.event = event registration = kwargs.pop("current_registration", None) - current_choices = registration.options.all() if registration is not None else [] + current_choices = \ + registration.options.all() if registration is not None\ + else [] paid = kwargs.pop("paid", None) if paid is True: kwargs["initial"] = {"status": "paid"} @@ -262,16 +284,20 @@ class AdminEventForm(forms.Form): choices[choice.event_option.id].append(choice.id) all_choices = choices for option in event.options.all(): - choices = [(choice.id, choice.value) for choice in option.choices.all()] + 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) + 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) else: - initial = None if option.id not in all_choices else all_choices[option.id][0] + 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, @@ -283,10 +309,12 @@ class AdminEventForm(forms.Form): 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 + widget = forms.Textarea if commentfield.fieldtype == "text" \ + else forms.TextInput field = forms.CharField(label=commentfield.name, widget=widget, required=False, diff --git a/gestioncof/models.py b/gestioncof/models.py index bac5ad62..a564a747 100644 --- a/gestioncof/models.py +++ b/gestioncof/models.py @@ -41,21 +41,28 @@ class CofProfile(models.Model): 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) + 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)) + 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) + 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="") + 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="") class Meta: verbose_name = "Profil COF" @@ -82,7 +89,8 @@ 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) + comments = models.TextField("Informations contextuelles sur le mail", + blank=True) class Meta: verbose_name = "Mails personnalisables" @@ -97,7 +105,8 @@ class Event(models.Model): 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) + registration_open = models.BooleanField("Inscriptions ouvertes", + default=True) old = models.BooleanField("Archiver (événement fini)", default=False) class Meta: @@ -110,7 +119,8 @@ class Event(models.Model): 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") + fieldtype = models.CharField("Type", max_length=10, + choices=TYPE_COMMENT_FIELD, default="text") default = models.TextField("Valeur par défaut", blank=True) class Meta: @@ -122,7 +132,8 @@ class EventCommentField(models.Model): class EventCommentValue(models.Model): commentfield = models.ForeignKey(EventCommentField, related_name="values") - registration = models.ForeignKey("EventRegistration", related_name="comments") + registration = models.ForeignKey("EventRegistration", + related_name="comments") content = models.TextField("Contenu", blank=True, null=True) @@ -153,7 +164,8 @@ class EventRegistration(models.Model): user = models.ForeignKey(User) event = models.ForeignKey(Event) options = models.ManyToManyField(EventOptionChoice) - filledcomments = models.ManyToManyField(EventCommentField, through=EventCommentValue) + filledcomments = models.ManyToManyField(EventCommentField, + through=EventCommentValue) paid = models.BooleanField("A payé", default=False) class Meta: @@ -161,7 +173,8 @@ class EventRegistration(models.Model): unique_together = ("user", "event") def __unicode__(self): - return u"Inscription de %s à %s" % (unicode(self.user), unicode(self.event.title)) + return u"Inscription de %s à %s" % (unicode(self.user), + unicode(self.event.title)) class Survey(models.Model): @@ -203,7 +216,8 @@ class SurveyQuestionAnswer(models.Model): 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" diff --git a/gestioncof/petits_cours_models.py b/gestioncof/petits_cours_models.py index 47339a4e..a9aede0c 100644 --- a/gestioncof/petits_cours_models.py +++ b/gestioncof/petits_cours_models.py @@ -4,8 +4,9 @@ from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ -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) LEVELS_CHOICES = ( ('college', _(u"Collège")), @@ -16,6 +17,7 @@ LEVELS_CHOICES = ( ('other', _(u"Autre (préciser dans les commentaires)")), ) + class PetitCoursSubject(models.Model): name = models.CharField(_(u"Matière"), max_length=30) users = models.ManyToManyField(User, related_name="petits_cours_matieres", @@ -28,12 +30,13 @@ class PetitCoursSubject(models.Model): def __unicode__(self): return self.name + class PetitCoursAbility(models.Model): user = models.ForeignKey(User) matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_(u"Matière")) - niveau = models.CharField (_(u"Niveau"), - choices=LEVELS_CHOICES, - max_length=choices_length (LEVELS_CHOICES)) + niveau = models.CharField(_(u"Niveau"), + choices=LEVELS_CHOICES, + max_length=choices_length(LEVELS_CHOICES)) agrege = models.BooleanField(_(u"Agrégé"), default=False) class Meta: @@ -41,7 +44,9 @@ class PetitCoursAbility(models.Model): verbose_name_plural = "Compétences des petits cours" def __unicode__(self): - return u"%s - %s - %s" % (self.user.username, self.matiere, self.niveau) + return u"%s - %s - %s" % (self.user.username, + self.matiere, self.niveau) + class PetitCoursDemande(models.Model): name = models.CharField(_(u"Nom/prénom"), max_length=200) @@ -49,28 +54,28 @@ class PetitCoursDemande(models.Model): phone = models.CharField(_(u"Téléphone (facultatif)"), max_length=20, blank=True) quand = models.CharField( - _(u"Quand ?"), - help_text=_(u"Indiquez ici la période désirée pour les petits" \ - + " cours (vacances scolaires, semaine, week-end)."), - max_length=300, blank=True) + _(u"Quand ?"), + help_text=_(u"Indiquez ici la période désirée pour les petits" + " cours (vacances scolaires, semaine, week-end)."), + max_length=300, blank=True) freq = models.CharField( - _(u"Fréquence"), - help_text=_(u"Indiquez ici la fréquence envisagée " \ + _(u"Fréquence"), + help_text=_(u"Indiquez ici la fréquence envisagée " + "(hebdomadaire, 2 fois par semaine, ...)"), - max_length=300, blank=True) + max_length=300, blank=True) lieu = models.CharField( - _(u"Lieu (si préférence)"), - help_text=_(u"Si vous avez avez une préférence sur le lieu."), - max_length=300, blank=True) + _(u"Lieu (si préférence)"), + help_text=_(u"Si vous avez avez une préférence sur le lieu."), + max_length=300, blank=True) matieres = models.ManyToManyField( - PetitCoursSubject, verbose_name=_(u"Matières"), - related_name="demandes") + PetitCoursSubject, verbose_name=_(u"Matières"), + related_name="demandes") agrege_requis = models.BooleanField(_(u"Agrégé requis"), default=False) - niveau = models.CharField (_(u"Niveau"), - default="", - choices=LEVELS_CHOICES, - max_length=choices_length (LEVELS_CHOICES)) + niveau = models.CharField(_(u"Niveau"), + default="", + choices=LEVELS_CHOICES, + max_length=choices_length(LEVELS_CHOICES)) remarques = models.TextField(_(u"Remarques et précisions"), blank=True) @@ -85,7 +90,9 @@ class PetitCoursDemande(models.Model): verbose_name_plural = "Demandes de petits cours" def __unicode__(self): - return u"Demande %d du %s" % (self.id, self.created.strftime("%d %b %Y")) + return u"Demande %d du %s" % (self.id, + self.created.strftime("%d %b %Y")) + class PetitCoursAttribution(models.Model): user = models.ForeignKey(User) @@ -94,7 +101,7 @@ class PetitCoursAttribution(models.Model): date = models.DateTimeField(_(u"Date d'attribution"), auto_now_add=True) rank = models.IntegerField("Rang dans l'email") selected = models.BooleanField(_(u"Sélectionné par le demandeur"), - default=False) + default=False) class Meta: verbose_name = "Attribution de petits cours" @@ -102,7 +109,8 @@ class PetitCoursAttribution(models.Model): def __unicode__(self): return u"Attribution de la demande %d à %s pour %s" \ - % (self.demande.id, self.user.username, self.matiere) + % (self.demande.id, self.user.username, self.matiere) + class PetitCoursAttributionCounter(models.Model): user = models.ForeignKey(User) @@ -115,5 +123,4 @@ class PetitCoursAttributionCounter(models.Model): def __unicode__(self): return u"%d demandes envoyées à %s pour %s" \ - % (self.count, self.user.username, self.matiere) - + % (self.count, self.user.username, self.matiere) diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index 534632af..a4353b09 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -56,10 +56,12 @@ def details(request, demande_id): 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 @@ -67,14 +69,15 @@ def _get_attrib_counter(user, matiere): def _get_demande_candidates(demande, redo=False): for matiere in demande.matieres.all(): - candidates = PetitCoursAbility.objects.filter(matiere=matiere, niveau=demande.niveau) + 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) 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.order_by('?').select_related().all() @@ -131,7 +134,11 @@ def _finalize_traitement(request, demande, proposals, proposed_for, mainmail = render_template("petits-cours-mail-demandeur.txt", {"proposals": proposals, "unsatisfied": unsatisfied, - "extra": ""}) + "extra": + '' + }) return render(request, "traitement_demande_petit_cours.html", {"demande": demande, "unsatisfied": unsatisfied, @@ -139,16 +146,18 @@ def _finalize_traitement(request, demande, proposals, proposed_for, "proposed_for": proposed_for, "proposed_mails": proposed_mails, "mainmail": mainmail, - "attribdata": base64.b64encode(simplejson.dumps(attribdata)), + "attribdata": + base64.b64encode(simplejson.dumps(attribdata)), "redo": redo, "errors": errors, - }) + }) def _generate_eleve_email(demande, proposed_for): proposed_mails = [] for user, matieres in proposed_for: - msg = render_template("petits-cours-mail-eleve.txt", {"demande": demande, "matieres": matieres}) + msg = render_template("petits-cours-mail-eleve.txt", + {"demande": demande, "matieres": matieres}) proposed_mails.append((user, msg)) return proposed_mails @@ -167,15 +176,18 @@ def _traitement_other_preparing(request, demande): attribdata[matiere.id] = [] proposals[matiere] = [] for choice_id in range(min(3, len(candidates))): - choice = int(request.POST["proposal-%d-%d" % (matiere.id, choice_id)]) + choice = int( + request.POST["proposal-%d-%d" % (matiere.id, choice_id)]) if choice == -1: continue if choice not in candidates: - errors.append(u"Choix invalide pour la proposition %d en %s" % (choice_id + 1, matiere)) + errors.append(u"Choix invalide pour la proposition %d" + "en %s" % (choice_id + 1, matiere)) continue user = candidates[choice] if user in proposals[matiere]: - errors.append(u"La proposition %d en %s est un doublon" % (choice_id + 1, matiere)) + errors.append(u"La proposition %d en %s est un doublon" % + (choice_id + 1, matiere)) continue proposals[matiere].append(user) attribdata[matiere.id].append(user.id) @@ -186,10 +198,14 @@ def _traitement_other_preparing(request, demande): if not proposals[matiere]: errors.append(u"Aucune proposition pour %s" % (matiere,)) elif len(proposals[matiere]) < 3: - errors.append(u"Seulement %d proposition%s pour %s" % (len(proposals[matiere]), "s" if len(proposals[matiere]) > 1 else "", matiere)) + 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): @@ -229,7 +245,7 @@ def _traitement_other(request, demande, redo): "unsatisfied": unsatisfied, "proposals": proposals, "proposed_for": proposed_for, - }) + }) def _traitement_post(request, demande): @@ -270,13 +286,15 @@ def _traitement_post(request, demande): mails_to_send.append(msg) mails_to_send.append(EmailMessage("Cours particuliers ENS", mainmail, frommail, [demande.email], - [bccaddress], headers={'Reply-To': replyto})) + [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, @@ -290,14 +308,15 @@ def _traitement_post(request, demande): return render(request, "traitement_demande_petit_cours_success.html", {"demande": demande, "redo": redo, - }) + }) class BaseMatieresFormSet(BaseInlineFormSet): def clean(self): super(BaseMatieresFormSet, 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 matieres = [] for i in range(0, self.total_form_count()): @@ -308,7 +327,9 @@ class BaseMatieresFormSet(BaseInlineFormSet): niveau = form.cleaned_data['niveau'] delete = form.cleaned_data['DELETE'] if not delete and (matiere, niveau) in matieres: - raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour la même matiere avec le même niveau.") + 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)) @@ -318,7 +339,8 @@ def inscription(request): if not profile.is_cof: return redirect("cof-denied") MatieresFormSet = inlineformset_factory(User, PetitCoursAbility, - fields=("matiere", "niveau", "agrege",), + fields=("matiere", "niveau", + "agrege",), formset=BaseMatieresFormSet) success = False if request.method == "POST": @@ -328,8 +350,10 @@ def inscription(request): 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() + lock_table(PetitCoursAttributionCounter, PetitCoursAbility, User, + PetitCoursSubject) + abilities = PetitCoursAbility.objects.\ + filter(user=request.user).all() for ability in abilities: counter = _get_attrib_counter(ability.user, ability.matiere) unlock_tables() @@ -337,7 +361,11 @@ def inscription(request): formset = MatieresFormSet(instance=request.user) else: 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}) + 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'}) @@ -348,7 +376,8 @@ class DemandeForm(ModelForm): class Meta: model = PetitCoursDemande - fields = ('name', 'email', 'phone', 'quand', 'freq', 'lieu', 'matieres', 'agrege_requis', 'niveau', 'remarques') + fields = ('name', 'email', 'phone', 'quand', 'freq', 'lieu', + 'matieres', 'agrege_requis', 'niveau', 'remarques') widgets = {'matieres': forms.CheckboxSelectMultiple} @@ -362,7 +391,8 @@ def demande(request): success = True else: form = DemandeForm() - return render(request, "demande-petit-cours.html", {"form": form, "success": success}) + return render(request, "demande-petit-cours.html", {"form": form, + "success": success}) @csrf_exempt @@ -375,4 +405,5 @@ def demande_raw(request): success = True else: form = DemandeForm() - return render(request, "demande-petit-cours-raw.html", {"form": form, "success": success}) + return render(request, "demande-petit-cours-raw.html", + {"form": form, "success": success}) diff --git a/gestioncof/urls.py b/gestioncof/urls.py index a8a38dbc..787dd80f 100644 --- a/gestioncof/urls.py +++ b/gestioncof/urls.py @@ -19,7 +19,8 @@ petitcours_patterns = [ name='petits-cours-demande-raw'), url(r'^demandes$', DemandeListView.as_view(), name='petits-cours-demandes-list'), - url(r'^demandes/(?P\d+)$', 'gestioncof.petits_cours_views.details', + url(r'^demandes/(?P\d+)$', + 'gestioncof.petits_cours_views.details', name='petits-cours-demande-details'), url(r'^demandes/(?P\d+)/traitement$', 'gestioncof.petits_cours_views.traitement', @@ -38,5 +39,3 @@ events_patterns = [ url(r'^(?P\d+)$', 'gestioncof.views.event'), url(r'^(?P\d+)/status$', 'gestioncof.views.event_status'), ] - - diff --git a/gestioncof/views.py b/gestioncof/views.py index cdf758b2..fb9fbcb8 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -8,8 +8,10 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.views import login as django_login_view from django.contrib.auth.models import User -from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, SurveyQuestionAnswer -from gestioncof.models import Event, EventRegistration, EventOption, EventOptionChoice +from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \ + SurveyQuestionAnswer +from gestioncof.models import Event, EventRegistration, EventOption, \ + EventOptionChoice from gestioncof.models import EventCommentField, EventCommentValue from gestioncof.shared import send_custom_mail from gestioncof.models import CofProfile, Clipper @@ -25,8 +27,10 @@ from bda.models import Tirage def home(request): data = {"surveys": Survey.objects.filter(old=False).all(), "events": Event.objects.filter(old=False).all(), - "open_surveys": Survey.objects.filter(survey_open=True, old=False).all(), - "open_events": Event.objects.filter(registration_open=True, old=False).all(), + "open_surveys": + Survey.objects.filter(survey_open=True, old=False).all(), + "open_events": + Event.objects.filter(registration_open=True, old=False).all(), "open_tirages": Tirage.objects.filter(active=True).all()} return render(request, "home.html", data) @@ -44,9 +48,11 @@ def login_ext(request): 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"}) + return render(request, "error.html", + {"error_type": "use_clipper_login"}) else: - return render(request, "error.html", {"error_type": "no_password"}) + return render(request, "error.html", + {"error_type": "no_password"}) except User.DoesNotExist: pass return django_login_view(request, template_name='login.html') @@ -75,7 +81,8 @@ def survey(request, survey_id): 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: @@ -87,7 +94,8 @@ def survey(request, survey_id): if form.is_valid(): all_answers = [] for question_id, answers_ids in form.answers(): - question = get_object_or_404(SurveyQuestion, id=question_id, + question = get_object_or_404(SurveyQuestion, + id=question_id, survey=survey) if type(answers_ids) != list: answers_ids = [answers_ids] @@ -102,21 +110,28 @@ def survey(request, survey_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) - return render(request, "survey.html", {"survey": survey, "form": form, "success": success, "deleted": deleted, "current_answer": current_answer}) + return render(request, "survey.html", {"survey": survey, "form": form, + "success": success, + "deleted": deleted, + "current_answer": current_answer}) def get_event_form_choices(event, form): @@ -138,14 +153,16 @@ def get_event_form_choices(event, form): 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) 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() @@ -160,17 +177,23 @@ def event(request, event_id): 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) - return render(request, "event.html", {"event": event, "form": form, "success": success}) + return render(request, "event.html", + {"event": event, "form": form, "success": success}) + def clean_post_for_status(initial): d = initial.copy() @@ -180,6 +203,7 @@ def clean_post_for_status(initial): d[k[3:]] = v return d + @buro_required def event_status(request, event_id): event = get_object_or_404(Event, id=event_id) @@ -192,15 +216,19 @@ def event_status(request, event_id): if value == "yes": 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() choices_count = {} @@ -210,7 +238,10 @@ def event_status(request, event_id): for user_choice in user_choices: for choice in user_choice.options.all(): 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}) + return render(request, "event_status.html", + {"event": event, "user_choices": user_choices, + "options": options, "choices_count": choices_count, + "form": form}) @buro_required @@ -221,13 +252,16 @@ def survey_status(request, survey_id): 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() answers_count = {} @@ -237,7 +271,10 @@ def survey_status(request, survey_id): for user_answer in user_answers: for answer in user_answer.answers.all(): 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}) + return render(request, "survey_status.html", + {"survey": survey, "user_answers": user_answers, + "questions": questions, "answers_count": answers_count, + "form": form}) @login_required @@ -272,7 +309,8 @@ def registration_form(request, login_clipper=None, username=None): user_form = RegistrationUserForm() profile_form = RegistrationProfileForm() user_form.fields['username'].initial = login_clipper - user_form.fields['email'].initial = login_clipper + "@clipper.ens.fr" + user_form.fields['email'].initial = \ + login_clipper + "@clipper.ens.fr" profile_form.fields['login_clipper'].initial = login_clipper if clipper.fullname: bits = clipper.fullname.split(" ") @@ -291,7 +329,10 @@ def registration_form(request, login_clipper=None, username=None): # new user user_form = RegistrationUserForm() profile_form = RegistrationProfileForm() - return render(request, "registration_form.html", {"user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper}) + 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): @@ -309,7 +350,8 @@ def registration_form2(request, login_clipper=None, username=None): profile_form = RegistrationProfileForm() 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" + user_form.fields['email'].initial = \ + login_clipper + "@clipper.ens.fr" profile_form.fields['login_clipper'].initial = login_clipper if clipper.fullname: bits = clipper.fullname.split(" ") @@ -327,8 +369,12 @@ def registration_form2(request, login_clipper=None, username=None): 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) event_forms.append(form) @@ -337,7 +383,10 @@ def registration_form2(request, login_clipper=None, username=None): user_form = RegistrationUserForm() profile_form = RegistrationProfileForm() 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}) + 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 @@ -350,7 +399,8 @@ def registration(request): 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] + 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: @@ -363,7 +413,8 @@ def registration(request): 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) + profile_form = RegistrationProfileForm(request_dict, + instance=profile) except User.DoesNotExist: try: clipper = Clipper.objects.filter(username=username).get() @@ -376,12 +427,14 @@ def registration(request): 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]): + 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) 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) @@ -390,26 +443,39 @@ def registration(request): 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.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}) success = True - return render(request, "registration_post.html", {"success": success, "user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper, "event_forms": event_forms}) + return render(request, "registration_post.html", + {"success": success, + "user_form": user_form, + "profile_form": profile_form, + "member": member, + "login_clipper": login_clipper, + "event_forms": event_forms}) else: return render(request, "registration.html") @@ -422,7 +488,9 @@ def export_members(request): writer = unicodecsv.writer(response) 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] + 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 @@ -437,8 +505,12 @@ def csv_export_mega(filename, qs): for reg in qs.all(): user = reg.user profile = user.profile - comments = "---".join([comment.content for comment in reg.comments.all()]) - bits = [user.username, user.first_name, user.last_name, user.email, profile.phone, profile.num, profile.comments if profile.comments else "", comments] + comments = "---".join( + [comment.content for comment in reg.comments.all()]) + bits = [user.username, user.first_name, user.last_name, user.email, + profile.phone, profile.num, + profile.comments if profile.comments else "", comments] + writer.writerow([unicode(bit) for bit in bits]) return response @@ -457,7 +529,8 @@ def export_mega_remarksonly(request): reg = val.registration user = reg.user profile = user.profile - bits = [user.username, user.first_name, user.last_name, user.email, profile.phone, profile.num, profile.comments, val.content] + bits = [user.username, user.first_name, user.last_name, user.email, + profile.phone, profile.num, profile.comments, val.content] writer.writerow([unicode(bit) for bit in bits]) return response @@ -476,7 +549,8 @@ def export_mega_bytype(request, 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) + qs = EventRegistration.objects.filter(event=event).filter( + options__id__exact=participant_type) return csv_export_mega(type + '_mega_2015.csv', qs) @@ -486,7 +560,8 @@ def export_mega_orgas(request): 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)) + 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) @@ -496,14 +571,16 @@ def export_mega_participants(request): 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)) + 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") + qs = EventRegistration.objects.filter(event=event).\ + order_by("user__username") return csv_export_mega('all_mega_2015.csv', qs) @@ -522,18 +599,22 @@ def utile_bda(request): def liste_bdadiff(request): titre = "BdA diffusion" personnes = CofProfile.objects.filter(mailing_bda=True, is_cof=True).all() - return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) + 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() - return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) + 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() - return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes}) + return render(request, "liste_mails.html", {"titre": titre, + "personnes": personnes}) diff --git a/gestioncof/widgets.py b/gestioncof/widgets.py index 4c864e38..0f36f202 100644 --- a/gestioncof/widgets.py +++ b/gestioncof/widgets.py @@ -2,8 +2,8 @@ from django.forms.widgets import Widget from django.forms.utils import flatatt from django.utils.safestring import mark_safe -class TriStateCheckbox(Widget): +class TriStateCheckbox(Widget): def __init__(self, attrs=None, choices=()): super(TriStateCheckbox, self).__init__(attrs) # choices can be any iterable, but we may need to render this widget @@ -12,7 +12,8 @@ class TriStateCheckbox(Widget): self.choices = list(choices) def render(self, name, value, attrs=None, choices=()): - if value is None: value = 'none' + if value is None: + value = 'none' final_attrs = self.build_attrs(attrs, value=value) output = [u"" % flatatt(final_attrs)] return mark_safe('\n'.join(output)) diff --git a/tirage_bda.py b/tirage_bda.py index bd021784..a4e46380 100644 --- a/tirage_bda.py +++ b/tirage_bda.py @@ -15,16 +15,19 @@ if __name__ == "__main__": start = time.time() shows = Spectacle.objects.all() members = Participant.objects.all() - choices = ChoixSpectacle.objects.order_by('participant', 'priority').select_related().all() + choices = ChoixSpectacle.objects.order_by('participant', 'priority').\ + select_related().all() available_slots = Spectacle.objects.aggregate(Sum('slots'))['slots__sum'] cursor = connection.cursor() - cursor.execute("SELECT SUM(`slots` * `price`) AS `total` FROM `bda_spectacle`;") + cursor.execute( + "SELECT SUM(`slots` * `price`) AS `total` FROM `bda_spectacle`;") total_price = cursor.fetchone()[0] print "%d spectacles" % len(shows) 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() @@ -54,7 +57,8 @@ if __name__ == "__main__": members2[member].append(show) member.total += show.price if len(members) < show.slots: - print "%d place(s) invendue(s) pour %s" % (show.slots - len(members), show) + print "%d place(s) invendue(s) pour %s" %\ + (show.slots - len(members), show) members2 = members2.items() print "Temps total: %.2fs" % (time.time() - start) print "Requêtes SQL:" From 6d68f6638fcc9d7b34f09d266b863b031151d492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sat, 9 Jul 2016 22:59:25 +0100 Subject: [PATCH 3/4] PEP8: few more changes Taken MR comments into account: * `and` is considered a binary operator, thus put at the beginning of the line when splitting a line, * same for `+`, * same for `.` (different reasons). --- bda/algorithm.py | 4 ++-- bda/forms.py | 4 ++-- bda/views.py | 8 ++++---- gestioncof/autocomplete.py | 4 ++-- gestioncof/forms.py | 12 ++++++------ gestioncof/petits_cours_views.py | 18 +++++++++--------- gestioncof/views.py | 8 ++++---- tirage_bda.py | 4 ++-- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/bda/algorithm.py b/bda/algorithm.py index a948d288..005e714f 100644 --- a/bda/algorithm.py +++ b/bda/algorithm.py @@ -87,8 +87,8 @@ class Algorithm(object): 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: + elif not self.choices[member][show].autoquit \ + and len(winners) < show.slots: self.appendResult(winners, member, show) self.appendResult(losers, member, show) else: diff --git a/bda/forms.py b/bda/forms.py index 1b93c6ef..213ec17b 100644 --- a/bda/forms.py +++ b/bda/forms.py @@ -43,5 +43,5 @@ class ResellForm(forms.Form): def __init__(self, participant, *args, **kwargs): super(ResellForm, self).__init__(*args, **kwargs) - self.fields['spectacle'].queryset = participant.attributions.all().\ - distinct() + self.fields['spectacle'].queryset = participant.attributions.all() \ + .distinct() diff --git a/bda/views.py b/bda/views.py index c09b5baa..d67044cf 100644 --- a/bda/views.py +++ b/bda/views.py @@ -119,8 +119,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) @@ -201,8 +201,8 @@ def do_tirage(request, tirage_id): data = {} shows = tirage_elt.spectacle_set.select_related().all() members = tirage_elt.participant_set.all() - choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt).\ - order_by('participant', 'priority').select_related().all() + choices = ChoixSpectacle.objects.filter(spectacle__tirage=tirage_elt) \ + .order_by('participant', 'priority').select_related().all() algo = Algorithm(shows, members, choices) results = algo(form.cleaned_data["token"]) total_slots = 0 diff --git a/gestioncof/autocomplete.py b/gestioncof/autocomplete.py index 4b222f06..21b5c3bc 100644 --- a/gestioncof/autocomplete.py +++ b/gestioncof/autocomplete.py @@ -39,8 +39,8 @@ def autocomplete(request): flat='True')) \ + list(queries['users'].values_list('profile__login_clipper', flat='True')) - queries['clippers'] = queries['clippers'].\ - exclude(username__in=usernames).distinct() + queries['clippers'] = queries['clippers'] \ + .exclude(username__in=usernames).distinct() # add clippers data.update(queries) diff --git a/gestioncof/forms.py b/gestioncof/forms.py index 8cfd6b9f..ed749814 100644 --- a/gestioncof/forms.py +++ b/gestioncof/forms.py @@ -102,8 +102,8 @@ class SurveyStatusFilterForm(forms.Form): for question in survey.questions.all(): for answer in question.answers.all(): name = "question_%d_answer_%d" % (question.id, answer.id) - if self.is_bound and\ - self.data.get(self.add_prefix(name), None): + if self.is_bound \ + and self.data.get(self.add_prefix(name), None): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" @@ -132,8 +132,8 @@ class EventStatusFilterForm(forms.Form): for option in event.options.all(): for choice in option.choices.all(): name = "option_%d_choice_%d" % (option.id, choice.id) - if self.is_bound and\ - self.data.get(self.add_prefix(name), None): + if self.is_bound \ + and self.data.get(self.add_prefix(name), None): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" @@ -309,8 +309,8 @@ class AdminEventForm(forms.Form): 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" \ diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index a4353b09..89bfe36e 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -56,12 +56,12 @@ def details(request, demande_id): 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 @@ -76,8 +76,8 @@ def _get_demande_candidates(demande, redo=False): if demande.agrege_requis: 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.order_by('?').select_related().all() @@ -352,8 +352,8 @@ def inscription(request): 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() diff --git a/gestioncof/views.py b/gestioncof/views.py index fb9fbcb8..11d15d53 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -427,8 +427,8 @@ def registration(request): 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]): + 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) was_cof = profile.is_cof @@ -579,8 +579,8 @@ def export_mega_participants(request): @buro_required def export_mega(request): event = Event.objects.filter(title="Mega 15") - qs = EventRegistration.objects.filter(event=event).\ - order_by("user__username") + qs = EventRegistration.objects.filter(event=event) \ + .order_by("user__username") return csv_export_mega('all_mega_2015.csv', qs) diff --git a/tirage_bda.py b/tirage_bda.py index a4e46380..8d01d6c6 100644 --- a/tirage_bda.py +++ b/tirage_bda.py @@ -15,8 +15,8 @@ if __name__ == "__main__": start = time.time() shows = Spectacle.objects.all() members = Participant.objects.all() - choices = ChoixSpectacle.objects.order_by('participant', 'priority').\ - select_related().all() + choices = ChoixSpectacle.objects.order_by('participant', 'priority') \ + .select_related().all() available_slots = Spectacle.objects.aggregate(Sum('slots'))['slots__sum'] cursor = connection.cursor() cursor.execute( From 483ddf0f86d3ccd3e7ca925565868083e91bf1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sat, 9 Jul 2016 23:26:02 +0100 Subject: [PATCH 4/4] PEP8: Forgot a few binops --- bda/admin.py | 4 ++-- gestioncof/admin.py | 4 ++-- gestioncof/csv_views.py | 4 ++-- gestioncof/forms.py | 3 +-- gestioncof/petits_cours_views.py | 12 ++++++------ tirage_bda.py | 8 ++++---- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/bda/admin.py b/bda/admin.py index bcbc6069..58228e7e 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -119,8 +119,8 @@ Le Bureau des Arts 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)) + 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" diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 3d5e8891..bb03bbd4 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -24,8 +24,8 @@ def add_link_field(target_model='', field='', link_text=unicode, if not link_obj.id: return "" url = reverse(reverse_path, args=(link_obj.id,)) - return mark_safe("%s" % - (url, link_text(link_obj))) + return mark_safe("%s" + % (url, link_text(link_obj))) link.allow_tags = True link.short_description = desc_text(reverse_name + ' link') cls.link = link diff --git a/gestioncof/csv_views.py b/gestioncof/csv_views.py index 6ba59d26..733768dc 100644 --- a/gestioncof/csv_views.py +++ b/gestioncof/csv_views.py @@ -7,8 +7,8 @@ from django.apps import apps def export(qs, fields=None): model = qs.model response = HttpResponse(content_type='text/csv') - response['Content-Disposition'] = 'attachment; filename=%s.csv' %\ - slugify(model.__name__) + response['Content-Disposition'] = 'attachment; filename=%s.csv' \ + % slugify(model.__name__) writer = csv.writer(response) # Write headers to CSV file if fields: diff --git a/gestioncof/forms.py b/gestioncof/forms.py index ed749814..bf983df5 100644 --- a/gestioncof/forms.py +++ b/gestioncof/forms.py @@ -108,8 +108,7 @@ class SurveyStatusFilterForm(forms.Form): else: initial = "none" field = forms.ChoiceField( - label="%s : %s" % - (question.question, answer.answer), + label="%s : %s" % (question.question, answer.answer), choices=[("yes", "yes"), ("no", "no"), ("none", "none")], widget=TriStateCheckbox, required=False, diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index 89bfe36e..2e8c420a 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -186,8 +186,8 @@ def _traitement_other_preparing(request, demande): continue user = candidates[choice] if user in proposals[matiere]: - errors.append(u"La proposition %d en %s est un doublon" % - (choice_id + 1, matiere)) + errors.append(u"La proposition %d en %s est un doublon" + % (choice_id + 1, matiere)) continue proposals[matiere].append(user) attribdata[matiere.id].append(user.id) @@ -198,10 +198,10 @@ def _traitement_other_preparing(request, demande): if not proposals[matiere]: errors.append(u"Aucune proposition pour %s" % (matiere,)) elif len(proposals[matiere]) < 3: - errors.append(u"Seulement %d proposition%s pour %s" % - (len(proposals[matiere]), "s" - if len(proposals[matiere]) > 1 else "", - matiere)) + 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, diff --git a/tirage_bda.py b/tirage_bda.py index 8d01d6c6..502cb45e 100644 --- a/tirage_bda.py +++ b/tirage_bda.py @@ -26,8 +26,8 @@ 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() @@ -57,8 +57,8 @@ if __name__ == "__main__": members2[member].append(show) member.total += show.price if len(members) < show.slots: - print "%d place(s) invendue(s) pour %s" %\ - (show.slots - len(members), show) + print "%d place(s) invendue(s) pour %s" \ + % (show.slots - len(members), show) members2 = members2.items() print "Temps total: %.2fs" % (time.time() - start) print "Requêtes SQL:"