diff --git a/Ernestophone/settings/common.py b/Ernestophone/settings/common.py index caeacf0..05994aa 100644 --- a/Ernestophone/settings/common.py +++ b/Ernestophone/settings/common.py @@ -1,4 +1,5 @@ import os + from django.utils.translation import gettext_lazy as _ try: @@ -31,64 +32,60 @@ DBPASSWD = import_secret("DBPASSWD") ACCOUNT_CREATION_PASS = import_secret("ACCOUNT_CREATION_PASS") - - -BASE_DIR = os.path.join( - os.path.dirname(__file__), "..", ".." -) +BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..") INSTALLED_APPS = [ - 'trombonoscope', - 'actu', - 'colorful', - 'pads', - 'calendrier', - 'gestion.apps.GestionConfig', - 'partitions.apps.PartitionsConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'avatar', - 'instruments', + "trombonoscope", + "actu", + "colorful", + "pads", + "calendrier", + "gestion.apps.GestionConfig", + "partitions.apps.PartitionsConfig", + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "avatar", + "instruments", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.middleware.locale.LocaleMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.middleware.locale.LocaleMiddleware", ] ROOT_URLCONF = "Ernestophone.urls" -TEMPLATES = [{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - - ], - 'libraries':{ - 'changelang': 'gestion.templatetags.changelang', - 'modulo': 'gestion.templatetags.modulo', - 'autotranslate': 'gestion.templatetags.autotranslate', - 'halflength': 'gestion.templatetags.halflength', - - } +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + "libraries": { + "changelang": "gestion.templatetags.changelang", + "modulo": "gestion.templatetags.modulo", + "autotranslate": "gestion.templatetags.autotranslate", + "halflength": "gestion.templatetags.halflength", + }, + }, } -}] +] WSGI_APPLICATION = "Ernestophone.wsgi.application" @@ -104,51 +101,51 @@ DATABASES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # I18n # I18n -LANGUAGE_CODE = 'fr' +LANGUAGE_CODE = "fr" LANGUAGES = ( - ('fr', _('Français')), - ('en', _('English')), + ("fr", _("Français")), + ("en", _("English")), ) -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True -LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'), ) +LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),) -AUTH_PROFILE_MODEL = 'gestion.ErnestoUser' +AUTH_PROFILE_MODEL = "gestion.ErnestoUser" LOGIN_URL = "/login" AVATAR_CLEANUP_DELETED = True AVATAR_AUTO_GENERATE_SIZES = (250,) AVATAR_CHANGE_TEMPLATE = "trombonoscope/change_avatar.html" -AVATAR_MAX_AVATARS_PER_USER=1 -AVATAR_EXPOSE_USERNAMES=False -AVATAR_STORAGE_DIR="trombonoscope" -AVATAR_ADD_TEMPLATE="trombonoscope/add_avatar.html" -AVATAR_DELETE_TEMPLATE="trombonoscope/delete_avatar.html" -AVATAR_DEFAULT_URL="Ernesto" -AVATAR_PROVIDERS=( - 'avatar.providers.PrimaryAvatarProvider', - 'avatar.providers.DefaultAvatarProvider', - ) -AVATAR_THUMB_FORMAT = 'JPEG' +AVATAR_MAX_AVATARS_PER_USER = 1 +AVATAR_EXPOSE_USERNAMES = False +AVATAR_STORAGE_DIR = "trombonoscope" +AVATAR_ADD_TEMPLATE = "trombonoscope/add_avatar.html" +AVATAR_DELETE_TEMPLATE = "trombonoscope/delete_avatar.html" +AVATAR_DEFAULT_URL = "Ernesto" +AVATAR_PROVIDERS = ( + "avatar.providers.PrimaryAvatarProvider", + "avatar.providers.DefaultAvatarProvider", +) +AVATAR_THUMB_FORMAT = "JPEG" diff --git a/Ernestophone/settings/local.py b/Ernestophone/settings/local.py index 84d52cb..9cca1ea 100644 --- a/Ernestophone/settings/local.py +++ b/Ernestophone/settings/local.py @@ -1,19 +1,14 @@ import os - from .common import * # noqa from .common import BASE_DIR, INSTALLED_APPS, MIDDLEWARE - EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" DEBUG = True INSTALLED_APPS += ["debug_toolbar"] -MIDDLEWARE = ( - ["debug_toolbar.middleware.DebugToolbarMiddleware"] - + MIDDLEWARE -) +MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE STATIC_URL = "/static/" STATIC_ROOT = "static" diff --git a/Ernestophone/settings/prod.py b/Ernestophone/settings/prod.py index 2721521..ffa7575 100644 --- a/Ernestophone/settings/prod.py +++ b/Ernestophone/settings/prod.py @@ -3,7 +3,6 @@ import os from .common import * # noqa from .common import BASE_DIR - DEBUG = False ALLOWED_HOSTS = [ @@ -12,11 +11,7 @@ ALLOWED_HOSTS = [ ] STATIC_URL = "/static/" -STATIC_ROOT = os.path.join( - BASE_DIR, "..", "..", "public", "ernesto", "static" -) +STATIC_ROOT = os.path.join(BASE_DIR, "..", "..", "public", "ernesto", "static") MEDIA_URL = "/media/" -MEDIA_ROOT = os.path.join( - BASE_DIR, "..", "media" -) +MEDIA_ROOT = os.path.join(BASE_DIR, "..", "media") diff --git a/Ernestophone/urls.py b/Ernestophone/urls.py index bd16f95..f44c1be 100644 --- a/Ernestophone/urls.py +++ b/Ernestophone/urls.py @@ -13,37 +13,39 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ -from django.contrib import admin -from django.urls import path, include -from gestion import views as gestion_views -from django.contrib.auth import views as auth_views -import django.contrib.auth.urls as urls -from django.conf.urls.static import static from django.conf import settings from django.conf.urls.i18n import i18n_patterns +from django.conf.urls.static import static +from django.contrib import admin +from django.contrib.auth import views as auth_views +from django.urls import include, path +from gestion import views as gestion_views urlpatterns = [] urlpatterns += i18n_patterns( - path('', gestion_views.home, name="home"), - path("registration", gestion_views.inscription_membre, name="registration"), - path("change", gestion_views.change_membre, name="change_membre"), - path("password", gestion_views.change_password, name="change_password"), - path("thanks", gestion_views.thanks, name="thanks"), - path("changename", gestion_views.changename, name="change-doodle-name"), - path("logout", auth_views.LogoutView.as_view(next_page="home"), name="logout"), + path("", gestion_views.Home.as_view(), name="home"), + path("registration", gestion_views.Inscription.as_view(), + name="registration"), + path("change", gestion_views.ChangeMembre.as_view(), name="change_membre"), + path("password", gestion_views.ChangePassword.as_view(), + name="change_password"), + path("thanks", gestion_views.Thanks.as_view(), name="thanks"), + path("changename", gestion_views.ChangeName.as_view(), name="change-doodle-name"), + path("logout", auth_views.LogoutView.as_view(next_page="home"), + name="logout"), + path("login", gestion_views.MyLoginView.as_view(), name="login"), + path("agenda/", include("calendrier.urls", namespace="calendrier")), + path("partitions/", include("partitions.urls")), + path("instruments/", include("instruments.urls")), + path("pads/", include("pads.urls")), path( - "login", - gestion_views.MyLoginView.as_view(), - name="login" + "admin/", + admin.site.urls, ), - path('agenda/', include('calendrier.urls',namespace='calendrier')), - path('partitions/', include('partitions.urls')), - path('instruments/', include('instruments.urls')), - path('pads/', include('pads.urls')), - path('admin/', admin.site.urls,), - path('trombonoscope/',include('trombonoscope.urls')), - path("actu/",include('actu.urls')), - path('avatar/', include('avatar.urls')), - prefix_default_language=False ) + path("trombonoscope/", include("trombonoscope.urls")), + path("actu/", include("actu.urls")), + path("avatar/", include("avatar.urls")), + prefix_default_language=False, +) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/Ernestophone/wsgi.py b/Ernestophone/wsgi.py index 4e94f46..d83b56c 100644 --- a/Ernestophone/wsgi.py +++ b/Ernestophone/wsgi.py @@ -1,4 +1,3 @@ - """ WSGI config for Ernestophone project. @@ -10,10 +9,8 @@ https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ import os -os.environ.setdefault( - "DJANGO_SETTINGS_MODULE", - "Ernestophone.settings.prod" -) +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ernestophone.settings.prod") from django.core.wsgi import get_wsgi_application + application = get_wsgi_application() diff --git a/actu/admin.py b/actu/admin.py index 8c38f3f..846f6b4 100644 --- a/actu/admin.py +++ b/actu/admin.py @@ -1,3 +1 @@ -from django.contrib import admin - # Register your models here. diff --git a/actu/apps.py b/actu/apps.py index 1706a35..69dff04 100644 --- a/actu/apps.py +++ b/actu/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class ActuConfig(AppConfig): - name = 'actu' + name = "actu" diff --git a/actu/migrations/0001_initial.py b/actu/migrations/0001_initial.py index f8c7382..28e8937 100644 --- a/actu/migrations/0001_initial.py +++ b/actu/migrations/0001_initial.py @@ -7,22 +7,34 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='Actu', + name="Actu", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('text', models.TextField(null=True, verbose_name='Info')), - ('text_en', models.TextField(blank=True, null=True, verbose_name='Info en anglais')), - ('order', models.IntegerField(verbose_name='ordre')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("text", models.TextField(null=True, verbose_name="Info")), + ( + "text_en", + models.TextField( + blank=True, null=True, verbose_name="Info en anglais" + ), + ), + ("order", models.IntegerField(verbose_name="ordre")), ], options={ - 'ordering': ('order',), - 'verbose_name_plural': 'Actualités', - 'verbose_name': 'Actualité', + "ordering": ("order",), + "verbose_name_plural": "Actualités", + "verbose_name": "Actualité", }, ), ] diff --git a/actu/models.py b/actu/models.py index e37280f..e5df7b1 100644 --- a/actu/models.py +++ b/actu/models.py @@ -1,14 +1,17 @@ from django.db import models from django.utils.translation import gettext_lazy as _ + class Actu(models.Model): + text = models.TextField(_("Info"), null=True, blank=False) text_en = models.TextField(("Info en anglais"), null=True, blank=True) order = models.IntegerField(verbose_name=_("ordre")) + def __str__(self): return self.text class Meta: verbose_name = _("Actualité") verbose_name_plural = _("Actualités") - ordering = ('order',) + ordering = ("order",) diff --git a/actu/urls.py b/actu/urls.py index d613564..6632b61 100644 --- a/actu/urls.py +++ b/actu/urls.py @@ -2,11 +2,10 @@ from django.urls import path from actu import views - app_name = "actu" urlpatterns = [ path("", views.ActuList.as_view(), name="liste"), path("ajouter", views.ActuCreate.as_view(), name="add_actu"), path("edition/", views.ActuUpdate.as_view(), name="edit_actu"), - path("supprimer/", views.ActuDelete.as_view(), name="delete_actu") + path("supprimer/", views.ActuDelete.as_view(), name="delete_actu"), ] diff --git a/actu/views.py b/actu/views.py index ec15121..5aa23af 100644 --- a/actu/views.py +++ b/actu/views.py @@ -1,9 +1,9 @@ -from django.shortcuts import render -from gestion.mixins import ChefRequiredMixin -from django.views.generic import CreateView, DeleteView, ListView, UpdateView -from django.urls import reverse_lazy -from actu.models import Actu from django.http import HttpResponseRedirect +from django.urls import reverse_lazy +from django.views.generic import CreateView, DeleteView, ListView, UpdateView + +from actu.models import Actu +from gestion.mixins import ChefRequiredMixin class ActuList(ChefRequiredMixin, ListView): @@ -14,7 +14,7 @@ class ActuList(ChefRequiredMixin, ListView): class ActuCreate(ChefRequiredMixin, CreateView): model = Actu - fields = ["text","order","text_en"] + fields = ["text", "order", "text_en"] template_name = "actu/create_actu.html" success_url = reverse_lazy("actu:liste") @@ -26,7 +26,7 @@ class ActuCreate(ChefRequiredMixin, CreateView): class ActuUpdate(ChefRequiredMixin, UpdateView): model = Actu - fields = ["text","order","text_en"] + fields = ["text", "order", "text_en"] template_name = "actu/update_actu.html" success_url = reverse_lazy("actu:liste") diff --git a/calendrier/admin.py b/calendrier/admin.py index 4bc528d..2d241a6 100644 --- a/calendrier/admin.py +++ b/calendrier/admin.py @@ -1,6 +1,5 @@ from django.contrib import admin - from .models import Event admin.site.register(Event) diff --git a/calendrier/apps.py b/calendrier/apps.py index ff4f137..ba19cd3 100644 --- a/calendrier/apps.py +++ b/calendrier/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class CalendrierConfig(AppConfig): - name = 'calendrier' + name = "calendrier" diff --git a/calendrier/calend.py b/calendrier/calend.py index 60eaaa1..0701527 100644 --- a/calendrier/calend.py +++ b/calendrier/calend.py @@ -1,44 +1,44 @@ -from django.utils.html import conditional_escape as esc -from itertools import groupby from calendar import HTMLCalendar -from django.utils.translation import gettext_lazy as _ from datetime import date +from itertools import groupby + +from django.utils.html import conditional_escape as esc +from django.utils.translation import gettext_lazy as _ class EventCalendar(HTMLCalendar): - def __init__(self, pEvents): super(EventCalendar, self).__init__() - self.events = self.group_by_day(pEvents.order_by('date')) + self.events = self.group_by_day(pEvents.order_by("date")) def formatday(self, day, weekday): if day != 0: cssclass = self.cssclasses[weekday] if date.today() == date(self.year, self.month, day): - cssclass += ' today' + cssclass += " today" if day in self.events: - cssclass += ' filled' + cssclass += " filled" body = [] for ev in self.events[day]: body.append(_('' % ev.id) body.append(esc(ev.nom)) - body.append('
') - return self.day_cell(cssclass, - '
%d
%s' - % (day, ''.join(body))) - return self.day_cell(cssclass, - '
%d
' % day) - return self.day_cell('noday', ' ') + body.append("
") + return self.day_cell( + cssclass, + '
%d
%s' % (day, "".join(body)), + ) + return self.day_cell(cssclass, '
%d
' % day) + return self.day_cell("noday", " ") def formatmonth(self, year, month): self.year, self.month = year, month return super(EventCalendar, self).formatmonth(year, month) def group_by_day(self, pEvents): - def field(ev): return(ev.date.day) - return dict( - [(dat, list(items)) for dat, items in groupby(pEvents, field)] - ) + def field(ev): + return ev.date.day + + return dict([(dat, list(items)) for dat, items in groupby(pEvents, field)]) def day_cell(self, cssclass, body): return '%s' % (cssclass, body) diff --git a/calendrier/forms.py b/calendrier/forms.py index 57e1a0c..3c112a1 100644 --- a/calendrier/forms.py +++ b/calendrier/forms.py @@ -1,61 +1,59 @@ from django import forms +from django.utils.translation import gettext_lazy as _ + from calendrier.models import Event, Participants from gestion.models import ErnestoUser -from django.utils.translation import gettext_lazy as _ class ModifEventForm(forms.ModelForm): class Meta: model = Event - exclude = ['slug'] + exclude = ["slug"] widgets = { - 'description': forms.Textarea(attrs={ - "placeholder": _("facultatif, balises html supportées")}), - 'date': forms.TextInput(attrs={"placeholder": 'jj/mm/aaaa'}), - 'debut': forms.TextInput(attrs={"placeholder": 'hh:mm'}), - 'fin': forms.TextInput(attrs={"placeholder": _('hh:mm facultatif')}) + "description": forms.Textarea( + attrs={"placeholder": _("facultatif, balises html supportées")} + ), + "date": forms.TextInput(attrs={"placeholder": "jj/mm/aaaa"}), + "debut": forms.TextInput(attrs={"placeholder": "hh:mm"}), + "fin": forms.TextInput(attrs={"placeholder": _("hh:mm facultatif")}), } - class EventForm(forms.ModelForm): - - class Meta: model = Event - exclude = ['slug'] + exclude = ["slug"] widgets = { - 'nomcourt': forms.TextInput( - attrs={"placeholder": _('9 caractères max')}), - 'description': forms.Textarea( - attrs={"placeholder": _("facultatif, balises html supportées")}), - 'date': forms.TextInput(attrs={"placeholder": 'jj/mm/aaaa'}), - 'debut': forms.TextInput(attrs={"placeholder": 'hh:mm'}), - 'fin': forms.TextInput(attrs={"placeholder": _('hh:mm facultatif')}), + "nomcourt": forms.TextInput(attrs={"placeholder": _("9 caractères max")}), + "description": forms.Textarea( + attrs={"placeholder": _("facultatif, balises html supportées")} + ), + "date": forms.TextInput(attrs={"placeholder": "jj/mm/aaaa"}), + "debut": forms.TextInput(attrs={"placeholder": "hh:mm"}), + "fin": forms.TextInput(attrs={"placeholder": _("hh:mm facultatif")}), } class ParticipantsForm(forms.ModelForm): class Meta: model = Participants - fields = ('reponse', 'details') + fields = ("reponse", "details") widgets = { - 'details': forms.Textarea( - attrs={"placeholder": _("50 caractères max")}), + "details": forms.Textarea(attrs={"placeholder": _("50 caractères max")}), } class ChangeDoodleName(forms.ModelForm): def __init__(self, *args, **kwargs): super(ChangeDoodleName, self).__init__(*args, **kwargs) - self.fields['doodlename'].initial = self.instance.profile.get_doodlename() + self.fields["doodlename"].initial = self.instance.profile.get_doodlename() def save(self, *args, **kwargs): super(ChangeDoodleName, self).save(*args, **kwargs) - self.instance.profile.doodlename = self.cleaned_data['doodlename'] + self.instance.profile.doodlename = self.cleaned_data["doodlename"] self.instance.profile.save() self.instance.save() class Meta: - model = ErnestoUser - fields = ('doodlename',) + model = ErnestoUser + fields = ("doodlename",) diff --git a/calendrier/migrations/0001_initial.py b/calendrier/migrations/0001_initial.py index 42840b3..9a406ac 100644 --- a/calendrier/migrations/0001_initial.py +++ b/calendrier/migrations/0001_initial.py @@ -7,37 +7,82 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('gestion', '0001_initial'), + ("gestion", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Event', + name="Event", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), - ('nom', models.CharField(max_length=100)), - ('nomcourt', models.CharField(max_length=9, verbose_name='Nom court')), - ('date', models.DateField()), - ('debut', models.TimeField()), - ('fin', models.TimeField(blank=True, null=True)), - ('slug', models.CharField(max_length=7, editable=False, unique=True)), - ('lieu', models.CharField(max_length=200)), - ('description', models.TextField(blank=True)), - ('desc_users', models.TextField(blank=True, verbose_name='Infos (visible seulement des fanfaron-ne-s)', null=True)), - ('calendrier', models.BooleanField(verbose_name='Afficher dans le calendrier pour tous', default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + verbose_name="ID", + serialize=False, + ), + ), + ("nom", models.CharField(max_length=100)), + ("nomcourt", models.CharField(max_length=9, verbose_name="Nom court")), + ("date", models.DateField()), + ("debut", models.TimeField()), + ("fin", models.TimeField(blank=True, null=True)), + ("slug", models.CharField(max_length=7, editable=False, unique=True)), + ("lieu", models.CharField(max_length=200)), + ("description", models.TextField(blank=True)), + ( + "desc_users", + models.TextField( + blank=True, + verbose_name="Infos (visible seulement des fanfaron-ne-s)", + null=True, + ), + ), + ( + "calendrier", + models.BooleanField( + verbose_name="Afficher dans le calendrier pour tous", + default=False, + ), + ), ], options={ - 'verbose_name': 'Événement', + "verbose_name": "Événement", }, ), migrations.CreateModel( - name='Participants', + name="Participants", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), - ('reponse', models.CharField(max_length=20, choices=[('oui', 'Oui'), ('non', 'Non'), ('pe', 'Peut-être')], default='non', verbose_name='Réponse')), - ('details', models.CharField(blank=True, max_length=50)), - ('event', models.ForeignKey(to='calendrier.Event', on_delete=models.CASCADE)), - ('participant', models.ForeignKey(to='gestion.ErnestoUser', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + verbose_name="ID", + serialize=False, + ), + ), + ( + "reponse", + models.CharField( + max_length=20, + choices=[("oui", "Oui"), ("non", "Non"), ("pe", "Peut-être")], + default="non", + verbose_name="Réponse", + ), + ), + ("details", models.CharField(blank=True, max_length=50)), + ( + "event", + models.ForeignKey(to="calendrier.Event", on_delete=models.CASCADE), + ), + ( + "participant", + models.ForeignKey( + to="gestion.ErnestoUser", on_delete=models.CASCADE + ), + ), ], ), ] diff --git a/calendrier/migrations/0002_auto_20200714_1559.py b/calendrier/migrations/0002_auto_20200714_1559.py index b8a2b90..e98e71c 100644 --- a/calendrier/migrations/0002_auto_20200714_1559.py +++ b/calendrier/migrations/0002_auto_20200714_1559.py @@ -1,43 +1,63 @@ # Generated by Django 2.2.14 on 2020-07-14 15:59 -from django.db import migrations, models import uuid +from django.db import migrations, models + class Migration(migrations.Migration): dependencies = [ - ('calendrier', '0001_initial'), + ("calendrier", "0001_initial"), ] operations = [ migrations.AlterModelOptions( - name='event', - options={'verbose_name': 'Evenement'}, + name="event", + options={"verbose_name": "Evenement"}, ), migrations.AddField( - model_name='event', - name='desc_users_en', - field=models.TextField(blank=True, null=True, verbose_name='Infos en anglais (visible seulement des fanfaron-ne-s)'), + model_name="event", + name="desc_users_en", + field=models.TextField( + blank=True, + null=True, + verbose_name="Infos en anglais (visible seulement des fanfaron-ne-s)", + ), ), migrations.AddField( - model_name='event', - name='description_en', + model_name="event", + name="description_en", field=models.TextField(blank=True), ), migrations.AlterField( - model_name='event', - name='calendrier', - field=models.CharField(choices=[('F', 'Visible seulement par les fanfarons'), ('T', 'Afficher dans le calendrier pour tous'), ('H', 'Hall of fame')], default='F', max_length=1), + model_name="event", + name="calendrier", + field=models.CharField( + choices=[ + ("F", "Visible seulement par les fanfarons"), + ("T", "Afficher dans le calendrier pour tous"), + ("H", "Hall of fame"), + ], + default="F", + max_length=1, + ), ), migrations.AlterField( - model_name='event', - name='slug', - field=models.CharField(default=uuid.uuid1, editable=False, max_length=7, unique=True), + model_name="event", + name="slug", + field=models.CharField( + default=uuid.uuid1, editable=False, max_length=7, unique=True + ), ), migrations.AlterField( - model_name='participants', - name='reponse', - field=models.CharField(choices=[('oui', 'Oui'), ('non', 'Non'), ('pe', 'Peut-etre')], default='non', max_length=20, verbose_name='Réponse'), + model_name="participants", + name="reponse", + field=models.CharField( + choices=[("oui", "Oui"), ("non", "Non"), ("pe", "Peut-etre")], + default="non", + max_length=20, + verbose_name="Réponse", + ), ), ] diff --git a/calendrier/models.py b/calendrier/models.py index 4e3c929..00033e9 100644 --- a/calendrier/models.py +++ b/calendrier/models.py @@ -1,53 +1,62 @@ -from django.db import models import uuid -from gestion.models import ErnestoUser + +from django.db import models from django.utils.translation import gettext_lazy as _ -from colorful.fields import RGBColorField + +from gestion.models import ErnestoUser ANSWERS = ( - ('oui', _('Oui')), - ('non', _('Non')), - ('pe', _('Peut-etre')), - ) + ("oui", _("Oui")), + ("non", _("Non")), + ("pe", _("Peut-etre")), +) + + class Event(models.Model): + nom = models.CharField(max_length=100) nomcourt = models.CharField(max_length=9, verbose_name=_("Nom court")) date = models.DateField() debut = models.TimeField() fin = models.TimeField(blank=True, null=True) - slug = models.CharField(max_length=7, editable=False, unique=True, default=uuid.uuid1) + slug = models.CharField( + max_length=7, editable=False, unique=True, default=uuid.uuid1 + ) lieu = models.CharField(max_length=200) description = models.TextField(blank=True) description_en = models.TextField(blank=True) desc_users = models.TextField( - blank=True, - verbose_name=_("Infos (visible seulement des fanfaron-ne-s)"), - null=True) + blank=True, + verbose_name=_("Infos (visible seulement des fanfaron-ne-s)"), + null=True, + ) desc_users_en = models.TextField( - blank=True, - verbose_name=_("Infos en anglais (visible seulement des fanfaron-ne-s)"), - null=True) + blank=True, + verbose_name=_("Infos en anglais (visible seulement des fanfaron-ne-s"), + null=True, + ) CALENDRIER_CHOICES = [ - ('F', _('Visible seulement par les fanfarons')), - ('T', _('Afficher dans le calendrier pour tous')), - ('H', _('Hall of fame')), + ("F", _("Visible seulement par les fanfarons")), + ("T", _("Afficher dans le calendrier pour tous")), + ("H", _("Hall of fame")), ] calendrier = models.CharField( max_length=1, choices=CALENDRIER_CHOICES, - default='F', + default="F", ) - def __str__(self): return self.nom class Meta: verbose_name = _("Evenement") + class Participants(models.Model): event = models.ForeignKey(Event, on_delete=models.CASCADE) participant = models.ForeignKey(ErnestoUser, on_delete=models.CASCADE) - reponse = models.CharField(_("Réponse"), max_length=20, default="non", - choices=ANSWERS) + reponse = models.CharField( + _("Réponse"), max_length=20, default="non", choices=ANSWERS + ) details = models.CharField(max_length=50, blank=True) diff --git a/calendrier/templates/calendrier/home.html b/calendrier/templates/calendrier/home.html index 5828e82..39130d3 100644 --- a/calendrier/templates/calendrier/home.html +++ b/calendrier/templates/calendrier/home.html @@ -73,6 +73,24 @@

+ + {% if photo %} +
+ {% if photo.url %} + {% if photo.auteur %}{{photo.auteur}}{%endif%} + {% elif photo.auteur %} + + + {% endif %} +
+ {% else %} + +
+ +
+ {% endif %} +
+ {% if events_a_venir_not_answered %}

{% blocktrans count counter=events_a_venir_not_answered|length %}Doodle à remplir !!!! :{% plural %}Doodles à remplir !!!! :{% endblocktrans %}

@@ -183,23 +201,6 @@
{% endif %} - - {% if photo %} -
- {% if photo.url %} - {% if photo.auteur %}{{photo.auteur}}{%endif%} - {% elif photo.auteur %} - - - {% endif %} -
- {% else %} - -
- -
- {% endif %} -
diff --git a/calendrier/templatetags/translate.py b/calendrier/templatetags/translate.py index 64416bc..3cdccbd 100644 --- a/calendrier/templatetags/translate.py +++ b/calendrier/templatetags/translate.py @@ -20,7 +20,7 @@ def translate(tex): tex = tex.replace("December", "Décembre", 1) tex = tex.replace("Mon", "Lun", 1) tex = tex.replace("Tue", "Mar", 1) - tex = tex.replace('Wed', "Mer", 1) + tex = tex.replace("Wed", "Mer", 1) tex = tex.replace("Thu", "Jeu", 1) tex = tex.replace("Fri", "Ven", 1) tex = tex.replace("Sat", "Sam", 1) diff --git a/calendrier/tests/test_views.py b/calendrier/tests/test_views.py index e9bbbe9..081f7b8 100644 --- a/calendrier/tests/test_views.py +++ b/calendrier/tests/test_views.py @@ -6,6 +6,7 @@ from django.test import Client, TestCase from django.utils import timezone from gestion.models import ErnestoUser + from ..models import Event User = get_user_model() @@ -28,11 +29,7 @@ class TestViews(TestCase): ernesto = new_user("ernesto", ernesto=True) ernesto_c = Client() ernesto_c.force_login(ernesto) - self.client_matrix = [ - (chef, chef_c), - (ernesto, ernesto_c), - (None, Client()) - ] + self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())] # A private and a public event now = timezone.now() later = now + timedelta(seconds=3600) @@ -44,7 +41,7 @@ class TestViews(TestCase): fin=later.time(), slug="privevt", lieu="somewhere", - calendrier=False + calendrier=False, ) self.pub_event = Event.objects.create( nom="public event", @@ -54,7 +51,7 @@ class TestViews(TestCase): fin=later.time(), slug="pubevt", lieu="somewhere", - calendrier=True + calendrier=True, ) # Everyone can see theses pages @@ -88,13 +85,16 @@ class TestViews(TestCase): chef, _ = self.client_matrix[0] codereps = ["oui", "non", "pe"] for coderep in codereps: - url = "/calendar/rep/{}/{}/{}".format(chef.profile.slug, self.priv_event.slug, coderep) + url = "/calendar/rep/{}/{}/{}".format( + chef.profile.slug, self.priv_event.slug, coderep + ) self._everyone_can_get(url, redirect_url="/calendar/") # Only ernesto members can get theses pages def _get_restricted_page(self, url, chef_only=False, redirect_url=None): """Shorthand for testing wether a page in only accessible by ernesto members""" + def user_allowed(user): if user is None: return False diff --git a/calendrier/urls.py b/calendrier/urls.py index 765254f..95cd463 100644 --- a/calendrier/urls.py +++ b/calendrier/urls.py @@ -1,17 +1,19 @@ from django.urls import path from . import views -from .views import EventUpdate, EventDelete +from .views import EventDelete, EventUpdate -app_name = 'calendrier' +app_name = "calendrier" urlpatterns = [ - path('', views.liste, name='liste'), - path("calendar", views.home, name="home"), - path("new", views.create_event, name="create_event"), + path("", views.Agenda.as_view(), name="liste"), + path("calendar", views.Home.as_view(), name="home"), + path("new", views.CreateEvent.as_view(), name="create_event"), path("edition/", EventUpdate.as_view(), name="edit_event"), path("supprimer/", EventDelete.as_view(), name="delete_event"), - path("/changename", views.changename, name="change-doodle-name"), - path("/reponse", views.reponse, name="reponse"), - path("/", views.calendar, name="view-month"), - path("", views.view_event, name="view-event"), + path("/changename", views.ChangeName.as_view(), + name="change-doodle-name"), + path("/reponse", views.ReponseEvent.as_view(), name="reponse"), + path("/", views.Calendar.as_view(), + name="view-month"), + path("", views.ViewEvent.as_view(), name="view-event"), ] diff --git a/calendrier/views.py b/calendrier/views.py index 3641eea..d3b498b 100644 --- a/calendrier/views.py +++ b/calendrier/views.py @@ -1,217 +1,312 @@ +import random +import string +from calendar import monthrange from collections import defaultdict from datetime import date, datetime -import string -import random + from django.db.models import Q - -from django.shortcuts import render, redirect, get_object_or_404 -from django.contrib.sites.shortcuts import get_current_site -from django.db.models import Count -from django.utils.safestring import mark_safe -from django.views.generic import UpdateView, DeleteView +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse, reverse_lazy -from django.contrib.auth.decorators import login_required -from django.utils.decorators import method_decorator -from django.core.mail import send_mail -from django.http import Http404 +from django.utils.safestring import mark_safe +from django.views.generic import DeleteView, UpdateView -from gestion.models import ErnestoUser from actu.models import Actu from calendrier.calend import EventCalendar -from calendar import monthrange -from calendrier.forms import ModifEventForm, EventForm, ParticipantsForm, ChangeDoodleName +from calendrier.forms import (ChangeDoodleName, EventForm, ModifEventForm, + ParticipantsForm) from calendrier.models import Event, Participants from gestion.models import Photo -from partitions.decorators import chef_required - +from django.views.generic import TemplateView +from django.contrib.auth.mixins import LoginRequiredMixin +from gestion.mixins import ChefRequiredMixin def generer(*args): caracteres = string.ascii_letters + string.digits aleatoire = [random.choice(caracteres) for _ in range(6)] - return ''.join(aleatoire) - -def liste(request): - if request.user.is_authenticated : - return redirect('calendrier:home') - lToday = datetime.today() - photo = Photo.objects.filter(cat='liste').order_by('?').first() - events_a_venir = Event.objects.filter(date__gte = lToday).exclude(calendrier__iexact = 'F').order_by("-date") - events_passe = Event.objects.filter(date__lt = lToday).filter(calendrier__iexact = 'H').order_by("-date") - return render(request, 'calendrier/agenda.html', {"events_a_venir": events_a_venir,"events_passe":events_passe,"photo":photo}) + return "".join(aleatoire) def named_month(pMonthNumber): - return date(1900, pMonthNumber, 1).strftime('%B') + return date(1900, pMonthNumber, 1).strftime("%B") -@login_required -def home(request): + +class Agenda(TemplateView): + template_name = "calendrier/agenda.html" + + def dispatch(self, request, *args, **kwargs): + if request.user.is_authenticated: + return redirect('calendrier:home') + return super(Agenda, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + lToday = datetime.today() + context['photo'] = Photo.objects.filter( + cat="liste").order_by("?").first() + context['events_a_venir'] = ( + Event.objects.filter(date__gte=lToday) + .exclude(calendrier__iexact="F") + .order_by("-date") + ) + context['events_passe'] = ( + Event.objects.filter(date__lt=lToday) + .filter(calendrier__iexact="H") + .order_by("-date") + ) + return context + + +class Calendar(LoginRequiredMixin, TemplateView): + template_name = "calendrier/home.html" + + @property + def pYear(self): + return self.kwargs['pYear'] + + @property + def pMonth(self): + return self.kwargs['pMonth'] + + def get_context_data(self, **kwargs): + context = super(Calendar, self).get_context_data(**kwargs) + actu = Actu.objects.all() + photo = Photo.objects.filter(cat="home").order_by("?").first() + lToday = datetime.now() + lYear = int(self.pYear) + lMonth = int(self.pMonth) + lCalendarFromMonth = datetime(lYear, lMonth, 1) + lCalendarToMonth = datetime(lYear, lMonth, + monthrange(lYear, lMonth)[1]) + lEvents = Event.objects.filter( + date__gte=lCalendarFromMonth, date__lte=lCalendarToMonth + ) + lCalendar = EventCalendar(lEvents).formatmonth(lYear, lMonth) + lPreviousYear = lYear + lPreviousMonth = lMonth - 1 + if lPreviousMonth == 0: + lPreviousMonth = 12 + lPreviousYear -= 1 + lNextYear = lYear + lNextMonth = lMonth + 1 + if lNextMonth == 13: + lNextMonth = 1 + lNextYear = lYear + 1 + lYearAfterThis = lYear + 1 + lYearBeforeThis = lYear - 1 + try: + events_a_venir_not_answered = Event.objects.filter( + date__gte=lToday).exclude( + participants__participant=self.request.user.profile + ) + events_a_venir_answered_yes = Event.objects.filter( + date__gte=lToday).filter( + Q(participants__participant=self.request.user.profile) + & Q(participants__reponse="oui") + ) + events_a_venir_answered_no = Event.objects.filter( + date__gte=lToday).filter( + Q(participants__participant=self.request.user.profile) + & Q(participants__reponse="non") + ) + events_a_venir_answered_pe = Event.objects.filter( + date__gte=lToday).filter( + Q(participants__participant=self.request.user.profile) + & Q(participants__reponse="pe") + ) + except Event.DoesNotExist: + events_a_venir_not_answered = Event.objects.filter( + date__gte=lToday).exclude( + participants__participant__user__username=self.request.user + ) + events_a_venir_answered_yes = Event.objects.filter( + date__gte=lToday).filter( + Q(participants__participant__user__username=self.request.user) + & Q(participants__reponse="oui") + ) + events_a_venir_answered_no = Event.objects.filter( + date__gte=lToday).filter( + Q(participants__participant__user__username=self.request.user) + & Q(participants__reponse="non") + ) + events_a_venir_answered_pe = Event.objects.filter( + date__gte=lToday).filter( + Q(participants__participant__user__username=self.request.user) + & Q(participants__reponse="pe") + ) + + context["Calendar"] = mark_safe(lCalendar) + context["Month"] = lMonth + context["MonthName"] = named_month(lMonth) + context["Year"] = lYear + context["PreviousMonth"] = lPreviousMonth + context["PreviousMonthName"] = named_month(lPreviousMonth) + context["PreviousYear"] = lPreviousYear + context["NextMonth"] = lNextMonth + context["NextMonthName"] = named_month(lNextMonth) + context["NextYear"] = lNextYear + context["YearBeforeThis"] = lYearBeforeThis + context["YearAfterThis"] = lYearAfterThis + context["events_a_venir_answered_yes"] = events_a_venir_answered_yes + context["events_a_venir_answered_no"] = events_a_venir_answered_no + context["events_a_venir_answered_pe"] = events_a_venir_answered_pe + context["events_a_venir_not_answered"] = events_a_venir_not_answered + context["actu"] = actu + context["photo"] = photo + return context + + +class Home(Calendar): lToday = datetime.now() - return calendar(request, lToday.year, lToday.month) -@login_required -def calendar(request, pYear, pMonth): - actu = Actu.objects.all() - photo = Photo.objects.filter(cat='home').order_by('?').first() - lToday = datetime.now() - lYear = int(pYear) - lMonth = int(pMonth) - lCalendarFromMonth = datetime(lYear, lMonth, 1) - lCalendarToMonth = datetime(lYear, lMonth, monthrange(lYear, lMonth)[1]) - lEvents = Event.objects.filter( - date__gte=lCalendarFromMonth, date__lte=lCalendarToMonth - ) - if request.user.is_authenticated: - lEvents = Event.objects.filter(date__gte=lCalendarFromMonth, - date__lte=lCalendarToMonth) - lCalendar = EventCalendar(lEvents).formatmonth(lYear, lMonth) - lPreviousYear = lYear - lPreviousMonth = lMonth - 1 - if lPreviousMonth == 0: - lPreviousMonth = 12 - lPreviousYear -= 1 - lNextYear = lYear - lNextMonth = lMonth + 1 - if lNextMonth == 13: - lNextMonth = 1 - lNextYear = lYear + 1 - lYearAfterThis = lYear + 1 - lYearBeforeThis = lYear - 1 - try: - events_a_venir_not_answered = Event.objects.filter(date__gte = lToday).exclude(participants__participant=request.user.profile) - events_a_venir_answered = Event.objects.filter(date__gte = lToday).filter(participants__participant=request.user.profile) - events_a_venir_answered_yes = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant=request.user.profile )& Q(participants__reponse= 'oui')) - events_a_venir_answered_no = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant=request.user.profile) & Q(participants__reponse= 'non')) - events_a_venir_answered_pe = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant=request.user.profile)& Q(participants__reponse= 'pe')) - except: - events_a_venir_not_answered = Event.objects.filter(date__gte = lToday).exclude(participants__participant__user__username=request.user) - events_a_venir_answered = Event.objects.filter(date__gte = lToday).filter(participants__participant__user__username=request.user) - events_a_venir_answered_yes = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant__user__username=request.user )& Q(participants__reponse= 'oui')) - events_a_venir_answered_no = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant__user__username=request.user) & Q(participants__reponse= 'non')) - events_a_venir_answered_pe = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant__user__username=request.user)& Q(participants__reponse= 'pe')) - return render(request, 'calendrier/home.html', { - 'Calendar': mark_safe(lCalendar), - 'Month': lMonth, - 'MonthName': named_month(lMonth), - 'Year': lYear, - 'PreviousMonth': lPreviousMonth, - 'PreviousMonthName': named_month(lPreviousMonth), - 'PreviousYear': lPreviousYear, - 'NextMonth': lNextMonth, - 'NextMonthName': named_month(lNextMonth), - 'NextYear': lNextYear, - 'YearBeforeThis': lYearBeforeThis, - 'YearAfterThis': lYearAfterThis, - "events_a_venir_answered_yes": events_a_venir_answered_yes, - "events_a_venir_answered_no": events_a_venir_answered_no, - "events_a_venir_answered_pe": events_a_venir_answered_pe, - "events_a_venir_not_answered": events_a_venir_not_answered, - "actu" : actu, - "photo" : photo, - }) + @property + def pYear(self): + return self.lToday.year -@login_required -def view_event(request, id): - event = get_object_or_404(Event, id=id) - participants = event.participants_set.all() - multi_instrumentistes = event.participants_set.filter(Q(participant__multi_instrumentiste = 'Oui')& ~Q(reponse = 'non')) - - # Restricted event, only erneso users can see it - if not request.user.is_authenticated and not event.calendrier: - return redirect(reverse('calendrier:home')) - - # Count the number of occurences of each instrument - instrument_count = defaultdict(lambda: (0, 0,[],[],[])) - for participant in participants: - instrument = participant.participant.instru - if (instrument == "Autre"): - instrument = participant.participant.instru_autre - - sure, maybe, namesoui, namespe, namesnon = instrument_count[instrument] - - if participant.reponse == "oui": - - namesoui += [participant.participant.get_doodlename()] - instrument_count[instrument] = (sure + 1, maybe,namesoui,namespe,namesnon) - elif participant.reponse == "pe": - namespe += [participant.participant.get_doodlename()] - instrument_count[instrument] = (sure, maybe + 1,namesoui,namespe,namesnon) - else: - namesnon += [participant.participant.get_doodlename()] - instrument_count[instrument] = (sure, maybe,namesoui,namespe,namesnon) - - instrument_count = [ - (instrument, sure, maybe,namesoui, namespe ,namesnon) - for instrument, (sure, maybe,namesoui,namespe,namesnon) in instrument_count.items() - ] - - context = { - "event": event, - "instrument_count": instrument_count, - "participants": participants, - "nboui": len(participants.filter(reponse="oui")), - "nbpe": len(participants.filter(reponse="pe")), - "nbnon": len(participants.filter(reponse="non")), - "multi_instrumentistes":multi_instrumentistes, - } - return render(request, 'calendrier/view_event.html', context=context) + @property + def pMonth(self): + return self.lToday.month +class ViewEvent(LoginRequiredMixin, TemplateView): + template_name = "calendrier/view_event.html" + + def get_context_data(self, **kwargs): + context = super(ViewEvent, self).get_context_data(**kwargs) + event = get_object_or_404(Event, id=self.kwargs['id']) + participants = event.participants_set.all() + multi_instrumentistes = event.participants_set.filter( + Q(participant__multi_instrumentiste="Oui") & ~Q(reponse="non") + ) + + # Restricted event, only erneso users can see it + if not self.request.user.is_authenticated and not event.calendrier: + return redirect(reverse("calendrier:home")) + + # Count the number of occurences of each instrument + instrument_count = defaultdict(lambda: (0, 0, [], [], [])) + for participant in participants: + instru = participant.participant.instru + if instru == "Autre": + instru = participant.participant.instru_autre + + sure, maybe, namesoui, namespe, namesnon = instrument_count[instru] + + if participant.reponse == "oui": + + namesoui += [participant.participant.get_doodlename()] + instrument_count[instru] = ( + sure + 1, + maybe, + namesoui, + namespe, + namesnon, + ) + elif participant.reponse == "pe": + namespe += [participant.participant.get_doodlename()] + instrument_count[instru] = ( + sure, + maybe + 1, + namesoui, + namespe, + namesnon, + ) + else: + namesnon += [participant.participant.get_doodlename()] + instrument_count[instru] = (sure, maybe, namesoui, + namespe, namesnon) + + instrument_count = [ + (instrument, sure, maybe, namesoui, namespe, namesnon) + for instrument, ( + sure, + maybe, + namesoui, + namespe, + namesnon, + ) in instrument_count.items() + ] + + context["event"] = event + context["instrument_count"] = instrument_count + context["participants"] = participants + context["nboui"] = len(participants.filter(reponse="oui")) + context["nbpe"] = len(participants.filter(reponse="pe")) + context["nbnon"] = len(participants.filter(reponse="non")) + context["multi_instrumentistes"] = multi_instrumentistes + return context +class ChangeName(LoginRequiredMixin, TemplateView): + form_class = ChangeDoodleName + template_name = "calendrier/changename.html" + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['form'] = self.form_class(instance=self.request.user) + context["id"] = self.kwargs['id'] + return context -@login_required -def changename(request,id): - if request.method == 'POST': + def post(self, request, *args, **kwargs): + success = False requbis = request.POST.copy() - form = ChangeDoodleName(requbis, instance=request.user) + form = self.form_class(requbis, instance=request.user) if form.is_valid(): form.save() success = True - return redirect('calendrier:view-event',id=id) - else: - form = ChangeDoodleName(instance=request.user) - return render(request, 'calendrier/changename.html',locals()) + return redirect("calendrier:view-event", id=self.kwargs['id']) + else: + context = self.get_context_data() + context['success'] = success + return render(request, self.template_name, context) -@chef_required -def create_event(request): - if request.method == "POST": - form = EventForm(request.POST) +class CreateEvent(LoginRequiredMixin, TemplateView): + form_class = EventForm + template_name = "calendrier/create.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['form'] = self.form_class() + return context + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST) if form.is_valid(): temp = True while temp: code = generer() try: Event.objects.get(slug=code) - except: + except Event.DoesNotExist: temp = False - nom = form.cleaned_data["nom"] date = form.cleaned_data["date"] - date = date.strftime('%d/%m/%Y') - debut = form.cleaned_data["debut"] + date = date.strftime("%d/%m/%Y") obj = form.save(commit=False) obj.slug = code obj.save() id = obj.id - envoi = True - return redirect('calendrier:view-event',id=id) - - else: - form = EventForm() - - return render(request, "calendrier/create.html", locals()) + return redirect("calendrier:view-event", id=id) + else: + context = self.get_context_data() + return render(request, self.template_name, context) +class ReponseEvent(LoginRequiredMixin, TemplateView): + form_class = ParticipantsForm + template_name = "calendrier/reponse.html" + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['form'] = self.form_class() + context['ev'] = get_object_or_404(Event, id=self.kwargs['id']) + context['id'] = self.kwargs['id'] + return context -@login_required -def reponse(request, id): - part = request.user.profile - ev = get_object_or_404(Event, id=id) - if request.method == "POST": - form = ParticipantsForm(request.POST) + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST) + ev = get_object_or_404(Event, id=self.kwargs['id']) + part = request.user.profile if form.is_valid(): try: p = Participants.objects.get(event=ev, participant=part) @@ -222,43 +317,33 @@ def reponse(request, id): obj.event = ev obj.participant = part obj.save() - envoi = True - return redirect('calendrier:view-event',id=id) - else: - form = ParticipantsForm() - return render(request, "calendrier/reponse.html", locals()) + return redirect("calendrier:view-event", id=self.kwargs['id']) + else: + context = self.get_context_data() + return render(request, self.template_name, context) - - -class EventUpdate(UpdateView): +class EventUpdate(ChefRequiredMixin, UpdateView): model = Event template_name = "calendrier/update.html" form_class = ModifEventForm def get_context_data(self, **kwargs): ctx = super(EventUpdate, self).get_context_data(**kwargs) - ctx['id'] = self.get_object().id + ctx["id"] = self.get_object().id return ctx def get_success_url(self): - return reverse('calendrier:view-event', kwargs={'id' : self.get_object().id}) - - @method_decorator(chef_required) - def dispatch(self, *args, **kwargs): - return super(EventUpdate, self).dispatch(*args, **kwargs) + return reverse("calendrier:view-event", + kwargs={"id": self.get_object().id}) -class EventDelete(DeleteView): +class EventDelete(ChefRequiredMixin, DeleteView): model = Event template_name = "calendrier/delete.html" success_url = reverse_lazy("calendrier:home") def get_context_data(self, **kwargs): ctx = super(EventDelete, self).get_context_data(**kwargs) - ctx['id'] = self.get_object().id + ctx["id"] = self.get_object().id return ctx - - @method_decorator(chef_required) - def dispatch(self, *args, **kwargs): - return super(EventDelete,self).dispatch(*args, **kwargs) diff --git a/gestion/admin.py b/gestion/admin.py index 7cf703e..c937797 100644 --- a/gestion/admin.py +++ b/gestion/admin.py @@ -6,12 +6,11 @@ les permissions. """ from django.contrib import admin -from django.contrib.auth.models import User, Group, Permission from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.models import Group, Permission, User -from gestion.models import ErnestoUser, VideoGallery, Photo from actu.models import Actu - +from gestion.models import ErnestoUser, Photo, VideoGallery class UserProfileInline(admin.StackedInline): @@ -112,6 +111,7 @@ class UserProfileAdmin(UserAdmin): user.groups.add(chef_group) user.save() + admin.site.unregister(User) admin.site.register(User, UserProfileAdmin) admin.site.register(VideoGallery) diff --git a/gestion/apps.py b/gestion/apps.py index 48586ea..a52a984 100644 --- a/gestion/apps.py +++ b/gestion/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class GestionConfig(AppConfig): - name = 'gestion' + name = "gestion" diff --git a/gestion/forms.py b/gestion/forms.py index 1112bb0..74cc113 100644 --- a/gestion/forms.py +++ b/gestion/forms.py @@ -1,47 +1,71 @@ from django import forms -from gestion.models import ErnestoUser +from django.contrib.auth.forms import UserChangeForm, UserCreationForm from django.contrib.auth.models import User -from django.contrib.auth.forms import UserCreationForm, UserChangeForm -from django.contrib.auth.tokens import default_token_generator from django.utils.translation import gettext_lazy as _ +from gestion.models import ErnestoUser class RegistrationFormUser(UserCreationForm): class Meta: model = User - fields = ('username', 'first_name', 'last_name', 'password1', - 'password2', 'email',) + fields = ( + "username", + "first_name", + "last_name", + "password1", + "password2", + "email", + ) + class ChangeFormUser(UserChangeForm): password = None + class Meta: model = User - fields = ('first_name', 'last_name', 'email',) - + fields = ( + "first_name", + "last_name", + "email", + ) class ChangeMembreForm(forms.ModelForm): def clean(self): cleaned_data = super(ChangeMembreForm, self).clean() - instru=cleaned_data.get("instru") + instru = cleaned_data.get("instru") instru_autre = cleaned_data.get("instru_autre") if (instru == "Autre") and not (instru_autre): raise forms.ValidationError(_("Préçisez quel autre instrument")) - multi_instru=cleaned_data.get("multi_instrumentiste") + multi_instru = cleaned_data.get("multi_instrumentiste") instru_bonus = cleaned_data.get("instru_bonus") if (multi_instru == "Oui") and not (instru_bonus): - raise forms.ValidationError(_("Préçisez quel·s instrument·s supplémentaire·s vous pouvez jouer")) + raise forms.ValidationError( + _("Préçisez quel·s instrument·s supplémentaire·s vous pouvez jouer") + ) return cleaned_data class Meta: model = ErnestoUser - fields = ("phone", "instru","instru_autre","multi_instrumentiste","instru_bonus") + fields = ( + "phone", + "instru", + "instru_autre", + "multi_instrumentiste", + "instru_bonus", + ) + class InscriptionMembreForm(ChangeMembreForm): validation = forms.CharField(max_length=100, widget=forms.PasswordInput) class Meta: model = ErnestoUser - fields = ("phone", "instru","instru_autre",'multi_instrumentiste', - 'instru_bonus' ) + fields = ( + "phone", + "instru", + "instru_autre", + "multi_instrumentiste", + "instru_bonus", + ) diff --git a/gestion/migrations/0001_initial.py b/gestion/migrations/0001_initial.py index ff61978..267609b 100644 --- a/gestion/migrations/0001_initial.py +++ b/gestion/migrations/0001_initial.py @@ -1,5 +1,5 @@ -from django.db import migrations, models from django.conf import settings +from django.db import migrations, models class Migration(migrations.Migration): @@ -10,28 +10,64 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='ErnestoUser', + name="ErnestoUser", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), - ('is_ernesto', models.BooleanField(verbose_name="Membre de l'Ernestophone", default=True)), - ('is_chef', models.BooleanField(verbose_name='Chef Fanfare', default=False)), - ('phone', models.CharField(blank=True, max_length=20, verbose_name='Téléphone')), - ('instru', models.CharField(blank=True, max_length=40, verbose_name='Instrument joué')), - ('slug', models.CharField(max_length=7, editable=False, unique=True)), - ('doodlename', models.CharField(blank=True, max_length=30, verbose_name='Nom pour le doodle')), - ('mails', models.BooleanField(verbose_name='Recevoir les mails', default=True)), ( - 'user', + "id", + models.AutoField( + auto_created=True, + primary_key=True, + verbose_name="ID", + serialize=False, + ), + ), + ( + "is_ernesto", + models.BooleanField( + verbose_name="Membre de l'Ernestophone", default=True + ), + ), + ( + "is_chef", + models.BooleanField(verbose_name="Chef Fanfare", default=False), + ), + ( + "phone", + models.CharField( + blank=True, max_length=20, verbose_name="Téléphone" + ), + ), + ( + "instru", + models.CharField( + blank=True, max_length=40, verbose_name="Instrument joué" + ), + ), + ("slug", models.CharField(max_length=7, editable=False, unique=True)), + ( + "doodlename", + models.CharField( + blank=True, max_length=30, verbose_name="Nom pour le doodle" + ), + ), + ( + "mails", + models.BooleanField( + verbose_name="Recevoir les mails", default=True + ), + ), + ( + "user", models.OneToOneField( to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, - related_name='profile' - ) + related_name="profile", + ), ), ], options={ - 'verbose_name': 'Profil Ernestophoniste', - 'verbose_name_plural': 'Profil Ernestophoniste', + "verbose_name": "Profil Ernestophoniste", + "verbose_name_plural": "Profil Ernestophoniste", }, ), ] diff --git a/gestion/migrations/0002_auto_20200908_2222.py b/gestion/migrations/0002_auto_20200908_2222.py index 94fe109..7a49b00 100644 --- a/gestion/migrations/0002_auto_20200908_2222.py +++ b/gestion/migrations/0002_auto_20200908_2222.py @@ -7,80 +7,157 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('gestion', '0001_initial'), + ("gestion", "0001_initial"), ] operations = [ migrations.CreateModel( - name='VideoGallery', + name="VideoGallery", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=127)), - ('order', models.IntegerField(verbose_name='ordre')), - ('url', models.URLField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=127)), + ("order", models.IntegerField(verbose_name="ordre")), + ("url", models.URLField()), ], options={ - 'verbose_name_plural': 'Videos', - 'verbose_name': 'Video', + "verbose_name_plural": "Videos", + "verbose_name": "Video", }, ), migrations.RemoveField( - model_name='ernestouser', - name='mails', + model_name="ernestouser", + name="mails", ), migrations.AddField( - model_name='ernestouser', - name='instru_autre', - field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Lequel ?'), + model_name="ernestouser", + name="instru_autre", + field=models.CharField( + blank=True, max_length=100, null=True, verbose_name="Lequel ?" + ), ), migrations.AddField( - model_name='ernestouser', - name='instru_bonus', - field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Le·s·quel·s ?'), + model_name="ernestouser", + name="instru_bonus", + field=models.CharField( + blank=True, max_length=100, null=True, verbose_name="Le·s·quel·s ?" + ), ), migrations.AddField( - model_name='ernestouser', - name='instru_trombonoscope', - field=models.CharField(blank=True, max_length=30, verbose_name='Instrument affiché sur le trombonoscope'), + model_name="ernestouser", + name="instru_trombonoscope", + field=models.CharField( + blank=True, + max_length=30, + verbose_name="Instrument affiché sur le trombonoscope", + ), ), migrations.AddField( - model_name='ernestouser', - name='multi_instrumentiste', - field=models.CharField(choices=[('Non', 'Non'), ('Oui', 'Oui')], default='Non', help_text='Seulement si tu connais les partitions par coeur', max_length=3, verbose_name="Je suis capable de jouer d'un autre instrument en manche :"), + model_name="ernestouser", + name="multi_instrumentiste", + field=models.CharField( + choices=[("Non", "Non"), ("Oui", "Oui")], + default="Non", + help_text="Seulement si tu connais les partitions par coeur", + max_length=3, + verbose_name="Je suis capable de jouer d'un autre instrument en manche :", + ), ), migrations.AddField( - model_name='ernestouser', - name='nom_trombonoscope', - field=models.CharField(blank=True, max_length=30, verbose_name='Nom affiché sur le trombonoscope'), + model_name="ernestouser", + name="nom_trombonoscope", + field=models.CharField( + blank=True, + max_length=30, + verbose_name="Nom affiché sur le trombonoscope", + ), ), migrations.AddField( - model_name='ernestouser', - name='trombonoscope', - field=models.CharField(choices=[('non', 'Non'), ('o_a', 'Oui en tant que fanfaron actuel'), ('o_v', 'Oui en tant que vie·ille·ux')], default='non', max_length=3, null=True, verbose_name='Je souhaite apparaitre dans le trombonoscope :'), + model_name="ernestouser", + name="trombonoscope", + field=models.CharField( + choices=[ + ("non", "Non"), + ("o_a", "Oui en tant que fanfaron actuel"), + ("o_v", "Oui en tant que vie·ille·ux"), + ], + default="non", + max_length=3, + null=True, + verbose_name="Je souhaite apparaitre dans le trombonoscope :", + ), ), migrations.AddField( - model_name='ernestouser', - name='trombonoscope_colors', - field=models.CharField(choices=[('#e4522f#ffffff', 'Orange et Blanc'), ('#ffffff#000000', 'Blanc et Noir'), ('#A8107C#000000', 'Rose et Noir'), ('#10A4A8#ffffff', 'Bleu et Blanc'), ('#26A810#000000', 'Vert et Noir'), ('#A81026#ffffff', 'Rouge et Blanc'), ('#E3E54C#000000', 'Jaune et Noir'), ('autre', 'Autre')], default='OrangeBlanc', max_length=40, verbose_name='Couleur du profil'), + model_name="ernestouser", + name="trombonoscope_colors", + field=models.CharField( + choices=[ + ("#e4522f#ffffff", "Orange et Blanc"), + ("#ffffff#000000", "Blanc et Noir"), + ("#A8107C#000000", "Rose et Noir"), + ("#10A4A8#ffffff", "Bleu et Blanc"), + ("#26A810#000000", "Vert et Noir"), + ("#A81026#ffffff", "Rouge et Blanc"), + ("#E3E54C#000000", "Jaune et Noir"), + ("autre", "Autre"), + ], + default="OrangeBlanc", + max_length=40, + verbose_name="Couleur du profil", + ), ), migrations.AddField( - model_name='ernestouser', - name='trombonoscope_fond', - field=colorful.fields.RGBColorField(default='#e4522f', verbose_name='Couleur de fond du profil'), + model_name="ernestouser", + name="trombonoscope_fond", + field=colorful.fields.RGBColorField( + default="#e4522f", verbose_name="Couleur de fond du profil" + ), ), migrations.AddField( - model_name='ernestouser', - name='trombonoscope_texte', - field=colorful.fields.RGBColorField(default='#ffffff', verbose_name='Couleur du texte du profil'), + model_name="ernestouser", + name="trombonoscope_texte", + field=colorful.fields.RGBColorField( + default="#ffffff", verbose_name="Couleur du texte du profil" + ), ), migrations.AlterField( - model_name='ernestouser', - name='instru', - field=models.CharField(choices=[('Clarinette', 'Clarinette'), ('Euphonium', 'Euphonium'), ('Percussion', 'Percussion'), ('Piccolo', 'Piccolo'), ('Saxophone Alto', 'Saxophone Alto'), ('Saxophone Ténor', 'Saxophone Ténor'), ('Saxophone Baryton', 'Saxophone Baryton'), ('Souba', 'Souba'), ('Trombone', 'Trombone'), ('Trompette', 'Trompette'), ('Autre', 'Autre'), ('ne sais pas', 'Je ne sais pas encore')], default='ne sais pas', max_length=40, verbose_name='Instrument joué'), + model_name="ernestouser", + name="instru", + field=models.CharField( + choices=[ + ("Clarinette", "Clarinette"), + ("Euphonium", "Euphonium"), + ("Percussion", "Percussion"), + ("Piccolo", "Piccolo"), + ("Saxophone Alto", "Saxophone Alto"), + ("Saxophone Ténor", "Saxophone Ténor"), + ("Saxophone Baryton", "Saxophone Baryton"), + ("Souba", "Souba"), + ("Trombone", "Trombone"), + ("Trompette", "Trompette"), + ("Autre", "Autre"), + ("ne sais pas", "Je ne sais pas encore"), + ], + default="ne sais pas", + max_length=40, + verbose_name="Instrument joué", + ), ), migrations.AlterField( - model_name='ernestouser', - name='phone', - field=models.CharField(blank=True, help_text='seulement visible par les chef·fe·s', max_length=20, verbose_name='Téléphone'), + model_name="ernestouser", + name="phone", + field=models.CharField( + blank=True, + help_text="seulement visible par les chef·fe·s", + max_length=20, + verbose_name="Téléphone", + ), ), ] diff --git a/gestion/migrations/0003_photo.py b/gestion/migrations/0003_photo.py index d1a188d..0c486c5 100644 --- a/gestion/migrations/0003_photo.py +++ b/gestion/migrations/0003_photo.py @@ -2,30 +2,84 @@ import colorful.fields from django.db import migrations, models + import gestion.models class Migration(migrations.Migration): dependencies = [ - ('gestion', '0002_auto_20200908_2222'), + ("gestion", "0002_auto_20200908_2222"), ] operations = [ migrations.CreateModel( - name='Photo', + name="Photo", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=127)), - ('cat', models.CharField(choices=[('home_join', 'Rejoignez nous'), ('home_contact', 'Nous Contacter'), ('home_rep', "Répertoire de l'acceuil"), ('login', 'Connexion'), ('change_membre', 'Modification du profil'), ('inscription_membre', 'Inscription'), ('home', 'Calendrier connecté'), ('liste', 'Agenda public'), ('part', 'Répertoire'), ('n', "N'apparait pas")], default='n', max_length=127)), - ('auteur', models.CharField(blank=True, max_length=127, null=True, verbose_name="Auteur de l'image")), - ('url', models.URLField(blank=True, null=True, verbose_name="Lien vers le site de l'auteur")), - ('color', colorful.fields.RGBColorField(default='#ffffff', verbose_name="Couleur du nom de l'auteur")), - ('image', models.ImageField(default=None, upload_to='deco', validators=[gestion.models.Photo.validate_image])), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=127)), + ( + "cat", + models.CharField( + choices=[ + ("home_join", "Rejoignez nous"), + ("home_contact", "Nous Contacter"), + ("home_rep", "Répertoire de l'acceuil"), + ("login", "Connexion"), + ("change_membre", "Modification du profil"), + ("inscription_membre", "Inscription"), + ("home", "Calendrier connecté"), + ("liste", "Agenda public"), + ("part", "Répertoire"), + ("n", "N'apparait pas"), + ], + default="n", + max_length=127, + ), + ), + ( + "auteur", + models.CharField( + blank=True, + max_length=127, + null=True, + verbose_name="Auteur de l'image", + ), + ), + ( + "url", + models.URLField( + blank=True, + null=True, + verbose_name="Lien vers le site de l'auteur", + ), + ), + ( + "color", + colorful.fields.RGBColorField( + default="#ffffff", verbose_name="Couleur du nom de l'auteur" + ), + ), + ( + "image", + models.ImageField( + default=None, + upload_to="deco", + validators=[gestion.models.Photo.validate_image], + ), + ), ], options={ - 'verbose_name': 'Photo', - 'verbose_name_plural': 'Photos', + "verbose_name": "Photo", + "verbose_name_plural": "Photos", }, ), ] diff --git a/gestion/migrations/0004_auto_20210331_2031.py b/gestion/migrations/0004_auto_20210331_2031.py index b23d524..8feac42 100644 --- a/gestion/migrations/0004_auto_20210331_2031.py +++ b/gestion/migrations/0004_auto_20210331_2031.py @@ -6,13 +6,29 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('gestion', '0003_photo'), + ("gestion", "0003_photo"), ] operations = [ migrations.AlterField( - model_name='photo', - name='cat', - field=models.CharField(choices=[('home_join', 'Rejoignez nous'), ('home_contact', 'Nous Contacter'), ('home_rep', "Répertoire de l'acceuil"), ('login', 'Connexion'), ('change_membre', 'Modification du profil'), ('inscription_membre', 'Inscription'), ('home', 'Calendrier connecté'), ('liste', 'Agenda public'), ('part', 'Répertoire'), ('instru', 'Instruments'), ('n', "N'apparait pas")], default='n', max_length=127), + model_name="photo", + name="cat", + field=models.CharField( + choices=[ + ("home_join", "Rejoignez nous"), + ("home_contact", "Nous Contacter"), + ("home_rep", "Répertoire de l'acceuil"), + ("login", "Connexion"), + ("change_membre", "Modification du profil"), + ("inscription_membre", "Inscription"), + ("home", "Calendrier connecté"), + ("liste", "Agenda public"), + ("part", "Répertoire"), + ("instru", "Instruments"), + ("n", "N'apparait pas"), + ], + default="n", + max_length=127, + ), ), ] diff --git a/gestion/models.py b/gestion/models.py index 6c942a1..c875def 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -1,38 +1,48 @@ # -*- coding: utf-8 -*- -from django.db import models from colorful.fields import RGBColorField from django.contrib.auth.models import User -from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError +from django.db import models +from django.utils.translation import gettext_lazy as _ + class Photo(models.Model): PHOTO_PLACEMENT = ( - ('home_join', _("Rejoignez nous")), - ('home_contact', _("Nous Contacter")), - ('home_rep', _("Répertoire de l'acceuil")), - ('login', _('Connexion')), - ('change_membre', _('Modification du profil')), - ('inscription_membre', _('Inscription')), - ('home', _('Calendrier connecté')), - ('liste', _('Agenda public')), - ('part', _('Répertoire')), - ('instru', _('Instruments')), - ('n',_("N'apparait pas")) - ) + ("home_join", _("Rejoignez nous")), + ("home_contact", _("Nous Contacter")), + ("home_rep", _("Répertoire de l'acceuil")), + ("login", _("Connexion")), + ("change_membre", _("Modification du profil")), + ("inscription_membre", _("Inscription")), + ("home", _("Calendrier connecté")), + ("liste", _("Agenda public")), + ("part", _("Répertoire")), + ("instru", _("Instruments")), + ("n", _("N'apparait pas")), + ) def validate_image(fieldfile_obj): filesize = fieldfile_obj.file.size - megabyte_limit = 1.0 - if filesize > megabyte_limit*1024*1024: - raise ValidationError("Max file size is %sMB" % str(megabyte_limit)) + mb_limit = 1.0 + if filesize > mb_limit * 1024 * 1024: + raise ValidationError("La taille max est %sMB" % str(mb_limit)) name = models.CharField(max_length=127) - cat = models.CharField(max_length = 127,choices = PHOTO_PLACEMENT,default='n') - auteur = models.CharField(max_length=127,verbose_name=_("Auteur de l'image"),null=True,blank=True) - url = models.URLField(verbose_name=_("Lien vers le site de l'auteur"),null=True,blank=True) - color = RGBColorField(_("Couleur du nom de l'auteur"),default='#ffffff') - image = models.ImageField(upload_to='deco',default=None,validators=[validate_image]) + cat = models.CharField(max_length=127, choices=PHOTO_PLACEMENT, + default="n") + auteur = models.CharField( + max_length=127, verbose_name=_("Auteur de l'image"), null=True, + blank=True + ) + url = models.URLField( + verbose_name=_("Lien vers le site de l'auteur"), null=True, blank=True + ) + color = RGBColorField(_("Couleur du nom de l'auteur"), default="#ffffff") + image = models.ImageField( + upload_to="deco", default=None, validators=[validate_image] + ) + def __str__(self): return self.name @@ -42,57 +52,101 @@ class Photo(models.Model): class ErnestoUser(models.Model): - user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile") - is_ernesto = models.BooleanField(_("Membre de l'Ernestophone"), default=True) + user = models.OneToOneField(User, on_delete=models.CASCADE, + related_name="profile") + is_ernesto = models.BooleanField(_("Membre de l'Ernestophone"), + default=True) is_chef = models.BooleanField(_("Chef Fanfare"), default=False) - phone = models.CharField(_("Téléphone"), max_length=20, blank=True ,help_text= _("seulement visible par les chef·fe·s")) + phone = models.CharField( + _("Téléphone"), + max_length=20, + blank=True, + help_text=_("seulement visible par les chef·fe·s"), + ) INSTRU_CHOICES = [ - ('Clarinette', _('Clarinette')), - ('Euphonium', _('Euphonium')), - ('Percussion', _('Percussion')), - ('Piccolo', _('Piccolo')), - ('Saxophone Alto', _('Saxophone Alto')), - ('Saxophone Ténor', _('Saxophone Ténor')), - ('Saxophone Baryton', _('Saxophone Baryton')), - ('Souba', _('Souba')), - ('Trombone', _('Trombone')), - ('Trompette', _('Trompette')), - ('Autre', _('Autre')), - ('ne sais pas', _('Je ne sais pas encore')), + ("Clarinette", _("Clarinette")), + ("Euphonium", _("Euphonium")), + ("Percussion", _("Percussion")), + ("Piccolo", _("Piccolo")), + ("Saxophone Alto", _("Saxophone Alto")), + ("Saxophone Ténor", _("Saxophone Ténor")), + ("Saxophone Baryton", _("Saxophone Baryton")), + ("Souba", _("Souba")), + ("Trombone", _("Trombone")), + ("Trompette", _("Trompette")), + ("Autre", _("Autre")), + ("ne sais pas", _("Je ne sais pas encore")), ] COLORS_CHOICES = [ - ('#e4522f#ffffff', _('Orange et Blanc')), - ('#ffffff#000000', _('Blanc et Noir')), - ('#A8107C#000000', _('Rose et Noir')), - ('#10A4A8#ffffff', _('Bleu et Blanc')), - ('#26A810#000000', _('Vert et Noir')), - ('#A81026#ffffff', _('Rouge et Blanc')), - ('#E3E54C#000000', _('Jaune et Noir')), - ('autre',_('Autre')), + ("#e4522f#ffffff", _("Orange et Blanc")), + ("#ffffff#000000", _("Blanc et Noir")), + ("#A8107C#000000", _("Rose et Noir")), + ("#10A4A8#ffffff", _("Bleu et Blanc")), + ("#26A810#000000", _("Vert et Noir")), + ("#A81026#ffffff", _("Rouge et Blanc")), + ("#E3E54C#000000", _("Jaune et Noir")), + ("autre", _("Autre")), + ] - ] - - instru = models.CharField(_("Instrument joué"), max_length=40, blank=False,choices=INSTRU_CHOICES,default='ne sais pas') - instru_autre = models.CharField(_("Lequel ?"),null=True,max_length=100,blank=True) + instru = models.CharField( + _("Instrument joué"), + max_length=40, + blank=False, + choices=INSTRU_CHOICES, + default="ne sais pas", + ) + instru_autre = models.CharField( + _("Lequel ?"), null=True, max_length=100, blank=True + ) slug = models.CharField(max_length=7, editable=False, unique=True) doodlename = models.CharField(_("Nom pour le doodle"), max_length=30, blank=True) - trombonoscope = models.CharField(_('Je souhaite apparaitre dans le trombonoscope :'),max_length=3,blank=False,null=True,choices=[('non',_('Non')),('o_a',_('Oui en tant que fanfaron actuel')),('o_v',_('Oui en tant que vie·ille·ux'))],default='non') - instru_trombonoscope = models.CharField(_("Instrument affiché sur le trombonoscope"), max_length=30, - blank=True) - nom_trombonoscope = models.CharField(_("Nom affiché sur le trombonoscope"), max_length=30, - blank=True) - trombonoscope_colors = models.CharField(_("Couleur du profil"), max_length=40, blank=False,choices=COLORS_CHOICES,default='OrangeBlanc') - trombonoscope_fond = RGBColorField(_("Couleur de fond du profil"),default='#e4522f') - trombonoscope_texte = RGBColorField(_("Couleur du texte du profil"),default='#ffffff') - - multi_instrumentiste = models.CharField(_("Je suis capable de jouer d'un autre instrument en manche :"),default='Non',null=False,max_length=3,choices=[('Non',_('Non')),('Oui',_('Oui'))],help_text= _("Seulement si tu connais les partitions par coeur")) - instru_bonus = models.CharField(_("Le·s·quel·s ?"),null=True,max_length=100,blank=True) - + trombonoscope = models.CharField( + _("Je souhaite apparaitre dans le trombonoscope:"), + max_length=3, + blank=False, + null=True, + choices=[ + ("non", _("Non")), + ("o_a", _("Oui en tant que fanfaron actuel")), + ("o_v", _("Oui en tant que vie·ille·ux")), + ], + default="non", + ) + instru_trombonoscope = models.CharField( + _("Instrument affiché sur le trombonoscope"), max_length=30, blank=True + ) + nom_trombonoscope = models.CharField( + _("Nom affiché sur le trombonoscope"), max_length=30, blank=True + ) + trombonoscope_colors = models.CharField( + _("Couleur du profil"), + max_length=40, + blank=False, + choices=COLORS_CHOICES, + default="OrangeBlanc", + ) + trombonoscope_fond = RGBColorField( + _("Couleur de fond du profil"), default="#e4522f" + ) + trombonoscope_texte = RGBColorField( + _("Couleur du texte du profil"), default="#ffffff" + ) + multi_instrumentiste = models.CharField( + _("Je suis capable de jouer d'un autre instrument en manche :"), + default="Non", + null=False, + max_length=3, + choices=[("Non", _("Non")), ("Oui", _("Oui"))], + help_text=_("Seulement si tu connais les partitions par coeur"), + ) + instru_bonus = models.CharField( + _("Le·s·quel·s ?"), null=True, max_length=100, blank=True + ) class Meta: verbose_name = _("Profil Ernestophoniste") diff --git a/gestion/templates/gestion/base.html b/gestion/templates/gestion/base.html index 8b7b3d8..c28dd71 100644 --- a/gestion/templates/gestion/base.html +++ b/gestion/templates/gestion/base.html @@ -33,13 +33,15 @@ diff --git a/gestion/templatetags/autotranslate.py b/gestion/templatetags/autotranslate.py index c5c6e76..e27cda2 100644 --- a/gestion/templatetags/autotranslate.py +++ b/gestion/templatetags/autotranslate.py @@ -3,12 +3,13 @@ from django.utils.safestring import mark_safe register = template.Library() + @register.simple_tag def autotranslate(current_language, description, description_en): - if( current_language != "fr" and description_en): + if current_language != "fr" and description_en: return mark_safe(description_en) - elif(current_language == "fr" and not description): + elif current_language == "fr" and not description: return mark_safe(description_en) else: return mark_safe(description) diff --git a/gestion/templatetags/changelang.py b/gestion/templatetags/changelang.py index 9d28884..5572216 100644 --- a/gestion/templatetags/changelang.py +++ b/gestion/templatetags/changelang.py @@ -12,7 +12,7 @@ def changelang(context, lang=None, *args, **kwargs): Usage: {% change_lang 'en' %} """ - path = context['request'].path + path = context["request"].path url_parts = resolve(path) url = path diff --git a/gestion/templatetags/halflength.py b/gestion/templatetags/halflength.py index 7649a48..dbc3b09 100644 --- a/gestion/templatetags/halflength.py +++ b/gestion/templatetags/halflength.py @@ -1,8 +1,10 @@ -from django.template import Library from math import ceil +from django.template import Library + register = Library() + @register.filter def half_length(liste): try: diff --git a/gestion/templatetags/modulo.py b/gestion/templatetags/modulo.py index a861cbc..ec2f5a0 100644 --- a/gestion/templatetags/modulo.py +++ b/gestion/templatetags/modulo.py @@ -1,8 +1,10 @@ -from django import template from datetime import date, timedelta +from django import template + register = template.Library() + @register.filter def modulo(num, val): return num % val diff --git a/gestion/views.py b/gestion/views.py index 969f06c..97bfdad 100644 --- a/gestion/views.py +++ b/gestion/views.py @@ -1,132 +1,187 @@ -from django.shortcuts import render, redirect -from partitions.models import Category -from gestion.forms import ChangeMembreForm, ChangeFormUser,RegistrationFormUser, InscriptionMembreForm -from django.conf import settings -from django.http import HttpResponseRedirect -from gestion.models import ErnestoUser, VideoGallery, Photo -from django.contrib.auth.decorators import login_required -from django.contrib.auth.forms import PasswordChangeForm -from calendrier.forms import ChangeDoodleName -from partitions.decorators import chef_required -from gestion.mixins import ChefRequiredMixin -from django.views.generic import CreateView, DeleteView, ListView, UpdateView -from django.contrib.auth.views import LoginView -from django.urls import reverse_lazy -from django.shortcuts import render_to_response -import string import random +import string + +from django.conf import settings +from django.contrib.auth.forms import PasswordChangeForm +from django.contrib.auth.views import LoginView +from django.shortcuts import redirect, render + +from calendrier.forms import ChangeDoodleName +from gestion.forms import (ChangeFormUser, ChangeMembreForm, + InscriptionMembreForm, RegistrationFormUser) +from gestion.models import ErnestoUser, Photo, VideoGallery +from partitions.models import Category +from django.views.generic import TemplateView +from django.contrib.auth.mixins import LoginRequiredMixin +from django.utils.translation import gettext_lazy as _ def generer(*args): caracteres = string.ascii_letters + string.digits - aleatoire = [random.choice(caracteres) for _ in range(6)] - return ''.join(aleatoire) + aleatoire = [random.choice(caracteres) for i in range(6)] + return "".join(aleatoire) -def home(request): - if request.user.is_authenticated : - return redirect('calendrier:home') - categories = Category.objects.filter(name = "Partitions actives").prefetch_related("partitionset_set") - videos = VideoGallery.objects.all() - photo_rep = Photo.objects.filter(cat='home_rep').order_by('?').first() - photo_join = Photo.objects.filter(cat='home_join').order_by('?').first() - photo_contact = Photo.objects.filter(cat='home_contact').order_by('?').first() - return render_to_response( 'gestion/index.html', {"request":request,"categories": categories,'videos':videos,'photo_rep':photo_rep,'photo_join':photo_join,'photo_contact':photo_contact}) +class Home(TemplateView): + template_name = "gestion/index.html" -class MyLoginView(LoginView): + def dispatch(self, request, *args, **kwargs): + if request.user.is_authenticated: + return redirect('calendrier:home') + return super(Home, self).dispatch(request, *args, **kwargs) - template_name = 'gestion/login.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - photo = Photo.objects.filter(cat='login').order_by('?').first() - context['photo'] = photo + context["categories"] = Category.objects.filter( + name="Partitions actives").prefetch_related( + "partitionset_set" + ) + context['videos'] = VideoGallery.objects.all() + context['photo_rep'] = Photo.objects.filter( + cat="home_rep").order_by("?").first() + context['photo_join'] = Photo.objects.filter( + cat="home_join").order_by("?").first() + context['photo_contact'] = Photo.objects.filter( + cat="home_contact").order_by("?").first() return context -def thanks(request): +class MyLoginView(LoginView): - return render(request, 'gestion/thanks.html', locals()) + template_name = "gestion/login.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["photo"] = Photo.objects.filter( + cat="login").order_by("?").first() + return context -@login_required -def changename(request): - if request.method == 'POST': +class Thanks(TemplateView): + template_name = "gestion/thanks.html" + + +class ChangeName(LoginRequiredMixin, TemplateView): + form_class = ChangeDoodleName + template_name = "gestion/changename.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['form'] = self.form_class(instance=self.request.user) + return context + + def post(self, request, *args, **kwargs): requbis = request.POST.copy() - form = ChangeDoodleName(requbis, instance=request.user) + form = self.form_class(requbis, + instance=request.user) if form.is_valid(): form.save() - success = True - return redirect('change_membre') - else: - form = ChangeDoodleName(instance=request.user) - return render(request, 'gestion/changename.html', locals()) + return redirect("change_membre") + + context = self.get_context_data() + context['form'] = form + return render(request, self.template_name, context) +class ChangeMembre(LoginRequiredMixin, TemplateView): + comp_form_class = ChangeMembreForm + user_form_class = ChangeFormUser + template_name = "gestion/change.html" -@login_required -def change_membre(request): - photo = Photo.objects.filter(cat='change_membre').order_by('?').first() - if request.method == 'POST': - comp_form = ChangeMembreForm(request.POST, instance=request.user.profile) - user_form = ChangeFormUser(request.POST, instance=request.user) + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + comp_form = self.comp_form_class(instance=self.request.user.profile) + user_form = self.user_form_class(instance=self.request.user) + context["comp_form"] = comp_form + context["user_form"] = user_form + context["photo"] = Photo.objects.filter( + cat="change_membre").order_by("?").first() + return context + + def post(self, request, *args, **kwargs): + success = False + comp_form = self.comp_form_class(request.POST, + instance=request.user.profile) + user_form = self.user_form_class(request.POST, instance=request.user) if user_form.is_valid() and comp_form.is_valid(): user_form.save() comp_form.save() success = True - return redirect('home') - else: - comp_form = ChangeMembreForm(instance=request.user.profile) - user_form = ChangeFormUser(instance=request.user) - return render(request, 'gestion/change.html', locals()) -@login_required -def change_password(request): - if request.method == 'POST': + context = self.get_context_data() + context['success'] = success + context['comp_form'] = comp_form + context['user_form'] = user_form + return render(request, self.template_name, context) + + +class ChangePassword(LoginRequiredMixin, TemplateView): + form_class = PasswordChangeForm + template_name = "gestion/changepasswd.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['form'] = self.form_class(self.request.user) + return context + + def post(self, request, *args, **kwargs): requbis = request.POST.copy() - form = PasswordChangeForm(request.user, data=requbis) + success = False + form = self.form_class(request.user, data=requbis) if form.is_valid(): - - request.user.profile.photo.delete() form.save() - success = True - - else: - form = PasswordChangeForm(request.user) - return render(request, 'gestion/changepasswd.html', locals()) + context = self.get_context_data() + context['success'] = success + context['form'] = form + return render(request, self.template_name, context) +class Inscription(TemplateView): + user_form_class = RegistrationFormUser + comp_form_class = InscriptionMembreForm + template_name = "gestion/registration.html" -def inscription_membre(request): - photo = Photo.objects.filter(cat='inscription_membre').order_by('?').first() - if request.method == 'POST': + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['comp_form'] = self.comp_form_class() + context['user_form'] = self.user_form_class() + context['photo'] = Photo.objects.filter( + cat="inscription_membre").order_by("?").first() + return context - user_form = RegistrationFormUser(request.POST) - comp_form = InscriptionMembreForm(request.POST) + def post(self, request, *args, **kwargs): + user_form = self.user_form_class(request.POST) + comp_form = self.comp_form_class(request.POST) if user_form.is_valid() and comp_form.is_valid(): - pseudo = user_form.cleaned_data['username'] - if not (comp_form.cleaned_data['validation'] - == settings.ACCOUNT_CREATION_PASS): - error = "Le champ Validation ne correspond pas à celui attendu" - return render(request, "gestion/registration.html", locals()) + + if not ( + comp_form.cleaned_data["validation"] == settings.ACCOUNT_CREATION_PASS + ): + error = _("Le champ Validation ne correspond pas à celui attendu") + context = self.get_context_data() + context['user_form'] = user_form + context['comp_form'] = comp_form + context['error'] = error + return render(request, self.template_name, context) member = user_form.save(commit=False) temp = True while temp: code = generer() try: ErnestoUser.objects.get(slug=code) - except: + except ErnestoUser.DoesNotExist: temp = False member.save() - (profile, _) = ErnestoUser.objects.get_or_create(user=member, + (profile, k) = ErnestoUser.objects.get_or_create(user=member, slug=code) - comp_form = InscriptionMembreForm(request.POST, instance=profile) + comp_form = self.comp_form_class(request.POST, instance=profile) obj = comp_form.save(commit=False) obj.slug = code obj.save() - envoi = True - return redirect('thanks') - else: - comp_form = InscriptionMembreForm() - user_form = RegistrationFormUser() - return render(request, 'gestion/registration.html', locals()) + return redirect("thanks") + else: + context = self.get_context_data() + context['user_form'] = user_form + context['comp_form'] = comp_form + return render(request, self.template_name, context) diff --git a/instruments/admin.py b/instruments/admin.py index 8454cbc..7024eca 100644 --- a/instruments/admin.py +++ b/instruments/admin.py @@ -1,8 +1,6 @@ from django.contrib import admin - -from .models import Instrument,Reparation - +from .models import Instrument, Reparation admin.site.register(Instrument) admin.site.register(Reparation) diff --git a/instruments/apps.py b/instruments/apps.py index ba2e645..e256250 100644 --- a/instruments/apps.py +++ b/instruments/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class InstrumentsConfig(AppConfig): - name = 'instruments' + name = "instruments" diff --git a/instruments/decorators.py b/instruments/decorators.py deleted file mode 100644 index 50a7ea9..0000000 --- a/instruments/decorators.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.contrib.auth.decorators import user_passes_test - - -def is_chef(user): - try: - profile = user.profile - return profile.is_chef - except: - return False - -chef_required = user_passes_test(lambda u: is_chef(u)) diff --git a/instruments/forms.py b/instruments/forms.py index e69de29..ee00070 100644 --- a/instruments/forms.py +++ b/instruments/forms.py @@ -0,0 +1,27 @@ +from django import forms + +from .models import Instrument, Reparation + + +class ChefReparationForm(forms.ModelForm): + class Meta: + model = Reparation + fields = ("date", "description", "description_en", "prix", "lieux") + + +class ChefEditInstrumentForm(forms.ModelForm): + class Meta: + model = Instrument + fields = ( + "statut", + "user", + "infos", + "type", + "owner", + "marque", + "model", + "serial", + "annee", + "prix", + "infos_en", + ) diff --git a/instruments/migrations/0001_initial.py b/instruments/migrations/0001_initial.py index 07bb3ae..1352833 100644 --- a/instruments/migrations/0001_initial.py +++ b/instruments/migrations/0001_initial.py @@ -1,56 +1,174 @@ # Generated by Django 2.2.17 on 2021-04-01 19:25 -from django.db import migrations, models import django.db.models.deletion import django.db.models.functions.text +from django.db import migrations, models class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='Instrument', + name="Instrument", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('model', models.CharField(blank=True, max_length=100, null=True, verbose_name='Modèle')), - ('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')), - ('etat', models.CharField(choices=[('Bon état', 'Bon état'), ('Etat moyen', 'Etat moyen'), ('Mauvais état', 'Mauvais état')], default='Bon état', max_length=100)), - ('marque', models.CharField(blank=True, max_length=100, null=True, verbose_name='Marque')), - ('serial', models.CharField(blank=True, default=' ', max_length=100, null=True, verbose_name='Numéro de série')), - ('annee', models.CharField(blank=True, max_length=100, null=True, verbose_name="Année d'achat")), - ('owner', models.CharField(default='Fanfare', max_length=100, verbose_name='Propriétaire')), - ('user', models.CharField(blank=True, max_length=100, verbose_name='Utilisateur')), - ('type', models.CharField(max_length=40, verbose_name='Instrument')), - ('statut', models.CharField(choices=[('Disponible', 'Disponible'), ('Prêté', 'Prêté')], default='Disponible', max_length=100)), - ('infos', models.TextField(blank=True, default='', verbose_name='Infos utiles')), - ('infos_en', models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "model", + models.CharField( + blank=True, max_length=100, null=True, verbose_name="Modèle" + ), + ), + ( + "prix", + models.CharField( + blank=True, default="", max_length=100, verbose_name="Prix" + ), + ), + ( + "etat", + models.CharField( + choices=[ + ("Bon état", "Bon état"), + ("Etat moyen", "Etat moyen"), + ("Mauvais état", "Mauvais état"), + ], + default="Bon état", + max_length=100, + ), + ), + ( + "marque", + models.CharField( + blank=True, max_length=100, null=True, verbose_name="Marque" + ), + ), + ( + "serial", + models.CharField( + blank=True, + default=" ", + max_length=100, + null=True, + verbose_name="Numéro de série", + ), + ), + ( + "annee", + models.CharField( + blank=True, + max_length=100, + null=True, + verbose_name="Année d'achat", + ), + ), + ( + "owner", + models.CharField( + default="Fanfare", max_length=100, verbose_name="Propriétaire" + ), + ), + ( + "user", + models.CharField( + blank=True, max_length=100, verbose_name="Utilisateur" + ), + ), + ("type", models.CharField(max_length=40, verbose_name="Instrument")), + ( + "statut", + models.CharField( + choices=[("Disponible", "Disponible"), ("Prêté", "Prêté")], + default="Disponible", + max_length=100, + ), + ), + ( + "infos", + models.TextField( + blank=True, default="", verbose_name="Infos utiles" + ), + ), + ( + "infos_en", + models.TextField( + blank=True, default="", verbose_name="Infos utiles en anglais" + ), + ), ], options={ - 'verbose_name': 'Instrument', - 'verbose_name_plural': 'Instruments', - 'ordering': (django.db.models.functions.text.Lower('type'),), + "verbose_name": "Instrument", + "verbose_name_plural": "Instruments", + "ordering": (django.db.models.functions.text.Lower("type"),), }, ), migrations.CreateModel( - name='Reparation', + name="Reparation", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('date', models.DateField(max_length=100, verbose_name='Date')), - ('description', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description')), - ('description_en', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description en anglais')), - ('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')), - ('lieux', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Lieux')), - ('instru', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='instruments.Instrument', verbose_name='Instrument')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("date", models.DateField(max_length=100, verbose_name="Date")), + ( + "description", + models.CharField( + blank=True, + default=" ", + max_length=100, + verbose_name="Description", + ), + ), + ( + "description_en", + models.CharField( + blank=True, + default=" ", + max_length=100, + verbose_name="Description en anglais", + ), + ), + ( + "prix", + models.CharField( + blank=True, default="", max_length=100, verbose_name="Prix" + ), + ), + ( + "lieux", + models.CharField( + blank=True, default=" ", max_length=100, verbose_name="Lieux" + ), + ), + ( + "instru", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="instruments.Instrument", + verbose_name="Instrument", + ), + ), ], options={ - 'verbose_name': 'Réparation', - 'verbose_name_plural': 'Réparations', - 'ordering': ('date',), + "verbose_name": "Réparation", + "verbose_name_plural": "Réparations", + "ordering": ("date",), }, ), ] diff --git a/instruments/models.py b/instruments/models.py index 5a6a3a8..09eeea4 100644 --- a/instruments/models.py +++ b/instruments/models.py @@ -1,6 +1,3 @@ -import os - -from django.conf import settings from django.db import models from django.db.models.functions import Lower from django.utils.translation import gettext_lazy as _ @@ -8,37 +5,62 @@ from django.utils.translation import gettext_lazy as _ class Instrument(models.Model): - model = models.CharField(_("Modèle"),max_length=100,null=True,blank=True) - prix = models.CharField(_("Prix"),max_length=100,default='',blank=True) - etat = models.CharField(max_length=100,default='Bon état',choices = [('Bon état',_('Bon état')),('Etat moyen',_('Etat moyen')),('Mauvais état',_('Mauvais état'))]) - marque = models.CharField(_("Marque"),max_length=100,null=True,blank=True) - serial = models.CharField(_("Numéro de série"),max_length=100,default=' ',null=True,blank=True) - annee = models.CharField(_("Année d'achat"),max_length=100,null=True,blank=True) - owner = models.CharField(_("Propriétaire"),max_length=100,default='Fanfare') - user = models.CharField(_('Utilisateur'),max_length=100,blank=True) + model = models.CharField(_("Modèle"), max_length=100, null=True, blank=True) + prix = models.CharField(_("Prix"), max_length=100, default="", blank=True) + etat = models.CharField( + max_length=100, + default="Bon état", + choices=[ + ("Bon état", _("Bon état")), + ("Etat moyen", _("Etat moyen")), + ("Mauvais état", _("Mauvais état")), + ], + ) + marque = models.CharField(_("Marque"), max_length=100, null=True, blank=True) + serial = models.CharField( + _("Numéro de série"), max_length=100, default=" ", null=True, blank=True + ) + annee = models.CharField(_("Année d'achat"), max_length=100, null=True, blank=True) + owner = models.CharField(_("Propriétaire"), max_length=100, default="Fanfare") + user = models.CharField(_("Utilisateur"), max_length=100, blank=True) type = models.CharField(_("Instrument"), max_length=40, blank=False) - statut = models.CharField(max_length=100,default='Disponible',choices = [('Disponible',_('Disponible')),('Prêté',_('Prêté'))]) - infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="") - infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="") + statut = models.CharField( + max_length=100, + default="Disponible", + choices=[("Disponible", _("Disponible")), ("Prêté", _("Prêté·e"))], + ) + infos = models.TextField(_("Infos utiles"), null=False, blank=True, default="") + infos_en = models.TextField( + "Infos utiles en anglais", null=False, blank=True, default="" + ) + def __str__(self): return self.type class Meta: - verbose_name = _('Instrument') - verbose_name_plural = _('Instruments') - ordering = (Lower('type'),) + verbose_name = _("Instrument") + verbose_name_plural = _("Instruments") + ordering = (Lower("type"),) + class Reparation(models.Model): - date = models.DateField(_("Date"),max_length=100) - instru = models.ForeignKey("Instrument", on_delete=models.CASCADE,verbose_name=_("Instrument")) - description = models.CharField(_("Description"),max_length=100,default=' ',blank=True) - description_en = models.CharField(_("Description en anglais"),max_length=100,default=' ',blank=True) - prix = models.CharField(_("Prix"),max_length=100,default='',blank=True) - lieux = models.CharField(_('Lieux'),max_length=100,default=' ',blank=True) + date = models.DateField(_("Date"), max_length=100) + instru = models.ForeignKey( + "Instrument", on_delete=models.CASCADE, verbose_name=_("Instrument") + ) + description = models.CharField( + _("Description"), max_length=100, default=" ", blank=True + ) + description_en = models.CharField( + _("Description en anglais"), max_length=100, default=" ", blank=True + ) + prix = models.CharField(_("Prix"), max_length=100, default="", blank=True) + lieux = models.CharField(_("Lieux"), max_length=100, default=" ", blank=True) + def __str__(self): return self.description class Meta: - verbose_name = _('Réparation') - verbose_name_plural = _('Réparations') - ordering = ('date',) + verbose_name = _("Réparation") + verbose_name_plural = _("Réparations") + ordering = ("date",) diff --git a/instruments/templates/instruments/instru_liste.html b/instruments/templates/instruments/instru_liste.html index 6d05810..0326448 100644 --- a/instruments/templates/instruments/instru_liste.html +++ b/instruments/templates/instruments/instru_liste.html @@ -1,8 +1,6 @@ {% extends "gestion/base.html" %} {% load static %} {% load i18n %} -{% load autotranslate %} -{% load halflength %} {% block titre %}{% trans "Instruments" %}{% endblock %} {% block content %}
@@ -19,9 +17,9 @@
{% else %}
- +
{% endif %} - + {% if user.profile.is_chef %} {% trans "Ajouter un instrument" %} {% endif %} @@ -38,9 +36,9 @@ {% for instrument in instrus_dispo %} - + - {{ instrument.type }} + {{ instrument.type }} {{ instrument.owner }} {{ instrument.etat }} @@ -76,7 +74,7 @@ {% for instrument in instrus_prete %} - {{ instrument.type }} + {{ instrument.type }} {{ instrument.owner }} {{ instrument.user }} {{ instrument.etat}} diff --git a/instruments/templates/instruments/update_instru.html b/instruments/templates/instruments/update_instru.html index e0974e4..3d9e05e 100644 --- a/instruments/templates/instruments/update_instru.html +++ b/instruments/templates/instruments/update_instru.html @@ -9,7 +9,7 @@
-

{% blocktrans with type=instru.type etat=instru.etat%} {{type}} en {{etat}} {% endblocktrans%}

+

{% blocktrans with type=instru.type etat=instru.etat statut=instru.statut%} {{type}} en {{etat}} : {{statut}} {% endblocktrans%}

@@ -22,11 +22,11 @@ {% trans "Modele : "%} {{instru.model}}
{% trans "Numéro de série : "%} {{instru.serial}}
{% trans "Prix : "%} {{instru.prix}}
- {% blocktrans with annee=instru.annee %} Acheté.e en {{annee}} {% endblocktrans%} + {% blocktrans with annee=instru.annee %} Acheté·e en {{annee}} {% endblocktrans%}

{% if infos or infos_en %} -

{% trans "Infos utiles :" %}

+

{% trans "Infos utiles :" %}

{% autotranslate current_language infos infos_en %}
@@ -95,16 +95,6 @@ {{ form.as_p }} - {% else %} - {% if instru.infos %} -
-

Infos utiles

-

{{ infos }}

-
- {% endif %} -
- -
{% endif %} diff --git a/instruments/tests/test_views.py b/instruments/tests/test_views.py index f73d729..e39f2d1 100644 --- a/instruments/tests/test_views.py +++ b/instruments/tests/test_views.py @@ -4,6 +4,7 @@ from django.template.defaultfilters import urlencode from django.test import Client, TestCase from gestion.models import ErnestoUser + from ..models import Category, Partition, PartitionSet User = get_user_model() @@ -11,12 +12,7 @@ User = get_user_model() def new_user(username, ernesto=False, chef=False): u = User.objects.create_user(username=username) - ErnestoUser.objects.create( - user=u, - slug=username, - is_chef=chef, - is_ernesto=ernesto - ) + ErnestoUser.objects.create(user=u, slug=username, is_chef=chef, is_ernesto=ernesto) return u @@ -32,16 +28,10 @@ class TestViews(TestCase): ernesto = new_user("ernesto", ernesto=True) ernesto_c = Client() ernesto_c.force_login(ernesto) - self.client_matrix = [ - (chef, chef_c), - (ernesto, ernesto_c), - (None, Client()) - ] + self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())] # A Partition set with 1 partition self.pset = PartitionSet.objects.create( - category=Category.objects.first(), - nom="My PSet", - auteur="PSet author" + category=Category.objects.first(), nom="My PSet", auteur="PSet author" ) file = File(open("partitions/tests/test_file.txt"), "test file") Partition.objects.create(nom="part1", part=file, morceau=self.pset) @@ -90,9 +80,7 @@ class TestViews(TestCase): def test_download(self): """Only ernesto members can download partitions""" part = self.pset.partition_set.first() - url = "/partitions/{}/{}/{}".format( - self.pset.nom, self.pset.auteur, part.id - ) + url = "/partitions/{}/{}/{}".format(self.pset.nom, self.pset.auteur, part.id) self._get_restricted_page(url) def test_new(self): diff --git a/instruments/urls.py b/instruments/urls.py index 023e808..e054bbd 100644 --- a/instruments/urls.py +++ b/instruments/urls.py @@ -2,13 +2,15 @@ from django.urls import path from . import views -app_name = 'instruments' +app_name = "instruments" urlpatterns = [ - path('', views.liste, name='liste'), - path("delete/", views.InstruDelete.as_view(), name="delete_instru"), - path("delete_reparation/", views.delete_rep, name="delete_rep"), - path("new", views.InstruCreate.as_view(), name="ajouter_instru"), - path("new_rep/", views.create_rep, name="ajouter_rep"), - path("update_rep/", views.RepUpdate.as_view(), name="update_rep"), - path("fiche/",views.fiche_instru,name="fiche_instru"), + path("", views.ListeInstru.as_view(), name="liste"), + path("delete/", views.DeleteInstru.as_view(), + name="delete_instru"), + path("delete_reparation/", views.DeleteRep.as_view(), + name="delete_rep"), + path("new", views.CreateInstru.as_view(), name="ajouter_instru"), + path("new_rep/", views.CreateRep.as_view(), name="ajouter_rep"), + path("update_rep/", views.UpdateRep.as_view(), name="update_rep"), + path("fiche/", views.FicheInstru.as_view(), name="fiche_instru"), ] diff --git a/instruments/views.py b/instruments/views.py index 6a50cbf..f9206f0 100644 --- a/instruments/views.py +++ b/instruments/views.py @@ -1,104 +1,125 @@ -from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse -from instruments.models import Instrument,Reparation -from gestion.models import Photo -from django.contrib.auth.decorators import login_required -from django.forms.models import modelform_factory -from django.utils.safestring import mark_safe -from django.utils.text import slugify -from django.core.files import File -from django.utils.encoding import smart_str -from django.http import Http404 -from instruments.decorators import chef_required -from django.conf import settings -from django.db.models import Q -import os -import zipfile -import io -from gestion.mixins import ChefRequiredMixin -from django.views.generic import CreateView, DeleteView, ListView, UpdateView +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse_lazy -from django.utils.translation import gettext_lazy as _ -from django.http import HttpResponseRedirect -@login_required -def liste(request): - photo = Photo.objects.filter(cat='instru').order_by('?').first() - instrus_dispo = Instrument.objects.all().order_by('type').filter(statut='Disponible') - instrus_prete = Instrument.objects.all().order_by('type').filter(statut='Prêté') - return render(request, 'instruments/instru_liste.html', {"instrus_dispo":instrus_dispo,"instrus_prete":instrus_prete,"photo":photo}) +from django.utils.safestring import mark_safe +from django.views.generic import CreateView, DeleteView, UpdateView +from django.views.generic import TemplateView +from gestion.mixins import ChefRequiredMixin +from django.contrib.auth.mixins import LoginRequiredMixin +from gestion.models import Photo +from instruments.forms import ChefEditInstrumentForm, ChefReparationForm +from instruments.models import Instrument, Reparation -class InstruCreate(ChefRequiredMixin, CreateView): + +class ListeInstru(LoginRequiredMixin, TemplateView): + template_name = "instruments/instru_liste.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['photo'] = Photo.objects.filter( + cat="instru").order_by("?").first() + context['instrus_dispo'] = Instrument.objects.all().order_by( + "type").filter(statut="Disponible") + context['instrus_prete'] = Instrument.objects.all().order_by( + "type").filter(statut="Prêté") + return context + + +class CreateInstru(ChefRequiredMixin, CreateView): model = Instrument - fields = ["owner",'etat','type','marque','model','serial','annee','prix'] + fields = ["owner", "etat", "type", "marque", + "model", "serial", "annee", "prix"] template_name = "instruments/create_instru.html" success_url = reverse_lazy("instruments:liste") -@chef_required -def create_rep(request, pk): - ChefEditForm = modelform_factory(Reparation, - fields=("date","description","description_en","prix",'lieux')) - if request.method == "POST": - form = ChefEditForm(request.POST) +class CreateRep(ChefRequiredMixin, TemplateView): + form_class = ChefReparationForm + template_name = "instruments/create_rep.html" + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["form"] = self.form_class() + context["pk"] = self.kwargs['pk'] + return context + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST) if form.is_valid(): rep = Reparation() - rep.date = form.cleaned_data['date'] - rep.description = form.cleaned_data['description'] - rep.description_en = form.cleaned_data['description_en'] - rep.prix = form.cleaned_data['prix'] - rep.lieux = form.cleaned_data['lieux'] - rep.id_instru = get_object_or_404(Instrument, id=pk) + rep.date = form.cleaned_data["date"] + rep.description = form.cleaned_data["description"] + rep.description_en = form.cleaned_data["description_en"] + rep.prix = form.cleaned_data["prix"] + rep.lieux = form.cleaned_data["lieux"] + rep.instru = get_object_or_404(Instrument, id=self.kwargs['pk']) rep.save() - return redirect( 'instruments:fiche_instru', pk=pk) - - else: - form = ChefEditForm(request.POST) - return render(request, 'instruments/create_rep.html', locals()) + return redirect("instruments:fiche_instru", pk=self.kwargs['pk']) + else: + context = self.get_context_data() + context['form'] = form + return render(request, self.template_name, context) - -@chef_required -def delete_rep(request,pk): - rep = get_object_or_404(Reparation, id=pk) - - id_instru = rep.instru.id - - rep.delete() - suppression = _("Réparation supprimée") - - - return redirect('instruments:fiche_instru',pk=id_instru) - -@login_required -def fiche_instru(request, pk): - instru = get_object_or_404(Instrument, id=pk) - reparations= Reparation.objects.filter(instru = pk).order_by('-date') - ChefEditForm = modelform_factory(Instrument, - fields=("statut","user","infos","type","owner","marque","model","serial","annee","prix","infos_en")) - if request.method == "POST" and request.user.profile.is_chef: - form = ChefEditForm(request.POST, instance=instru) - if form.is_valid(): - form.save() - form = ChefEditForm(instance=instru) - infos = mark_safe(instru.infos) - infos_en = mark_safe(instru.infos_en) - return render(request, 'instruments/update_instru.html', locals()) - - -class RepUpdate(ChefRequiredMixin, UpdateView): +class DeleteRep(ChefRequiredMixin, TemplateView): model = Reparation - fields = ["date","description","description_en","prix",'lieux'] + template_name = "instruments/delete_instru.html" + + def get(self, request, *args, **kwargs): + + rep = get_object_or_404(self.model, id=self.kwargs['pk']) + id_instru = rep.instru.id + rep.delete() + return redirect("instruments:fiche_instru", pk=id_instru) + + +class FicheInstru(LoginRequiredMixin, TemplateView): + + template_name = "instruments/update_instru.html" + model = Instrument + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + instru = get_object_or_404(self.model, id=self.kwargs['pk']) + reparations = Reparation.objects.filter( + instru=self.kwargs['pk']).order_by("-date") + + form = ChefEditInstrumentForm(instance=instru) + infos = mark_safe(instru.infos) + infos_en = mark_safe(instru.infos_en) + + context["reparations"] = reparations + context["instru"] = instru + context["form"] = form + context["infos"] = infos + context["infos_en"] = infos_en + return context + + def post(self, request, *args, **kwargs): + instru = get_object_or_404(self.model, id=self.kwargs['pk']) + form = ChefEditInstrumentForm(request.POST, instance=instru) + if request.user.profile.is_chef: + if form.is_valid(): + form.save() + context = self.get_context_data() + context['form'] = form + return render(request, self.template_name, context) + + +class UpdateRep(ChefRequiredMixin, UpdateView): + model = Reparation + fields = ["date", "description", "description_en", "prix", "lieux"] template_name = "instruments/update_rep.html" def get_success_url(self): - # if you are passing 'pk' from 'urls' to 'DeleteView' for company - # capture that 'pk' as companyid and pass it to 'reverse_lazy()' function - id_instru=get_object_or_404(Reparation, id=self.kwargs['pk']).instru.id - return reverse_lazy('instruments:fiche_instru', kwargs={'pk': id_instru}) + id_instru = get_object_or_404(Reparation, + id=self.kwargs["pk"]).instru.id + return reverse_lazy("instruments:fiche_instru", + kwargs={"pk": id_instru}) -class InstruDelete(ChefRequiredMixin, DeleteView): + +class DeleteInstru(ChefRequiredMixin, DeleteView): model = Instrument template_name = "instruments/delete_instru.html" success_url = reverse_lazy("instruments:liste") diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo index bf96329..31f6bfd 100644 Binary files a/locale/en/LC_MESSAGES/django.mo and b/locale/en/LC_MESSAGES/django.mo differ diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index 7d4d8db..6407358 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-08-23 19:09+0200\n" +"POT-Creation-Date: 2021-04-29 00:25+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Mau'\n" "Language-Team: English \n" @@ -18,27 +18,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: Ernestophone/settings/common.py:124 +#: Ernestophone/settings/common.py:122 msgid "Français" msgstr "French" -#: Ernestophone/settings/common.py:125 +#: Ernestophone/settings/common.py:123 msgid "English" msgstr "English" -#: actu/models.py:5 +#: actu/models.py:7 msgid "Info" msgstr "Info" -#: actu/models.py:7 gestion/models.py:78 partitions/models.py:11 +#: actu/models.py:9 gestion/models.py:166 partitions/models.py:11 msgid "ordre" msgstr "order" -#: actu/models.py:12 +#: actu/models.py:15 msgid "Actualité" msgstr "News" -#: actu/models.py:13 +#: actu/models.py:16 msgid "Actualités" msgstr "News" @@ -50,14 +50,21 @@ msgstr "News list" msgid "Ajouter une actualité" msgstr "Add news report" -#: actu/templates/actu/actualité.html:19 pads/templates/pads/list.html:21 +#: actu/templates/actu/actualité.html:19 +#: instruments/templates/instruments/update_instru.html:71 +#: pads/templates/pads/list.html:21 msgid "Modifier" msgstr "Modify" -#: actu/templates/actu/actualité.html:20 pads/templates/pads/list.html:22 +#: actu/templates/actu/actualité.html:20 +#: instruments/templates/instruments/instru_liste.html:48 +#: instruments/templates/instruments/instru_liste.html:85 +#: instruments/templates/instruments/update_instru.html:72 +#: pads/templates/pads/list.html:22 #: partitions/templates/partitions/part.html:38 #: partitions/templates/partitions/part.html:58 -#: partitions/templates/partitions/repertoire.html:60 +#: partitions/templates/partitions/repertoire.html:72 +#: trombonoscope/templates/trombonoscope/delete_avatar.html:31 msgid "Supprimer" msgstr "Delete" @@ -69,7 +76,9 @@ msgstr "No news at the moment" msgid "Ajout d'une actualité" msgstr "Add news report" -#: actu/templates/actu/create_actu.html:9 pads/templates/pads/create.html:9 +#: actu/templates/actu/create_actu.html:9 +#: instruments/templates/instruments/create_instru.html:9 +#: pads/templates/pads/create.html:9 #: partitions/templates/partitions/new.html:27 msgid "Retour à la liste" msgstr "Back to the list" @@ -82,6 +91,9 @@ msgstr "This news report has been saved" #: actu/templates/actu/update_actu.html:12 #: calendrier/templates/calendrier/create.html:18 #: calendrier/templates/calendrier/update.html:14 +#: instruments/templates/instruments/create_instru.html:14 +#: instruments/templates/instruments/create_rep.html:14 +#: instruments/templates/instruments/update_rep.html:14 #: pads/templates/pads/create.html:14 pads/templates/pads/update.html:12 #: partitions/templates/partitions/upload.html:22 msgid "Enregistrer" @@ -100,12 +112,14 @@ msgstr "Back to the news" msgid " Voulez vous vraiment supprimer l'actualité %(object)s?" msgstr "Do you really want to delete the %(object)s news " -#: actu/templates/actu/delete_actu.html:12 calendrier/models.py:7 +#: actu/templates/actu/delete_actu.html:12 calendrier/models.py:9 #: calendrier/templates/calendrier/delete.html:15 #: calendrier/templates/calendrier/view_event.html:65 #: calendrier/templates/calendrier/view_event.html:88 -#: calendrier/templates/calendrier/view_event.html:102 gestion/models.py:58 -#: pads/templates/pads/delete.html:12 +#: calendrier/templates/calendrier/view_event.html:102 gestion/models.py:144 +#: instruments/templates/instruments/delete_instru.html:12 +#: instruments/templates/instruments/delete_rep.html:12 +#: pads/templates/pads/delete.html:12 partitions/models.py:50 #: partitions/templates/partitions/conf_delete.html:11 #: partitions/templates/partitions/conf_delete_morc.html:10 msgid "Oui" @@ -119,148 +133,151 @@ msgstr "Change a newscast" msgid " ranging from pop songs to pieces for brass bands." -#: gestion/templates/gestion/index.html:85 +#: gestion/templates/gestion/index.html:96 msgid "L'Ernestophone in a nutshell" msgstr "The Ernestophone in a nutshell" -#: gestion/templates/gestion/index.html:86 +#: gestion/templates/gestion/index.html:98 msgid "" "L'Ernestophone, c'est la fanfare de l'École\n" " normale supérieure, (re)créée en septembre 2011, pour le plus\n" @@ -755,41 +865,41 @@ msgstr "" "The Ernestophone is Ecole normale superieure's marching band, (re)created in " "September of 2011, for the joy of all the kids, including the grown-up ones." -#: gestion/templates/gestion/index.html:93 +#: gestion/templates/gestion/index.html:105 msgid "Notre répertoire" msgstr "Our repertoire" -#: gestion/templates/gestion/index.html:94 +#: gestion/templates/gestion/index.html:106 msgid "Rejoins-nous !" msgstr "Join us!" -#: gestion/templates/gestion/index.html:95 +#: gestion/templates/gestion/index.html:107 msgid "Nous contacter !" msgstr "Contact us!" -#: gestion/templates/gestion/index.html:101 +#: gestion/templates/gestion/index.html:113 msgid "Notre répertoire actuel" msgstr "Our current repertoire" -#: gestion/templates/gestion/index.html:113 -#: gestion/templates/gestion/index.html:140 partitions/models.py:35 -#: partitions/models.py:55 partitions/templates/partitions/repertoire.html:38 -#: partitions/templates/partitions/repertoire.html:79 +#: gestion/templates/gestion/index.html:125 +#: gestion/templates/gestion/index.html:152 partitions/models.py:36 +#: partitions/models.py:70 partitions/templates/partitions/repertoire.html:50 +#: partitions/templates/partitions/repertoire.html:91 msgid "Morceau" msgstr "Score" -#: gestion/templates/gestion/index.html:114 -#: gestion/templates/gestion/index.html:141 -#: partitions/templates/partitions/repertoire.html:39 -#: partitions/templates/partitions/repertoire.html:80 +#: gestion/templates/gestion/index.html:126 +#: gestion/templates/gestion/index.html:153 +#: partitions/templates/partitions/repertoire.html:51 +#: partitions/templates/partitions/repertoire.html:92 msgid "Compositeur" msgstr "Composer" -#: gestion/templates/gestion/index.html:156 +#: gestion/templates/gestion/index.html:168 msgid "Voir le répertoire présent et passé" msgstr "Show current and past repertoire" -#: gestion/templates/gestion/index.html:173 +#: gestion/templates/gestion/index.html:195 msgid "" "La fanfare c'est un savant mélange entre la claire trompette, le tonitruant " "trombone, la famille des saxophones (le Baryton alias le grand père, le " @@ -814,7 +924,7 @@ msgstr "" "happy to have you in our ranks!
We lend instruments to any COF member " "wishing to discover the joy of playing music in our band!" -#: gestion/templates/gestion/index.html:188 +#: gestion/templates/gestion/index.html:221 msgid "" " Demande à être inscrit sur
la mailing liste pour recevoir les dernières infos de nos bien aimé.e." @@ -823,7 +933,7 @@ msgstr "" "Ask to be sign up to our mailing liste to receive the latest info from our beloved chiefs!" -#: gestion/templates/gestion/index.html:198 +#: gestion/templates/gestion/index.html:242 msgid "" "Vous préparez un\n" " évenement et vous recherchez une fanfare dynamique ? " @@ -835,7 +945,7 @@ msgstr "" " event and searching for a dynamic marching band ? Don't hesitate to send us " "a message, we would be glad to come play for you! Check out our" -#: gestion/templates/gestion/index.html:201 +#: gestion/templates/gestion/index.html:245 msgid "agenda" msgstr "schedule" @@ -843,11 +953,6 @@ msgstr "schedule" msgid "L'Ernestophone : Connexion" msgstr "The Ernestophone : Log in" -#: gestion/templates/gestion/login.html:13 -#: gestion/templates/gestion/login.html:27 -msgid "Connexion" -msgstr "Log in" - #: gestion/templates/gestion/login.html:19 msgid "Mot de passe ou nom d'utilisateur incorrect" msgstr "Password or username invalid" @@ -876,6 +981,255 @@ msgstr "Your Account has been registered" msgid "Connecte toi !" msgstr "Log in!" +#: gestion/views.py:161 +msgid "Le champ Validation ne correspond pas à celui attendu" +msgstr "Validation field don't match the expected value" + +#: instruments/models.py:8 +msgid "Modèle" +msgstr "model" + +#: instruments/models.py:9 instruments/models.py:57 +#: instruments/templates/instruments/update_instru.html:49 +msgid "Prix" +msgstr "Price" + +#: instruments/models.py:14 +msgid "Bon état" +msgstr "Good shape" + +#: instruments/models.py:15 +msgid "Etat moyen" +msgstr "Medium shape" + +#: instruments/models.py:16 +msgid "Mauvais état" +msgstr "Bad shape" + +#: instruments/models.py:19 +msgid "Marque" +msgstr "Brand" + +#: instruments/models.py:21 +msgid "Numéro de série" +msgstr "Serial number" + +#: instruments/models.py:23 +msgid "Année d'achat" +msgstr "Year of purchase" + +#: instruments/models.py:24 +#: instruments/templates/instruments/instru_liste.html:33 +#: instruments/templates/instruments/instru_liste.html:67 +msgid "Propriétaire" +msgstr "Owner" + +#: instruments/models.py:25 +#: instruments/templates/instruments/instru_liste.html:68 +msgid "Utilisateur" +msgstr "User" + +#: instruments/models.py:30 +msgid "Disponible" +msgstr "Free" + +#: instruments/models.py:30 +#, fuzzy +#| msgid "Prêté" +msgid "Prêté·e" +msgstr "Used" + +#: instruments/models.py:32 partitions/models.py:53 +msgid "Infos utiles" +msgstr "Useful info" + +#: instruments/models.py:52 +#: instruments/templates/instruments/update_instru.html:48 +#, fuzzy +#| msgid "Valider l'inscription" +msgid "Description" +msgstr "Confirm registration" + +#: instruments/models.py:55 +msgid "Description en anglais" +msgstr "Description in english" + +#: instruments/models.py:58 +#, fuzzy +#| msgid "Lieu" +msgid "Lieux" +msgstr "Location" + +#: instruments/models.py:64 +msgid "Réparation" +msgstr "Repair" + +#: instruments/models.py:65 +msgid "Réparations" +msgstr "Repairs" + +#: instruments/templates/instruments/create_instru.html:3 +#, fuzzy +#| msgid "Ajout d'une actualité" +msgid "Ajout d'une instrument" +msgstr "Add news report" + +#: instruments/templates/instruments/create_instru.html:10 +#, fuzzy +#| msgid "Cette actualité a été enregistrée" +msgid "Cet instrument a été enregistré" +msgstr "This news report has been saved" + +#: instruments/templates/instruments/create_rep.html:3 +#: instruments/templates/instruments/update_rep.html:3 +#, fuzzy +#| msgid "Ajouter une partition :" +msgid "Ajout d'une réparation" +msgstr "Add a part:" + +#: instruments/templates/instruments/create_rep.html:9 +#: instruments/templates/instruments/update_rep.html:9 +#, fuzzy +#| msgid "Retour à la liste" +msgid "Retour à la fiche" +msgstr "Back to the list" + +#: instruments/templates/instruments/create_rep.html:10 +#: instruments/templates/instruments/update_rep.html:10 +#, fuzzy +#| msgid "Cette actualité a été enregistrée" +msgid "Cette réparation a été enregistrée" +msgstr "This news report has been saved" + +#: instruments/templates/instruments/delete_instru.html:3 +#, fuzzy +#| msgid "Suppression d'un événement" +msgid "Suppression d'un instrument" +msgstr "Event deletion" + +#: instruments/templates/instruments/delete_instru.html:10 +#, fuzzy +#| msgid "Retour aux partitions" +msgid "Retour aux instruments" +msgstr "Back to sheet music" + +#: instruments/templates/instruments/delete_instru.html:11 +#, fuzzy, python-format +#| msgid " Voulez vous vraiment supprimer le pad %(object)s?" +msgid " Voulez vous vraiment supprimer le.a %(object)s?" +msgstr "Do you really want to delete the %(object)s event " + +#: instruments/templates/instruments/delete_rep.html:3 +#, fuzzy +#| msgid "Suppression d'un pad" +msgid "Suppression d'une réparation" +msgstr "Deletion of a pad" + +#: instruments/templates/instruments/delete_rep.html:10 +#, fuzzy +#| msgid "Retour à la liste" +msgid "Retour à la fiche instrument" +msgstr "Back to the list" + +#: instruments/templates/instruments/delete_rep.html:11 +#, fuzzy, python-format +#| msgid " Voulez vous vraiment supprimer le pad %(object)s?" +msgid " Voulez vous vraiment supprimer la réparation %(object)s?" +msgstr "Do you really want to delete the %(object)s event " + +#: instruments/templates/instruments/instru_liste.html:24 +#, fuzzy +#| msgid "Ajouter un évènement" +msgid "Ajouter un instrument" +msgstr "Add an event" + +#: instruments/templates/instruments/instru_liste.html:27 +#, fuzzy +#| msgid "Instrument·s bonus" +msgid "Instruments Disponibles :" +msgstr "Extra instrument" + +#: instruments/templates/instruments/instru_liste.html:32 +#: instruments/templates/instruments/instru_liste.html:66 +#, fuzzy +#| msgid "Instrument" +msgid "Intrument" +msgstr "Instrument" + +#: instruments/templates/instruments/instru_liste.html:34 +#: instruments/templates/instruments/instru_liste.html:69 +msgid "Etat" +msgstr "Shape" + +#: instruments/templates/instruments/instru_liste.html:45 +#: instruments/templates/instruments/instru_liste.html:82 +msgid "Consulter" +msgstr "Consult" + +#: instruments/templates/instruments/instru_liste.html:60 +#, fuzzy +#| msgid "Instrument joué" +msgid "Instruments Prêtés :" +msgstr "Played instrument" + +#: instruments/templates/instruments/update_instru.html:12 +#, fuzzy, python-format +#| msgid "Le %(date)s à %(debut)s " +msgid " %(type)s en %(etat)s : %(statut)s " +msgstr "On %(date)s at %(debut)s" + +#: instruments/templates/instruments/update_instru.html:16 +msgid "Propriétaire : " +msgstr "Owner : " + +#: instruments/templates/instruments/update_instru.html:17 +msgid "Statut : " +msgstr "Status : " + +#: instruments/templates/instruments/update_instru.html:19 +msgid "Utilisateur : " +msgstr "User : " + +#: instruments/templates/instruments/update_instru.html:21 +msgid "Marque : " +msgstr "Brand : " + +#: instruments/templates/instruments/update_instru.html:22 +msgid "Modele : " +msgstr "Model : " + +#: instruments/templates/instruments/update_instru.html:23 +msgid "Numéro de série : " +msgstr "Serial number : " + +#: instruments/templates/instruments/update_instru.html:24 +msgid "Prix : " +msgstr "Price : " + +#: instruments/templates/instruments/update_instru.html:25 +#, fuzzy, python-format +#| msgid " Acheté.e en %(annee)s " +msgid " Acheté·e en %(annee)s " +msgstr "Purchased in %(annee)s" + +#: instruments/templates/instruments/update_instru.html:29 +#: partitions/templates/partitions/part.html:73 +#: partitions/templates/partitions/part.html:97 +msgid "Infos utiles :" +msgstr "Useful information:" + +#: instruments/templates/instruments/update_instru.html:42 +msgid "Réparation :" +msgid_plural "Réparations " +msgstr[0] "Repair :" +msgstr[1] "Repairs :" + +#: instruments/templates/instruments/update_instru.html:50 +#, fuzzy +#| msgid " %(lieu)s" +msgid "lieu" +msgstr "%(lieu)s" + #: pads/templates/pads/create.html:3 msgid "Ajout d'un pad" msgstr "Add a pad" @@ -917,31 +1271,31 @@ msgstr "No pad at the moment" msgid "Modification du pad" msgstr "Change the pad" -#: partitions/models.py:17 +#: partitions/models.py:18 msgid "Categorie" msgstr "Category" -#: partitions/models.py:18 +#: partitions/models.py:19 msgid "Categories" msgstr "Categories" -#: partitions/models.py:36 partitions/models.py:56 +#: partitions/models.py:37 partitions/models.py:71 msgid "Morceaux" msgstr "Scores" -#: partitions/models.py:46 +#: partitions/models.py:45 msgid "Type de partition" msgstr "Type of sheet music" -#: partitions/models.py:49 -msgid "Infos utiles" -msgstr "Useful info" +#: partitions/models.py:48 +msgid "Téléchargeable non connecté ?" +msgstr "Downloable unlogged ?" -#: partitions/models.py:51 +#: partitions/models.py:58 msgid "Url d'une video youtube" msgstr "Url of a youtube clip" -#: partitions/models.py:51 +#: partitions/models.py:62 msgid "" "Dans Youtube cliquer sur partager puis importer pour récuperer la bonne " "adresse" @@ -980,7 +1334,7 @@ msgstr "" #: partitions/templates/partitions/new.html:3 #: partitions/templates/partitions/new.html:9 -#: partitions/templates/partitions/repertoire.html:15 +#: partitions/templates/partitions/repertoire.html:27 msgid "Ajouter un morceau" msgstr "Add a score" @@ -1005,11 +1359,6 @@ msgstr "No sheet music for now" msgid "Ajouter un média" msgstr "Add a media" -#: partitions/templates/partitions/part.html:73 -#: partitions/templates/partitions/part.html:97 -msgid "Infos utiles :" -msgstr "Useful information:" - #: partitions/templates/partitions/part.html:110 msgid "Retour au répertoire" msgstr "Back to repertoire" @@ -1018,8 +1367,8 @@ msgstr "Back to repertoire" msgid "L'Ernestophone : répertoire" msgstr "The Ernestophone: Repertoire" -#: partitions/templates/partitions/repertoire.html:15 -#: partitions/templates/partitions/repertoire.html:17 +#: partitions/templates/partitions/repertoire.html:27 +#: partitions/templates/partitions/repertoire.html:29 msgid "Télécharger tous les musecores actifs" msgstr "Download all active musescores" @@ -1035,31 +1384,27 @@ msgstr "Add a part:" msgid "Retour aux partitions" msgstr "Back to sheet music" -#: partitions/views.py:83 +#: partitions/views.py:142 msgid "Le caractère / n'est pas autorisé dans le nom" msgstr "The / character is not allowed in the name" -#: partitions/views.py:90 partitions/views.py:150 +#: partitions/views.py:150 partitions/views.py:237 msgid "Un morceau du même nom existe déjà" msgstr "A score with the same name already exists" -#: partitions/views.py:130 -msgid "Partition supprimée" -msgstr "Sheet music deleted" - -#: partitions/views.py:144 +#: partitions/views.py:229 msgid "Le caractère / n'est pas autorisé" msgstr "The / character is not allowed" #: trombonoscope/templates/trombonoscope/add_avatar.html:3 -#: trombonoscope/templates/trombonoscope/change_avatar.html:3 -#: trombonoscope/templates/trombonoscope/change_avatar.html:12 +#: trombonoscope/templates/trombonoscope/change_avatar.html:4 +#: trombonoscope/templates/trombonoscope/change_avatar.html:13 #: trombonoscope/templates/trombonoscope/delete_avatar.html:3 msgid "Modification de l'avatar" msgstr "Change the picture" #: trombonoscope/templates/trombonoscope/add_avatar.html:12 -#: trombonoscope/templates/trombonoscope/change_avatar.html:13 +#: trombonoscope/templates/trombonoscope/change_avatar.html:14 msgid "Avatar courant: " msgstr "Current avatar :" @@ -1070,37 +1415,37 @@ msgid "Ajouter une nouvelle image" msgstr "Add a score" #: trombonoscope/templates/trombonoscope/add_avatar.html:21 -#: trombonoscope/templates/trombonoscope/change_avatar.html:24 +#: trombonoscope/templates/trombonoscope/change_avatar.html:28 #: trombonoscope/templates/trombonoscope/delete_avatar.html:15 #: trombonoscope/templates/trombonoscope/delete_avatar.html:31 msgid "Retour au profil" msgstr "Back to profile" -#: trombonoscope/templates/trombonoscope/change_avatar.html:16 +#: trombonoscope/templates/trombonoscope/change_avatar.html:19 msgid "" "Tu n'as pas encore ajouté d'avatar. Le logo Ernestophone sera utilisé par " "defaut." msgstr "" "Tou don't have an avatar yet. The logo Ernestophone will be used instead." -#: trombonoscope/templates/trombonoscope/change_avatar.html:20 +#: trombonoscope/templates/trombonoscope/change_avatar.html:24 msgid "Modifier mon avatar" msgstr "Modify my picture" -#: trombonoscope/templates/trombonoscope/change_avatar.html:26 -#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:24 +#: trombonoscope/templates/trombonoscope/change_avatar.html:30 +#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:31 msgid "Supprimer l'avatar " msgstr "Deleting the picture" -#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:12 +#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:13 msgid "Modification du profil trombonoscope" msgstr "Yearbook profile modification" -#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:19 +#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:20 msgid "Avatar pour le trombonoscope :" msgstr "Picture for the yearbook :" -#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:22 +#: trombonoscope/templates/trombonoscope/changetrombonoscope.html:29 msgid "Changer l'avatar " msgstr "Change the picture" @@ -1120,10 +1465,6 @@ msgstr "Download a picture" msgid "Séléctione l'avatar pour le supprimer" msgstr "Select the avatar to confirm suppression" -#: trombonoscope/templates/trombonoscope/delete_avatar.html:31 -msgid "Delete These" -msgstr "" - #: trombonoscope/templates/trombonoscope/trombonoscope.html:6 msgid "L'Ernestophone : Trombonoscope" msgstr "The Ernestophone: Yearbook" @@ -1136,1213 +1477,32 @@ msgstr "Change my yearbook profile" msgid "Trombonoscope actuel :" msgstr "Current yearbook" -#: trombonoscope/templates/trombonoscope/trombonoscope.html:50 +#: trombonoscope/templates/trombonoscope/trombonoscope.html:56 msgid "Trombonoscope des anciens :" msgstr "Yearbook of former members:" -#: venv/lib/python3.5/site-packages/django/contrib/messages/apps.py:7 -msgid "Messages" -msgstr "" +#~ msgid "Photo pour le trombonoscope" +#~ msgstr "Picture for the yearbook" -#: venv/lib/python3.5/site-packages/django/contrib/sitemaps/apps.py:7 -msgid "Site Maps" -msgstr "" +#~ msgid "Partition supprimée" +#~ msgstr "Sheet music deleted" -#: venv/lib/python3.5/site-packages/django/contrib/staticfiles/apps.py:9 -msgid "Static Files" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/contrib/syndication/apps.py:7 -msgid "Syndication" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/paginator.py:45 -msgid "That page number is not an integer" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/paginator.py:47 -msgid "That page number is less than 1" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/paginator.py:52 -msgid "That page contains no results" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:31 -msgid "Enter a valid value." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:102 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:658 -msgid "Enter a valid URL." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:154 -msgid "Enter a valid integer." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:165 -msgid "Enter a valid email address." -msgstr "" - -#. Translators: "letters" means latin letters: a-z and A-Z. -#: venv/lib/python3.5/site-packages/django/core/validators.py:239 -msgid "" -"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:246 -msgid "" -"Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or " -"hyphens." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:255 -#: venv/lib/python3.5/site-packages/django/core/validators.py:275 -msgid "Enter a valid IPv4 address." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:260 -#: venv/lib/python3.5/site-packages/django/core/validators.py:276 -msgid "Enter a valid IPv6 address." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:270 -#: venv/lib/python3.5/site-packages/django/core/validators.py:274 -msgid "Enter a valid IPv4 or IPv6 address." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:304 -msgid "Enter only digits separated by commas." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:310 -#, python-format -msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:342 -#, python-format -msgid "Ensure this value is less than or equal to %(limit_value)s." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:351 -#, python-format -msgid "Ensure this value is greater than or equal to %(limit_value)s." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:361 -#, python-format -msgid "" -"Ensure this value has at least %(limit_value)d character (it has " -"%(show_value)d)." -msgid_plural "" -"Ensure this value has at least %(limit_value)d characters (it has " -"%(show_value)d)." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:376 -#, python-format -msgid "" -"Ensure this value has at most %(limit_value)d character (it has " -"%(show_value)d)." -msgid_plural "" -"Ensure this value has at most %(limit_value)d characters (it has " -"%(show_value)d)." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:395 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:290 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:325 -msgid "Enter a number." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:397 -#, python-format -msgid "Ensure that there are no more than %(max)s digit in total." -msgid_plural "Ensure that there are no more than %(max)s digits in total." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:402 -#, python-format -msgid "Ensure that there are no more than %(max)s decimal place." -msgid_plural "Ensure that there are no more than %(max)s decimal places." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:407 -#, python-format -msgid "" -"Ensure that there are no more than %(max)s digit before the decimal point." -msgid_plural "" -"Ensure that there are no more than %(max)s digits before the decimal point." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:469 -#, python-format -msgid "" -"File extension '%(extension)s' is not allowed. Allowed extensions are: " -"'%(allowed_extensions)s'." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/core/validators.py:521 -msgid "Null characters are not allowed." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/base.py:1162 -#: venv/lib/python3.5/site-packages/django/forms/models.py:756 #, fuzzy -#| msgid "agenda" -msgid "and" -msgstr "schedule" +#~| msgid "agenda" +#~ msgid "and" +#~ msgstr "schedule" -#: venv/lib/python3.5/site-packages/django/db/models/base.py:1164 -#, python-format -msgid "%(model_name)s with this %(field_labels)s already exists." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:104 -#, python-format -msgid "Value %(value)r is not a valid choice." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:105 -msgid "This field cannot be null." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:106 -msgid "This field cannot be blank." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:107 -#, python-format -msgid "%(model_name)s with this %(field_label)s already exists." -msgstr "" - -#. Translators: The 'lookup_type' is one of 'date', 'year' or 'month'. -#. Eg: "Title must be unique for pub_date year" -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:111 -#, python-format -msgid "" -"%(field_label)s must be unique for %(date_field_label)s %(lookup_type)s." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:128 -#, python-format -msgid "Field of type: %(field_type)s" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:905 -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1772 -msgid "Integer" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:909 -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1770 -#, python-format -msgid "'%(value)s' value must be an integer." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:984 -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1850 -msgid "Big (8 byte) integer" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:996 -#, python-format -msgid "'%(value)s' value must be either True or False." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:997 -#, python-format -msgid "'%(value)s' value must be either True, False, or None." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:999 -msgid "Boolean (Either True or False)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1040 -#, python-format -msgid "String (up to %(max_length)s)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1104 -msgid "Comma-separated integers" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1153 -#, python-format -msgid "" -"'%(value)s' value has an invalid date format. It must be in YYYY-MM-DD " -"format." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1155 -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1298 -#, python-format -msgid "" -"'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid " -"date." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1158 -msgid "Date (without time)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1296 -#, python-format -msgid "" -"'%(value)s' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[." -"uuuuuu]][TZ] format." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1300 -#, python-format -msgid "" -"'%(value)s' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]]" -"[TZ]) but it is an invalid date/time." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1304 -msgid "Date (with time)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1452 -#, python-format -msgid "'%(value)s' value must be a decimal number." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1454 -msgid "Decimal number" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1593 -#, python-format -msgid "" -"'%(value)s' value has an invalid format. It must be in [DD] [HH:[MM:]]ss[." -"uuuuuu] format." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1596 -msgid "Duration" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1646 -msgid "Email address" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1669 -msgid "File path" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1735 -#, python-format -msgid "'%(value)s' value must be a float." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1737 -msgid "Floating point number" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1866 -msgid "IPv4 address" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1897 -msgid "IP address" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1977 -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1978 -#, python-format -msgid "'%(value)s' value must be either None, True or False." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:1980 -msgid "Boolean (Either True, False or None)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2015 -msgid "Positive integer" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2028 -msgid "Positive small integer" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2042 -#, python-format -msgid "Slug (up to %(max_length)s)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2074 -msgid "Small integer" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2081 -msgid "Text" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2109 -#, python-format -msgid "" -"'%(value)s' value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] " -"format." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2111 -#, python-format -msgid "" -"'%(value)s' value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an " -"invalid time." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2114 -msgid "Time" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2240 -msgid "URL" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2262 -msgid "Raw binary data" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2312 -#, python-format -msgid "'%(value)s' is not a valid UUID." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/__init__.py:2314 -msgid "Universally unique identifier" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/files.py:221 -msgid "File" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/files.py:360 -msgid "Image" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/related.py:778 -#, python-format -msgid "%(model)s instance with %(field)s %(value)r does not exist." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/related.py:780 -msgid "Foreign Key (type determined by related field)" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/related.py:1007 -msgid "One-to-one relationship" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/related.py:1057 -#, python-format -msgid "%(from)s-%(to)s relationship" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/related.py:1058 -#, python-format -msgid "%(from)s-%(to)s relationships" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/db/models/fields/related.py:1100 -msgid "Many-to-many relationship" -msgstr "" - -#. Translators: If found as last label character, these punctuation -#. characters will prevent the default label_suffix to be appended to the label -#: venv/lib/python3.5/site-packages/django/forms/boundfield.py:146 -msgid ":?.!" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:53 -msgid "This field is required." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:245 -msgid "Enter a whole number." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:396 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:1126 -msgid "Enter a valid date." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:420 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:1127 -msgid "Enter a valid time." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:442 -msgid "Enter a valid date/time." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:471 -msgid "Enter a valid duration." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:472 -#, python-brace-format -msgid "The number of days must be between {min_days} and {max_days}." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:532 -msgid "No file was submitted. Check the encoding type on the form." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:533 -msgid "No file was submitted." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:534 -msgid "The submitted file is empty." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:536 -#, python-format -msgid "Ensure this filename has at most %(max)d character (it has %(length)d)." -msgid_plural "" -"Ensure this filename has at most %(max)d characters (it has %(length)d)." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:539 -msgid "Please either submit a file or check the clear checkbox, not both." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:600 -msgid "" -"Upload a valid image. The file you uploaded was either not an image or a " -"corrupted image." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:762 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:852 -#: venv/lib/python3.5/site-packages/django/forms/models.py:1270 -#, python-format -msgid "Select a valid choice. %(value)s is not one of the available choices." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:853 -#: venv/lib/python3.5/site-packages/django/forms/fields.py:968 -#: venv/lib/python3.5/site-packages/django/forms/models.py:1269 -msgid "Enter a list of values." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:969 -msgid "Enter a complete value." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/fields.py:1185 -msgid "Enter a valid UUID." -msgstr "" - -#. Translators: This is the default suffix added to form field labels -#: venv/lib/python3.5/site-packages/django/forms/forms.py:86 -msgid ":" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/forms.py:212 -#, python-format -msgid "(Hidden field %(name)s) %(error)s" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/formsets.py:91 -msgid "ManagementForm data is missing or has been tampered with" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/formsets.py:338 -#, python-format -msgid "Please submit %d or fewer forms." -msgid_plural "Please submit %d or fewer forms." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/forms/formsets.py:345 -#, python-format -msgid "Please submit %d or more forms." -msgid_plural "Please submit %d or more forms." -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/forms/formsets.py:371 -#: venv/lib/python3.5/site-packages/django/forms/formsets.py:373 -msgid "Order" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/formsets.py:375 -msgid "Delete" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:751 -#, python-format -msgid "Please correct the duplicate data for %(field)s." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:755 -#, python-format -msgid "Please correct the duplicate data for %(field)s, which must be unique." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:761 -#, python-format -msgid "" -"Please correct the duplicate data for %(field_name)s which must be unique " -"for the %(lookup)s in %(date_field)s." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:770 -msgid "Please correct the duplicate values below." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:1091 -msgid "The inline value did not match the parent instance." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:1158 -msgid "Select a valid choice. That choice is not one of the available choices." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/models.py:1272 -#, python-format -msgid "\"%(pk)s\" is not a valid value." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/utils.py:162 -#, python-format -msgid "" -"%(datetime)s couldn't be interpreted in time zone %(current_timezone)s; it " -"may be ambiguous or it may not exist." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/widgets.py:395 -msgid "Clear" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/widgets.py:396 -msgid "Currently" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/widgets.py:397 -msgid "Change" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/widgets.py:709 -msgid "Unknown" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/widgets.py:710 -msgid "Yes" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/forms/widgets.py:711 #, fuzzy -#| msgid "Non" -msgid "No" -msgstr "No" +#~| msgid "Non" +#~ msgid "No" +#~ msgstr "No" -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:788 -msgid "yes,no,maybe" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:817 -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:834 -#, python-format -msgid "%(size)d byte" -msgid_plural "%(size)d bytes" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:836 -#, python-format -msgid "%s KB" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:838 -#, python-format -msgid "%s MB" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:840 -#, python-format -msgid "%s GB" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:842 -#, python-format -msgid "%s TB" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/template/defaultfilters.py:844 -#, python-format -msgid "%s PB" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dateformat.py:62 -msgid "p.m." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dateformat.py:63 -msgid "a.m." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dateformat.py:68 -msgid "PM" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dateformat.py:69 -msgid "AM" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dateformat.py:150 -msgid "midnight" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dateformat.py:152 -msgid "noon" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:6 -msgid "Monday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:6 -msgid "Tuesday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:6 -msgid "Wednesday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:6 -msgid "Thursday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:6 -msgid "Friday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:7 -msgid "Saturday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:7 -msgid "Sunday" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:10 #, fuzzy -#| msgid "Non" -msgid "Mon" -msgstr "No" +#~| msgid "Non" +#~ msgid "Mon" +#~ msgstr "No" -#: venv/lib/python3.5/site-packages/django/utils/dates.py:10 -msgid "Tue" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:10 -msgid "Wed" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:10 -msgid "Thu" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:10 -msgid "Fri" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:11 -msgid "Sat" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:11 -msgid "Sun" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:14 -msgid "January" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:14 -msgid "February" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:14 -msgid "March" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:14 -msgid "April" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:14 -msgid "May" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:14 -msgid "June" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:15 -msgid "July" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:15 -msgid "August" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:15 -msgid "September" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:15 -msgid "October" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:15 -msgid "November" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:16 -msgid "December" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:19 -msgid "jan" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:19 -msgid "feb" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:19 -msgid "mar" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:19 -msgid "apr" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:19 -msgid "may" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:19 -msgid "jun" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:20 -msgid "jul" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:20 -msgid "aug" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:20 -msgid "sep" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:20 -msgid "oct" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:20 -msgid "nov" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:20 -msgid "dec" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:23 -msgctxt "abbrev. month" -msgid "Jan." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:24 -msgctxt "abbrev. month" -msgid "Feb." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:25 -msgctxt "abbrev. month" -msgid "March" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:26 -msgctxt "abbrev. month" -msgid "April" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:27 -msgctxt "abbrev. month" -msgid "May" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:28 -msgctxt "abbrev. month" -msgid "June" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:29 -msgctxt "abbrev. month" -msgid "July" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:30 -msgctxt "abbrev. month" -msgid "Aug." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:31 -msgctxt "abbrev. month" -msgid "Sept." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:32 -msgctxt "abbrev. month" -msgid "Oct." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:33 -msgctxt "abbrev. month" -msgid "Nov." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:34 -msgctxt "abbrev. month" -msgid "Dec." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:37 -msgctxt "alt. month" -msgid "January" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:38 -msgctxt "alt. month" -msgid "February" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:39 -msgctxt "alt. month" -msgid "March" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:40 -msgctxt "alt. month" -msgid "April" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:41 -msgctxt "alt. month" -msgid "May" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:42 -msgctxt "alt. month" -msgid "June" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:43 -msgctxt "alt. month" -msgid "July" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:44 -msgctxt "alt. month" -msgid "August" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:45 -msgctxt "alt. month" -msgid "September" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:46 -msgctxt "alt. month" -msgid "October" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:47 -msgctxt "alt. month" -msgid "November" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/dates.py:48 -msgctxt "alt. month" -msgid "December" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/ipv6.py:8 -msgid "This is not a valid IPv6 address." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/text.py:67 -#, python-format -msgctxt "String to return when truncating text" -msgid "%(truncated_text)s…" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/text.py:233 -msgid "or" -msgstr "" - -#. Translators: This string is used as a separator between list elements -#: venv/lib/python3.5/site-packages/django/utils/text.py:252 -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:83 -msgid ", " -msgstr "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:9 -#, python-format -msgid "%d year" -msgid_plural "%d years" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:10 -#, python-format -msgid "%d month" -msgid_plural "%d months" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:11 -#, python-format -msgid "%d week" -msgid_plural "%d weeks" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:12 -#, python-format -msgid "%d day" -msgid_plural "%d days" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:13 -#, python-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:14 -#, python-format -msgid "%d minute" -msgid_plural "%d minutes" -msgstr[0] "" -msgstr[1] "" - -#: venv/lib/python3.5/site-packages/django/utils/timesince.py:72 -msgid "0 minutes" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:110 -msgid "Forbidden" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:111 -msgid "CSRF verification failed. Request aborted." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:115 -msgid "" -"You are seeing this message because this HTTPS site requires a 'Referer " -"header' to be sent by your Web browser, but none was sent. This header is " -"required for security reasons, to ensure that your browser is not being " -"hijacked by third parties." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:120 -msgid "" -"If you have configured your browser to disable 'Referer' headers, please re-" -"enable them, at least for this site, or for HTTPS connections, or for 'same-" -"origin' requests." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:124 -msgid "" -"If you are using the tag or " -"including the 'Referrer-Policy: no-referrer' header, please remove them. The " -"CSRF protection requires the 'Referer' header to do strict referer checking. " -"If you're concerned about privacy, use alternatives like for links to third-party sites." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:132 -msgid "" -"You are seeing this message because this site requires a CSRF cookie when " -"submitting forms. This cookie is required for security reasons, to ensure " -"that your browser is not being hijacked by third parties." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:137 -msgid "" -"If you have configured your browser to disable cookies, please re-enable " -"them, at least for this site, or for 'same-origin' requests." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/csrf.py:142 -msgid "More information is available with DEBUG=True." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:41 -msgid "No year specified" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:61 -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:111 -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:208 -msgid "Date out of range" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:90 -msgid "No month specified" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:142 -msgid "No day specified" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:188 -msgid "No week specified" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:338 -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:367 -#, python-format -msgid "No %(verbose_name_plural)s available" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:589 -#, python-format -msgid "" -"Future %(verbose_name_plural)s not available because %(class_name)s." -"allow_future is False." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/dates.py:623 -#, python-format -msgid "Invalid date string '%(datestr)s' given format '%(format)s'" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/detail.py:54 -#, python-format -msgid "No %(verbose_name)s found matching the query" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/list.py:67 -msgid "Page is not 'last', nor can it be converted to an int." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/list.py:72 -#, python-format -msgid "Invalid page (%(page_number)s): %(message)s" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/generic/list.py:154 -#, python-format -msgid "Empty list and '%(class_name)s.allow_empty' is False." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/static.py:40 -msgid "Directory indexes are not allowed here." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/static.py:42 -#, python-format -msgid "\"%(path)s\" does not exist" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/static.py:80 -#, python-format -msgid "Index of %(directory)s" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:6 -msgid "Django: the Web framework for perfectionists with deadlines." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:345 -#, python-format -msgid "" -"View release notes for Django %(version)s" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:367 -msgid "The install worked successfully! Congratulations!" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:368 -#, python-format -msgid "" -"You are seeing this page because DEBUG=True is in your settings file and you have not configured any " -"URLs." -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:383 -msgid "Django Documentation" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:384 -msgid "Topics, references, & how-to's" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:395 -msgid "Tutorial: A Polling App" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:396 -msgid "Get started with Django" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:407 -msgid "Django Community" -msgstr "" - -#: venv/lib/python3.5/site-packages/django/views/templates/default_urlconf.html:408 -msgid "Connect, get help, or contribute" -msgstr "" - -#: venv/lib/python3.5/site-packages/random_image/apps.py:9 -msgid "Random images" -msgstr "" - -#: venv/lib/python3.5/site-packages/random_image/models.py:20 -msgid "start date" -msgstr "" - -#: venv/lib/python3.5/site-packages/random_image/models.py:21 #, fuzzy -#| msgid " Le %(date)s" -msgid "end date" -msgstr "On %(date)s" - -#: venv/lib/python3.5/site-packages/random_image/models.py:22 -msgid "random_image_container" -msgstr "" - -#: venv/lib/python3.5/site-packages/random_image/models.py:28 -msgid "image" -msgstr "" - -#: venv/lib/python3.5/site-packages/random_image/models.py:29 -msgid "images" -msgstr "" +#~| msgid " Le %(date)s" +#~ msgid "end date" +#~ msgstr "On %(date)s" diff --git a/manage.py b/manage.py index 81b678e..414e4f4 100755 --- a/manage.py +++ b/manage.py @@ -3,10 +3,7 @@ import os import sys if __name__ == "__main__": - os.environ.setdefault( - "DJANGO_SETTINGS_MODULE", - "Ernestophone.settings.local" - ) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ernestophone.settings.local") from django.core.management import execute_from_command_line diff --git a/pads/admin.py b/pads/admin.py index 8c38f3f..846f6b4 100644 --- a/pads/admin.py +++ b/pads/admin.py @@ -1,3 +1 @@ -from django.contrib import admin - # Register your models here. diff --git a/pads/apps.py b/pads/apps.py index 834f677..a4c46e5 100644 --- a/pads/apps.py +++ b/pads/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class PadsConfig(AppConfig): - name = 'pads' + name = "pads" diff --git a/pads/forms.py b/pads/forms.py index 61adf1e..3c313e2 100644 --- a/pads/forms.py +++ b/pads/forms.py @@ -1,8 +1,12 @@ from django import forms + from pads.models import Pad class PadForm(forms.ModelForm): class Meta: model = Pad - fields = ('nom', 'url',) + fields = ( + "nom", + "url", + ) diff --git a/pads/migrations/0001_initial.py b/pads/migrations/0001_initial.py index bea7ce9..f8a3295 100644 --- a/pads/migrations/0001_initial.py +++ b/pads/migrations/0001_initial.py @@ -6,20 +6,27 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='Pad', + name="Pad", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), - ('nom', models.CharField(max_length=100)), - ('url', models.URLField()), - ('date', models.DateField(verbose_name='Créé le')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + verbose_name="ID", + serialize=False, + ), + ), + ("nom", models.CharField(max_length=100)), + ("url", models.URLField()), + ("date", models.DateField(verbose_name="Créé le")), ], options={ - 'verbose_name': 'Pad', + "verbose_name": "Pad", }, ), ] diff --git a/pads/migrations/0002_auto_20200716_1742.py b/pads/migrations/0002_auto_20200716_1742.py index 1c83b54..5a2370a 100644 --- a/pads/migrations/0002_auto_20200716_1742.py +++ b/pads/migrations/0002_auto_20200716_1742.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('pads', '0001_initial'), + ("pads", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='pad', - name='date', - field=models.DateField(verbose_name='Cree le'), + model_name="pad", + name="date", + field=models.DateField(verbose_name="Cree le"), ), ] diff --git a/pads/models.py b/pads/models.py index f071ad4..b4f212e 100644 --- a/pads/models.py +++ b/pads/models.py @@ -11,4 +11,6 @@ class Pad(models.Model): class Meta: verbose_name = "Pad" + + # Create your models here. diff --git a/pads/urls.py b/pads/urls.py index 1aebfc3..8cdc865 100644 --- a/pads/urls.py +++ b/pads/urls.py @@ -2,7 +2,6 @@ from django.urls import path from pads import views - app_name = "pads" urlpatterns = [ path("", views.PadList.as_view(), name="list"), diff --git a/pads/views.py b/pads/views.py index 4dd68ce..c3ef998 100644 --- a/pads/views.py +++ b/pads/views.py @@ -3,6 +3,7 @@ from django.http import HttpResponseRedirect from django.urls import reverse_lazy from django.utils import timezone from django.views.generic import CreateView, DeleteView, ListView, UpdateView + from gestion.mixins import ChefRequiredMixin from pads.models import Pad diff --git a/partitions/admin.py b/partitions/admin.py index 4f7641d..dc2e8bd 100644 --- a/partitions/admin.py +++ b/partitions/admin.py @@ -1,7 +1,6 @@ from django.contrib import admin - -from .models import Category,PartitionSet +from .models import Category, PartitionSet admin.site.register(Category) admin.site.register(PartitionSet) diff --git a/partitions/apps.py b/partitions/apps.py index 095e886..7592569 100644 --- a/partitions/apps.py +++ b/partitions/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class PartitionsConfig(AppConfig): - name = 'partitions' + name = "partitions" diff --git a/partitions/decorators.py b/partitions/decorators.py deleted file mode 100644 index 50a7ea9..0000000 --- a/partitions/decorators.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.contrib.auth.decorators import user_passes_test - - -def is_chef(user): - try: - profile = user.profile - return profile.is_chef - except: - return False - -chef_required = user_passes_test(lambda u: is_chef(u)) diff --git a/partitions/forms.py b/partitions/forms.py index 0fe9bb9..c795b1a 100644 --- a/partitions/forms.py +++ b/partitions/forms.py @@ -1,5 +1,7 @@ from django import forms +from .models import PartitionSet + class UploadFileForm(forms.Form): title = forms.CharField(max_length=50) @@ -9,3 +11,9 @@ class UploadFileForm(forms.Form): class UploadMorceauForm(forms.Form): titre = forms.CharField(max_length=100) auteur = forms.CharField(max_length=100) + + +class ChefEditMorceauForm(forms.ModelForm): + class Meta: + model = PartitionSet + fields = ("category", "download_unlogged", "infos", "url", "infos_en") diff --git a/partitions/migrations/0001_initial.py b/partitions/migrations/0001_initial.py index af80c0a..6f788b7 100644 --- a/partitions/migrations/0001_initial.py +++ b/partitions/migrations/0001_initial.py @@ -6,31 +6,66 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='Partition', + name="Partition", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), - ('nom', models.CharField(max_length=100)), - ('part', models.FileField(upload_to='partitions/')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + verbose_name="ID", + serialize=False, + ), + ), + ("nom", models.CharField(max_length=100)), + ("part", models.FileField(upload_to="partitions/")), ], ), migrations.CreateModel( - name='PartitionSet', + name="PartitionSet", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), - ('nom', models.CharField(max_length=100)), - ('auteur', models.CharField(max_length=100)), - ('category', models.CharField(max_length=8, choices=[('active', 'Actif'), ('incoming', 'À venir'), ('old', 'Archive'), ('optional', 'Optionnel')], default='incoming', verbose_name='Types de partitions')), - ('infos', models.TextField(blank=True, verbose_name='Infos utiles', null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + verbose_name="ID", + serialize=False, + ), + ), + ("nom", models.CharField(max_length=100)), + ("auteur", models.CharField(max_length=100)), + ( + "category", + models.CharField( + max_length=8, + choices=[ + ("active", "Actif"), + ("incoming", "À venir"), + ("old", "Archive"), + ("optional", "Optionnel"), + ], + default="incoming", + verbose_name="Types de partitions", + ), + ), + ( + "infos", + models.TextField( + blank=True, verbose_name="Infos utiles", null=True + ), + ), ], ), migrations.AddField( - model_name='partition', - name='morceau', - field=models.ForeignKey(to='partitions.PartitionSet', on_delete=models.CASCADE), + model_name="partition", + name="morceau", + field=models.ForeignKey( + to="partitions.PartitionSet", on_delete=models.CASCADE + ), ), ] diff --git a/partitions/migrations/0002_category.py b/partitions/migrations/0002_category.py index 37f55c0..d05b8e7 100644 --- a/partitions/migrations/0002_category.py +++ b/partitions/migrations/0002_category.py @@ -1,19 +1,21 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models def create_categories(apps, schema_editor): # Insert the previously hardcoded categories in the database Category = apps.get_model("partitions", "Category") - Category.objects.bulk_create([ - Category(name="Partitions actives", order=1), - Category(name="Partitions optionnelles", order=2), - Category(name="Partitions à venir", order=3), - Category(name="Archives", order=4) - ]) + Category.objects.bulk_create( + [ + Category(name="Partitions actives", order=1), + Category(name="Partitions optionnelles", order=2), + Category(name="Partitions à venir", order=3), + Category(name="Archives", order=4), + ] + ) def set_new_categories(apps, schema_editor): @@ -24,7 +26,7 @@ def set_new_categories(apps, schema_editor): "active": assoc_list[0], "incoming": assoc_list[2], "old": assoc_list[3], - "optional": assoc_list[1] + "optional": assoc_list[1], } for par_set in PartitionSet.objects.all(): par_set.category = mapping[par_set.category_old] @@ -39,7 +41,7 @@ def reset_old_categories(apps, schema_editor): assoc_list[0][1]: "active", assoc_list[2][1]: "incoming", assoc_list[3][1]: "old", - assoc_list[1][1]: "optional" + assoc_list[1][1]: "optional", } for par_set in PartitionSet.objects.all(): par_set.category_old = mapping[par_set.category] @@ -49,29 +51,39 @@ def reset_old_categories(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('partitions', '0001_initial'), + ("partitions", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Category', + name="Category", fields=[ - ('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)), - ('name', models.CharField(max_length=127)), - ('order', models.IntegerField(verbose_name='order')), + ( + "id", + models.AutoField( + verbose_name="ID", + primary_key=True, + serialize=False, + auto_created=True, + ), + ), + ("name", models.CharField(max_length=127)), + ("order", models.IntegerField(verbose_name="order")), ], - options={'verbose_name': 'catégorie', 'verbose_name_plural': 'catégories'}, + options={"verbose_name": "catégorie", "verbose_name_plural": "catégories"}, ), migrations.RunPython(create_categories, migrations.RunPython.noop), - migrations.RenameField(model_name="partitionset", old_name="category", new_name="category_old"), + migrations.RenameField( + model_name="partitionset", old_name="category", new_name="category_old" + ), migrations.AddField( - model_name='partitionset', - name='category', + model_name="partitionset", + name="category", field=models.ForeignKey( - verbose_name='Type de partition', - to='partitions.Category', + verbose_name="Type de partition", + to="partitions.Category", on_delete=django.db.models.deletion.PROTECT, - default=1 # Dummy, will be set by the RunPython operation + default=1, # Dummy, will be set by the RunPython operation ), preserve_default=False, ), diff --git a/partitions/migrations/0003_auto_20200716_1749.py b/partitions/migrations/0003_auto_20200716_1749.py index d4b5364..0dddbc0 100644 --- a/partitions/migrations/0003_auto_20200716_1749.py +++ b/partitions/migrations/0003_auto_20200716_1749.py @@ -1,47 +1,78 @@ # Generated by Django 2.2.14 on 2020-07-16 17:49 -from django.db import migrations, models import django.db.models.expressions import django.db.models.functions.text +from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('partitions', '0002_category'), + ("partitions", "0002_category"), ] operations = [ migrations.AlterModelOptions( - name='category', - options={'ordering': ('order',), 'verbose_name': 'Categorie', 'verbose_name_plural': 'Categories'}, + name="category", + options={ + "ordering": ("order",), + "verbose_name": "Categorie", + "verbose_name_plural": "Categories", + }, ), migrations.AlterModelOptions( - name='partition', - options={'ordering': (django.db.models.expressions.CombinedExpression(django.db.models.expressions.Value('-'), '+', django.db.models.functions.text.Lower('nom')),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'}, + name="partition", + options={ + "ordering": ( + django.db.models.expressions.CombinedExpression( + django.db.models.expressions.Value("-"), + "+", + django.db.models.functions.text.Lower("nom"), + ), + ), + "verbose_name": "Morceau", + "verbose_name_plural": "Morceaux", + }, ), migrations.AlterModelOptions( - name='partitionset', - options={'ordering': (django.db.models.expressions.CombinedExpression(django.db.models.expressions.Value('-'), '+', django.db.models.functions.text.Lower('nom')),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'}, + name="partitionset", + options={ + "ordering": ( + django.db.models.expressions.CombinedExpression( + django.db.models.expressions.Value("-"), + "+", + django.db.models.functions.text.Lower("nom"), + ), + ), + "verbose_name": "Morceau", + "verbose_name_plural": "Morceaux", + }, ), migrations.AddField( - model_name='category', - name='nom_en', + model_name="category", + name="nom_en", field=models.CharField(blank=True, max_length=100, null=True), ), migrations.AddField( - model_name='partitionset', - name='infos_en', - field=models.TextField(blank=True, null=True, verbose_name='Infos utiles en anglais'), + model_name="partitionset", + name="infos_en", + field=models.TextField( + blank=True, null=True, verbose_name="Infos utiles en anglais" + ), ), migrations.AddField( - model_name='partitionset', - name='url', - field=models.URLField(blank=True, help_text='Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse', null=True, verbose_name="Url d'une video youtube"), + model_name="partitionset", + name="url", + field=models.URLField( + blank=True, + help_text="Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse", + null=True, + verbose_name="Url d'une video youtube", + ), ), migrations.AlterField( - model_name='category', - name='order', - field=models.IntegerField(verbose_name='ordre'), + model_name="category", + name="order", + field=models.IntegerField(verbose_name="ordre"), ), ] diff --git a/partitions/migrations/0004_auto_20210331_1350.py b/partitions/migrations/0004_auto_20210331_1350.py index 019f90f..e685ce2 100644 --- a/partitions/migrations/0004_auto_20210331_1350.py +++ b/partitions/migrations/0004_auto_20210331_1350.py @@ -1,37 +1,52 @@ # Generated by Django 2.2.17 on 2021-03-31 13:50 -from django.db import migrations, models import django.db.models.functions.text +from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('partitions', '0003_auto_20200716_1749'), + ("partitions", "0003_auto_20200716_1749"), ] operations = [ migrations.AlterModelOptions( - name='partition', - options={'ordering': (django.db.models.functions.text.Lower('nom'),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'}, + name="partition", + options={ + "ordering": (django.db.models.functions.text.Lower("nom"),), + "verbose_name": "Morceau", + "verbose_name_plural": "Morceaux", + }, ), migrations.AlterModelOptions( - name='partitionset', - options={'ordering': (django.db.models.functions.text.Lower('nom'),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'}, + name="partitionset", + options={ + "ordering": (django.db.models.functions.text.Lower("nom"),), + "verbose_name": "Morceau", + "verbose_name_plural": "Morceaux", + }, ), migrations.AddField( - model_name='partitionset', - name='download_unlogged', - field=models.CharField(choices=[('n', 'Non'), ('o', 'Oui')], default='n', max_length=1, verbose_name='Téléchargeable non connecté ?'), + model_name="partitionset", + name="download_unlogged", + field=models.CharField( + choices=[("n", "Non"), ("o", "Oui")], + default="n", + max_length=1, + verbose_name="Téléchargeable non connecté ?", + ), ), migrations.AlterField( - model_name='partitionset', - name='infos', - field=models.TextField(blank=True, default='', verbose_name='Infos utiles'), + model_name="partitionset", + name="infos", + field=models.TextField(blank=True, default="", verbose_name="Infos utiles"), ), migrations.AlterField( - model_name='partitionset', - name='infos_en', - field=models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais'), + model_name="partitionset", + name="infos_en", + field=models.TextField( + blank=True, default="", verbose_name="Infos utiles en anglais" + ), ), ] diff --git a/partitions/models.py b/partitions/models.py index 269022f..7470d56 100644 --- a/partitions/models.py +++ b/partitions/models.py @@ -2,29 +2,28 @@ import os from django.conf import settings from django.db import models -from colorful.fields import RGBColorField from django.db.models.functions import Lower from django.utils.translation import gettext_lazy as _ - class Category(models.Model): name = models.CharField(max_length=127) order = models.IntegerField(verbose_name=_("ordre")) - nom_en = models.CharField(max_length=100,null=True,blank=True) + nom_en = models.CharField(max_length=100, null=True, blank=True) + def __str__(self): return self.name class Meta: verbose_name = _("Categorie") verbose_name_plural = _("Categories") - ordering = ('order',) + ordering = ("order",) class Partition(models.Model): nom = models.CharField(max_length=100) part = models.FileField(upload_to="partitions/") - morceau = models.ForeignKey('PartitionSet', on_delete=models.CASCADE) + morceau = models.ForeignKey("PartitionSet", on_delete=models.CASCADE) def __str__(self): return self.nom @@ -34,26 +33,40 @@ class Partition(models.Model): super(Partition, self).delete(*args, **kwargs) class Meta: - verbose_name = _('Morceau') - verbose_name_plural = _('Morceaux') - ordering = (Lower('nom'),) + verbose_name = _("Morceau") + verbose_name_plural = _("Morceaux") + ordering = (Lower("nom"),) class PartitionSet(models.Model): nom = models.CharField(max_length=100) auteur = models.CharField(max_length=100) category = models.ForeignKey( - Category, - on_delete=models.PROTECT, - verbose_name=_("Type de partition") + Category, on_delete=models.PROTECT, verbose_name=_("Type de partition") ) - download_unlogged = models.CharField(_("Téléchargeable non connecté ?"),default='n',choices = [('n',_('Non')),('o',_('Oui'))],max_length=1) - infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="") - infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="") - url = models.URLField(_("Url d'une video youtube"),null=True,blank=True, help_text= _("Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse")) + download_unlogged = models.CharField( + _("Téléchargeable non connecté ?"), + default="n", + choices=[("n", _("Non")), ("o", _("Oui"))], + max_length=1, + ) + infos = models.TextField(_("Infos utiles"), null=False, blank=True, default="") + infos_en = models.TextField( + "Infos utiles en anglais", null=False, blank=True, default="" + ) + url = models.URLField( + _("Url d'une video youtube"), + null=True, + blank=True, + help_text=_( + "Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse" + ), + ) + def __str__(self): - return("%s - %s [%s]" % (self.nom, self.auteur, self.category)) + return "%s - %s [%s]" % (self.nom, self.auteur, self.category) + class Meta: - verbose_name = _('Morceau') - verbose_name_plural = _('Morceaux') - ordering = (Lower('nom'),) + verbose_name = _("Morceau") + verbose_name_plural = _("Morceaux") + ordering = (Lower("nom"),) diff --git a/partitions/templates/partitions/conf_delete.html b/partitions/templates/partitions/conf_delete.html index c88681d..9bef2ac 100644 --- a/partitions/templates/partitions/conf_delete.html +++ b/partitions/templates/partitions/conf_delete.html @@ -7,7 +7,7 @@

{% trans "Confirmation de suppression" %}

-

{% trans "Voulez-vous vraiment supprimer cette partition ?" %}"

+

{% trans "Voulez-vous vraiment supprimer cette partition ?" %}

{% trans "Oui" %}

{% trans "Retour à la liste des partitions" %}

diff --git a/partitions/templates/partitions/part.html b/partitions/templates/partitions/part.html index 3a7ed74..5685b15 100644 --- a/partitions/templates/partitions/part.html +++ b/partitions/templates/partitions/part.html @@ -74,7 +74,7 @@
{% autotranslate current_language infos infos_en %}
- + {% endif %} {% endif %} diff --git a/partitions/templates/partitions/repertoire.html b/partitions/templates/partitions/repertoire.html index 3f0f48d..c87b093 100644 --- a/partitions/templates/partitions/repertoire.html +++ b/partitions/templates/partitions/repertoire.html @@ -20,9 +20,9 @@
{% else %}
- +
{% endif %} -
+ {% if user.profile.is_chef %} {% trans "Ajouter un morceau" %}   {% trans "Télécharger tous les musecores actifs" %} {% elif user.is_authenticated %} diff --git a/partitions/tests/test_views.py b/partitions/tests/test_views.py index f73d729..e39f2d1 100644 --- a/partitions/tests/test_views.py +++ b/partitions/tests/test_views.py @@ -4,6 +4,7 @@ from django.template.defaultfilters import urlencode from django.test import Client, TestCase from gestion.models import ErnestoUser + from ..models import Category, Partition, PartitionSet User = get_user_model() @@ -11,12 +12,7 @@ User = get_user_model() def new_user(username, ernesto=False, chef=False): u = User.objects.create_user(username=username) - ErnestoUser.objects.create( - user=u, - slug=username, - is_chef=chef, - is_ernesto=ernesto - ) + ErnestoUser.objects.create(user=u, slug=username, is_chef=chef, is_ernesto=ernesto) return u @@ -32,16 +28,10 @@ class TestViews(TestCase): ernesto = new_user("ernesto", ernesto=True) ernesto_c = Client() ernesto_c.force_login(ernesto) - self.client_matrix = [ - (chef, chef_c), - (ernesto, ernesto_c), - (None, Client()) - ] + self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())] # A Partition set with 1 partition self.pset = PartitionSet.objects.create( - category=Category.objects.first(), - nom="My PSet", - auteur="PSet author" + category=Category.objects.first(), nom="My PSet", auteur="PSet author" ) file = File(open("partitions/tests/test_file.txt"), "test file") Partition.objects.create(nom="part1", part=file, morceau=self.pset) @@ -90,9 +80,7 @@ class TestViews(TestCase): def test_download(self): """Only ernesto members can download partitions""" part = self.pset.partition_set.first() - url = "/partitions/{}/{}/{}".format( - self.pset.nom, self.pset.auteur, part.id - ) + url = "/partitions/{}/{}/{}".format(self.pset.nom, self.pset.auteur, part.id) self._get_restricted_page(url) def test_new(self): diff --git a/partitions/urls.py b/partitions/urls.py index 67c5866..273530e 100644 --- a/partitions/urls.py +++ b/partitions/urls.py @@ -2,17 +2,26 @@ from django.urls import path from . import views -app_name = 'partitions' +app_name = "partitions" urlpatterns = [ - path('', views.liste, name='liste'), - path('download', views.download_musecores, name='download_musecores'), - path("//upload", views.upload, name="upload"), - path("/", views.listepart, name="listepart"), - path("//see/", views.see, name="see"), - path("//", views.download, name="download"), - path("///conf", views.conf_delete, name="conf_delete"), - path("///delete", views.delete, name="delete"), - path("//delete", views.delete_morc, name="delete_morc"), - path("//conf", views.conf_delete_morc, name="conf_delete_morc"), - path("new", views.ajouter_morceau, name="ajouter_morceau"), + path("", views.Repertoire.as_view(), name="liste"), + path("download", views.download_musecores, name="download_musecores"), + path("//upload", views.Upload.as_view(), + name="upload"), + path("/", views.Morceau.as_view(), name="listepart"), + path("//see/", views.see, + name="see"), + path("//", views.download, + name="download"), + path("///conf", views.ConfDelete.as_view(), + name="conf_delete"), + path("///delete", views.DeletePart.as_view(), + name="delete"), + path("//delete", views.DeleteMorc.as_view(), + name="delete_morc"), + path( + "//conf", views.ConfDeleteMorc.as_view(), + name="conf_delete_morc" + ), + path("new", views.CreateMorc.as_view(), name="ajouter_morceau"), ] diff --git a/partitions/views.py b/partitions/views.py index f22a4e7..5001688 100644 --- a/partitions/views.py +++ b/partitions/views.py @@ -1,27 +1,34 @@ -from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse -from partitions.models import Category, Partition, PartitionSet -from gestion.models import Photo -from django.contrib.auth.decorators import login_required -from partitions.forms import UploadFileForm, UploadMorceauForm -from django.forms.models import modelform_factory -from django.utils.safestring import mark_safe -from django.utils.text import slugify -from django.core.files import File -from django.utils.encoding import smart_str -from django.http import Http404 -from partitions.decorators import chef_required -from django.conf import settings -from django.db.models import Q +import io import os import zipfile -import io + +from django.core.files import File +from django.db.models import Q +from django.http import Http404 +from django.shortcuts import HttpResponse, get_object_or_404, redirect, render +from django.utils.safestring import mark_safe +from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ +from gestion.models import Photo +from partitions.forms import UploadFileForm, UploadMorceauForm +from partitions.models import Category, Partition, PartitionSet +from django.contrib.auth.mixins import LoginRequiredMixin +from django.views.generic import TemplateView + +from .forms import ChefEditMorceauForm +from gestion.mixins import ChefRequiredMixin + + def download_musecores(request): - p = Partition.objects.filter(Q(part__contains = ".mscz") & Q(Q(morceau__category__name = "Partitions actives" )|Q(morceau__category__name = "Partitions optionnelles" ))) - - + p = Partition.objects.filter( + Q(part__contains=".mscz") + & Q( + Q(morceau__category__name="Partitions actives") + | Q(morceau__category__name="Partitions optionnelles") + ) + ) zip_subdir = "Ernestophone_musescores" zip_filename = "%s.zip" % zip_subdir @@ -32,14 +39,22 @@ def download_musecores(request): # The zip compressor zf = zipfile.ZipFile(s, "w") - for part in p : + for part in p: fpath = part.part.path - typ=".mscz" + typ = ".mscz" # Calculate path for file in zip fdir, fname = os.path.split(fpath) - zip_path = os.path.join(zip_subdir, '%s_%s_%s.%s' % ( - slugify(part.morceau.nom), slugify(part.morceau.auteur), slugify(part.nom), typ)) + zip_path = os.path.join( + zip_subdir, + "%s_%s_%s.%s" + % ( + slugify(part.morceau.nom), + slugify(part.morceau.auteur), + slugify(part.nom), + typ, + ), + ) # Add file, at correct path zf.write(fpath, zip_path) @@ -49,70 +64,117 @@ def download_musecores(request): # Grab ZIP file from in-memory, make response with correct MIME-type resp = HttpResponse(s.getvalue()) # ..and correct content-disposition - resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename + resp["Content-Disposition"] = "attachment; filename=%s" % zip_filename return resp -def liste(request): - categories = Category.objects.prefetch_related("partitionset_set").order_by("order") - photo = Photo.objects.filter(cat='part').order_by('?').first() - return render(request, 'partitions/repertoire.html', {"categories": categories,"photo":photo}) -@login_required -def listepart(request, nom, auteur): - p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur) - part = p.partition_set.all().order_by('nom') - ChefEditForm = modelform_factory(PartitionSet, - fields=("category","download_unlogged", "infos","url","infos_en")) - if request.method == "POST" and request.user.profile.is_chef: - form = ChefEditForm(request.POST, instance=p) - if form.is_valid(): - form.save() - form = ChefEditForm(instance=p) - infos = mark_safe(p.infos) - infos_en = mark_safe(p.infos_en) - return render(request, 'partitions/part.html', locals()) +class Repertoire(TemplateView): + template_name = "partitions/repertoire.html" -@chef_required -def upload(request, nom, auteur): - if request.method == "POST": + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['categories'] = Category.objects.prefetch_related( + "partitionset_set").order_by("order") + context['photo'] = Photo.objects.filter( + cat="part").order_by("?").first() + return context + + +class Morceau(LoginRequiredMixin, TemplateView): + template_name = "partitions/part.html" + form_class = ChefEditMorceauForm + + def get_context_data(self, **kwargs): + context = super(Morceau, self).get_context_data(**kwargs) + p = get_object_or_404(PartitionSet, nom=self.kwargs['nom'], + auteur=self.kwargs['auteur']) + part = p.partition_set.all().order_by("nom") + form = self.form_class(instance=p) + infos = mark_safe(p.infos) + infos_en = mark_safe(p.infos_en) + + context["p"] = p + context["infos"] = infos + context["infos_en"] = infos_en + context["form"] = form + context["part"] = part + context["nom"] = self.kwargs['nom'] + context["auteur"] = self.kwargs['auteur'] + + return context + + def post(self, request, *args, **kwargs): + p = get_object_or_404(PartitionSet, nom=self.kwargs['nom'], + auteur=self.kwargs['auteur']) + if request.user.profile.is_chef: + form = self.form_class(request.POST, instance=p) + if form.is_valid(): + form.save() + context = self.get_context_data() + return render(request, self.template_name, context) + + +class Upload(ChefRequiredMixin, TemplateView): + form_class = UploadFileForm + sauvegarde = False + error = False + template_name = "partitions/upload.html" + + def get_context_data(self, **kwargs): + context = super(Upload, self).get_context_data(**kwargs) + form = self.form_class() + + context["sauvegarde"] = self.sauvegarde + context["nom"] = self.kwargs['nom'] + context["auteur"] = self.kwargs['auteur'] + context["form"] = form + context["error"] = self.error + return context + + def post(self, request, *args, **kwargs): form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): partition = Partition() - partition.part = form.cleaned_data['file'] - partition.nom = form.cleaned_data['title'] - if '/' in partition.nom: - error = _("Le caractère / n'est pas autorisé dans le nom") - form = UploadFileForm() - return render(request, "partitions/upload.html", locals()) - mor = get_object_or_404(PartitionSet, nom=nom, auteur=auteur) + partition.part = form.cleaned_data["file"] + partition.nom = form.cleaned_data["title"] + if "/" in partition.nom: + self.error = _("Le caractère / n'est pas autorisé dans le nom") + context = self.get_context_data() + return render(request, self.template_name, context) + mor = get_object_or_404(PartitionSet, nom=self.kwargs['nom'], + auteur=self.kwargs['auteur']) partition.morceau = mor try: mor.partition_set.get(nom=partition.nom) - error = _("Un morceau du même nom existe déjà") + self.error = _("Un morceau du même nom existe déjà") except Partition.DoesNotExist: partition.save() - sauvegarde = True - else: - form = UploadFileForm() - return render(request, 'partitions/upload.html', locals()) + self.sauvegarde = True + + context = self.get_context_data() + context['form'] = form + return render(request, self.template_name, context) def see(request, nom, auteur, partition_id): partition = get_object_or_404(Partition, id=partition_id) _, extension = os.path.splitext(partition.part.path) download_unlogged = partition.morceau.download_unlogged - if(download_unlogged == 'o' or request.user.is_authenticated): + if download_unlogged == "o" or request.user.is_authenticated: if ".pdf" == extension: - with open(partition.part.path, 'rb') as f: + with open(partition.part.path, "rb") as f: myfile = File(f) response = HttpResponse(content=myfile.read()) response["Content-Type"] = "application/pdf" response["Content-Disposition"] = "inline; filename=%s_%s_%s.pdf" % ( - slugify(nom), slugify(auteur), slugify(partition.nom)) + slugify(nom), + slugify(auteur), + slugify(partition.nom), + ) return response elif ".mp3" == extension: - with open(partition.part.path, 'rb') as f: + with open(partition.part.path, "rb") as f: myfile = File(f) response = HttpResponse() response.write(myfile.read()) @@ -122,38 +184,56 @@ def see(request, nom, auteur, partition_id): else: p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur) part = p.partition_set.all() - return render(request, 'partitions/part.html', locals()) - else : - return redirect('login') + return render( + request, + "partitions/part.html", + {"p": p, "part": part, "nom": nom, "auteur": auteur}, + ) + else: + return redirect("login") -@chef_required -def delete(request, nom, auteur, id): - p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur) - try: - part = p.partition_set.get(id=id) - except Partition.DoesNotExist: - raise Http404 - part.delete() - suppression = _("Partition supprimée") - p.refresh_from_db() - part = p.partition_set.all() - return redirect('partitions:listepart',nom=nom,auteur=auteur) -@chef_required -def ajouter_morceau(request): - if request.method == "POST": - form = UploadMorceauForm(request.POST) +class DeletePart(ChefRequiredMixin, TemplateView): + model = PartitionSet + + def get(self, request, *args, **kwargs): + p = get_object_or_404(self.model, nom=self.kwargs['nom'], + auteur=self.kwargs['auteur']) + try: + part = p.partition_set.get(id=self.kwargs['id']) + except Partition.DoesNotExist: + raise Http404 + part.delete() + return redirect("partitions:listepart", nom=self.kwargs['nom'], + auteur=self.kwargs['auteur']) + + +class CreateMorc(ChefRequiredMixin, TemplateView): + form_class = UploadMorceauForm + template_name = "partitions/new.html" + + def get_context_data(self, **kwargs): + context = super(CreateMorc, self).get_context_data(**kwargs) + context['form'] = self.form_class() + return context + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST) + sauvegarde = False + error = False if form.is_valid(): partitionset = PartitionSet() - partitionset.nom = form.cleaned_data['titre'] - partitionset.auteur = form.cleaned_data['auteur'] - if '/' in partitionset.auteur or '/' in partitionset.nom: + partitionset.nom = form.cleaned_data["titre"] + partitionset.auteur = form.cleaned_data["auteur"] + if "/" in partitionset.auteur or "/" in partitionset.nom: error = _("Le caractère / n'est pas autorisé") - form = UploadMorceauForm() - return render(request, 'partitions/new.html', locals()) + context = self.get_context_data() + context['error'] = error + return render(request, self.template_name, context) try: - PartitionSet.objects.get(nom=partitionset.nom, - auteur=partitionset.auteur) + PartitionSet.objects.get( + nom=partitionset.nom, auteur=partitionset.auteur + ) error = _("Un morceau du même nom existe déjà") except PartitionSet.DoesNotExist: # XXX. Hideous @@ -165,50 +245,64 @@ def ajouter_morceau(request): partitionset.category = cat partitionset.save() sauvegarde = True - return redirect('partitions:liste') - else: - form = UploadMorceauForm() - return render(request, 'partitions/new.html', locals()) + return redirect("partitions:liste") + context = self.get_context_data() + context['sauvegarde'] = sauvegarde + context['error'] = error + context['form'] = form + return render(request, self.template_name, context) +class ConfDelete(ChefRequiredMixin, TemplateView): + template_name = "partitions/conf_delete.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['nom'] = self.kwargs.get("nom") + context['auteur'] = self.kwargs.get("auteur") + context['id'] = self.kwargs.get("id") + return context -@chef_required -def conf_delete(request, nom, auteur, id): - part = get_object_or_404(Partition, id=id) - return render(request, 'partitions/conf_delete.html', locals()) +class DeleteMorc(ChefRequiredMixin, TemplateView): + model = PartitionSet -@chef_required -def delete_morc(request, nom, auteur): - p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur) - part = p.partition_set.all() - for pa in part: - pa.delete() - p.delete() - partitions = PartitionSet.objects.all() - categories = Category.objects.prefetch_related("partitionset_set") - return redirect('partitions:liste') + def get(self, request, *args, **kwargs): + p = get_object_or_404(self.model, nom=self.kwargs['nom'], + auteur=self.kwargs['auteur']) + part = p.partition_set.all() + for pa in part: + pa.delete() + p.delete() + return redirect("partitions:liste") -@chef_required -def conf_delete_morc(request, nom, auteur): - return render(request, 'partitions/conf_delete_morc.html', locals()) - +class ConfDeleteMorc(ChefRequiredMixin, TemplateView): + template_name = "partitions/conf_delete_morc.html" + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['nom'] = self.kwargs.get("nom") + context['auteur'] = self.kwargs.get("auteur") + return context def download(request, nom, auteur, partition_id): partition = get_object_or_404(Partition, id=partition_id) download_unlogged = partition.morceau.download_unlogged - if(download_unlogged == 'o' or request.user.is_authenticated): - with open(partition.part.path, 'rb') as f: + if download_unlogged == "o" or request.user.is_authenticated: + with open(partition.part.path, "rb") as f: myfile = File(f) response = HttpResponse(content=myfile.read()) typ = os.path.splitext(myfile.name)[1][1:] - response['Content-Type'] = 'application/%s' % (typ, ) - response['Content-Disposition'] = 'attachment; filename=%s_%s_%s.%s' % ( - slugify(nom), slugify(auteur), slugify(partition.nom), typ) + response["Content-Type"] = "application/%s" % (typ,) + response["Content-Disposition"] = "attachment; filename=%s_%s_%s.%s" % ( + slugify(nom), + slugify(auteur), + slugify(partition.nom), + typ, + ) return response - else : - return redirect('login') + else: + return redirect("login") diff --git a/trombonoscope/admin.py b/trombonoscope/admin.py index 8c38f3f..846f6b4 100644 --- a/trombonoscope/admin.py +++ b/trombonoscope/admin.py @@ -1,3 +1 @@ -from django.contrib import admin - # Register your models here. diff --git a/trombonoscope/apps.py b/trombonoscope/apps.py index 68546d0..c00b836 100644 --- a/trombonoscope/apps.py +++ b/trombonoscope/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class TrombonoscopeConfig(AppConfig): - name = 'trombonoscope' + name = "trombonoscope" diff --git a/trombonoscope/forms.py b/trombonoscope/forms.py index 77d845d..b51f2f3 100644 --- a/trombonoscope/forms.py +++ b/trombonoscope/forms.py @@ -1,25 +1,26 @@ from django import forms + from gestion.models import ErnestoUser -from django.utils.translation import gettext_lazy as _ class ChangeTrombonoscope(forms.ModelForm): - - def save(self, *args, **kwargs): super(ChangeTrombonoscope, self).save(*args, **kwargs) - trombonoscope = self.cleaned_data["trombonoscope"] - - trombonoscope_colors = self.cleaned_data['trombonoscope_colors'] - if(trombonoscope_colors != 'autre'): - - self.instance.trombonoscope_fond=trombonoscope_colors[:7] - self.instance.trombonoscope_texte=trombonoscope_colors[7:] - self.instance.save( ) - + trombonoscope_colors = self.cleaned_data["trombonoscope_colors"] + if trombonoscope_colors != "autre": + self.instance.trombonoscope_fond = trombonoscope_colors[:7] + self.instance.trombonoscope_texte = trombonoscope_colors[7:] + self.instance.save() class Meta: model = ErnestoUser - fields = ("trombonoscope","nom_trombonoscope","instru_trombonoscope","trombonoscope_colors","trombonoscope_fond","trombonoscope_texte") + fields = ( + "trombonoscope", + "nom_trombonoscope", + "instru_trombonoscope", + "trombonoscope_colors", + "trombonoscope_fond", + "trombonoscope_texte", + ) diff --git a/trombonoscope/models.py b/trombonoscope/models.py index 71a8362..6b20219 100644 --- a/trombonoscope/models.py +++ b/trombonoscope/models.py @@ -1,3 +1 @@ -from django.db import models - # Create your models here. diff --git a/trombonoscope/templatetags/modulo.py b/trombonoscope/templatetags/modulo.py index a861cbc..ec2f5a0 100644 --- a/trombonoscope/templatetags/modulo.py +++ b/trombonoscope/templatetags/modulo.py @@ -1,8 +1,10 @@ -from django import template from datetime import date, timedelta +from django import template + register = template.Library() + @register.filter def modulo(num, val): return num % val diff --git a/trombonoscope/urls.py b/trombonoscope/urls.py index ea5ce60..d480bb8 100644 --- a/trombonoscope/urls.py +++ b/trombonoscope/urls.py @@ -2,10 +2,8 @@ from django.urls import path from trombonoscope import views - app_name = "trombonoscope" urlpatterns = [ - - path("", views.trombonoscope, name="view"), - path("modif_profil", views.changetrombonoscope, name="change"), + path("", views.Trombonoscope.as_view(), name="view"), + path("modif_profil", views.ChangeTrombonoscope.as_view(), name="change"), ] diff --git a/trombonoscope/views.py b/trombonoscope/views.py index cf183e6..4b47fcb 100644 --- a/trombonoscope/views.py +++ b/trombonoscope/views.py @@ -1,24 +1,39 @@ -from django.shortcuts import render -from django.contrib.auth.decorators import login_required +from django.shortcuts import redirect, render + from gestion.models import ErnestoUser from trombonoscope.forms import ChangeTrombonoscope -from django.shortcuts import render, redirect +from django.contrib.auth.mixins import LoginRequiredMixin +from django.views.generic import TemplateView -@login_required -def changetrombonoscope(request): - if request.method == 'POST': - requbis = request.POST.copy() - form = ChangeTrombonoscope(request.POST,request.FILES, instance=request.user.profile) + +class ChangeTrombonoscope(LoginRequiredMixin, TemplateView): + form_class = ChangeTrombonoscope + template_name = "trombonoscope/changetrombonoscope.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + form = self.form_class(instance=self.request.user.profile) + context['form'] = form + return context + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST, request.FILES, + instance=request.user.profile) if form.is_valid(): form.save() - success = True - return redirect('trombonoscope:view') - else: - form = ChangeTrombonoscope(instance=request.user.profile) - return render(request, 'trombonoscope/changetrombonoscope.html', locals()) + return redirect("trombonoscope:view") + context = self.get_context_data() + context['form'] = form + return render(request, self.template_name, context) -@login_required -def trombonoscope(request): - trombonoscope_actuel = ErnestoUser.objects.filter(trombonoscope = "o_a") - trombonoscope_vieux = ErnestoUser.objects.filter(trombonoscope = "o_v") - return render(request, 'trombonoscope/trombonoscope.html', {'trombonoscope_actuel':trombonoscope_actuel,'trombonoscope_vieux':trombonoscope_vieux}) + +class Trombonoscope(LoginRequiredMixin, TemplateView): + template_name = "trombonoscope/trombonoscope.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['trombonoscope_vieux'] = ErnestoUser.objects.filter( + trombonoscope="o_v") + context['trombonoscope_actuel'] = ErnestoUser.objects.filter( + trombonoscope="o_a") + return context