diff --git a/bda/admin.py b/bda/admin.py index d989295d..cc4746ca 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + from django.core.mail import send_mail from django.contrib import admin @@ -52,9 +54,9 @@ class ParticipantAdmin(admin.ModelAdmin): def total(self, obj): tot = obj.total if tot: - return u"%.02f €" % tot + return "%.02f €" % tot else: - return u"0 €" + return "0 €" total.admin_order_field = "total" total.short_description = "Total à payer" list_display = ("user", "nb_places", "total", "paid", "paymenttype", @@ -70,7 +72,7 @@ class ParticipantAdmin(admin.ModelAdmin): for member in queryset.all(): attribs = member.attributions.all() if len(attribs) == 0: - mail = u"""Cher-e %s, + mail = """Cher-e %s, Tu t'es inscrit-e pour le tirage au sort du BdA. Malheureusement, tu n'as obtenu aucune place. @@ -120,7 +122,7 @@ Le Bureau des Arts attribs_text = "" name = member.user.get_full_name() for attrib in attribs: - attribs_text += u"- 1 place pour %s\n" % attrib + attribs_text += "- 1 place pour %s\n" % attrib deadline = member.tirage.fermeture + timedelta(days=7) mail = mail % (name, attribs_text, deadline.strftime('%d %b %Y')) @@ -129,14 +131,14 @@ Le Bureau des Arts fail_silently=True) count = len(queryset.all()) if count == 1: - message_bit = u"1 membre a" + message_bit = "1 membre a" plural = "" else: - message_bit = u"%d membres ont" % count + message_bit = "%d membres ont" % count plural = "s" - self.message_user(request, u"%s été informé%s avec succès." + self.message_user(request, "%s été informé%s avec succès." % (message_bit, plural)) - send_attribs.short_description = u"Envoyer les résultats par mail" + send_attribs.short_description = "Envoyer les résultats par mail" class AttributionAdminForm(forms.ModelForm): diff --git a/bda/algorithm.py b/bda/algorithm.py index 005e714f..4a2dbdcc 100644 --- a/bda/algorithm.py +++ b/bda/algorithm.py @@ -1,6 +1,7 @@ # coding: utf-8 from __future__ import division +from __future__ import unicode_literals from django.db.models import Max diff --git a/bda/autocomplete_light_registry.py b/bda/autocomplete_light_registry.py index 7aa43b07..aa6d4d57 100644 --- a/bda/autocomplete_light_registry.py +++ b/bda/autocomplete_light_registry.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + import autocomplete_light from bda.models import Participant, Spectacle diff --git a/bda/models.py b/bda/models.py index 349a71e4..d7d64db0 100644 --- a/bda/models.py +++ b/bda/models.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + import calendar from django.db import models @@ -8,6 +10,7 @@ from django.template import loader, Context from django.core import mail from django.conf import settings from django.utils import timezone +from django.utils.encoding import python_2_unicode_compatible def render_template(template_name, data): @@ -16,6 +19,7 @@ def render_template(template_name, data): return tmpl.render(ctxt) +@python_2_unicode_compatible class Tirage(models.Model): title = models.CharField("Titre", max_length=300) ouverture = models.DateTimeField("Date et heure d'ouverture du tirage") @@ -26,18 +30,20 @@ class Tirage(models.Model): def date_no_seconds(self): return self.fermeture.strftime('%d %b %Y %H:%M') - def __unicode__(self): - return u"%s - %s" % (self.title, self.date_no_seconds()) + def __str__(self): + return "%s - %s" % (self.title, self.date_no_seconds()) +@python_2_unicode_compatible class Salle(models.Model): name = models.CharField("Nom", max_length=300) address = models.TextField("Adresse") - def __unicode__(self): + def __str__(self): return self.name +@python_2_unicode_compatible class Spectacle(models.Model): title = models.CharField("Titre", max_length=300) date = models.DateTimeField("Date & heure") @@ -57,7 +63,7 @@ class Spectacle(models.Model): ordering = ("priority", "date", "title",) def __repr__(self): - return u"[%s]" % self.__unicode__() + return "[%s]" % self def timestamp(self): return "%d" % calendar.timegm(self.date.utctimetuple()) @@ -65,9 +71,9 @@ class Spectacle(models.Model): def date_no_seconds(self): return self.date.strftime('%d %b %Y %H:%M') - def __unicode__(self): - return u"%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), - self.location, self.price) + def __str__(self): + return "%s - %s, %s, %.02f€" % (self.title, self.date_no_seconds(), + self.location, self.price) def send_rappel(self): # On récupère la liste des participants @@ -156,10 +162,11 @@ class ChoixSpectacle(models.Model): verbose_name_plural = "voeux" +@python2_unicode_compatible class Attribution(models.Model): participant = models.ForeignKey(Participant) spectacle = models.ForeignKey(Spectacle, related_name="attribues") - given = models.BooleanField(u"Donnée", default=False) + given = models.BooleanField("Donnée", default=False) - def __unicode__(self): - return u"%s -- %s" % (self.participant, self.spectacle) + def __str__(self): + return "%s -- %s" % (self.participant, self.spectacle) diff --git a/bda/views.py b/bda/views.py index 844ef60c..1ca76a5a 100644 --- a/bda/views.py +++ b/bda/views.py @@ -1,6 +1,7 @@ # coding: utf-8 from __future__ import division +from __future__ import unicode_literals from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required @@ -145,7 +146,7 @@ def inscription(request, tirage_id): return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": - u"Tirage au sort dans la journée !", + "Tirage au sort dans la journée !", "choices": choices}) def formfield_callback(f, **kwargs): @@ -223,7 +224,7 @@ def do_tirage(request, tirage_id): deficit = (show.slots - len(members)) * show.price total_sold += show.slots * show.price if deficit >= 0: - if u"Opéra" in show.location.name: + if "Opéra" in show.location.name: opera_deficit += deficit total_deficit += deficit data["total_sold"] = total_sold - total_deficit @@ -277,7 +278,7 @@ def do_resell(request, form): spectacle = form.cleaned_data["spectacle"] count = form.cleaned_data["count"] places = "2 places" if count == "2" else "une place" - mail = u"""Bonjour, + mail = """Bonjour, Je souhaite revendre %s pour %s le %s (%s) à %.02f€. Contactez moi par email si vous êtes intéressé·e·s ! diff --git a/cof/urls.py b/cof/urls.py index b5d2b65a..16c6a5f6 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -1,5 +1,7 @@ # -*-coding:utf-8 -* +from __future__ import unicode_literals + from django.conf import settings from django.conf.urls import patterns, include, url from django.conf.urls.static import static diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 8a1fb431..1c9ea5ca 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + from django.contrib import admin from gestioncof.models import * from gestioncof.petits_cours_models import * @@ -8,6 +10,7 @@ from django.contrib.auth.admin import UserAdmin from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ +import django.utils.six as six import autocomplete_light @@ -168,17 +171,21 @@ class UserProfileAdmin(UserAdmin): ] +# FIXME: This is absolutely horrible. 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) + return "%s %s (%s)" % (self.first_name, self.last_name, self.username) else: return self.username -User.__unicode__ = user_unicode +if six.PY2: + User.__unicode__ = user_unicode +else: + User.__str__ = user_unicode class EventRegistrationAdmin(admin.ModelAdmin): form = autocomplete_light.modelform_factory(EventRegistration, exclude=[]) - list_display = ('__unicode__', 'event', 'user', 'paid') + list_display = ('__unicode__' if six.PY2 else '__str__', 'event', 'user', 'paid') list_filter = ('paid',) search_fields = ('user__username', 'user__first_name', 'user__last_name', 'user__email', 'event__title') diff --git a/gestioncof/autocomplete.py b/gestioncof/autocomplete.py index 21b5c3bc..248a6ae7 100644 --- a/gestioncof/autocomplete.py +++ b/gestioncof/autocomplete.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + from django import shortcuts from django.http import Http404 from django.db.models import Q diff --git a/gestioncof/autocomplete_light_registry.py b/gestioncof/autocomplete_light_registry.py index 4a2737cb..1b211691 100644 --- a/gestioncof/autocomplete_light_registry.py +++ b/gestioncof/autocomplete_light_registry.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + import autocomplete_light from django.contrib.auth.models import User diff --git a/gestioncof/csv_views.py b/gestioncof/csv_views.py index 733768dc..f8037413 100644 --- a/gestioncof/csv_views.py +++ b/gestioncof/csv_views.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + import csv from django.http import HttpResponse, HttpResponseForbidden from django.template.defaultfilters import slugify diff --git a/gestioncof/decorators.py b/gestioncof/decorators.py index 62c527df..e5416e32 100644 --- a/gestioncof/decorators.py +++ b/gestioncof/decorators.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + from django_cas_ng.decorators import user_passes_test diff --git a/gestioncof/models.py b/gestioncof/models.py index 540145d5..ccb85bad 100644 --- a/gestioncof/models.py +++ b/gestioncof/models.py @@ -1,32 +1,36 @@ # coding: utf-8 +from __future__ import unicode_literals + from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import python_2_unicode_compatible +import django.utils.six as six from django.db.models.signals import post_save -from petits_cours_models import * +from gestioncof.petits_cours_models import * OCCUPATION_CHOICES = ( - ('exterieur', _(u"Extérieur")), - ('1A', _(u"1A")), - ('2A', _(u"2A")), - ('3A', _(u"3A")), - ('4A', _(u"4A")), - ('archicube', _(u"Archicube")), - ('doctorant', _(u"Doctorant")), - ('CST', _(u"CST")), + ('exterieur', _("Extérieur")), + ('1A', _("1A")), + ('2A', _("2A")), + ('3A', _("3A")), + ('4A', _("4A")), + ('archicube', _("Archicube")), + ('doctorant', _("Doctorant")), + ('CST', _("CST")), ) TYPE_COTIZ_CHOICES = ( - ('etudiant', _(u"Normalien étudiant")), - ('normalien', _(u"Normalien élève")), - ('exterieur', _(u"Extérieur")), + ('etudiant', _("Normalien étudiant")), + ('normalien', _("Normalien élève")), + ('exterieur', _("Extérieur")), ) TYPE_COMMENT_FIELD = ( - ('text', _(u"Texte long")), - ('char', _(u"Texte court")), + ('text', _("Texte long")), + ('char', _("Texte court")), ) @@ -69,8 +73,8 @@ class CofProfile(models.Model): verbose_name = "Profil COF" verbose_name_plural = "Profils COF" - def __unicode__(self): - return unicode(self.user.username) + def __str__(self): + return six.text_type(self.user.username) def create_user_profile(sender, instance, created, **kwargs): @@ -86,6 +90,7 @@ class Club(models.Model): membres = models.ManyToManyField(User, related_name="clubs") +@python_2_unicode_compatible class CustomMail(models.Model): shortname = models.SlugField(max_length=50, blank=False) title = models.CharField("Titre", max_length=200, blank=False) @@ -97,10 +102,11 @@ class CustomMail(models.Model): verbose_name = "Mail personnalisable" verbose_name_plural = "Mails personnalisables" - def __unicode__(self): - return u"%s: %s" % (self.shortname, self.title) + def __str__(self): + return "%s: %s" % (self.shortname, self.title) +@python_2_unicode_compatible class Event(models.Model): title = models.CharField("Titre", max_length=200) location = models.CharField("Lieu", max_length=200) @@ -116,10 +122,11 @@ class Event(models.Model): class Meta: verbose_name = "Événement" - def __unicode__(self): - return unicode(self.title) + def __str__(self): + return six.text_type(self.title) +@python_2_unicode_compatible class EventCommentField(models.Model): event = models.ForeignKey(Event, related_name="commentfields") name = models.CharField("Champ", max_length=200) @@ -130,8 +137,8 @@ class EventCommentField(models.Model): class Meta: verbose_name = "Champ" - def __unicode__(self): - return unicode(self.name) + def __str__(self): + return six.text_type(self.name) class EventCommentValue(models.Model): @@ -141,6 +148,7 @@ class EventCommentValue(models.Model): content = models.TextField("Contenu", blank=True, null=True) +@python_2_unicode_compatible class EventOption(models.Model): event = models.ForeignKey(Event, related_name="options") name = models.CharField("Option", max_length=200) @@ -149,10 +157,11 @@ class EventOption(models.Model): class Meta: verbose_name = "Option" - def __unicode__(self): - return unicode(self.name) + def __str__(self): + return six.text_type(self.name) +@python_2_unicode_compatible class EventOptionChoice(models.Model): event_option = models.ForeignKey(EventOption, related_name="choices") value = models.CharField("Valeur", max_length=200) @@ -161,10 +170,11 @@ class EventOptionChoice(models.Model): verbose_name = "Choix" verbose_name_plural = "Choix" - def __unicode__(self): - return unicode(self.value) + def __str__(self): + return six.text_type(self.value) +@python_2_unicode_compatible class EventRegistration(models.Model): user = models.ForeignKey(User) event = models.ForeignKey(Event) @@ -182,6 +192,7 @@ class EventRegistration(models.Model): unicode(self.event.title)) +@python_2_unicode_compatible class Survey(models.Model): title = models.CharField("Titre", max_length=200) details = models.TextField("Détails", blank=True) @@ -191,10 +202,11 @@ class Survey(models.Model): class Meta: verbose_name = "Sondage" - def __unicode__(self): - return unicode(self.title) + def __str__(self): + return six.text_type(self.title) +@python_2_unicode_compatible class SurveyQuestion(models.Model): survey = models.ForeignKey(Survey, related_name="questions") question = models.CharField("Question", max_length=200) @@ -203,10 +215,11 @@ class SurveyQuestion(models.Model): class Meta: verbose_name = "Question" - def __unicode__(self): - return unicode(self.question) + def __str__(self): + return six.text_type(self.question) +@python_2_unicode_compatible class SurveyQuestionAnswer(models.Model): survey_question = models.ForeignKey(SurveyQuestion, related_name="answers") answer = models.CharField("Réponse", max_length=200) @@ -214,8 +227,8 @@ class SurveyQuestionAnswer(models.Model): class Meta: verbose_name = "Réponse" - def __unicode__(self): - return unicode(self.answer) + def __str__(self): + return six.text_type(self.answer) class SurveyAnswer(models.Model): diff --git a/gestioncof/petits_cours_models.py b/gestioncof/petits_cours_models.py index a9aede0c..b8487478 100644 --- a/gestioncof/petits_cours_models.py +++ b/gestioncof/petits_cours_models.py @@ -1,25 +1,30 @@ # coding: utf-8 +from __future__ import unicode_literals + from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import python_2_unicode_compatible +from django.utils.six.moves import reduce def choices_length(choices): return reduce(lambda m, choice: max(m, len(choice[0])), choices, 0) LEVELS_CHOICES = ( - ('college', _(u"Collège")), - ('lycee', _(u"Lycée")), - ('prepa1styear', _(u"Prépa 1ère année / L1")), - ('prepa2ndyear', _(u"Prépa 2ème année / L2")), - ('licence3', _(u"Licence 3")), - ('other', _(u"Autre (préciser dans les commentaires)")), + ('college', _("Collège")), + ('lycee', _("Lycée")), + ('prepa1styear', _("Prépa 1ère année / L1")), + ('prepa2ndyear', _("Prépa 2ème année / L2")), + ('licence3', _("Licence 3")), + ('other', _("Autre (préciser dans les commentaires)")), ) +@python_2_unicode_compatible class PetitCoursSubject(models.Model): - name = models.CharField(_(u"Matière"), max_length=30) + name = models.CharField(_("Matière"), max_length=30) users = models.ManyToManyField(User, related_name="petits_cours_matieres", through="PetitCoursAbility") @@ -27,10 +32,11 @@ class PetitCoursSubject(models.Model): verbose_name = "Matière de petits cours" verbose_name_plural = "Matières des petits cours" - def __unicode__(self): + def __str__(self): return self.name +@python_2_unicode_compatible class PetitCoursAbility(models.Model): user = models.ForeignKey(User) matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_(u"Matière")) @@ -43,11 +49,12 @@ class PetitCoursAbility(models.Model): verbose_name = "Compétence petits cours" verbose_name_plural = "Compétences des petits cours" - def __unicode__(self): - return u"%s - %s - %s" % (self.user.username, + def __str__(self): + return "%s - %s - %s" % (self.user.username, self.matiere, self.niveau) +@python_2_unicode_compatible class PetitCoursDemande(models.Model): name = models.CharField(_(u"Nom/prénom"), max_length=200) email = models.CharField(_(u"Adresse email"), max_length=300) @@ -89,11 +96,12 @@ class PetitCoursDemande(models.Model): verbose_name = "Demande de petits cours" verbose_name_plural = "Demandes de petits cours" - def __unicode__(self): - return u"Demande %d du %s" % (self.id, - self.created.strftime("%d %b %Y")) + def __str__(self): + return "Demande %d du %s" % (self.id, + self.created.strftime("%d %b %Y")) +@python_2_unicode_compatible class PetitCoursAttribution(models.Model): user = models.ForeignKey(User) demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande")) @@ -107,11 +115,12 @@ class PetitCoursAttribution(models.Model): verbose_name = "Attribution de petits cours" verbose_name_plural = "Attributions de petits cours" - def __unicode__(self): + def __str__(self): return u"Attribution de la demande %d à %s pour %s" \ % (self.demande.id, self.user.username, self.matiere) +@python_2_unicode_compatible class PetitCoursAttributionCounter(models.Model): user = models.ForeignKey(User) matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere")) @@ -122,5 +131,5 @@ class PetitCoursAttributionCounter(models.Model): verbose_name_plural = "Compteurs d'attributions de petits cours" def __unicode__(self): - return u"%d demandes envoyées à %s pour %s" \ + return "%d demandes envoyées à %s pour %s" \ % (self.count, self.user.username, self.matiere) diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index 2e8c420a..7cba7ae1 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + from django.shortcuts import render, get_object_or_404, redirect from django.core import mail from django.core.mail import EmailMessage @@ -196,9 +198,9 @@ def _traitement_other_preparing(request, demande): else: proposed_for[user].append(matiere) if not proposals[matiere]: - errors.append(u"Aucune proposition pour %s" % (matiere,)) + errors.append("Aucune proposition pour %s" % (matiere,)) elif len(proposals[matiere]) < 3: - errors.append(u"Seulement %d proposition%s pour %s" + errors.append("Seulement %d proposition%s pour %s" % (len(proposals[matiere]), "s" if len(proposals[matiere]) > 1 else "", matiere)) diff --git a/gestioncof/templatetags/utils.py b/gestioncof/templatetags/utils.py index 5847f9a6..4785c822 100644 --- a/gestioncof/templatetags/utils.py +++ b/gestioncof/templatetags/utils.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + from django import template from django.utils.safestring import mark_safe @@ -22,7 +24,7 @@ def highlight_text(text, q): @register.filter def highlight_user(user, q): if user.first_name and user.last_name: - text = u"%s %s (%s)" % (user.first_name, user.last_name, user.username) + text = "%s %s (%s)" % (user.first_name, user.last_name, user.username) else: text = user.username return highlight_text(text, q) @@ -30,7 +32,7 @@ def highlight_user(user, q): @register.filter def highlight_clipper(clipper, q): if clipper.fullname: - text = u"%s (%s)" % (clipper.fullname, clipper.username) + text = "%s (%s)" % (clipper.fullname, clipper.username) else: text = clipper.username return highlight_text(text, q) diff --git a/gestioncof/views.py b/gestioncof/views.py index 11d15d53..dc05d816 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + import unicodecsv from django.shortcuts import redirect, get_object_or_404, render @@ -7,6 +9,7 @@ from django.http import Http404, HttpResponse 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 +import django.utils.six as six from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \ SurveyQuestionAnswer @@ -277,6 +280,35 @@ def survey_status(request, survey_id): "form": form}) +class UserProfileForm(forms.ModelForm): + first_name = forms.CharField(label=_('Prénom'), max_length=30) + last_name = forms.CharField(label=_('Nom'), max_length=30) + + def __init__(self, *args, **kw): + super(UserProfileForm, self).__init__(*args, **kw) + self.fields['first_name'].initial = self.instance.user.first_name + self.fields['last_name'].initial = self.instance.user.last_name + + self.fields.keyOrder = [ + 'first_name', + 'last_name', + 'phone', + 'mailing_cof', + 'mailing_bda', + 'mailing_bda_revente', + ] + + def save(self, *args, **kw): + super(UserProfileForm, self).save(*args, **kw) + self.instance.user.first_name = self.cleaned_data.get('first_name') + self.instance.user.last_name = self.cleaned_data.get('last_name') + self.instance.user.save() + + class Meta: + model = CofProfile + fields = ("phone", "mailing_cof", "mailing_bda", "mailing_bda_revente",) +>>>>>>> Compatibilité python 3 + @login_required def profile(request): success = False diff --git a/gestioncof/widgets.py b/gestioncof/widgets.py index 0f36f202..d819f5a2 100644 --- a/gestioncof/widgets.py +++ b/gestioncof/widgets.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + from django.forms.widgets import Widget from django.forms.utils import flatatt from django.utils.safestring import mark_safe @@ -15,5 +17,5 @@ class TriStateCheckbox(Widget): if value is None: value = 'none' final_attrs = self.build_attrs(attrs, value=value) - output = [u"" % flatatt(final_attrs)] + output = ["" % flatatt(final_attrs)] return mark_safe('\n'.join(output)) diff --git a/sync_clipper.py b/sync_clipper.py index 4dac6447..78a88e76 100644 --- a/sync_clipper.py +++ b/sync_clipper.py @@ -1,4 +1,7 @@ #!/usr/bin/env python + +from __future__ import print_function, unicode_literals + import os import sys @@ -7,10 +10,10 @@ if __name__ == "__main__": from gestioncof.models import Clipper current = {} - print "[ FETCHING ]" + print("[ FETCHING ]") for clipper in Clipper.objects.all(): current[clipper.username] = clipper - print "[ SYNCING ]" + print("[ SYNCING ]") for line in sys.stdin: bits = line.split(":") username = bits[0] @@ -20,9 +23,9 @@ if __name__ == "__main__": if clipper.fullname != fullname: clipper.fullname = fullname clipper.save() - print "Updated", username + print("Updated", username) else: clipper = Clipper(username=username, fullname=fullname) clipper.save() - print "Created", username - print "[ DONE ]" + print("Created", username) + print("[ DONE ]")