mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-25 06:13:07 +02:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			food_trace
			...
			f6c0544842
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f6c0544842 | ||
|  | dde1baa25c | ||
|  | 7a7ee47e0b | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -48,7 +48,6 @@ backups/ | ||||
| env/ | ||||
| venv/ | ||||
| db.sqlite3 | ||||
| shell.nix | ||||
|  | ||||
| # ansibles customs host | ||||
| ansible/host_vars/*.yaml | ||||
|   | ||||
| @@ -8,7 +8,7 @@ variables: | ||||
|   GIT_SUBMODULE_STRATEGY: recursive | ||||
|  | ||||
| # Ubuntu 22.04 | ||||
| py310-django52: | ||||
| py310-django42: | ||||
|   stage: test | ||||
|   image: ubuntu:22.04 | ||||
|   before_script: | ||||
| @@ -22,10 +22,10 @@ py310-django52: | ||||
|         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-django52 | ||||
|   script: tox -e py310-django42 | ||||
|  | ||||
| # Debian Bookworm | ||||
| py311-django52: | ||||
| py311-django42: | ||||
|   stage: test | ||||
|   image: debian:bookworm | ||||
|   before_script: | ||||
| @@ -37,7 +37,7 @@ py311-django52: | ||||
|         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-django52 | ||||
|   script: tox -e py311-django42 | ||||
|  | ||||
| linters: | ||||
|   stage: quality-assurance | ||||
|   | ||||
| @@ -145,7 +145,7 @@ class AddIngredientForms(forms.ModelForm): | ||||
|             polymorphic_ctype__model="transformedfood", | ||||
|             is_ready=False, | ||||
|             end_of_life='', | ||||
|         ).filter(PermissionBackend.filter_queryset(get_current_request(), Food, "change")).exclude(pk=pk) | ||||
|         ).filter(PermissionBackend.filter_queryset(get_current_request(), TransformedFood, "change")).exclude(pk=pk) | ||||
|  | ||||
|     class Meta: | ||||
|         model = TransformedFood | ||||
|   | ||||
| @@ -12,21 +12,18 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
|   </h3> | ||||
|   <div class="card-body"> | ||||
|     <ul> | ||||
|       {% if QR_code %} | ||||
|       <li> {{QR_code}} </li> | ||||
|       {% endif %} | ||||
|       {% for field, value in fields %} | ||||
|       <li> {{ field }} : {{ value }}</li> | ||||
|       {% endfor %} | ||||
|       {% if meals %} | ||||
|       <li> {% trans "Contained in" %} : | ||||
|       <li> {% trans "Contained in" %} :  | ||||
|       {% for meal in meals %} | ||||
|       <a href="{% url "food:transformedfood_view" pk=meal.pk %}">{{ meal.name }}</a>{% if not forloop.last %},{% endif %} | ||||
|       <a href="{% url "food:transformedfood_view" pk=meal.pk %}">{{ meal.name }}</a>{% if not forloop.last %},{% endif %}  | ||||
|       {% endfor %} | ||||
|       </li> | ||||
|       {% endif %} | ||||
|       {% if foods %} | ||||
|       <li> {% trans "Contain" %} : | ||||
|       <li> {% trans "Contain" %} :  | ||||
|       {% for food in foods %} | ||||
|         <a href="{% url "food:food_view" pk=food.pk %}">{{ food.name }}</a>{% if not forloop.last %},{% endif %} | ||||
|       {% endfor %} | ||||
| @@ -34,23 +31,23 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
|       {% endif %} | ||||
|     </ul> | ||||
|       {% if update %} | ||||
|         <a class="btn btn-sm btn-secondary" href="{% url "food:food_update" pk=food.pk %}"> | ||||
|           {% trans "Update" %} | ||||
|         </a> | ||||
| 	<a class="btn btn-sm btn-secondary" href="{% url "food:food_update" pk=food.pk %}"> | ||||
| 	  {% trans "Update" %} | ||||
| 	</a> | ||||
|       {% endif %} | ||||
|       {% if add_ingredient %} | ||||
|         <a class="btn btn-sm btn-primary" href="{% url "food:add_ingredient" pk=food.pk %}"> | ||||
|           {% trans "Add to a meal" %} | ||||
|         </a> | ||||
| 	<a class="btn btn-sm btn-primary" href="{% url "food:add_ingredient" pk=food.pk %}"> | ||||
| 	  {% trans "Add to a meal" %} | ||||
| 	</a> | ||||
|       {% endif %} | ||||
|       {% if manage_ingredients %} | ||||
|         <a class="btn btn-sm btn-secondary" href="{% url "food:manage_ingredients" pk=food.pk %}"> | ||||
|           {% trans "Manage ingredients" %} | ||||
|         </a> | ||||
| 	  {% trans "Manage ingredients" %} | ||||
| 	</a> | ||||
|       {% endif %} | ||||
|         <a class="btn btn-sm btn-primary" href="{% url "food:food_list" %}"> | ||||
|           {% trans "Return to the food list" %} | ||||
|         </a> | ||||
| 	<a class="btn btn-sm btn-primary" href="{% url "food:food_list" %}"> | ||||
| 	  {% trans "Return to the food list" %} | ||||
| 	</a> | ||||
|   </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -7,52 +7,7 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block content %} | ||||
| <div class="card bg-light"> | ||||
|   <h3 class="card-header text-center"> | ||||
|       {{ title }} | ||||
|   </h3> | ||||
|   <div class="card-body"> | ||||
|     <style> | ||||
|       input[type=number]::-webkit-inner-spin-button, | ||||
|       input[type=number]::-webkit-outer-spin-button { | ||||
|           -webkit-appearance: none; | ||||
|           margin: 0; | ||||
|       } | ||||
|       input[type=number] { | ||||
|           appearance: textfield; | ||||
|           padding: 6px; | ||||
|           border: 1px solid #ccc; | ||||
|           border-radius: 4px; | ||||
|           width: 100px; | ||||
|       } | ||||
|     </style> | ||||
|     <div class="d-flex align-items-center" style="max-width: 300px;"> | ||||
|       <form method="get" action="{% url 'food:redirect_view' %}" class="d-flex w-100"> | ||||
|         <input type="number" name="slug" placeholder="QR-code" required class="form-control form-control-sm" style="max-width: 120px;"> | ||||
|         <button type="submit" class="btn btn-sm btn-primary">{% trans "View food" %}</button> | ||||
|       </form> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="card-body"> | ||||
|       <input id="searchbar" type="text" class="form-control" | ||||
|           placeholder="{% trans "Search by attribute such as name..." %}"> | ||||
|   </div> | ||||
|  | ||||
|   {% block extra_inside_card %} | ||||
|   {% endblock %} | ||||
|  | ||||
|   <div id="dynamic-table"> | ||||
|       {% if table.data %} | ||||
|       {% render_table table %} | ||||
|       {% else %} | ||||
|       <div class="card-body"> | ||||
|           <div class="alert alert-warning"> | ||||
|               {% trans "There is no results." %} | ||||
|           </div> | ||||
|       </div> | ||||
|       {% endif %} | ||||
|   </div> | ||||
| </div> | ||||
| {{ block.super }} | ||||
| <br> | ||||
| <div class="card bg-light mb-3"> | ||||
|   <h3 class="card-header text-center"> | ||||
| @@ -113,20 +68,4 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
|   {% endfor %} | ||||
|   {% endif %} | ||||
| </div> | ||||
|  | ||||
|  | ||||
| <script> | ||||
|   document.addEventListener('DOMContentLoaded', function() { | ||||
|       document.getElementById('goButton').addEventListener('click', function(event) { | ||||
|           event.preventDefault(); | ||||
|           const slug = document.getElementById('slugInput').value; | ||||
|           if (slug && !isNaN(slug)) { | ||||
|               window.location.href = `/food/${slug}/`; | ||||
|           } else { | ||||
|               alert("Veuillez entrer un nombre valide."); | ||||
|           } | ||||
|       }); | ||||
|   }); | ||||
|   </script> | ||||
|  | ||||
| {% endblock %} | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -18,5 +18,4 @@ urlpatterns = [ | ||||
|     path('detail/basic/<int:pk>', views.BasicFoodDetailView.as_view(), name='basicfood_view'), | ||||
|     path('detail/transformed/<int:pk>', views.TransformedFoodDetailView.as_view(), name='transformedfood_view'), | ||||
|     path('add/ingredient/<int:pk>', views.AddIngredientView.as_view(), name='add_ingredient'), | ||||
|     path('redirect/', views.QRCodeRedirectView.as_view(), name='redirect_view'), | ||||
| ] | ||||
|   | ||||
| @@ -10,7 +10,6 @@ from django.db.models import Q | ||||
| from django.http import HttpResponseRedirect, Http404 | ||||
| from django.views.generic import DetailView, UpdateView, CreateView | ||||
| from django.views.generic.list import ListView | ||||
| from django.views.generic.base import RedirectView | ||||
| from django.urls import reverse_lazy | ||||
| from django.utils import timezone | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| @@ -455,8 +454,6 @@ class FoodDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): | ||||
|         context["fields"] = [( | ||||
|             Food._meta.get_field(field).verbose_name.capitalize(), | ||||
|             value) for field, value in fields.items()] | ||||
|         if self.object.QR_code.exists(): | ||||
|             context["QR_code"] = self.object.QR_code.first() | ||||
|         context["meals"] = self.object.transformed_ingredient_inv.all() | ||||
|         context["update"] = PermissionBackend.check_perm(self.request, "food.change_food") | ||||
|         context["add_ingredient"] = (self.object.end_of_life == '' and PermissionBackend.check_perm(self.request, "food.change_transformedfood")) | ||||
| @@ -510,14 +507,3 @@ class TransformedFoodDetailView(FoodDetailView): | ||||
|         if Food.objects.filter(pk=kwargs['pk']).count() == 1: | ||||
|             kwargs['stop_redirect'] = (Food.objects.get(pk=kwargs['pk']).polymorphic_ctype.model == 'transformedfood') | ||||
|         return super().get(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| class QRCodeRedirectView(RedirectView): | ||||
|     """ | ||||
|     Redirects to the QR code creation page from Food List | ||||
|     """ | ||||
|     def get_redirect_url(self, *args, **kwargs): | ||||
|         slug = self.request.GET.get('slug') | ||||
|         if slug: | ||||
|             return reverse_lazy('food:qrcode_create', kwargs={'slug': slug}) | ||||
|         return reverse_lazy('food:list') | ||||
|   | ||||
| @@ -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): | ||||
|   | ||||
| @@ -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='alias2') | ||||
|     router.register(path + '/consumer', ConsumerViewSet) | ||||
|  | ||||
|     router.register(path + '/transaction/category', TemplateCategoryViewSet) | ||||
|     router.register(path + '/transaction/transaction', TransactionViewSet) | ||||
|   | ||||
| @@ -18,18 +18,7 @@ class PermissionScopes(BaseScopes): | ||||
|     and can be useful to make queries through the API with limited privileges. | ||||
|     """ | ||||
|  | ||||
|     def get_all_scopes(self, **kwargs): | ||||
|         scopes = {} | ||||
|         if 'scopes' in kwargs: | ||||
|             for scope in kwargs['scopes']: | ||||
|                 if scope == 'openid': | ||||
|                     scopes['openid'] = "OpenID Connect" | ||||
|                 else: | ||||
|                     p = Permission.objects.get(id=scope.split('_')[0]) | ||||
|                     club = Club.objects.get(id=scope.split('_')[1]) | ||||
|                     scopes[scope] = f"{p.description} (club {club.name})" | ||||
|             return scopes | ||||
|  | ||||
|     def get_all_scopes(self): | ||||
|         scopes = {f"{p.id}_{club.id}": f"{p.description} (club {club.name})" | ||||
|                   for p in Permission.objects.all() for club in Club.objects.all()} | ||||
|         scopes['openid'] = "OpenID Connect" | ||||
|   | ||||
| @@ -13,7 +13,6 @@ EXCLUDED = [ | ||||
|     'cas_server.serviceticket', | ||||
|     'cas_server.user', | ||||
|     'cas_server.userattributes', | ||||
|     'constance.constance', | ||||
|     'contenttypes.contenttype', | ||||
|     'logs.changelog', | ||||
|     'migrations.migration', | ||||
|   | ||||
| @@ -164,24 +164,14 @@ class ScopesView(LoginRequiredMixin, TemplateView): | ||||
|         from oauth2_provider.models import Application | ||||
|         from .scopes import PermissionScopes | ||||
|  | ||||
|         oidc = False | ||||
|         scopes = PermissionScopes() | ||||
|         context["scopes"] = {} | ||||
|         all_scopes = scopes.get_all_scopes() | ||||
|         for app in Application.objects.filter(user=self.request.user).all(): | ||||
|             available_scopes = PermissionScopes().get_available_scopes(app) | ||||
|             available_scopes = scopes.get_available_scopes(app) | ||||
|             context["scopes"][app] = OrderedDict() | ||||
|             all_scopes = PermissionScopes().get_all_scopes(scopes=available_scopes) | ||||
|             scopes = {} | ||||
|             for scope in available_scopes: | ||||
|                 scopes[scope] = all_scopes[scope] | ||||
|             # remove OIDC scope for sort | ||||
|             if 'openid' in scopes: | ||||
|                 del scopes['openid'] | ||||
|                 oidc = True | ||||
|             items = [(k, v) for (k, v) in scopes.items()] | ||||
|             items.sort(key=lambda x: (int(x[0].split("_")[1]), int(x[0].split("_")[0]))) | ||||
|             # add oidc if necessary | ||||
|             if oidc: | ||||
|                 items.append(('openid', PermissionScopes().get_all_scopes(scopes=['openid'])['openid'])) | ||||
|             items = [(k, v) for (k, v) in all_scopes.items() if k in available_scopes] | ||||
|             # items.sort(key=lambda x: (int(x[0].split("_")[1]), int(x[0].split("_")[0]))) | ||||
|             for k, v in items: | ||||
|                 context["scopes"][app][k] = v | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: \n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-07-11 16:10+0200\n" | ||||
| "POT-Creation-Date: 2025-06-27 19:15+0200\n" | ||||
| "PO-Revision-Date: 2022-04-11 22:05+0200\n" | ||||
| "Last-Translator: bleizi <bleizi@crans.org>\n" | ||||
| "Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n" | ||||
| @@ -357,7 +357,7 @@ msgstr "Détails de l'activité" | ||||
| #: apps/note/models/transactions.py:261 | ||||
| #: apps/note/templates/note/transaction_form.html:17 | ||||
| #: apps/note/templates/note/transaction_form.html:152 | ||||
| #: note_kfet/templates/base.html:79 | ||||
| #: note_kfet/templates/base.html:78 | ||||
| msgid "Transfer" | ||||
| msgstr "Virement" | ||||
|  | ||||
| @@ -474,7 +474,7 @@ msgstr "Inviter" | ||||
| msgid "Create new activity" | ||||
| msgstr "Créer une nouvelle activité" | ||||
|  | ||||
| #: apps/activity/views.py:71 note_kfet/templates/base.html:97 | ||||
| #: apps/activity/views.py:71 note_kfet/templates/base.html:96 | ||||
| msgid "Activities" | ||||
| msgstr "Activités" | ||||
|  | ||||
| @@ -563,7 +563,7 @@ msgstr "Nom" | ||||
| #, fuzzy | ||||
| #| msgid "QR-code number" | ||||
| msgid "QR code number" | ||||
| msgstr "Numéro de QR-code" | ||||
| msgstr "numéro de QR-code" | ||||
|  | ||||
| #: apps/food/models.py:23 | ||||
| msgid "Allergen" | ||||
| @@ -597,7 +597,7 @@ msgstr "est prêt" | ||||
| msgid "order" | ||||
| msgstr "consigne" | ||||
|  | ||||
| #: apps/food/models.py:107 apps/food/views.py:35 | ||||
| #: apps/food/models.py:107 apps/food/views.py:34 | ||||
| #: note_kfet/templates/base.html:72 | ||||
| msgid "Food" | ||||
| msgstr "Bouffe" | ||||
| @@ -657,75 +657,61 @@ msgstr "QR-codes" | ||||
| #: apps/food/models.py:286 | ||||
| #: apps/food/templates/food/transformedfood_update.html:24 | ||||
| msgid "QR-code number" | ||||
| msgstr "Numéro de QR-code" | ||||
| msgstr "numéro de QR-code" | ||||
|  | ||||
| #: apps/food/templates/food/food_detail.html:22 | ||||
| #: apps/food/templates/food/food_detail.html:19 | ||||
| msgid "Contained in" | ||||
| msgstr "Contenu dans" | ||||
|  | ||||
| #: apps/food/templates/food/food_detail.html:29 | ||||
| #: apps/food/templates/food/food_detail.html:26 | ||||
| msgid "Contain" | ||||
| msgstr "Contient" | ||||
|  | ||||
| #: apps/food/templates/food/food_detail.html:38 | ||||
| #: apps/food/templates/food/food_detail.html:35 | ||||
| msgid "Update" | ||||
| msgstr "Modifier" | ||||
|  | ||||
| #: apps/food/templates/food/food_detail.html:43 | ||||
| #: apps/food/templates/food/food_detail.html:40 | ||||
| msgid "Add to a meal" | ||||
| msgstr "Ajouter à un plat" | ||||
|  | ||||
| #: apps/food/templates/food/food_detail.html:48 | ||||
| #: apps/food/templates/food/food_detail.html:45 | ||||
| msgid "Manage ingredients" | ||||
| msgstr "Gérer les ingrédients" | ||||
|  | ||||
| #: apps/food/templates/food/food_detail.html:52 | ||||
| #: apps/food/templates/food/food_detail.html:49 | ||||
| msgid "Return to the food list" | ||||
| msgstr "Retour à la liste de nourriture" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:32 | ||||
| msgid "View food" | ||||
| msgstr "Voir l'aliment" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:37 | ||||
| #: note_kfet/templates/base_search.html:15 | ||||
| msgid "Search by attribute such as name..." | ||||
| msgstr "Chercher par un attribut tel que le nom..." | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:49 | ||||
| #: note_kfet/templates/base_search.html:23 | ||||
| msgid "There is no results." | ||||
| msgstr "Il n'y a pas de résultat." | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:58 | ||||
| #: apps/food/templates/food/food_list.html:14 | ||||
| msgid "Meal served" | ||||
| msgstr "Plat servis" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:63 | ||||
| #: apps/food/templates/food/food_list.html:19 | ||||
| msgid "New meal" | ||||
| msgstr "Nouveau plat" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:72 | ||||
| #: apps/food/templates/food/food_list.html:28 | ||||
| msgid "There is no meal served." | ||||
| msgstr "Il n'y a pas de plat servi." | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:79 | ||||
| #: apps/food/templates/food/food_list.html:35 | ||||
| msgid "Free food" | ||||
| msgstr "Open" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:86 | ||||
| #: apps/food/templates/food/food_list.html:42 | ||||
| msgid "There is no free food." | ||||
| msgstr "Il n'y a pas de bouffe en open" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:94 | ||||
| #: apps/food/templates/food/food_list.html:50 | ||||
| msgid "Food of your clubs" | ||||
| msgstr "Bouffe de tes clubs" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:100 | ||||
| #: apps/food/templates/food/food_list.html:56 | ||||
| msgid "Food of club" | ||||
| msgstr "Bouffe du club" | ||||
|  | ||||
| #: apps/food/templates/food/food_list.html:107 | ||||
| #: apps/food/templates/food/food_list.html:63 | ||||
| msgid "Yours club has not food yet." | ||||
| msgstr "Ton club n'a pas de bouffe pour l'instant" | ||||
|  | ||||
| @@ -799,49 +785,49 @@ msgstr "semaines" | ||||
| msgid "and" | ||||
| msgstr "et" | ||||
|  | ||||
| #: apps/food/views.py:120 | ||||
| #: apps/food/views.py:118 | ||||
| msgid "Add a new QRCode" | ||||
| msgstr "Ajouter un nouveau QR-code" | ||||
|  | ||||
| #: apps/food/views.py:169 | ||||
| #: apps/food/views.py:167 | ||||
| msgid "Add an aliment" | ||||
| msgstr "Ajouter un nouvel aliment" | ||||
|  | ||||
| #: apps/food/views.py:228 | ||||
| #: apps/food/views.py:235 | ||||
| msgid "Add a meal" | ||||
| msgstr "Ajouter un plat" | ||||
|  | ||||
| #: apps/food/views.py:259 | ||||
| #: apps/food/views.py:275 | ||||
| msgid "Manage ingredients of:" | ||||
| msgstr "Gestion des ingrédienrs de :" | ||||
|  | ||||
| #: apps/food/views.py:273 apps/food/views.py:281 | ||||
| #: apps/food/views.py:289 apps/food/views.py:297 | ||||
| #, python-brace-format | ||||
| msgid "Fully used in {meal}" | ||||
| msgstr "Aliment entièrement utilisé dans : {meal}" | ||||
|  | ||||
| #: apps/food/views.py:320 | ||||
| #: apps/food/views.py:344 | ||||
| msgid "Add the ingredient:" | ||||
| msgstr "Ajouter l'ingrédient" | ||||
|  | ||||
| #: apps/food/views.py:346 | ||||
| #: apps/food/views.py:370 | ||||
| #, python-brace-format | ||||
| msgid "Food fully used in : {meal.name}" | ||||
| msgstr "Aliment entièrement utilisé dans : {meal.name}" | ||||
|  | ||||
| #: apps/food/views.py:365 | ||||
| #: apps/food/views.py:389 | ||||
| msgid "Update an aliment" | ||||
| msgstr "Modifier un aliment" | ||||
|  | ||||
| #: apps/food/views.py:413 | ||||
| #: apps/food/views.py:437 | ||||
| msgid "Details of:" | ||||
| msgstr "Détails de :" | ||||
|  | ||||
| #: apps/food/views.py:423 apps/treasury/tables.py:149 | ||||
| #: apps/food/views.py:447 apps/treasury/tables.py:149 | ||||
| msgid "Yes" | ||||
| msgstr "Oui" | ||||
|  | ||||
| #: apps/food/views.py:425 apps/member/models.py:99 apps/treasury/tables.py:149 | ||||
| #: apps/food/views.py:449 apps/member/models.py:99 apps/treasury/tables.py:149 | ||||
| msgid "No" | ||||
| msgstr "Non" | ||||
|  | ||||
| @@ -1976,8 +1962,8 @@ msgstr "" | ||||
| "mode de paiement et un⋅e utilisateur⋅rice 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:1105 | ||||
| #: apps/wei/views.py:1109 | ||||
| #: apps/note/models/transactions.py:363 apps/wei/views.py:1097 | ||||
| #: apps/wei/views.py:1101 | ||||
| msgid "This field is required." | ||||
| msgstr "Ce champ est requis." | ||||
|  | ||||
| @@ -2079,8 +2065,6 @@ msgstr "Historique des transactions récentes" | ||||
| #: apps/note/templates/note/mails/weekly_report.txt:32 | ||||
| #: apps/registration/templates/registration/mails/email_validation_email.html:40 | ||||
| #: apps/registration/templates/registration/mails/email_validation_email.txt:16 | ||||
| #: apps/scripts/templates/scripts/food_report.html:48 | ||||
| #: apps/scripts/templates/scripts/food_report.txt:14 | ||||
| msgid "Mail generated by the Note Kfet on the" | ||||
| msgstr "Mail généré par la Note Kfet le" | ||||
|  | ||||
| @@ -2192,7 +2176,7 @@ msgstr "Chercher un bouton" | ||||
| msgid "Update button" | ||||
| msgstr "Modifier le bouton" | ||||
|  | ||||
| #: apps/note/views.py:156 note_kfet/templates/base.html:67 | ||||
| #: apps/note/views.py:156 note_kfet/templates/base.html:66 | ||||
| msgid "Consumptions" | ||||
| msgstr "Consommations" | ||||
|  | ||||
| @@ -2285,7 +2269,7 @@ msgstr "s'applique au club" | ||||
| msgid "role permissions" | ||||
| msgstr "permissions par rôles" | ||||
|  | ||||
| #: apps/permission/signals.py:75 | ||||
| #: apps/permission/signals.py:73 | ||||
| #, python-brace-format | ||||
| msgid "" | ||||
| "You don't have the permission to change the field {field} on this instance " | ||||
| @@ -2294,7 +2278,7 @@ msgstr "" | ||||
| "Vous n'avez pas la permission de modifier le champ {field} sur l'instance du " | ||||
| "modèle {app_label}.{model_name}." | ||||
|  | ||||
| #: apps/permission/signals.py:85 apps/permission/views.py:104 | ||||
| #: apps/permission/signals.py:83 apps/permission/views.py:104 | ||||
| #, python-brace-format | ||||
| msgid "" | ||||
| "You don't have the permission to add an instance of model {app_label}." | ||||
| @@ -2303,7 +2287,7 @@ msgstr "" | ||||
| "Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}." | ||||
| "{model_name}." | ||||
|  | ||||
| #: apps/permission/signals.py:114 | ||||
| #: apps/permission/signals.py:112 | ||||
| #, python-brace-format | ||||
| msgid "" | ||||
| "You don't have the permission to delete this instance of model {app_label}." | ||||
| @@ -2391,7 +2375,7 @@ msgstr "" | ||||
| "Vous n'avez pas la permission d'ajouter une instance du modèle « {model} » " | ||||
| "avec ces paramètres. Merci de les corriger et de réessayer." | ||||
|  | ||||
| #: apps/permission/views.py:111 note_kfet/templates/base.html:121 | ||||
| #: apps/permission/views.py:111 note_kfet/templates/base.html:120 | ||||
| msgid "Rights" | ||||
| msgstr "Droits" | ||||
|  | ||||
| @@ -2596,7 +2580,7 @@ msgstr "" | ||||
| msgid "Invalidate pre-registration" | ||||
| msgstr "Invalider l'inscription" | ||||
|  | ||||
| #: apps/treasury/apps.py:12 note_kfet/templates/base.html:103 | ||||
| #: apps/treasury/apps.py:12 note_kfet/templates/base.html:102 | ||||
| msgid "Treasury" | ||||
| msgstr "Trésorerie" | ||||
|  | ||||
| @@ -3012,7 +2996,7 @@ msgstr "Gérer les crédits de la Société générale" | ||||
|  | ||||
| #: apps/wei/apps.py:10 apps/wei/models.py:42 apps/wei/models.py:43 | ||||
| #: apps/wei/models.py:67 apps/wei/models.py:192 | ||||
| #: note_kfet/templates/base.html:109 | ||||
| #: note_kfet/templates/base.html:108 | ||||
| msgid "WEI" | ||||
| msgstr "WEI" | ||||
|  | ||||
| @@ -3057,7 +3041,7 @@ msgstr "Rôles au WEI" | ||||
| msgid "Select the roles that you are interested in." | ||||
| msgstr "Sélectionnez les rôles qui vous intéressent." | ||||
|  | ||||
| #: apps/wei/forms/registration.py:160 | ||||
| #: apps/wei/forms/registration.py:147 | ||||
| msgid "This team doesn't belong to the given bus." | ||||
| msgstr "Cette équipe n'appartient pas à ce bus." | ||||
|  | ||||
| @@ -3136,7 +3120,7 @@ msgstr "Rôle au WEI" | ||||
| msgid "Credit from Société générale" | ||||
| msgstr "Crédit de la Société générale" | ||||
|  | ||||
| #: apps/wei/models.py:202 apps/wei/views.py:992 | ||||
| #: apps/wei/models.py:202 apps/wei/views.py:984 | ||||
| msgid "Caution check given" | ||||
| msgstr "Chèque de caution donné" | ||||
|  | ||||
| @@ -3368,6 +3352,7 @@ msgid "View club" | ||||
| msgstr "Voir le club" | ||||
|  | ||||
| #: apps/wei/templates/wei/bus_detail.html:26 | ||||
| #| msgid "survey information" | ||||
| msgid "Edit information" | ||||
| msgstr "Modifier les informations" | ||||
|  | ||||
| @@ -3388,8 +3373,8 @@ msgstr "Télécharger au format PDF" | ||||
|  | ||||
| #: apps/wei/templates/wei/survey.html:11 | ||||
| #: apps/wei/templates/wei/survey_closed.html:11 | ||||
| #: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1167 | ||||
| #: apps/wei/views.py:1222 apps/wei/views.py:1269 | ||||
| #: apps/wei/templates/wei/survey_end.html:11 apps/wei/views.py:1159 | ||||
| #: apps/wei/views.py:1214 apps/wei/views.py:1261 | ||||
| msgid "Survey WEI" | ||||
| msgstr "Questionnaire WEI" | ||||
|  | ||||
| @@ -3669,51 +3654,51 @@ msgstr "" | ||||
| msgid "Update WEI Registration" | ||||
| msgstr "Modifier l'inscription WEI" | ||||
|  | ||||
| #: apps/wei/views.py:811 | ||||
| #: apps/wei/views.py:810 | ||||
| msgid "No membership found for this registration" | ||||
| msgstr "Pas d'adhésion trouvée pour cette inscription" | ||||
|  | ||||
| #: apps/wei/views.py:820 | ||||
| #: apps/wei/views.py:819 | ||||
| msgid "You don't have the permission to update memberships" | ||||
| msgstr "" | ||||
| "Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}." | ||||
| "{model_name}." | ||||
|  | ||||
| #: apps/wei/views.py:826 | ||||
| #: apps/wei/views.py:825 | ||||
| #, python-format | ||||
| msgid "You don't have the permission to update the field %(field)s" | ||||
| msgstr "Vous n'avez pas la permission de modifier le champ %(field)s" | ||||
|  | ||||
| #: apps/wei/views.py:871 | ||||
| #: apps/wei/views.py:870 | ||||
| msgid "Delete WEI registration" | ||||
| msgstr "Supprimer l'inscription WEI" | ||||
|  | ||||
| #: apps/wei/views.py:882 | ||||
| #: apps/wei/views.py:881 | ||||
| msgid "You don't have the right to delete this WEI registration." | ||||
| msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI." | ||||
|  | ||||
| #: apps/wei/views.py:900 | ||||
| #: apps/wei/views.py:899 | ||||
| msgid "Validate WEI registration" | ||||
| msgstr "Valider l'inscription WEI" | ||||
|  | ||||
| #: apps/wei/views.py:993 | ||||
| #: apps/wei/views.py:985 | ||||
| msgid "Please make sure the check is given before validating the registration" | ||||
| msgstr "" | ||||
| "Merci de vous assurer que le chèque a bien été donné avant de valider " | ||||
| "l'adhésion" | ||||
|  | ||||
| #: apps/wei/views.py:999 | ||||
| #: apps/wei/views.py:991 | ||||
| msgid "Create deposit transaction" | ||||
| msgstr "Créer une transaction de caution" | ||||
|  | ||||
| #: apps/wei/views.py:1000 | ||||
| #: apps/wei/views.py:992 | ||||
| #, python-format | ||||
| msgid "" | ||||
| "A transaction of %(amount).2f€ will be created from the user's Note account" | ||||
| msgstr "" | ||||
| "Un transaction de %(amount).2f€ va être créée depuis la note de l'utilisateur" | ||||
|  | ||||
| #: apps/wei/views.py:1095 | ||||
| #: apps/wei/views.py:1087 | ||||
| #, python-format | ||||
| msgid "" | ||||
| "This user doesn't have enough money to join this club and pay the deposit. " | ||||
| @@ -3723,21 +3708,21 @@ msgstr "" | ||||
| "payer la cautionSolde actuel : %(balance)d€, crédit : %(credit)d€, requis : " | ||||
| "%(needed)d€" | ||||
|  | ||||
| #: apps/wei/views.py:1148 | ||||
| #: apps/wei/views.py:1140 | ||||
| #, fuzzy, python-format | ||||
| #| msgid "total amount" | ||||
| msgid "Caution %(name)s" | ||||
| msgstr "montant total" | ||||
|  | ||||
| #: apps/wei/views.py:1362 | ||||
| #: apps/wei/views.py:1354 | ||||
| msgid "Attribute buses to first year members" | ||||
| msgstr "Répartir les 1A dans les bus" | ||||
|  | ||||
| #: apps/wei/views.py:1388 | ||||
| #: apps/wei/views.py:1380 | ||||
| msgid "Attribute bus" | ||||
| msgstr "Attribuer un bus" | ||||
|  | ||||
| #: apps/wei/views.py:1428 | ||||
| #: apps/wei/views.py:1420 | ||||
| msgid "" | ||||
| "No first year student without a bus found. Either all of them have a bus, or " | ||||
| "none has filled the survey yet." | ||||
| @@ -3761,13 +3746,13 @@ msgstr "bde" | ||||
|  | ||||
| #: apps/wrapped/models.py:65 | ||||
| msgid "data json" | ||||
| msgstr "données json" | ||||
| msgstr "donnée json" | ||||
|  | ||||
| #: apps/wrapped/models.py:66 | ||||
| msgid "data in the wrapped and generated by the script generate_wrapped" | ||||
| msgstr "donnée dans le wrapped et générée par le script generate_wrapped" | ||||
|  | ||||
| #: apps/wrapped/models.py:70 note_kfet/templates/base.html:115 | ||||
| #: apps/wrapped/models.py:70 note_kfet/templates/base.html:114 | ||||
| msgid "Wrapped" | ||||
| msgstr "Wrapped" | ||||
|  | ||||
| @@ -3800,7 +3785,7 @@ msgid "Copy link" | ||||
| msgstr "Copier le lien" | ||||
|  | ||||
| #: apps/wrapped/templates/wrapped/1/wrapped_base.html:16 | ||||
| #: note_kfet/templates/base.html:15 | ||||
| #: note_kfet/templates/base.html:14 | ||||
| msgid "The ENS Paris-Saclay BDE note." | ||||
| msgstr "La note du BDE de l'ENS Paris-Saclay." | ||||
|  | ||||
| @@ -3903,7 +3888,7 @@ msgid "" | ||||
| "Do not forget to ask permission to people who are in your wrapped before to " | ||||
| "make them public" | ||||
| msgstr "" | ||||
| "N'oublie pas de demander la permission des personnes apparaissant dans un " | ||||
| "N'oublies pas de demander la permission des personnes apparaissant dans un " | ||||
| "wrapped avant de le rendre public" | ||||
|  | ||||
| #: apps/wrapped/templates/wrapped/wrapped_list.html:40 | ||||
| @@ -3922,19 +3907,19 @@ msgstr "Le wrapped est public" | ||||
| msgid "List of wrapped" | ||||
| msgstr "Liste des wrapped" | ||||
|  | ||||
| #: note_kfet/settings/base.py:180 | ||||
| #: note_kfet/settings/base.py:177 | ||||
| msgid "German" | ||||
| msgstr "Allemand" | ||||
|  | ||||
| #: note_kfet/settings/base.py:181 | ||||
| #: note_kfet/settings/base.py:178 | ||||
| msgid "English" | ||||
| msgstr "Anglais" | ||||
|  | ||||
| #: note_kfet/settings/base.py:182 | ||||
| #: note_kfet/settings/base.py:179 | ||||
| msgid "Spanish" | ||||
| msgstr "Espagnol" | ||||
|  | ||||
| #: note_kfet/settings/base.py:183 | ||||
| #: note_kfet/settings/base.py:180 | ||||
| msgid "French" | ||||
| msgstr "Français" | ||||
|  | ||||
| @@ -3995,34 +3980,34 @@ msgstr "" | ||||
| msgid "Reset" | ||||
| msgstr "Réinitialiser" | ||||
|  | ||||
| #: note_kfet/templates/base.html:85 | ||||
| #: note_kfet/templates/base.html:84 | ||||
| msgid "Users" | ||||
| msgstr "Utilisateur·rices" | ||||
|  | ||||
| #: note_kfet/templates/base.html:91 | ||||
| #: note_kfet/templates/base.html:90 | ||||
| msgid "Clubs" | ||||
| msgstr "Clubs" | ||||
|  | ||||
| #: note_kfet/templates/base.html:126 | ||||
| #: note_kfet/templates/base.html:125 | ||||
| msgid "Admin" | ||||
| msgstr "Admin" | ||||
|  | ||||
| #: note_kfet/templates/base.html:140 | ||||
| #: note_kfet/templates/base.html:139 | ||||
| msgid "My account" | ||||
| msgstr "Mon compte" | ||||
|  | ||||
| #: note_kfet/templates/base.html:145 | ||||
| #: note_kfet/templates/base.html:142 | ||||
| msgid "Log out" | ||||
| msgstr "Se déconnecter" | ||||
|  | ||||
| #: note_kfet/templates/base.html:154 | ||||
| #: note_kfet/templates/base.html:150 | ||||
| #: note_kfet/templates/registration/signup.html:6 | ||||
| #: note_kfet/templates/registration/signup.html:11 | ||||
| #: note_kfet/templates/registration/signup.html:28 | ||||
| msgid "Sign up" | ||||
| msgstr "Inscription" | ||||
|  | ||||
| #: note_kfet/templates/base.html:161 | ||||
| #: note_kfet/templates/base.html:157 | ||||
| #: note_kfet/templates/registration/login.html:6 | ||||
| #: note_kfet/templates/registration/login.html:15 | ||||
| #: note_kfet/templates/registration/login.html:38 | ||||
| @@ -4030,7 +4015,7 @@ msgstr "Inscription" | ||||
| msgid "Log in" | ||||
| msgstr "Se connecter" | ||||
|  | ||||
| #: note_kfet/templates/base.html:175 | ||||
| #: note_kfet/templates/base.html:171 | ||||
| msgid "" | ||||
| "You are not a BDE member anymore. Please renew your membership if you want " | ||||
| "to use the note." | ||||
| @@ -4038,7 +4023,7 @@ msgstr "" | ||||
| "Vous n'êtes plus adhérent·e BDE. Merci de réadhérer si vous voulez profiter " | ||||
| "de la note." | ||||
|  | ||||
| #: note_kfet/templates/base.html:181 | ||||
| #: note_kfet/templates/base.html:177 | ||||
| msgid "" | ||||
| "Your e-mail address is not validated. Please check your mail inbox and click " | ||||
| "on the validation link." | ||||
| @@ -4046,7 +4031,7 @@ msgstr "" | ||||
| "Votre adresse e-mail n'est pas validée. Merci de vérifier votre boîte mail " | ||||
| "et de cliquer sur le lien de validation." | ||||
|  | ||||
| #: note_kfet/templates/base.html:187 | ||||
| #: note_kfet/templates/base.html:183 | ||||
| msgid "" | ||||
| "You declared that you opened a bank account in the Société générale. The " | ||||
| "bank did not validate the creation of the account to the BDE, so the " | ||||
| @@ -4060,38 +4045,22 @@ msgstr "" | ||||
| "vérification peut durer quelques jours. Merci de vous assurer de bien aller " | ||||
| "au bout de vos démarches." | ||||
|  | ||||
| #: note_kfet/templates/base.html:214 | ||||
| #: note_kfet/templates/base.html:206 | ||||
| msgid "Contact us" | ||||
| msgstr "Nous contacter" | ||||
|  | ||||
| #: note_kfet/templates/base.html:216 | ||||
| #: note_kfet/templates/base.html:208 | ||||
| msgid "Technical Support" | ||||
| msgstr "Support technique" | ||||
|  | ||||
| #: note_kfet/templates/base.html:218 | ||||
| #: note_kfet/templates/base.html:210 | ||||
| msgid "Charte Info (FR)" | ||||
| msgstr "Charte Info (FR)" | ||||
|  | ||||
| #: note_kfet/templates/base.html:220 | ||||
| #: note_kfet/templates/base.html:212 | ||||
| msgid "FAQ (FR)" | ||||
| msgstr "FAQ (FR)" | ||||
|  | ||||
| #: note_kfet/templates/base.html:222 | ||||
| msgid "Managed by BDE" | ||||
| msgstr "Gérer par le BDE" | ||||
|  | ||||
| #: note_kfet/templates/base.html:224 | ||||
| msgid "Hosted by Cr@ns" | ||||
| msgstr "Hébergé par le Cr@ans" | ||||
|  | ||||
| #: note_kfet/templates/base.html:266 | ||||
| msgid "The note is not available for now" | ||||
| msgstr "La note est indisponible pour le moment" | ||||
|  | ||||
| #: note_kfet/templates/base.html:268 | ||||
| msgid "Thank you for your understanding -- The Respos Info of BDE" | ||||
| msgstr "Merci de votre compréhension -- Les Respos Info du BDE" | ||||
|  | ||||
| #: note_kfet/templates/base_search.html:15 | ||||
| msgid "Search by attribute such as name..." | ||||
| msgstr "Chercher par un attribut tel que le nom..." | ||||
| @@ -4100,41 +4069,6 @@ msgstr "Chercher par un attribut tel que le nom..." | ||||
| msgid "There is no results." | ||||
| msgstr "Il n'y a pas de résultat." | ||||
|  | ||||
| #: note_kfet/templates/cas/logged.html:8 | ||||
| msgid "" | ||||
| "<h3>Log In Successful</h3>You have successfully logged into the Central " | ||||
| "Authentication Service.<br/>For security reasons, please Log Out and Exit " | ||||
| "your web browser when you are done accessing services that require " | ||||
| "authentication!" | ||||
| msgstr "" | ||||
| "<h3>Connection réussie</h3>Vous vous êtes bien connecté au Service Central d'Authentification." | ||||
| "<br/>Pour des raisons de sécurité, veuillez vous déconnecter et fermer votre navigateur internet " | ||||
| "une fois que vous aurez fini d'accéder aux services qui requiert une authentification !" | ||||
|  | ||||
| #: note_kfet/templates/cas/logged.html:14 | ||||
| msgid "Log me out from all my sessions" | ||||
| msgstr "Me déconnecter de toutes mes sessions" | ||||
|  | ||||
| #: note_kfet/templates/cas/logged.html:20 | ||||
| msgid "Forget the identity provider" | ||||
| msgstr "Oublier le fournisseur d'identité" | ||||
|  | ||||
| #: note_kfet/templates/cas/logged.html:24 | ||||
| msgid "Logout" | ||||
| msgstr "Déconnexion" | ||||
|  | ||||
| #: note_kfet/templates/cas/login.html:11 | ||||
| msgid "Please log in" | ||||
| msgstr "Veuillez vous connecter" | ||||
|  | ||||
| #: note_kfet/templates/cas/login.html:23 | ||||
| msgid "Login" | ||||
| msgstr "Connexion" | ||||
|  | ||||
| #: note_kfet/templates/cas/warn.html:14 | ||||
| msgid "Connect to the service" | ||||
| msgstr "Connexion au service" | ||||
|  | ||||
| #: note_kfet/templates/oauth2_provider/application_confirm_delete.html:8 | ||||
| msgid "Are you sure to delete the application" | ||||
| msgstr "Êtes-vous sûr⋅e de vouloir supprimer l'application" | ||||
| @@ -4355,86 +4289,10 @@ msgstr "" | ||||
| "d'adhésion. Vous devez également valider votre adresse email en suivant le " | ||||
| "lien que vous avez reçu." | ||||
|  | ||||
| #, fuzzy | ||||
| #~| msgid "QR-code" | ||||
| #~ msgid "Go to QR-code" | ||||
| #~ msgstr "QR-code" | ||||
|  | ||||
| #, python-brace-format | ||||
| #~ msgid "QR-code number {qr_code_number}" | ||||
| #~ msgstr "Numéro du QR-code {qr_code_number}" | ||||
|  | ||||
| #~ msgid "was eaten" | ||||
| #~ msgstr "a été mangé" | ||||
|  | ||||
| #~ msgid "is active" | ||||
| #~ msgstr "est en cours" | ||||
|  | ||||
| #~ msgid "foods" | ||||
| #~ msgstr "bouffes" | ||||
|  | ||||
| #~ msgid "Arrival date" | ||||
| #~ msgstr "Date d'arrivée" | ||||
|  | ||||
| #~ msgid "Active" | ||||
| #~ msgstr "Actif" | ||||
|  | ||||
| #~ msgid "Eaten" | ||||
| #~ msgstr "Mangé" | ||||
|  | ||||
| #~ msgid "number" | ||||
| #~ msgstr "numéro" | ||||
|  | ||||
| #~ msgid "View details" | ||||
| #~ msgstr "Voir plus" | ||||
|  | ||||
| #~ msgid "Ready" | ||||
| #~ msgstr "Prêt" | ||||
|  | ||||
| #~ msgid "Creation date" | ||||
| #~ msgstr "Date de création" | ||||
|  | ||||
| #~ msgid "Ingredients" | ||||
| #~ msgstr "Ingrédients" | ||||
|  | ||||
| #~ msgid "Open" | ||||
| #~ msgstr "Open" | ||||
|  | ||||
| #~ msgid "All meals" | ||||
| #~ msgstr "Tout les plats" | ||||
|  | ||||
| #~ msgid "There is no meal." | ||||
| #~ msgstr "Il n'y a pas de plat" | ||||
|  | ||||
| #~ msgid "The product is already prepared" | ||||
| #~ msgstr "Le produit est déjà prêt" | ||||
|  | ||||
| #~ msgid "Add a new basic food with QRCode" | ||||
| #~ msgstr "Ajouter un nouvel ingrédient avec un QR-code" | ||||
|  | ||||
| #~ msgid "QRCode" | ||||
| #~ msgstr "QR-code" | ||||
|  | ||||
| #~ msgid "Add a new meal" | ||||
| #~ msgstr "Ajouter un nouveau plat" | ||||
|  | ||||
| #~ msgid "Update a meal" | ||||
| #~ msgstr "Modifier le plat" | ||||
|  | ||||
| #, fuzzy | ||||
| #~| msgid "invalidate" | ||||
| #~ msgid "Enter a valid color." | ||||
| #~ msgstr "dévalider" | ||||
|  | ||||
| #, fuzzy | ||||
| #~| msgid "invalidate" | ||||
| #~ msgid "Enter a valid value." | ||||
| #~ msgstr "dévalider" | ||||
|  | ||||
| #, fuzzy | ||||
| #~| msgid "Invitation" | ||||
| #~ msgid "Syndication" | ||||
| #~ msgstr "Invitation" | ||||
| #, fuzzy, python-format | ||||
| #~| msgid "Creation date" | ||||
| #~ msgid "Deposit %(name)s" | ||||
| #~ msgstr "Caution %(name)s" | ||||
|  | ||||
| #, fuzzy | ||||
| #~| msgid "There is no results." | ||||
| @@ -4848,7 +4706,7 @@ msgstr "" | ||||
|  | ||||
| #, python-brace-format | ||||
| #~ msgid "QR-code number {qr_code_number}" | ||||
| #~ msgstr "Numéro du QR-code {qr_code_number}" | ||||
| #~ msgstr "numéro du QR-code {qr_code_number}" | ||||
|  | ||||
| #~ msgid "was eaten" | ||||
| #~ msgstr "a été mangé" | ||||
|   | ||||
| @@ -27,6 +27,5 @@ MAILTO=notekfet2020@lists.crans.org | ||||
| # Vider les tokens Oauth2 | ||||
|  00  6     *   *   *     root   cd /var/www/note_kfet && env/bin/python manage.py cleartokens -v 0 | ||||
| # Envoyer la liste des abonnés à la NL BDA | ||||
|  00  10    *   *   0     root   cd /var/www/note_kfet && env/bin/python manage.py extract_ml_registrations -t art -e "bda.ensparissaclay@gmail.com" | ||||
| # Envoyer la liste de la bouffe au club et aux GCKs | ||||
|  00  8     *   *   1     root   cd /var/www/note_kfet && env/bin/python manage.py send_mail_for_food --report --club | ||||
|  00  10     *   *   0     root   cd /var/www/note_kfet && env/bin/python manage.py extract_ml_registrations -t art -e "bda.ensparissaclay@gmail.com" | ||||
|   | ||||
| @@ -56,8 +56,3 @@ if "cas_server" in settings.INSTALLED_APPS: | ||||
|     from cas_server.models import * | ||||
|     admin_site.register(ServicePattern, ServicePatternAdmin) | ||||
|     admin_site.register(FederatedIendityProvider, FederatedIendityProviderAdmin) | ||||
|  | ||||
| if "constance" in settings.INSTALLED_APPS: | ||||
|     from constance.admin import * | ||||
|     from constance.models import * | ||||
|     admin_site.register([Config], ConstanceAdmin) | ||||
|   | ||||
| @@ -39,9 +39,7 @@ SECURE_HSTS_PRELOAD = True | ||||
| INSTALLED_APPS = [ | ||||
|     # External apps | ||||
|     'bootstrap_datepicker_plus', | ||||
|     'cas_server', | ||||
|     'colorfield', | ||||
|     'constance', | ||||
|     'crispy_bootstrap4', | ||||
|     'crispy_forms', | ||||
| #    'django_htcpcp_tea', | ||||
| @@ -113,7 +111,6 @@ TEMPLATES = [ | ||||
|         'APP_DIRS': True, | ||||
|         'OPTIONS': { | ||||
|             'context_processors': [ | ||||
|                 'constance.context_processors.config', | ||||
|                 'django.template.context_processors.debug', | ||||
|                 'django.template.context_processors.request', | ||||
|                 'django.contrib.auth.context_processors.auth', | ||||
| @@ -310,30 +307,6 @@ PHONENUMBER_DEFAULT_REGION = 'FR' | ||||
|  | ||||
| # We add custom information to CAS, in order to give a normalized name to other services | ||||
| CAS_AUTH_CLASS = 'member.auth.CustomAuthUser' | ||||
| CAS_LOGIN_TEMPLATE = 'cas/login.html' | ||||
| CAS_LOGOUT_TEMPLATE = 'cas/logout.html' | ||||
| CAS_WARN_TEMPLATE = 'cas/warn.html' | ||||
| CAS_LOGGED_TEMPLATE = 'cas/logged.html' | ||||
|  | ||||
| # Default field for primary key | ||||
| DEFAULT_AUTO_FIELD = "django.db.models.AutoField" | ||||
|  | ||||
| # Constance settings | ||||
| CONSTANCE_ADDITIONAL_FIELDS = { | ||||
|     'banner_type': ['django.forms.fields.ChoiceField', { | ||||
|         'widget': 'django.forms.Select', | ||||
|         'choices': (('info', 'Info'), ('success', 'Success'), ('warning', 'Warning'), ('danger', 'Danger')) | ||||
|     }], | ||||
| } | ||||
| CONSTANCE_CONFIG = { | ||||
|     'BANNER_MESSAGE': ('', 'Some message', str), | ||||
|     'BANNER_TYPE': ('info', 'Banner type', 'banner_type'), | ||||
|     'MAINTENANCE': (False, 'check for mainteance mode', bool), | ||||
|     'MAINTENANCE_MESSAGE': ('', 'Some maintenance message', str), | ||||
| } | ||||
| CONSTANCE_CONFIG_FIELDSETS = { | ||||
|     'Maintenance': ('MAINTENANCE_MESSAGE', 'MAINTENANCE'), | ||||
|     'Banner': ('BANNER_MESSAGE', 'BANNER_TYPE'), | ||||
| } | ||||
| CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend' | ||||
| CONSTANCE_SUPERUSER_ONLY = True | ||||
|   | ||||
| @@ -5,7 +5,6 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
| <!DOCTYPE html> | ||||
| {% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} | ||||
| <html lang="{{ LANGUAGE_CODE|default:"en" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %} class="position-relative h-100"> | ||||
| {% if not config.MAINTENANCE %} | ||||
| <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||||
| @@ -139,12 +138,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"> | ||||
| 					<i class="fa fa-sign-out"></i> {% trans "Log out" %} | ||||
| 				    </button> | ||||
|                                 </form> | ||||
|                                 <a class="dropdown-item" href="{% url 'logout' %}"> | ||||
|                                     <i class="fa fa-sign-out"></i> {% trans "Log out" %} | ||||
|                                 </a> | ||||
|                             </div> | ||||
|                         </li> | ||||
|                     {% else %} | ||||
| @@ -192,11 +188,7 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
|                     {% endblocktrans %} | ||||
|                 </div> | ||||
|             {% endif %} | ||||
| 	    {% if config.BANNER_MESSAGE and user.is_authenticated %} | ||||
| 	    <div class="alert alert-{{ config.BANNER_TYPE }}"> | ||||
| 	      {{ config.BANNER_MESSAGE }} | ||||
| 	    </div> | ||||
| 	    {% endif %} | ||||
|             {# TODO Add banners #} | ||||
|         </div> | ||||
|         {% block content %} | ||||
|             <p>Default content...</p> | ||||
| @@ -218,10 +210,6 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
|                            class="text-muted">{% trans "Charte Info (FR)" %}</a> — | ||||
|                         <a href="https://note.crans.org/doc/faq/" | ||||
|                            class="text-muted">{% trans "FAQ (FR)" %}</a> — | ||||
| 		   	<a href="https://bde.ens-cachan.fr" | ||||
| 			   class="text-muted">{% trans "Managed by BDE" %}</a> — | ||||
| 		   	<a href="https://crans.org" | ||||
| 			   class="text-muted">{% trans "Hosted by Cr@ns" %}</a> — | ||||
|                     </span> | ||||
|                     {% csrf_token %} | ||||
|                     <select title="language" name="language" | ||||
| @@ -258,15 +246,4 @@ SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  | ||||
| {% block extrajavascript %}{% endblock %} | ||||
| </body> | ||||
| {% endif %} | ||||
| {% if config.MAINTENANCE %} | ||||
| <body> | ||||
|   <div style="text-align:center"> | ||||
|     <br /> | ||||
|     {% trans "The note is not available for now" %}<br /><br /> | ||||
|     {{ config.MAINTENANCE_MESSAGE }}<br /><br /> | ||||
|     {% trans "Thank you for your understanding -- The Respos Info of BDE" %} | ||||
|   </div> | ||||
| </body> | ||||
| {% endif %} | ||||
| </html> | ||||
|   | ||||
| @@ -1,28 +0,0 @@ | ||||
| {% extends "base.html" %} | ||||
| {% comment %} | ||||
| Copyright (C) by BDE ENS-Paris-Saclay | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
| {% block content %} | ||||
| <div class="alert alert-success" role="alert">{% blocktrans %}<h3>Log In Successful</h3>You have successfully logged into the Central Authentication Service.<br/>For security reasons, please Log Out and Exit your web browser when you are done accessing services that require authentication!{% endblocktrans %}</div> | ||||
| <div class="card bg-light mx-auto" style="max-width:30rem;"> | ||||
|   <div class="card-body"> | ||||
|     <form class="form-signin" method="get" action="logout"> | ||||
|       <div class="checkbox"> | ||||
| 	<label> | ||||
| 	  <input type="checkbox" name="all" value="1">{% trans "Log me out from all my sessions" %} | ||||
| 	</label> | ||||
|       </div> | ||||
|       {% if settings.CAS_FEDERATE and request.COOKIES.remember_provider %} | ||||
|       <div class="checkbox"> | ||||
| 	<label> | ||||
| 	  <input type="checkbox" name="forget_provider" value="1">{% trans "Forget the identity provider" %} | ||||
| 	</label> | ||||
|       </div> | ||||
|       {% endif %} | ||||
|       <button class="btn btn-danger btn-block btn-lg" type="submit">{% trans "Logout" %}</button> | ||||
|     </form> | ||||
|   </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
| @@ -1,42 +0,0 @@ | ||||
| {% extends "base.html" %} | ||||
| {% comment %} | ||||
| Copyright (C) by BDE ENS-Paris-Saclay | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block ante_messages %} | ||||
|   {% if auto_submit %}<noscript>{% endif %} | ||||
|   <div class="card-header text-center"> | ||||
|     <h2 class="form-signin-heading">{% trans "Please log in" %}</h2> | ||||
|   </div> | ||||
|   {% if auto_submit %}</noscript>{% endif %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block content %} | ||||
|   <div class="card bg-light mx-auto" style="max-width: 30rem;"> | ||||
|     <div class="card-body"> | ||||
| 	<form class="form-signin" method="post" id="login_form"{% if post_url %} action="{{post_url}}"{% endif %}> | ||||
| 	  {% csrf_token %} | ||||
| 	  {% include "cas_server/bs4/form.html" %} | ||||
| 	  {% if auto_submit %}<noscript>{% endif %} | ||||
| 	  <button class="btn btn-primary btn-block btn-lg" type="submit">{% trans "Login" %}</button> | ||||
| 	  {% if auto_submit %}</noscript>{% endif %} | ||||
| 	</div> | ||||
|       </form> | ||||
|     </div> | ||||
|   </div> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block javascript_inline %} | ||||
| jQuery(function( $ ){ | ||||
|   $("#id_warn").click(function(e){ | ||||
|     if($("#id_warn").is(':checked')){ | ||||
|       createCookie("warn", "on", 10 * 365); | ||||
|     } else { | ||||
|       eraseCookie("warn"); | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
| {% if auto_submit %}document.getElementById('login_form').submit(); // SUBMIT FORM{% endif %} | ||||
| {% endblock %} | ||||
| @@ -1,10 +0,0 @@ | ||||
| {% extends "base.html" %} | ||||
| {% comment %} | ||||
| Copyright (C) by BDE ENS-Paris-Saclay | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n static %} | ||||
| {% block content %} | ||||
|     <div class="alert alert-success" role="alert">{{ logout_msg }}</div> | ||||
| {% endblock %} | ||||
|    | ||||
| @@ -1,19 +0,0 @@ | ||||
| {% extends "base.html" %} | ||||
| {% comment %} | ||||
| Copyright (C) by BDE ENS-Paris-Saclay | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n static %} | ||||
|  | ||||
| {% block content %} | ||||
|   <div class="card bg-light mx-auto" style="max-width: 30rem;"> | ||||
|     <div class="card-body"> | ||||
|       <form class="form-signin" method="post"> | ||||
| 	{% csrf_token %} | ||||
| 	{% include "cas_server/bs4/form.html" %} | ||||
| 	<button class="btn btn-primary btn-block btn-lg" type="submit">{% trans "Connect to the service" %}</button> | ||||
|       </form> | ||||
|     </div> | ||||
|   </div> | ||||
| {% endblock %} | ||||
|    | ||||
| @@ -1,21 +1,20 @@ | ||||
| beautifulsoup4~=4.13.4 | ||||
| crispy-bootstrap4~=2025.6 | ||||
| Django~=5.2.4 | ||||
| beautifulsoup4~=4.12.3 | ||||
| crispy-bootstrap4~=2023.1 | ||||
| Django~=4.2.9 | ||||
| django-bootstrap-datepicker-plus~=5.0.5 | ||||
| django-cas-server~=3.1.0 | ||||
| django-colorfield~=0.14.0 | ||||
| django-constance~=4.3.2 | ||||
| django-crispy-forms~=2.4.0 | ||||
| django-extensions>=4.1.0 | ||||
| django-filter~=25.1 | ||||
| #django-cas-server~=2.0.0 | ||||
| django-colorfield~=0.11.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.2 | ||||
| django-oauth-toolkit~=3.0.1 | ||||
| django-phonenumber-field~=8.1.0 | ||||
| django-mailer~=2.3.1 | ||||
| django-oauth-toolkit~=2.3.0 | ||||
| django-phonenumber-field~=7.3.0 | ||||
| django-polymorphic~=3.1.0 | ||||
| djangorestframework~=3.16.0 | ||||
| djangorestframework~=3.14.0 | ||||
| django-rest-polymorphic~=0.1.10 | ||||
| django-tables2~=2.7.5 | ||||
| django-tables2~=2.7.0 | ||||
| python-memcached~=1.62 | ||||
| phonenumbers~=9.0.8 | ||||
| Pillow>=11.3.0 | ||||
| phonenumbers~=8.13.28 | ||||
| Pillow>=10.2.0 | ||||
|   | ||||
							
								
								
									
										34
									
								
								shell-static.nix
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										34
									
								
								shell-static.nix
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| # This is a workaround meant for use with the nix package manager. If you don't know what it is or don't use it, please ignore this file. | ||||
| #  | ||||
| # The nk20 javascript static location are hardcoded for imperative system. | ||||
| # This make ./manage.py collectstatic hard to use with nixos. | ||||
| #  | ||||
| # A workaround is to enter a FHSUserEnv with the static placed under /share/javascript/<static>. | ||||
| # This emulate a debian like system and enable collecting static normally with ./manage.py collectstatics. | ||||
| # The regular shell.nix should be enough for other configurations. | ||||
| # | ||||
| # Warning, you are still supposed to use pip package with a venv ! | ||||
| { pkgs ? import <nixpkgs> {} }: | ||||
| (pkgs.buildFHSUserEnv { | ||||
|   name = "pipzone"; | ||||
|   targetPkgs = pkgs: (with pkgs; | ||||
|   let | ||||
|     fhs-static = stdenv.mkDerivation { | ||||
|       name = "fhs-static"; | ||||
|       buildCommand = '' | ||||
|       mkdir -p $out/share/javascript/bootstrap4 | ||||
|       mkdir -p $out/share/javascript/jquery | ||||
|       ln -s ${python39Packages.xstatic-bootstrap}/lib/python3.9/site-packages/xstatic/pkg/bootstrap/data/* $out/share/javascript/bootstrap4 | ||||
|       ln -s ${python39Packages.xstatic-jquery}/lib/python3.9/site-packages/xstatic/pkg/jquery/data/* $out/share/javascript/jquery | ||||
|     ''; | ||||
|     }; | ||||
|   in [ | ||||
|     fhs-static | ||||
|     python39 | ||||
|     gettext | ||||
|     python39Packages.pip | ||||
|     python39Packages.virtualenv | ||||
|     python39Packages.setuptools | ||||
|   ]); | ||||
|   runScript = "bash"; | ||||
| }).env | ||||
							
								
								
									
										23
									
								
								shell.nix
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								shell.nix
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # This is meant for use with the nix package manager. If you don't know what it is or don't use it, please ignore this file. | ||||
| # | ||||
| # This shell.nix contains all dependencies require to create a venv and pip install -r requirements.txt. | ||||
| # | ||||
| # Please check shell-static.nix for running ./manage.py collectstatics. | ||||
| { pkgs ? import <nixpkgs> {} }: | ||||
| pkgs.mkShell { | ||||
|   buildInputs = with pkgs; [ | ||||
|     python39 | ||||
|     python39Packages.pip | ||||
|     python39Packages.setuptools | ||||
|     gettext | ||||
|  | ||||
|   ]; | ||||
|   shellHook = '' | ||||
|     # Tells pip to put packages into $PIP_PREFIX instead of the usual locations. | ||||
|     # See https://pip.pypa.io/en/stable/user_guide/#environment-variables. | ||||
|     export PIP_PREFIX=$(pwd)/_build/pip_packages | ||||
|     export PYTHONPATH="$PIP_PREFIX/${pkgs.python39.sitePackages}:$PYTHONPATH" | ||||
|     export PATH="$PIP_PREFIX/bin:$PATH" | ||||
|     unset SOURCE_DATE_EPOCH | ||||
|   ''; | ||||
| } | ||||
							
								
								
									
										9
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								tox.ini
									
									
									
									
									
								
							| @@ -1,13 +1,13 @@ | ||||
| [tox] | ||||
| envlist = | ||||
|     # Ubuntu 22.04 Python | ||||
|     py310-django52 | ||||
|     py310-django42 | ||||
|  | ||||
|     # Debian Bookworm Python | ||||
|     py311-django52 | ||||
|     py311-django42 | ||||
|  | ||||
|     # Ubuntu 24.04 Python | ||||
|     py312-django52 | ||||
|     py312-django42 | ||||
|  | ||||
|     linters | ||||
| skipsdist = True | ||||
| @@ -32,7 +32,8 @@ deps = | ||||
|     pep8-naming | ||||
|     pyflakes | ||||
| commands = | ||||
|     flake8 apps --extend-exclude apps/scripts | ||||
|     flake8 apps --extend-exclude apps/scripts,apps/wrapped/management/commands | ||||
|     flake8 apps/wrapped/management/commands --extend-ignore=C901 | ||||
|  | ||||
| [flake8] | ||||
| ignore = W503, I100, I101, B019 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user