1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-07-08 00:00:49 +02:00

Compare commits

..

12 Commits

24 changed files with 198 additions and 453 deletions

View File

@ -7,8 +7,23 @@ stages:
variables:
GIT_SUBMODULE_STRATEGY: recursive
# Debian Bullseye
py39-django42:
stage: test
image: debian:bullseye
before_script:
- >
apt-get update &&
apt-get install --no-install-recommends -y
python3-django python3-django-crispy-forms
python3-django-extensions python3-django-filters python3-django-polymorphic
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
python3-bs4 python3-setuptools tox texlive-xetex
script: tox -e py39-django42
# Ubuntu 22.04
py310-django50:
py310-django42:
stage: test
image: ubuntu:22.04
before_script:
@ -22,10 +37,10 @@ py310-django50:
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
python3-bs4 python3-setuptools tox texlive-xetex
script: tox -e py310-django50
script: tox -e py310-django42
# Debian Bookworm
py311-django50:
py311-django42:
stage: test
image: debian:bookworm
before_script:
@ -37,11 +52,13 @@ py311-django50:
python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
python3-bs4 python3-setuptools tox texlive-xetex
script: tox -e py311-django50
script: tox -e py311-django42
linters:
stage: quality-assurance
image: debian:bullseye
image: debian:bookworm
before_script:
- apt-get update && apt-get install -y tox
script: tox -e linters

View File

@ -1,11 +1,10 @@
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from bootstrap_datepicker_plus.widgets import DateTimePickerInput
from datetime import timedelta
from random import shuffle
from bootstrap_datepicker_plus.widgets import DateTimePickerInput
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone

View File

@ -17,9 +17,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
</form>
</div>
</div>
{% endblock %}
{% block extrajavascript %}
<script>
var date_end = document.getElementById("id_date_end");
var date_start = document.getElementById("id_date_start");

View File

@ -2,7 +2,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.urls import include, re_path
from django.conf.urls import include
from django.urls import re_path
from rest_framework import routers
from .views import UserInformationView

View File

@ -4,7 +4,6 @@
import io
from bootstrap_datepicker_plus.widgets import DatePickerInput
from PIL import Image, ImageSequence
from django import forms
from django.conf import settings
from django.contrib.auth.forms import AuthenticationForm
@ -16,6 +15,7 @@ from django.utils.translation import gettext_lazy as _
from note.models import NoteSpecial, Alias
from note_kfet.inputs import Autocomplete, AmountInput
from permission.models import PermissionMask, Role
from PIL import Image, ImageSequence
from .models import Profile, Club, Membership

View File

@ -44,7 +44,7 @@ class TemplateLoggedInTests(TestCase):
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, 302, 302)
def test_logout(self):
response = self.client.post(reverse("logout"))
response = self.client.get(reverse("logout"))
self.assertEqual(response.status_code, 200)
def test_admin_index(self):

View File

@ -13,7 +13,7 @@ def register_note_urls(router, path):
router.register(path + '/note', NotePolymorphicViewSet)
router.register(path + '/alias', AliasViewSet)
router.register(path + '/trust', TrustViewSet)
router.register(path + '/consumer', ConsumerViewSet, basename="consumer")
router.register(path + '/consumer', ConsumerViewSet)
router.register(path + '/transaction/category', TemplateCategoryViewSet)
router.register(path + '/transaction/transaction', TransactionViewSet)

View File

@ -179,10 +179,19 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
# We match first an alias if it is matched without normalization,
# then if the normalized pattern matches a normalized alias.
queryset = queryset.filter(
Q(**{f'name{suffix}': alias_prefix + alias})
| Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
| Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()})
)
**{f'name{suffix}': alias_prefix + alias}
).union(
queryset.filter(
Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
& ~Q(**{f'name{suffix}': alias_prefix + alias})
),
all=True).union(
queryset.filter(
Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()})
& ~Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)})
& ~Q(**{f'name{suffix}': alias_prefix + alias})
),
all=True)
queryset = queryset if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' \
else queryset.order_by("name")

View File

@ -1,6 +1,5 @@
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from datetime import datetime
from bootstrap_datepicker_plus.widgets import DateTimePickerInput

View File

@ -18,7 +18,6 @@ def create_special_notes(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
('note', '0001_initial'),
('logs', '0001_initial'),
]
operations = [

View File

@ -1,25 +0,0 @@
# Generated by Django 5.0.7 on 2024-07-11 09:24
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('note', '0006_trust'),
]
operations = [
migrations.AlterField(
model_name='note',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
),
migrations.AlterField(
model_name='transaction',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
),
]

View File

@ -9,7 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
name="{{ widget.name }}"
{# Other attributes are loaded #}
{% for name, value in widget.attrs.items %}
{% if value != False %}{{ name }}{% if value != True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}
{% if value is not False %}{{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}
{% endfor %}>
<div class="input-group-append">
<span class="input-group-text"></span>

View File

@ -44,6 +44,8 @@ class PermissionOAuth2Validator(OAuth2Validator):
subset of permissions.
"""
oidc_claim_scope = None # fix breaking change of django-oauth-toolkit 2.0.0
valid_scopes = set()
for t in Permission.PERMISSION_TYPES:

View File

@ -1,19 +0,0 @@
# Generated by Django 5.0.7 on 2024-07-11 09:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('note', '0007_alter_note_polymorphic_ctype_and_more'),
('treasury', '0008_auto_20240322_0045'),
]
operations = [
migrations.AlterField(
model_name='sogecredit',
name='transactions',
field=models.ManyToManyField(blank=True, related_name='+', to='note.membershiptransaction', verbose_name='membership transactions'),
),
]

View File

@ -82,7 +82,7 @@ msgstr "peut inviter"
#: apps/activity/models.py:44
#: apps/activity/templates/activity/includes/activity_info.html:46
msgid "guest entry fee"
msgstr "cotisation de l'entrée invitée"
msgstr "cotisation de l'entrée invité"
#: apps/activity/models.py:49
msgid "activity type"
@ -119,12 +119,12 @@ msgstr "type"
#: apps/wei/models.py:171 apps/wei/templates/wei/attribute_bus_1A.html:13
#: apps/wei/templates/wei/survey.html:15
msgid "user"
msgstr "utilisateur·ice"
msgstr "utilisateur"
#: apps/activity/models.py:96
#: apps/activity/templates/activity/includes/activity_info.html:36
msgid "organizer"
msgstr "organisateur·ice"
msgstr "organisateur"
#: apps/activity/models.py:97
msgid "Club that organizes the activity. The entry fees will go to this club."
@ -188,7 +188,7 @@ msgstr "entrées"
#: apps/activity/models.py:193
#, python-brace-format
msgid "Entry for {guest}, invited by {note} to the activity {activity}"
msgstr "Entrée pour {guest}, invité·e par {note} à l'activité {activity}"
msgstr "Entrée pour {guest}, invité par {note} à l'activité {activity}"
#: apps/activity/models.py:195
#, python-brace-format
@ -197,7 +197,7 @@ msgstr "Entrée de la note {note} pour l'activité « {activity} »"
#: apps/activity/models.py:202
msgid "Already entered on "
msgstr "Déjà rentré·e le "
msgstr "Déjà rentré le "
#: apps/activity/models.py:202 apps/activity/tables.py:56
msgid "{:%Y-%m-%d %H:%M:%S}"
@ -228,11 +228,11 @@ msgstr "hôte"
#: apps/activity/models.py:256
msgid "guest"
msgstr "invité·e"
msgstr "invité"
#: apps/activity/models.py:257
msgid "guests"
msgstr "invité·e·s"
msgstr "invités"
#: apps/activity/models.py:310
msgid "Invitation"
@ -252,7 +252,7 @@ msgstr "Supprimer"
#: apps/activity/tables.py:56
msgid "Entered on "
msgstr "Entré·e le "
msgstr "Entré le "
#: apps/activity/tables.py:58
msgid "remove"
@ -285,11 +285,11 @@ msgstr "Solde du compte"
#: apps/activity/templates/activity/activity_detail.html:15
msgid "Guests list"
msgstr "Liste des invité·e·s"
msgstr "Liste des invités"
#: apps/activity/templates/activity/activity_detail.html:33
msgid "Guest deleted"
msgstr "Invité·e supprimé·e"
msgstr "Invité supprimé"
#: apps/activity/templates/activity/activity_entry.html:14
#: apps/note/models/transactions.py:261
@ -324,7 +324,7 @@ msgstr "Retour à la page de l'activité"
#: apps/activity/templates/activity/activity_entry.html:129
msgid "Entry done, but caution: the user is not a Kfet member."
msgstr ""
"Entrée effectuée, mais attention : la personne n'est pas un·e adhérent·e Kfet."
"Entrée effectuée, mais attention : la personne n'est pas un adhérent Kfet."
#: apps/activity/templates/activity/activity_entry.html:132
msgid "Entry done!"
@ -365,7 +365,7 @@ msgstr "Toutes les activités"
#: apps/activity/templates/activity/includes/activity_info.html:32
msgid "creater"
msgstr "créateur·ice"
msgstr "créateur"
#: apps/activity/templates/activity/includes/activity_info.html:53
msgid "opened"
@ -419,7 +419,7 @@ msgstr "Invitation pour l'activité « {} »"
#: apps/activity/views.py:178
msgid "You are not allowed to display the entry interface for this activity."
msgstr ""
"Vous n'êtes pas autorisé·e à afficher l'interface des entrées pour cette "
"Vous n'êtes pas autorisé à afficher l'interface des entrées pour cette "
"activité."
#: apps/activity/views.py:181
@ -500,12 +500,12 @@ msgstr "Les logs ne peuvent pas être détruits."
#: apps/member/admin.py:50 apps/member/models.py:232
#: apps/member/templates/member/includes/club_info.html:34
msgid "membership fee (paid students)"
msgstr "cotisation pour adhérer (normalien·ne élève)"
msgstr "cotisation pour adhérer (normalien élève)"
#: apps/member/admin.py:51 apps/member/models.py:237
#: apps/member/templates/member/includes/club_info.html:37
msgid "membership fee (unpaid students)"
msgstr "cotisation pour adhérer (normalien·ne étudiant·e)"
msgstr "cotisation pour adhérer (normalien étudiant)"
#: apps/member/admin.py:65 apps/member/models.py:325
msgid "roles"
@ -517,7 +517,7 @@ msgstr "cotisation"
#: apps/member/apps.py:14 apps/wei/tables.py:226 apps/wei/tables.py:257
msgid "member"
msgstr "adhérent·e"
msgstr "adhérent"
#: apps/member/forms.py:24
msgid "Permission mask"
@ -542,7 +542,7 @@ msgid ""
"href=https://perso.crans.org/club-bde/Charte-anti-VSS.pdf target=_blank> "
"available here in pdf</a>"
msgstr ""
"Cochez après avoir lu la charte anti-VSS <a href=https://perso."
"Cochez après avoir lu la chartre anti-VSS <a href=https://perso."
"crans.org/club-bde/Charte-anti-VSS.pdf target=_blank> disponible en pdf ici</"
"a>"
@ -587,7 +587,7 @@ msgstr "Pas de rechargement"
#: apps/member/forms.py:182
msgid "You can credit the note of the user."
msgstr "Vous pouvez créditer la note de l'utilisateur·ice avant l'adhésion."
msgstr "Vous pouvez créditer la note de l'utilisateur avant l'adhésion."
#: apps/member/forms.py:186 apps/registration/forms.py:85
#: apps/wei/forms/registration.py:97
@ -602,7 +602,7 @@ msgstr "Banque"
#: apps/member/forms.py:230
msgid "User"
msgstr "Utilisateur·ice"
msgstr "Utilisateur"
#: apps/member/forms.py:244
msgid "Roles"
@ -731,11 +731,11 @@ msgstr "adresse"
#: apps/registration/templates/registration/future_profile_detail.html:43
#: apps/wei/templates/wei/weimembership_form.html:47
msgid "paid"
msgstr "payé·e"
msgstr "payé"
#: apps/member/models.py:90
msgid "Tells if the user receive a salary."
msgstr "Indique si l'utilisateur·ice perçoit un salaire."
msgstr "Indique si l'utilisateur perçoit un salaire."
#: apps/member/models.py:99 apps/treasury/tables.py:143
msgid "No"
@ -754,7 +754,7 @@ msgid ""
"Register on the mailing list to stay informed of the events of the campus (1 "
"mail/week)"
msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé·e des événements sur "
"S'inscrire sur la liste de diffusion pour rester informé des événements sur "
"le campus (1 mail par semaine)"
#: apps/member/models.py:108
@ -762,7 +762,7 @@ msgid ""
"Register on the mailing list to stay informed of the sport events of the "
"campus (1 mail/week)"
msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé·e des actualités "
"S'inscrire sur la liste de diffusion pour rester informé des actualités "
"sportives sur le campus (1 mail par semaine)"
#: apps/member/models.py:113
@ -770,7 +770,7 @@ msgid ""
"Register on the mailing list to stay informed of the art events of the "
"campus (1 mail/week)"
msgstr ""
"S'inscrire sur la liste de diffusion pour rester informé·e des actualités "
"S'inscrire sur la liste de diffusion pour rester informé des actualités "
"artistiques sur le campus (1 mail par semaine)"
#: apps/member/models.py:117
@ -795,7 +795,7 @@ msgstr "Charte VSS lue"
#: apps/member/models.py:142 apps/member/models.py:143
msgid "user profile"
msgstr "profil utilisateur·ice"
msgstr "profil utilisateur"
#: apps/member/models.py:177
msgid "Activate your Note Kfet account"
@ -839,7 +839,7 @@ msgstr "début de l'adhésion"
#: apps/member/models.py:252
msgid "Date from which the members can renew their membership."
msgstr ""
"Date à partir de laquelle les adhérent·e·s peuvent renouveler leur adhésion."
"Date à partir de laquelle les adhérents peuvent renouveler leur adhésion."
#: apps/member/models.py:258
#: apps/member/templates/member/includes/club_info.html:21
@ -849,7 +849,7 @@ msgstr "fin de l'adhésion"
#: apps/member/models.py:259
msgid "Maximal date of a membership, after which members must renew it."
msgstr ""
"Date maximale d'une fin d'adhésion, après laquelle les adhérent·e·s doivent la "
"Date maximale d'une fin d'adhésion, après laquelle les adhérents doivent la "
"renouveler."
#: apps/member/models.py:263 apps/member/models.py:319
@ -889,11 +889,11 @@ msgstr "Le rôle {role} ne s'applique pas au club {club}."
#: apps/member/models.py:376 apps/member/views.py:712
msgid "User is already a member of the club"
msgstr "L'utilisateur·ice est déjà membre du club"
msgstr "L'utilisateur est déjà membre du club"
#: apps/member/models.py:388 apps/member/views.py:721
msgid "User is not a member of the parent club"
msgstr "L'utilisateur·ice n'est pas membre du club parent"
msgstr "L'utilisateur n'est pas membre du club parent"
#: apps/member/tables.py:139
msgid "Renew"
@ -906,7 +906,7 @@ msgid ""
"%(pretty_fee)s will be charged to renew automatically the membership in this/"
"these club·s."
msgstr ""
"Cet·te utilisateur·ice n'est pas membre du/des club·s parent·s %(clubs)s. Un "
"Cet utilisateur n'est pas membre du/des club·s parent·s %(clubs)s. Un "
"montant supplémentaire de %(pretty_fee)s sera débité afin de renouveler "
"automatiquement l'adhésion dans ce·s club·s."
@ -916,7 +916,7 @@ msgid ""
"The user is not a member of the club·s %(clubs)s. Please create the required "
"memberships, otherwise it will fail."
msgstr ""
"Cet·te utilisateur·ice n'est pas membre du/des club·s parent·s %(clubs)s. Merci de "
"Cet utilisateur n'est pas membre du/des club·s parent·s %(clubs)s. Merci de "
"d'abord créer l'adhésion requise, sinon cette adhésion va échouer."
#: apps/member/templates/member/add_members.html:29
@ -934,7 +934,7 @@ msgid ""
"This club has parents %(clubs)s. Please make sure that the user is a member "
"of this or these club·s, otherwise the creation of this membership will fail."
msgstr ""
"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur·ice "
"Ce club a pour parents %(clubs)s. Merci de vous assurer que l'utilisateur "
"est membre de ce·s club·s, sinon la création de cette adhésion va échouer."
#: apps/member/templates/member/base.html:17
@ -956,7 +956,7 @@ msgstr "Voir le profil"
#: apps/member/templates/member/base.html:57
msgid "Add member"
msgstr "Ajouter un·e membre"
msgstr "Ajouter un membre"
#: apps/member/templates/member/base.html:72
#: apps/member/templates/member/base.html:93
@ -983,8 +983,8 @@ msgid ""
"If you use the force mode, the user won't be able to unlock the note by "
"itself."
msgstr ""
"Si vous verrouillez la note de force, l'utilisateur·ice ne pourra plus la "
"déverrouiller soi-même."
"Si vous verrouillez la note de force, l'utilisateur ne pourra plus la "
"déverrouiller lui-même."
#: apps/member/templates/member/base.html:110
#: apps/member/templates/member/base.html:137 apps/treasury/forms.py:91
@ -1165,7 +1165,7 @@ msgstr "Recadrer et envoyer"
#: apps/registration/templates/registration/future_profile_detail.html:28
#: apps/wei/templates/wei/weimembership_form.html:26
msgid "This user doesn't have confirmed his/her e-mail address."
msgstr "Cet·te utilisateur·ice n'a pas encore confirmé son adresse e-mail."
msgstr "Cet utilisateur n'a pas encore confirmé son adresse e-mail."
#: apps/member/templates/member/profile_detail.html:13
#: apps/registration/templates/registration/future_profile_detail.html:29
@ -1179,7 +1179,7 @@ msgstr "Voir mes adhésions"
#: apps/member/templates/member/profile_trust.html:10
msgid "Add friends"
msgstr "Ajouter des ami·e·s"
msgstr "Ajouter des amis"
#: apps/member/templates/member/profile_trust.html:28
msgid ""
@ -1191,12 +1191,12 @@ msgid ""
msgstr ""
"Ajouter quelqu'un⋅e en ami⋅e lui permet de me prélever de l'argent (tant que "
"ma note reste positive). Ceci sert à simplifier les remboursements entre "
"ami⋅e·s via note. En effet, une personne peut effectuer tous les transferts "
"ami⋅es via note. En effet, une personne peut effectuer tous les transferts "
"sans posséder de droits supplémentaires."
#: apps/member/templates/member/profile_trust.html:39
msgid "People having you as a friend"
msgstr "Personnes vous ayant ajouté·e"
msgstr "Personnes vous ayant ajouté"
#: apps/member/templates/member/profile_update.html:18
msgid "Save Changes"
@ -1212,11 +1212,11 @@ msgstr "Cette adresse doit être valide."
#: apps/member/views.py:139
msgid "Profile detail"
msgstr "Détails de l'utilisateur·ice"
msgstr "Détails de l'utilisateur"
#: apps/member/views.py:205
msgid "Search user"
msgstr "Chercher un·e utilisateur·ice"
msgstr "Chercher un utilisateur"
#: apps/member/views.py:253
msgid "Note friendships"
@ -1248,14 +1248,14 @@ msgstr "Modifier le club"
#: apps/member/views.py:574
msgid "Add new member to the club"
msgstr "Ajouter un·e nouvelle·au membre au club"
msgstr "Ajouter un nouveau membre au club"
#: apps/member/views.py:703 apps/wei/views.py:973
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
msgstr ""
"Cet·te utilisateur·ice n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
"avoir un solde négatif."
#: apps/member/views.py:725
@ -1268,7 +1268,7 @@ msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
#: apps/member/views.py:880
msgid "Manage roles of an user in the club"
msgstr "Gérer les rôles d'un·e utilisateur·ice dans le club"
msgstr "Gérer les rôles d'un utilisateur dans le club"
#: apps/member/views.py:905
msgid "Members of the club"
@ -1343,7 +1343,7 @@ msgstr "en centimes, argent crédité pour cette instance"
#: apps/note/models/notes.py:37
msgid "last negative date"
msgstr "dernière date de négatif"
msgstr "dernier date de négatif"
#: apps/note/models/notes.py:38
msgid "last time the balance was negative"
@ -1359,7 +1359,7 @@ msgstr "créée le"
#: apps/note/models/notes.py:58
msgid "active"
msgstr "actif·ve"
msgstr "actif"
#: apps/note/models/notes.py:61
msgid ""
@ -1379,8 +1379,8 @@ msgstr ""
#: apps/note/models/notes.py:70
msgid "The note is blocked by the the BDE and can't be manually reactivated."
msgstr ""
"La note est bloquée de force par le BDE et ne peut pas être débloquée par le·a "
"possesseur·ice de la note."
"La note est bloquée de force par le BDE et ne peut pas être débloquée par le "
"possesseur de la note."
#: apps/note/models/notes.py:78
msgid "notes"
@ -1392,11 +1392,11 @@ msgstr "Cet alias est déjà pris."
#: apps/note/models/notes.py:152
msgid "one's note"
msgstr "note d'un·e utilisateur·ice"
msgstr "note d'un utilisateur"
#: apps/note/models/notes.py:153
msgid "users note"
msgstr "notes des utilisateur·ice·s"
msgstr "notes des utilisateurs"
#: apps/note/models/notes.py:159
#, python-format
@ -1430,7 +1430,7 @@ msgstr "note"
#: apps/note/models/notes.py:239
msgid "trusted"
msgstr "ami·e"
msgstr "ami"
#: apps/note/models/notes.py:243
msgid "frienship"
@ -1553,7 +1553,7 @@ msgid ""
"The destination of this transaction must equal to the destination of the "
"template."
msgstr ""
"Le·a destinataire de cette transaction doit être identique à celui du bouton "
"Le destinataire de cette transaction doit être identique à celui du bouton "
"utilisé."
#: apps/note/models/transactions.py:290
@ -1582,7 +1582,7 @@ msgid ""
"payment method and a User or a Club"
msgstr ""
"Une transaction spéciale n'est possible que entre une note associée à un "
"mode de paiement et un·e utilisateur·ice ou un club"
"mode de paiement et un utilisateur ou un club"
#: apps/note/models/transactions.py:357 apps/note/models/transactions.py:360
#: apps/note/models/transactions.py:363 apps/wei/views.py:978
@ -1624,7 +1624,7 @@ msgstr "Supprimer"
#: apps/note/tables.py:191
msgid "Trust back"
msgstr "Ajouter en ami·e"
msgstr "Ajouter en ami"
#: apps/note/tables.py:211
msgid "Add back"
@ -1706,11 +1706,11 @@ msgstr "Mail généré par la Note Kfet le"
#: apps/note/templates/note/transaction_form.html:58
#: apps/note/templates/note/transaction_form.html:178
msgid "Select emitters"
msgstr "Sélection des émetteur·ice·s"
msgstr "Sélection des émetteurs"
#: apps/note/templates/note/transaction_form.html:73
msgid "I am the emitter"
msgstr "Je suis l'émetteur·ice"
msgstr "Je suis l'émetteur"
#: apps/note/templates/note/transaction_form.html:85
#: apps/note/templates/note/transaction_form.html:180
@ -1735,7 +1735,7 @@ msgstr "Nom"
#: apps/note/templates/note/transaction_form.html:177
msgid "Select emitter"
msgstr "Sélection de l'émetteur·ice"
msgstr "Sélection de l'émetteur"
#: apps/note/templates/note/transaction_form.html:179
msgid "Select receiver"
@ -1873,7 +1873,7 @@ msgid ""
"is expired."
msgstr ""
"Indique si la permission doit être attribuée même si l'adhésion de "
"l'utilisateur·ice est expirée."
"l'utilisateur est expirée."
#: apps/permission/models.py:182
#: apps/permission/templates/permission/all_rights.html:89
@ -1931,16 +1931,16 @@ msgstr ""
#: apps/permission/templates/permission/all_rights.html:12
msgid "Users that have surnormal rights"
msgstr "Liste des utilisateur·ice·s ayant des droits surnormaux"
msgstr "Liste des utilisateurs ayant des droits surnormaux"
#: apps/permission/templates/permission/all_rights.html:16
msgid "Superusers have all rights on everything, to manage the website."
msgstr ""
"Les super-utilisateur·ice·s ont tous les droits sur tout, afin de gérer le site."
"Les super-utilisateurs ont tous les droits sur tout, afin de gérer le site."
#: apps/permission/templates/permission/all_rights.html:21
msgid "Superusers"
msgstr "Super-utilisateur·ice·s"
msgstr "Super-utilisateurs"
#: apps/permission/templates/permission/all_rights.html:45
msgid "Roles description"
@ -2095,7 +2095,7 @@ msgstr "Valider le compte"
#: apps/registration/templates/registration/future_profile_detail.html:63
msgid ""
"The user declared that he/she opened a bank account in the Société générale."
msgstr "L'utilisateur·ice a déclaré avoir ouvert un compte à la société générale."
msgstr "L'utilisateur a déclaré avoir ouvert un compte à la société générale."
#: apps/registration/templates/registration/future_profile_detail.html:73
#: apps/wei/templates/wei/weimembership_form.html:127
@ -2105,7 +2105,7 @@ msgstr "Valider l'inscription"
#: apps/registration/templates/registration/future_user_list.html:9
msgid "New user"
msgstr "Nouvel·le utilisateur·ice"
msgstr "Nouvel utilisateur"
#: apps/registration/templates/registration/mails/email_validation_email.html:12
#: apps/registration/templates/registration/mails/email_validation_email.txt:3
@ -2149,7 +2149,7 @@ msgstr "L'équipe de la Note Kfet."
#: apps/registration/views.py:41
msgid "Register new user"
msgstr "Enregistrer un·e nouvel·le utilisateur·ice"
msgstr "Enregistrer un nouvel utilisateur"
#: apps/registration/views.py:99
msgid "Email validation"
@ -2173,11 +2173,11 @@ msgstr "Renvoyer le lien de validation"
#: apps/registration/views.py:182
msgid "Pre-registered users list"
msgstr "Liste des utilisateur·ice·s en attente d'inscription"
msgstr "Liste des utilisateurs en attente d'inscription"
#: apps/registration/views.py:206
msgid "Unregistered users"
msgstr "Utilisateur·ice·s en attente d'inscription"
msgstr "Utilisateurs en attente d'inscription"
#: apps/registration/views.py:219
msgid "Registration detail"
@ -2360,14 +2360,14 @@ msgstr "Crédits de la Société générale"
#: apps/treasury/models.py:315
#, python-brace-format
msgid "Soge credit for {user}"
msgstr "Crédit de la société générale pour l'utilisateur·ice {user}"
msgstr "Crédit de la société générale pour l'utilisateur {user}"
#: apps/treasury/models.py:445
msgid ""
"This user doesn't have enough money to pay the memberships with its note. "
"Please ask her/him to credit the note before invalidating this credit."
msgstr ""
"Cet·te utilisateur·ice n'a pas assez d'argent pour payer les adhésions avec sa "
"Cet utilisateur n'a pas assez d'argent pour payer les adhésions avec sa "
"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
#: apps/treasury/tables.py:20
@ -2519,12 +2519,12 @@ msgid ""
"If this credit is validated, then the user won't be able to ask for a credit "
"from the Société générale."
msgstr ""
"Si ce crédit est validé, alors l'utilisateur·ice ne pourra plus demander d'être "
"crédité·e par la Société générale à l'avenir."
"Si ce crédit est validé, alors l'utilisateur ne pourra plus demander d'être "
"crédité par la Société générale à l'avenir."
#: apps/treasury/templates/treasury/sogecredit_detail.html:44
msgid "If you think there is an error, please contact the \"respos info\"."
msgstr "Si vous pensez qu'il y a une erreur, merci de contacter un·e respo info."
msgstr "Si vous pensez qu'il y a une erreur, merci de contacter un respo info."
#: apps/treasury/templates/treasury/sogecredit_detail.html:50
msgid "This credit is already validated."
@ -2535,13 +2535,13 @@ msgid ""
"Warning: if you don't validate this credit, the note of the user doesn't "
"have enough money to pay its memberships."
msgstr ""
"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur·ice n'a "
"Attention : si vous ne validez pas ce crédit, la note de l'utilisateur n'a "
"pas assez d'argent pour payer les adhésions."
#: apps/treasury/templates/treasury/sogecredit_detail.html:56
msgid "Please ask the user to credit its note before deleting this credit."
msgstr ""
"Merci de demander à l'utilisateur·ice de recharger sa note avant de supprimer la "
"Merci de demander à l'utilisateur de recharger sa note avant de supprimer la "
"demande de crédit."
#: apps/treasury/templates/treasury/sogecredit_detail.html:63
@ -2560,7 +2560,7 @@ msgstr "Filtrer avec uniquement les crédits non valides"
#: apps/treasury/templates/treasury/sogecredit_list.html:50
msgid "There is no matched user that have asked for a Société générale credit."
msgstr ""
"Il n'y a pas d'utilisateur·ice trouvé·e ayant demandé un crédit de la Société "
"Il n'y a pas d'utilisateur trouvé ayant demandé un crédit de la Société "
"générale."
#: apps/treasury/templates/treasury/sogecredit_list.html:63
@ -2582,7 +2582,7 @@ msgstr "Liste des factures"
#: apps/treasury/views.py:105 apps/treasury/views.py:275
#: apps/treasury/views.py:401
msgid "You are not able to see the treasury interface."
msgstr "Vous n'êtes pas autorisé·e à voir l'interface de trésorerie."
msgstr "Vous n'êtes pas autorisé à voir l'interface de trésorerie."
#: apps/treasury/views.py:115
msgid "Update an invoice"
@ -2621,7 +2621,7 @@ msgstr "WEI"
#: apps/wei/forms/registration.py:35
msgid "The selected user is not validated. Please validate its account first"
msgstr ""
"L'utilisateur·ice sélectionné·e n'est pas validé·e. Merci de d'abord valider son "
"L'utilisateur sélectionné n'est pas validé. Merci de d'abord valider son "
"compte"
#: apps/wei/forms/registration.py:59 apps/wei/models.py:126
@ -2634,8 +2634,8 @@ msgid ""
"This choice is not definitive. The WEI organizers are free to attribute for "
"you a bus and a team, in particular if you are a free eletron."
msgstr ""
"Ce choix n'est pas définitif. Les organisateur·ice·s du WEI sont libres de vous "
"attribuer un bus et une équipe, en particulier si vous êtes un·e électron "
"Ce choix n'est pas définitif. Les organisateurs du WEI sont libres de vous "
"attribuer un bus et une équipe, en particulier si vous êtes un électron "
"libre."
#: apps/wei/forms/registration.py:67
@ -2787,7 +2787,7 @@ msgstr "première année"
#: apps/wei/models.py:249
msgid "Tells if the user is new in the school."
msgstr "Indique si l'utilisateur·ice est nouveau dans l'école."
msgstr "Indique si l'utilisateur est nouveau dans l'école."
#: apps/wei/models.py:254
msgid "registration information"
@ -2803,11 +2803,11 @@ msgstr ""
#: apps/wei/models.py:261
msgid "WEI User"
msgstr "Participant·e au WEI"
msgstr "Participant au WEI"
#: apps/wei/models.py:262
msgid "WEI Users"
msgstr "Participant·e·s au WEI"
msgstr "Participants au WEI"
#: apps/wei/models.py:334
msgid "team"
@ -2827,19 +2827,19 @@ msgstr "Adhésions au WEI"
#: apps/wei/tables.py:105
msgid "The user does not have enough money."
msgstr "L'utilisateur·ice n'a pas assez d'argent."
msgstr "L'utilisateur n'a pas assez d'argent."
#: apps/wei/tables.py:108
msgid ""
"The user is in first year. You may validate the credit, the algorithm will "
"run later."
msgstr ""
"L'utilisateur·ice est en première année, vous pouvez valider le crédit, "
"L'utilisateur est en première année, vous pouvez valider le crédit, "
"l'algorithme tournera plus tard."
#: apps/wei/tables.py:111
msgid "The user has enough money, you can validate the registration."
msgstr "L'utilisateur·ice a assez d'argent, l'inscription est possible."
msgstr "L'utilisateur a assez d'argent, l'inscription est possible."
#: apps/wei/tables.py:143
msgid "Year"
@ -2860,19 +2860,19 @@ msgstr "Nombre de membres"
#: apps/wei/tables.py:226 apps/wei/tables.py:257
msgid "members"
msgstr "adhérent·e·s"
msgstr "adhérents"
#: apps/wei/tables.py:287
msgid "suggested first year"
msgstr "1A suggéré·e·s"
msgstr "1A suggérés"
#: apps/wei/tables.py:293
msgid "validated first year"
msgstr "1A validé·e·s"
msgstr "1A validés"
#: apps/wei/tables.py:299
msgid "validated staff"
msgstr "2A+ validé·e·s"
msgstr "2A+ validés"
#: apps/wei/tables.py:310
msgid "free seats"
@ -3052,7 +3052,7 @@ msgstr "L'inscription a déjà été validée et ne peut pas être dévalidée."
#: apps/wei/templates/wei/weimembership_form.html:132
msgid "The user joined the bus"
msgstr "L'utilisateur·ice a rejoint le bus"
msgstr "L'utilisateur a rejoint le bus"
#: apps/wei/templates/wei/weimembership_form.html:133
msgid "in the team"
@ -3097,7 +3097,7 @@ msgstr ""
#: apps/wei/templates/wei/weimembership_form.html:166
msgid "The user didn't give her/his caution check."
msgstr "L'utilisateur·ice n'a pas donné son chèque de caution."
msgstr "L'utilisateur n'a pas donné son chèque de caution."
#: apps/wei/templates/wei/weimembership_form.html:174
msgid ""
@ -3105,7 +3105,7 @@ msgid ""
"membership will be processed automatically, the WEI registration includes "
"the membership fee."
msgstr ""
"Cet·te utilisateur·ice n'est pas membre du club Kfet pour l'année à venir. "
"Cet utilisateur n'est pas membre du club Kfet pour l'année à venir. "
"L'adhésion va être faite automatiquement, l'inscription au WEI inclut le "
"coût d'adhésion."
@ -3199,7 +3199,7 @@ msgid ""
"This user can't be in her/his first year since he/she has already "
"participated to a WEI."
msgstr ""
"Cet·te utilisateur·ice ne peut pas être en première année puisqu'iel a déjà "
"Cet utilisateur ne peut pas être en première année puisqu'il a déjà "
"participé à un WEI."
#: apps/wei/views.py:578
@ -3313,7 +3313,7 @@ msgstr "La note du BDE de l'ENS Paris-Saclay."
#: note_kfet/templates/base.html:78
msgid "Users"
msgstr "Utilisateur·ice·s"
msgstr "Utilisateurs"
#: note_kfet/templates/base.html:84
msgid "Clubs"
@ -3351,7 +3351,7 @@ msgid ""
"You are not a BDE member anymore. Please renew your membership if you want "
"to use the note."
msgstr ""
"Vous n'êtes plus adhérent·e BDE. Merci de réadhérer si vous voulez profiter de "
"Vous n'êtes plus adhérent BDE. Merci de réadhérer si vous voulez profiter de "
"la note."
#: note_kfet/templates/base.html:165
@ -3370,7 +3370,7 @@ msgid ""
"last a few days. Please make sure that you go to the end of the account "
"creation."
msgstr ""
"Vous avez déclaré·e que vous avez ouvert un compte bancaire à la société "
"Vous avez déclaré que vous avez ouvert un compte bancaire à la société "
"générale. La banque n'a pas encore validé la création du compte auprès du "
"BDE, l'adhésion et le WEI ne sont donc pas encore payés. Cette procédure de "
"vérification peut durer quelques jours. Merci de vous assurer de bien aller "
@ -3388,10 +3388,6 @@ msgstr "Support technique"
msgid "FAQ (FR)"
msgstr "FAQ (FR)"
#: note_kfet/templates/base.html:200
msgid "Charte Info (FR)"
msgstr "Charte Info (FR)"
#: note_kfet/templates/base_search.html:15
msgid "Search by attribute such as name…"
msgstr "Chercher par un attribut tel que le nom …"
@ -3593,7 +3589,7 @@ msgid ""
"you registered with, and check your spam folder."
msgstr ""
"Si vous ne recevez pas d'email, vérifiez que vous avez bien utilisé "
"l'adresse associée à votre compte, et regarder également le dossier spam."
"l'adresse associé à votre compte, et regarder également le dossier spam."
#: note_kfet/templates/registration/password_reset_form.html:13
msgid ""
@ -3614,7 +3610,7 @@ msgid ""
"Kfet and pay the registration fee. You must also validate your email address "
"by following the link you received."
msgstr ""
"Si vous vous êtes déjà inscrit·e·s, votre inscription a bien été prise en "
"Si vous vous êtes déjà inscrits, votre inscription a bien été prise en "
"compte. Le BDE doit d'abord valider votre compte avant que vous puissiez "
"vous connecter. Vous devez vous rendre à la Kfet et payer les frais "
"d'adhésion. Vous devez également valider votre adresse email en suivant le "
@ -3626,7 +3622,7 @@ msgstr ""
#, fuzzy
#~| msgid "People having you as a friend"
#~ msgid "You already have that person as a friend"
#~ msgstr "Personnes vous ayant ajouté·e"
#~ msgstr "Personnes vous ayant ajouté"
#~ msgid ""
#~ "I declare that I opened or I will open soon a bank account in the Société "

View File

@ -32,6 +32,12 @@ if "oauth2_provider" in settings.INSTALLED_APPS:
admin_site.register(AccessToken, AccessTokenAdmin)
admin_site.register(RefreshToken, RefreshTokenAdmin)
if "django_htcpcp_tea" in settings.INSTALLED_APPS:
from django_htcpcp_tea.admin import *
from django_htcpcp_tea.models import *
admin_site.register(Pot, PotAdmin)
admin_site.register(TeaType, TeaTypeAdmin)
admin_site.register(Addition, AdditionAdmin)
if "mailer" in settings.INSTALLED_APPS:
from mailer.admin import *
@ -44,3 +50,9 @@ if "rest_framework" in settings.INSTALLED_APPS:
from rest_framework.authtoken.admin import *
from rest_framework.authtoken.models import *
admin_site.register(Token, TokenAdmin)
if "cas_server" in settings.INSTALLED_APPS:
from cas_server.admin import *
from cas_server.models import *
admin_site.register(ServicePattern, ServicePatternAdmin)
admin_site.register(FederatedIendityProvider, FederatedIendityProviderAdmin)

View File

@ -4,7 +4,7 @@
"pk": 1,
"fields": {
"domain": "note.crans.org",
"name": "La Note Kfet 🍪"
"name": "La Note Kfet \ud83c\udf7b"
}
}
]

View File

@ -68,264 +68,3 @@ class ColorWidget(Widget):
def value_from_datadict(self, data, files, name):
val = super().value_from_datadict(data, files, name)
return int(val[1:], 16)
"""
The remaining of this file comes from the project `django-bootstrap-datepicker-plus` available on Github:
https://github.com/monim67/django-bootstrap-datepicker-plus
This is distributed under Apache License 2.0.
This adds datetime pickers with bootstrap.
"""
"""Contains Base Date-Picker input class for widgets of this package."""
class DatePickerDictionary:
"""Keeps track of all date-picker input classes."""
_i = 0
items = dict()
@classmethod
def generate_id(cls):
"""Return a unique ID for each date-picker input class."""
cls._i += 1
return 'dp_%s' % cls._i
class BasePickerInput(DateTimeBaseInput):
"""Base Date-Picker input class for widgets of this package."""
template_name = 'bootstrap_datepicker_plus/date-picker.html'
picker_type = 'DATE'
format = '%Y-%m-%d'
config = {}
_default_config = {
'id': None,
'picker_type': None,
'linked_to': None,
'options': {} # final merged options
}
options = {} # options extended by user
options_param = {} # options passed as parameter
_default_options = {
'showClose': True,
'showClear': True,
'showTodayButton': True,
"locale": "fr",
}
# source: https://github.com/tutorcruncher/django-bootstrap3-datetimepicker
# file: /blob/31fbb09/bootstrap3_datetime/widgets.py#L33
format_map = (
('DDD', r'%j'),
('DD', r'%d'),
('MMMM', r'%B'),
('MMM', r'%b'),
('MM', r'%m'),
('YYYY', r'%Y'),
('YY', r'%y'),
('HH', r'%H'),
('hh', r'%I'),
('mm', r'%M'),
('ss', r'%S'),
('a', r'%p'),
('ZZ', r'%z'),
)
class Media:
"""JS/CSS resources needed to render the date-picker calendar."""
js = (
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/'
'moment-with-locales.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/'
'4.17.47/js/bootstrap-datetimepicker.min.js',
'bootstrap_datepicker_plus/js/datepicker-widget.js'
)
css = {'all': (
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/'
'4.17.47/css/bootstrap-datetimepicker.css',
'bootstrap_datepicker_plus/css/datepicker-widget.css'
), }
@classmethod
def format_py2js(cls, datetime_format):
"""Convert python datetime format to moment datetime format."""
for js_format, py_format in cls.format_map:
datetime_format = datetime_format.replace(py_format, js_format)
return datetime_format
@classmethod
def format_js2py(cls, datetime_format):
"""Convert moment datetime format to python datetime format."""
for js_format, py_format in cls.format_map:
datetime_format = datetime_format.replace(js_format, py_format)
return datetime_format
def __init__(self, attrs=None, format=None, options=None):
"""Initialize the Date-picker widget."""
self.format_param = format
self.options_param = options if options else {}
self.config = self._default_config.copy()
self.config['id'] = DatePickerDictionary.generate_id()
self.config['picker_type'] = self.picker_type
self.config['options'] = self._calculate_options()
attrs = attrs if attrs else {}
if 'class' not in attrs:
attrs['class'] = 'form-control'
super().__init__(attrs, self._calculate_format())
def _calculate_options(self):
"""Calculate and Return the options."""
_options = self._default_options.copy()
_options.update(self.options)
if self.options_param:
_options.update(self.options_param)
return _options
def _calculate_format(self):
"""Calculate and Return the datetime format."""
_format = self.format_param if self.format_param else self.format
if self.config['options'].get('format'):
_format = self.format_js2py(self.config['options'].get('format'))
else:
self.config['options']['format'] = self.format_py2js(_format)
return _format
def get_context(self, name, value, attrs):
"""Return widget context dictionary."""
context = super().get_context(
name, value, attrs)
context['widget']['attrs']['dp_config'] = json_dumps(self.config)
return context
def start_of(self, event_id):
"""
Set Date-Picker as the start-date of a date-range.
Args:
- event_id (string): User-defined unique id for linking two fields
"""
DatePickerDictionary.items[str(event_id)] = self
return self
def end_of(self, event_id, import_options=True):
"""
Set Date-Picker as the end-date of a date-range.
Args:
- event_id (string): User-defined unique id for linking two fields
- import_options (bool): inherit options from start-date input,
default: TRUE
"""
event_id = str(event_id)
if event_id in DatePickerDictionary.items:
linked_picker = DatePickerDictionary.items[event_id]
self.config['linked_to'] = linked_picker.config['id']
if import_options:
backup_moment_format = self.config['options']['format']
self.config['options'].update(linked_picker.config['options'])
self.config['options'].update(self.options_param)
if self.format_param or 'format' in self.options_param:
self.config['options']['format'] = backup_moment_format
else:
self.format = linked_picker.format
# Setting useCurrent is necessary, see following issue
# https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
self.config['options']['useCurrent'] = False
self._link_to(linked_picker)
else:
raise KeyError(
'start-date not specified for event_id "%s"' % event_id)
return self
def _link_to(self, linked_picker):
"""
Executed when two date-inputs are linked together.
This method for sub-classes to override to customize the linking.
"""
pass
class DatePickerInput(BasePickerInput):
"""
Widget to display a Date-Picker Calendar on a DateField property.
Args:
- attrs (dict): HTML attributes of rendered HTML input
- format (string): Python DateTime format eg. "%Y-%m-%d"
- options (dict): Options to customize the widget, see README
"""
picker_type = 'DATE'
format = '%Y-%m-%d'
format_key = 'DATE_INPUT_FORMATS'
class TimePickerInput(BasePickerInput):
"""
Widget to display a Time-Picker Calendar on a TimeField property.
Args:
- attrs (dict): HTML attributes of rendered HTML input
- format (string): Python DateTime format eg. "%Y-%m-%d"
- options (dict): Options to customize the widget, see README
"""
picker_type = 'TIME'
format = '%H:%M'
format_key = 'TIME_INPUT_FORMATS'
template_name = 'bootstrap_datepicker_plus/time_picker.html'
class DateTimePickerInput(BasePickerInput):
"""
Widget to display a DateTime-Picker Calendar on a DateTimeField property.
Args:
- attrs (dict): HTML attributes of rendered HTML input
- format (string): Python DateTime format eg. "%Y-%m-%d"
- options (dict): Options to customize the widget, see README
"""
picker_type = 'DATETIME'
format = '%Y-%m-%d %H:%M'
format_key = 'DATETIME_INPUT_FORMATS'
class MonthPickerInput(BasePickerInput):
"""
Widget to display a Month-Picker Calendar on a DateField property.
Args:
- attrs (dict): HTML attributes of rendered HTML input
- format (string): Python DateTime format eg. "%Y-%m-%d"
- options (dict): Options to customize the widget, see README
"""
picker_type = 'MONTH'
format = '01/%m/%Y'
format_key = 'DATE_INPUT_FORMATS'
class YearPickerInput(BasePickerInput):
"""
Widget to display a Year-Picker Calendar on a DateField property.
Args:
- attrs (dict): HTML attributes of rendered HTML input
- format (string): Python DateTime format eg. "%Y-%m-%d"
- options (dict): Options to customize the widget, see README
"""
picker_type = 'YEAR'
format = '01/01/%Y'
format_key = 'DATE_INPUT_FORMATS'
def _link_to(self, linked_picker):
"""Customize the options when linked with other date-time input"""
yformat = self.config['options']['format'].replace('-01-01', '-12-31')
self.config['options']['format'] = yformat

View File

@ -40,8 +40,9 @@ INSTALLED_APPS = [
# External apps
'bootstrap_datepicker_plus',
'colorfield',
'crispy_forms',
'crispy_bootstrap4',
'crispy_forms',
# 'django_htcpcp_tea',
'django_tables2',
'mailer',
'phonenumber_field',
@ -95,6 +96,9 @@ MIDDLEWARE = [
'note_kfet.middlewares.TurbolinksMiddleware',
'note_kfet.middlewares.ClacksMiddleware',
]
if "django_htcpcp_tea" in INSTALLED_APPS:
MIDDLEWARE.append('django_htcpcp_tea.middleware.HTCPCPTeaMiddleware')
ROOT_URLCONF = 'note_kfet.urls'
@ -262,6 +266,9 @@ OAUTH2_PROVIDER = {
'REFRESH_TOKEN_EXPIRE_SECONDS': timedelta(days=14),
}
# PKCE (fix a breaking change of django-oauth-toolkit 2.0.0)
PKCE_REQUIRED = False
# Take control on how widget templates are sourced
# See https://docs.djangoproject.com/en/2.2/ref/forms/renderers/#templatessetting
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
@ -273,6 +280,7 @@ LOGIN_REDIRECT_URL = '/'
SESSION_COOKIE_AGE = 60 * 60 * 3
# Use Crispy Bootstrap4 theme
CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap4'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
# Use Django Table2 Bootstrap4 theme

View File

@ -8,7 +8,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if widget.value != None and widget.value != "" %}value="{{ widget.value }}"{% endif %}
name="{{ widget.name }}_name" autocomplete="off"
{% for name, value in widget.attrs.items %}
{% if value != False %}{{ name }}{% if value != True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}
{% if value is not False %}{{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}
{% endfor %}
aria-describedby="{{widget.attrs.id}}_tooltip">
{% if widget.resetable %}

View File

@ -126,12 +126,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
<a class="dropdown-item" href="{% url 'member:user_detail' pk=request.user.pk %}">
<i class="fa fa-user"></i> {% trans "My account" %}
</a>
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button class="dropdown-item" type="submit">
<a class="dropdown-item" href="{% url 'logout' %}">
<i class="fa fa-sign-out"></i> {% trans "Log out" %}
</button>
</form>
</a>
</div>
</li>
{% else %}
@ -197,8 +194,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
class="text-muted">{% trans "Contact us" %}</a> &mdash;
<a href="mailto:{{ "SUPPORT_EMAIL" | getenv }}"
class="text-muted">{% trans "Technical Support" %}</a> &mdash;
<a href="https://perso.crans.org/club-bde/charte_informatique.pdf"
class="text-muted">{% trans "Charte Info (FR)" %}</a> &mdash;
<a href="https://note.crans.org/doc/faq/"
class="text-muted">{% trans "FAQ (FR)" %}</a> &mdash;
</span>

View File

@ -43,12 +43,22 @@ if "oauth2_provider" in settings.INSTALLED_APPS:
path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
)
if "cas_server" in settings.INSTALLED_APPS:
urlpatterns.append(
path('cas/', include('cas_server.urls', namespace='cas_server'))
)
if "debug_toolbar" in settings.INSTALLED_APPS:
import debug_toolbar
urlpatterns = [
path('__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
if "django_htcpcp_tea" in settings.INSTALLED_APPS:
# Make coffee
urlpatterns.append(
path('coffee/', include('django_htcpcp_tea.urls'))
)
handler400 = bad_request
handler403 = permission_denied

View File

@ -1,17 +1,20 @@
beautifulsoup4~=4.12.3
crispy-bootstrap4~=2024.1
Django~=5.0.7
crispy-bootstrap4~=2023.1
Django~=4.2.9
django-bootstrap-datepicker-plus~=5.0.5
#django-cas-server~=2.0.0
django-colorfield~=0.11.0
django-crispy-forms~=2.2
django-extensions~=3.2.3
django-filter~=24.2
django-mailer~=2.3.2
django-oauth-toolkit~=2.4.0
django-phonenumber-field~=8.0.0
django-crispy-forms~=2.1.0
django-extensions>=3.2.3
django-filter~=23.5
#django-htcpcp-tea~=0.8.1
django-mailer~=2.3.1
django-oauth-toolkit~=2.3.0
django-phonenumber-field~=7.3.0
django-polymorphic~=3.1.0
djangorestframework~=3.14.0
django-rest-polymorphic~=0.1.10
django-tables2~=2.7.0
djangorestframework~=3.15.2
phonenumbers~=8.13.40
Pillow>=5.4.1
python-memcached~=1.62
phonenumbers~=8.13.28
Pillow>=10.2.0

11
tox.ini
View File

@ -1,10 +1,13 @@
[tox]
envlist =
# Ubuntu 20.04 Python
py310-django50
# Debian Bullseye Python
py311-django50
py39-django42
# Ubuntu 22.04 Python
py310-django42
# Debian Bookworm Python
py311-django42
linters
skipsdist = True