diff --git a/bda/models.py b/bda/models.py index b91da5ef..ca7cb6a5 100644 --- a/bda/models.py +++ b/bda/models.py @@ -17,7 +17,7 @@ class Spectacle (models.Model): date = models.DateTimeField ("Date & heure") location = models.ForeignKey(Salle) description = models.TextField ("Description", blank = True) - #slots_description = models.TextField ("Description des places", blank = True) + slots_description = models.TextField ("Description des places", blank = True) price = models.FloatField("Prix d'une place", blank = True) slots = models.IntegerField ("Places") priority = models.IntegerField ("Priorité", default = 1000) diff --git a/bda/views.py b/bda/views.py index d99a3abe..367ae765 100644 --- a/bda/views.py +++ b/bda/views.py @@ -33,7 +33,7 @@ class BaseBdaFormSet(BaseInlineFormSet): raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") spectacles.append(spectacle) -@buro_required +@cof_required def etat_places(request): spectacles1 = ChoixSpectacle.objects.all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle')) spectacles2 = ChoixSpectacle.objects.filter(double = True).all().values('spectacle','spectacle__title').annotate(total = models.Count('spectacle')) @@ -53,7 +53,7 @@ def etat_places(request): @cof_required def inscription(request): - if time.time() > 1349474400: + if False and time.time() > 1349474400: return render(request, "error.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort le 6 octobre dans la soirée "}) BdaFormSet = inlineformset_factory(Participant, ChoixSpectacle, fields = ("spectacle","double","autoquit","priority",), formset = BaseBdaFormSet) participant, created = Participant.objects.get_or_create(user = request.user) diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 9fe8c82b..b161f6de 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -229,6 +229,23 @@ class VoterAdmin(UserProfileAdmin): ] """ +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',) + search_fields = ('user__username', 'user__first_name', 'user__last_name', 'user__email', 'matiere__name') + +class PetitCoursDemandeAdmin(admin.ModelAdmin): + list_display = ('name','email','agrege_requis','niveau','created','traitee','processed') + list_filter = ('traitee','niveau') + admin.site.register(Survey, SurveyAdmin) admin.site.register(SurveyQuestion, SurveyQuestionAdmin) admin.site.register(Event, EventAdmin) @@ -237,7 +254,9 @@ admin.site.unregister(User) admin.site.register(User, UserProfileAdmin) admin.site.register(CofProfile) admin.site.register(PetitCoursSubject) -admin.site.register(PetitCoursAbility) -admin.site.register(PetitCoursDemande) +admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin) +admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin) +admin.site.register(PetitCoursAttributionCounter, PetitCoursAttributionCounterAdmin) +admin.site.register(PetitCoursDemande, PetitCoursDemandeAdmin) #admin.site.register(Voter, VoterAdmin) admin.site.register(EventRegistration, EventRegistrationAdmin) diff --git a/gestioncof/decorators.py b/gestioncof/decorators.py index 6ffb2d39..4565f0cb 100644 --- a/gestioncof/decorators.py +++ b/gestioncof/decorators.py @@ -8,6 +8,7 @@ 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") def is_buro(user): try: diff --git a/gestioncof/models.py b/gestioncof/models.py index 2d251181..92eaaad2 100644 --- a/gestioncof/models.py +++ b/gestioncof/models.py @@ -47,7 +47,8 @@ class CofProfile(models.Model): mailing_bda_revente = models.BooleanField("Recevoir les mails de revente de places BdA", default = False) is_buro = models.BooleanField("Membre du Burô", default = False) petits_cours_accept = models.BooleanField("Recevoir des petits cours", default = False) - petits_cours_sent = models.IntegerField("Nombre de propositions petits cours reçues", default = 0) + petits_cours_remarques = models.TextField(_(u"Remarques et précisions pour les petits cours"), + blank = True, default = "") class Meta: verbose_name = "Profil COF" diff --git a/gestioncof/shared.py b/gestioncof/shared.py index efcd0e50..0b9cd462 100644 --- a/gestioncof/shared.py +++ b/gestioncof/shared.py @@ -1,14 +1,38 @@ from django.contrib.sites.models import Site from django.conf import settings -from django_cas.backends import CASBackend +from django_cas.backends import CASBackend, _verify as CASverify +from django_cas.models import User from django.db import models, connection from gestioncof.models import CofProfile class COFCASBackend(CASBackend): - def authenticate(self, ticket, service): + def authenticate_cas(self, ticket, service, request): + """Verifies CAS ticket and gets or creates User object""" + + username, attributes = CASverify(ticket, service) + if attributes: + request.session['attributes'] = attributes + if not username: + return None + profiles = CofProfile.objects.filter(login_clipper = username) + if len(profiles) > 0: + profile = profiles.order_by('-is_cof')[0] + user = profile.user + return user + try: + user = User.objects.get(username=username) + except User.DoesNotExist: + # user will have an "unusable" password + user = User.objects.create_user(username, '') + user.save() + return user + + def authenticate(self, ticket, service, request): """Authenticates CAS ticket and retrieves user data""" - user = super(COFCASBackend, self).authenticate(ticket, service) + user = self.authenticate_cas(ticket, service, request) + if user is None: + return user try: profile = user.get_profile() except CofProfile.DoesNotExist: @@ -34,15 +58,21 @@ def context_processor (request): } return data -def lock_table(model): +def lock_table(*models): + query = "LOCK TABLES " + for i, model in enumerate(models): + table = model._meta.db_table + if i > 0: query += ", " + query += "%s WRITE" % table cursor = connection.cursor() - table = model._meta.db_table - cursor.execute("LOCK TABLES %s WRITE" % table) + cursor.execute(query) row = cursor.fetchone() return row -def unlock_table(model): +def unlock_tables(*models): cursor = connection.cursor() cursor.execute("UNLOCK TABLES") row = cursor.fetchone() return row + +unlock_table = unlock_tables diff --git a/gestioncof/views.py b/gestioncof/views.py index 0adda9f8..cb38268f 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -656,11 +656,13 @@ def export_members(request): @buro_required def export_mega_orgas(request): response = HttpResponse(mimetype = 'text/csv') - response['Content-Disposition'] = 'attachment; filename=participants_mega.csv' + response['Content-Disposition'] = 'attachment; filename=orgas_mega.csv' writer = unicodecsv.UnicodeWriter(response) - event = Event.objects.filter(title = "MEGA") - for reg in EventRegistration.objects.filter(event = event).exclude(options__id__exact = 3).all(): + event = Event.objects.get(title = "MEGA") + type_option = event.options.get(name = "Type") + participant_type = type_option.choices.get(value = "Participant").id + for reg in EventRegistration.objects.filter(event = event).exclude(options__id__exact = participant_type).all(): user = reg.user profile = user.get_profile() bits = [user.username, user.first_name, user.last_name, user.email, profile.phone, profile.num] @@ -674,8 +676,10 @@ def export_mega_participants(request): response['Content-Disposition'] = 'attachment; filename=participants_mega.csv' writer = unicodecsv.UnicodeWriter(response) - event = Event.objects.filter(title = "MEGA") - for reg in EventRegistration.objects.filter(event = event).filter(options__id__exact = 3).all(): + event = Event.objects.get(title = "MEGA") + type_option = event.options.get(name = "Type") + participant_type = type_option.choices.get(value = "Participant").id + for reg in EventRegistration.objects.filter(event = event).filter(options__id__exact = participant_type).all(): user = reg.user profile = user.get_profile() bits = [user.username, user.first_name, user.last_name, user.email, profile.phone, profile.num] @@ -704,4 +708,4 @@ def utile_cof(request): @buro_required def utile_bda(request): - return render(request, "utile_bda.html", {}) \ No newline at end of file + return render(request, "utile_bda.html", {}) diff --git a/media/cof.css b/media/cof.css index f709b7fe..609c1ca9 100644 --- a/media/cof.css +++ b/media/cof.css @@ -239,6 +239,12 @@ fieldset legend { background-color: transparent; } +.error { + font-weight: bold; + color: #B00000; + background-color: transparent; +} + #main form ul.errorlist li { font-weight: bold; color: #B00000; @@ -462,3 +468,123 @@ hr { .tristate:hover { cursor: pointer; } + +abbr[title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 16px; + font-weight: 300; + line-height: 25px; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} diff --git a/templates/gestioncof/demande-petit-cours.html b/templates/gestioncof/demande-petit-cours.html index 2ab1d2df..3a447e3a 100644 --- a/templates/gestioncof/demande-petit-cours.html +++ b/templates/gestioncof/demande-petit-cours.html @@ -5,7 +5,7 @@ {% if success %}

Votre demande a été enregistrée avec succès !

{% else %} -
+ {% csrf_token %} {{ form.as_table }} diff --git a/templates/gestioncof/home.html b/templates/gestioncof/home.html index a53a06c6..38a83b4e 100644 --- a/templates/gestioncof/home.html +++ b/templates/gestioncof/home.html @@ -4,7 +4,7 @@ {% endblock %} {% block realcontent %} -

Bienvenue, {% if user.first_name %}{{ user.first_name }}{% else %}{{ user.username }}{% endif %}

+

Bienvenue, {% if user.first_name %}{{ user.first_name }}{% else %}{{ user.username }}{% endif %} {% if user.profile.is_cof %}Membre du COF{% else %}Non-membre du COF{% endif %}

{% if open_events %}

Événements

{% endif %} + +

BdA

+

Divers

{% if user.get_profile.is_buro %}

Administration