From bddb88d97fe689134df7bd7ca37e95d8c01631d0 Mon Sep 17 00:00:00 2001 From: tleb Date: Fri, 18 Oct 2019 18:13:53 +0200 Subject: [PATCH] Comment UV API and fix little bugs --- api/views/__init__.py | 1 + api/views/api.py | 99 +-------- api/views/uv.py | 120 +++++++++++ locale/fr/LC_MESSAGES/django.po | 226 +++++++++++--------- pedagogy/templates/pedagogy/uv_create.jinja | 6 +- 5 files changed, 247 insertions(+), 205 deletions(-) create mode 100644 api/views/uv.py diff --git a/api/views/__init__.py b/api/views/__init__.py index 3d731738..21aacd98 100644 --- a/api/views/__init__.py +++ b/api/views/__init__.py @@ -77,3 +77,4 @@ from .user import * from .club import * from .group import * from .launderette import * +from .uv import * diff --git a/api/views/api.py b/api/views/api.py index f70517ce..82d9942b 100644 --- a/api/views/api.py +++ b/api/views/api.py @@ -24,15 +24,9 @@ from rest_framework.response import Response from rest_framework.decorators import api_view, renderer_classes -from rest_framework.renderers import StaticHTMLRenderer, JSONRenderer -from rest_framework.views import APIView -from django.core.exceptions import PermissionDenied -from rest_framework import serializers -import urllib.request -import json +from rest_framework.renderers import StaticHTMLRenderer from core.templatetags.renderer import markdown -from pedagogy.views import CanCreateUVFunctionMixin @api_view(["POST"]) @@ -46,94 +40,3 @@ def RenderMarkdown(request): except: data = "Error" return Response(data) - - -@api_view(["GET"]) -@renderer_classes((JSONRenderer,)) -def uv_endpoint(request): - if not request.user.is_authenticated or not CanCreateUVFunctionMixin.can_create_uv( - request.user - ): - raise PermissionDenied - - lang = "fr" - - params = request.query_params - if "year" not in params or "code" not in params: - raise serializers.ValidationError("Missing query parameter") - - uvs_url = "https://extranet1.utbm.fr/gpedago/api/guide/uvs/{lang}/{year}" - response = urllib.request.urlopen(uvs_url.format(lang=lang, year=params["year"])) - - uvs = json.loads(response.read().decode("utf-8")) - - try: - found = next(uv for uv in uvs if uv["code"] == params["code"]) - except StopIteration: - # shouldn't be 404, rather something like 204 - return Response(status=404) - - uv_url = "https://extranet1.utbm.fr/gpedago/api/guide/uv/{lang}/{year}/{code}/{formation}" - response = urllib.request.urlopen( - uv_url.format( - lang=lang, - year=params["year"], - code=params["code"], - formation=found["codeFormation"], - ) - ) - - uv = json.loads(response.read().decode("utf-8")) - - res = {} - - res["credit_type"] = found["codeCategorie"] - - semesters = { - (True, True): "AUTUMN_AND_SPRING", - (True, False): "AUTOMN", - (False, True): "SPRING", - } - res["semester"] = semesters.get( - (found["ouvertAutomne"], found["ouvertPrintemps"]), "CLOSED" - ) - - langs = {"es": "SP", "en": "EN", "de": "DE"} - res["language"] = langs.get(uv["codeLangue"], "FR") - - if uv["departement"] == "Pôle Humanités": - res["department"] = "HUMA" - else: - departments = { - "AL": "IMSI", - "AE": "EE", - "GI": "GI", - "GC": "EE", - "GM": "MC", - "TC": "TC", - "GP": "IMSI", - "ED": "EDIM", - "AI": "GI", - "AM": "MC", - } - res["department"] = departments.get(uv["codeFormation"], "NA") - - res["credits"] = uv["creditsEcts"] - - activities = ("CM", "TD", "TP", "THE", "TE") - for activity in activities: - res["hours_{}".format(activity)] = 0 - for activity in uv["activites"]: - if activity["code"] in activities: - res["hours_{}".format(activity["code"])] += activity["nbh"] // 60 - - res["manager"] = uv["automne"]["responsable"] - - res["title"] = uv["libelle"] - - res["objectives"] = uv["objectifs"] - res["program"] = uv["programme"] - res["skills"] = uv["acquisitionCompetences"] - res["key_concepts"] = uv["acquisitionNotions"] - - return Response(res) diff --git a/api/views/uv.py b/api/views/uv.py new file mode 100644 index 00000000..940aa3a7 --- /dev/null +++ b/api/views/uv.py @@ -0,0 +1,120 @@ +from rest_framework.response import Response +from rest_framework.decorators import api_view, renderer_classes +from rest_framework.renderers import JSONRenderer +from django.core.exceptions import PermissionDenied +from rest_framework import serializers +import urllib.request +import json + +from pedagogy.views import CanCreateUVFunctionMixin + + +@api_view(["GET"]) +@renderer_classes((JSONRenderer,)) +def uv_endpoint(request): + # is authenticated and has the right to create an UV + if not request.user.is_authenticated or not CanCreateUVFunctionMixin.can_create_uv( + request.user + ): + raise PermissionDenied + + params = request.query_params + if "year" not in params or "code" not in params: + raise serializers.ValidationError("Missing query parameter") + + short_uv, full_uv = find_uv("fr", params["year"], params["code"]) + if short_uv is None or full_uv is None: + return Response(status=204) + + return Response(make_clean_uv(short_uv, full_uv)) + + +def find_uv(lang, year, code): + """ + Uses the UTBM API to find a UV. + short_uv is the UV entry in the UV list. It is returned as it contains + information which are not in full_uv. + full_uv is the detailed representation of an UV. + """ + # query the UV list + uvs_url = "https://extranet1.utbm.fr/gpedago/api/guide/uvs/{lang}/{year}" + response = urllib.request.urlopen(uvs_url.format(lang=lang, year=year)) + uvs = json.loads(response.read().decode("utf-8")) + + try: + # find the first UV which matches the code + short_uv = next(uv for uv in uvs if uv["code"] == code) + except StopIteration: + return (None, None) + + # get detailed information about the UV + uv_url = "https://extranet1.utbm.fr/gpedago/api/guide/uv/{lang}/{year}/{code}/{formation}" + response = urllib.request.urlopen( + uv_url.format( + lang=lang, year=year, code=code, formation=short_uv["codeFormation"] + ) + ) + full_uv = json.loads(response.read().decode("utf-8")) + + return (short_uv, full_uv) + + +def make_clean_uv(short_uv, full_uv): + """ + Cleans the data up so that it corresponds to our data representation. + """ + res = {} + + res["credit_type"] = short_uv["codeCategorie"] + + # probably wrong on a few UVs as we pick the first UV we find but + # availability depends on the formation + semesters = { + (True, True): "AUTUMN_AND_SPRING", + (True, False): "AUTUMN", + (False, True): "SPRING", + } + res["semester"] = semesters.get( + (short_uv["ouvertAutomne"], short_uv["ouvertPrintemps"]), "CLOSED" + ) + + langs = {"es": "SP", "en": "EN", "de": "DE"} + res["language"] = langs.get(full_uv["codeLangue"], "FR") + + if full_uv["departement"] == "Pôle Humanités": + res["department"] = "HUMA" + else: + departments = { + "AL": "IMSI", + "AE": "EE", + "GI": "GI", + "GC": "EE", + "GM": "MC", + "TC": "TC", + "GP": "IMSI", + "ED": "EDIM", + "AI": "GI", + "AM": "MC", + } + res["department"] = departments.get(full_uv["codeFormation"], "NA") + + res["credits"] = full_uv["creditsEcts"] + + activities = ("CM", "TD", "TP", "THE", "TE") + for activity in activities: + res["hours_{}".format(activity)] = 0 + for activity in full_uv["activites"]: + if activity["code"] in activities: + res["hours_{}".format(activity["code"])] += activity["nbh"] // 60 + + # wrong if the manager changes depending on the semester + res["manager"] = full_uv["automne"]["responsable"] + + res["title"] = full_uv["libelle"] + + res["objectives"] = full_uv["objectifs"] + res["program"] = full_uv["programme"] + res["skills"] = full_uv["acquisitionCompetences"] + res["key_concepts"] = full_uv["acquisitionNotions"] + + return res diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index bb935af5..473bbcc9 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-10-13 17:21+0200\n" +"POT-Creation-Date: 2019-10-18 18:04+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -88,12 +88,12 @@ msgstr "Compte club" msgid "%(club_account)s on %(bank_account)s" msgstr "%(club_account)s sur %(bank_account)s" -#: accounting/models.py:214 club/models.py:281 counter/models.py:616 +#: accounting/models.py:214 club/models.py:281 counter/models.py:632 #: election/models.py:18 launderette/models.py:194 msgid "start date" msgstr "date de début" -#: accounting/models.py:215 club/models.py:282 counter/models.py:617 +#: accounting/models.py:215 club/models.py:282 counter/models.py:633 #: election/models.py:19 msgid "end date" msgstr "date de fin" @@ -129,13 +129,13 @@ msgstr "classeur" #: accounting/models.py:290 core/models.py:825 core/models.py:1363 #: core/models.py:1411 core/models.py:1440 counter/models.py:364 -#: counter/models.py:457 counter/models.py:646 eboutic/models.py:46 +#: counter/models.py:457 counter/models.py:662 eboutic/models.py:46 #: eboutic/models.py:93 forum/models.py:311 forum/models.py:408 #: stock/models.py:104 msgid "date" msgstr "date" -#: accounting/models.py:291 counter/models.py:123 counter/models.py:647 +#: accounting/models.py:291 counter/models.py:123 counter/models.py:663 #: pedagogy/models.py:219 stock/models.py:107 msgid "comment" msgstr "commentaire" @@ -654,7 +654,7 @@ msgid "Target" msgstr "Cible" #: accounting/templates/accounting/journal_details.jinja:38 -#: core/views/forms.py:112 +#: core/views/forms.py:94 msgid "Code" msgstr "Code" @@ -1046,7 +1046,7 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs" msgid "A club with that unix_name already exists" msgstr "Un club avec ce nom UNIX existe déjà." -#: club/models.py:267 counter/models.py:607 counter/models.py:637 +#: club/models.py:267 counter/models.py:623 counter/models.py:653 #: eboutic/models.py:42 eboutic/models.py:89 election/models.py:192 #: launderette/models.py:145 launderette/models.py:213 sas/models.py:244 #: trombi/models.py:213 @@ -1155,7 +1155,7 @@ msgid "There are no members in this club." msgstr "Il n'y a pas de membres dans ce club." #: club/templates/club/club_members.jinja:78 -#: core/templates/core/file_detail.jinja:19 core/views/forms.py:355 +#: core/templates/core/file_detail.jinja:19 core/views/forms.py:337 #: launderette/views.py:226 trombi/templates/trombi/detail.jinja:19 msgid "Add" msgstr "Ajouter" @@ -1363,7 +1363,7 @@ msgstr "Anciens membres" msgid "History" msgstr "Historique" -#: club/views.py:115 core/templates/core/base.jinja:119 core/views/user.py:219 +#: club/views.py:115 core/templates/core/base.jinja:118 core/views/user.py:219 #: sas/templates/sas/picture.jinja:95 trombi/views.py:61 msgid "Tools" msgstr "Outils" @@ -1651,7 +1651,7 @@ msgid "Calls to moderate" msgstr "Appels à modérer" #: com/templates/com/news_admin_list.jinja:242 -#: core/templates/core/base.jinja:171 +#: core/templates/core/base.jinja:170 msgid "Events" msgstr "Événements" @@ -1930,23 +1930,23 @@ msgstr "Jusqu'à" msgid "Automoderation" msgstr "Automodération" -#: com/views.py:227 com/views.py:231 com/views.py:241 +#: com/views.py:227 com/views.py:231 com/views.py:245 msgid "This field is required." msgstr "Ce champ est obligatoire." -#: com/views.py:237 +#: com/views.py:241 msgid "You crazy? You can not finish an event before starting it." msgstr "T'es fou? Un événement ne peut pas finir avant même de commencer." -#: com/views.py:466 +#: com/views.py:470 msgid "Delete and save to regenerate" msgstr "Supprimer et sauver pour regénérer" -#: com/views.py:481 +#: com/views.py:485 msgid "Weekmail of the " msgstr "Weekmail du " -#: com/views.py:591 +#: com/views.py:595 msgid "" "You must be a board member of the selected club to post in the Weekmail." msgstr "" @@ -2372,24 +2372,24 @@ msgstr "500, Erreur Serveur" msgid "Welcome!" msgstr "Bienvenue !" -#: core/templates/core/base.jinja:49 +#: core/templates/core/base.jinja:48 msgid "Username" msgstr "Nom d'utilisateur" -#: core/templates/core/base.jinja:51 +#: core/templates/core/base.jinja:50 msgid "Password" msgstr "Mot de passe" -#: core/templates/core/base.jinja:53 core/templates/core/login.jinja:4 +#: core/templates/core/base.jinja:52 core/templates/core/login.jinja:4 #: core/templates/core/password_reset_complete.jinja:5 msgid "Login" msgstr "Connexion" -#: core/templates/core/base.jinja:55 core/templates/core/register.jinja:18 +#: core/templates/core/base.jinja:54 core/templates/core/register.jinja:18 msgid "Register" msgstr "S'enregister" -#: core/templates/core/base.jinja:81 core/templates/core/base.jinja:82 +#: core/templates/core/base.jinja:80 core/templates/core/base.jinja:81 #: forum/templates/forum/macros.jinja:171 #: forum/templates/forum/macros.jinja:175 #: matmat/templates/matmat/search_form.jinja:37 @@ -2399,64 +2399,64 @@ msgstr "S'enregister" msgid "Search" msgstr "Recherche" -#: core/templates/core/base.jinja:108 +#: core/templates/core/base.jinja:107 msgid "View more" msgstr "Voir plus" -#: core/templates/core/base.jinja:112 +#: core/templates/core/base.jinja:111 #: forum/templates/forum/last_unread.jinja:17 msgid "Mark all as read" msgstr "Marquer tout commme lu" -#: core/templates/core/base.jinja:122 +#: core/templates/core/base.jinja:121 msgid "Logout" msgstr "Déconnexion" -#: core/templates/core/base.jinja:155 +#: core/templates/core/base.jinja:154 msgid "Main" msgstr "Accueil" -#: core/templates/core/base.jinja:157 +#: core/templates/core/base.jinja:156 msgid "Associations & Clubs" msgstr "Associations & Clubs" -#: core/templates/core/base.jinja:161 +#: core/templates/core/base.jinja:160 msgid "AE" msgstr "L'AE" -#: core/templates/core/base.jinja:162 +#: core/templates/core/base.jinja:161 msgid "AE's clubs" msgstr "Les clubs de L'AE" -#: core/templates/core/base.jinja:163 +#: core/templates/core/base.jinja:162 msgid "BdF" msgstr "Le BdF" -#: core/templates/core/base.jinja:164 +#: core/templates/core/base.jinja:163 msgid "BDS" msgstr "Le BDS" -#: core/templates/core/base.jinja:165 +#: core/templates/core/base.jinja:164 msgid "CETU" msgstr "Le CETU" -#: core/templates/core/base.jinja:166 +#: core/templates/core/base.jinja:165 msgid "Doceo" msgstr "Doceo" -#: core/templates/core/base.jinja:167 +#: core/templates/core/base.jinja:166 msgid "Positions" msgstr "Postes à pourvoir" -#: core/templates/core/base.jinja:175 +#: core/templates/core/base.jinja:174 msgid "Calendar" msgstr "Calendrier" -#: core/templates/core/base.jinja:176 +#: core/templates/core/base.jinja:175 msgid "Big event" msgstr "Grandes Activités" -#: core/templates/core/base.jinja:179 +#: core/templates/core/base.jinja:178 #: forum/templates/forum/favorite_topics.jinja:14 #: forum/templates/forum/last_unread.jinja:14 #: forum/templates/forum/macros.jinja:90 forum/templates/forum/main.jinja:6 @@ -2465,11 +2465,11 @@ msgstr "Grandes Activités" msgid "Forum" msgstr "Forum" -#: core/templates/core/base.jinja:180 +#: core/templates/core/base.jinja:179 msgid "Gallery" msgstr "Photos" -#: core/templates/core/base.jinja:181 counter/models.py:223 +#: core/templates/core/base.jinja:180 counter/models.py:223 #: counter/templates/counter/counter_list.jinja:11 #: eboutic/templates/eboutic/eboutic_main.jinja:4 #: eboutic/templates/eboutic/eboutic_main.jinja:24 @@ -2479,75 +2479,75 @@ msgstr "Photos" msgid "Eboutic" msgstr "Eboutic" -#: core/templates/core/base.jinja:183 +#: core/templates/core/base.jinja:182 msgid "Services" msgstr "Services" -#: core/templates/core/base.jinja:187 +#: core/templates/core/base.jinja:186 msgid "Matmatronch" msgstr "Matmatronch" -#: core/templates/core/base.jinja:188 launderette/models.py:47 +#: core/templates/core/base.jinja:187 launderette/models.py:47 #: launderette/templates/launderette/launderette_book.jinja:5 #: launderette/templates/launderette/launderette_book_choose.jinja:4 #: launderette/templates/launderette/launderette_main.jinja:4 msgid "Launderette" msgstr "Laverie" -#: core/templates/core/base.jinja:189 core/templates/core/file.jinja:20 +#: core/templates/core/base.jinja:188 core/templates/core/file.jinja:20 #: core/views/files.py:84 msgid "Files" msgstr "Fichiers" -#: core/templates/core/base.jinja:190 core/templates/core/user_tools.jinja:108 +#: core/templates/core/base.jinja:189 core/templates/core/user_tools.jinja:108 msgid "Pedagogy" msgstr "Pédagogie" -#: core/templates/core/base.jinja:194 +#: core/templates/core/base.jinja:193 msgid "My Benefits" msgstr "Mes Avantages" -#: core/templates/core/base.jinja:198 +#: core/templates/core/base.jinja:197 msgid "Sponsors" msgstr "Partenaires" -#: core/templates/core/base.jinja:199 +#: core/templates/core/base.jinja:198 msgid "Subscriber benefits" msgstr "Les avantages cotisants" -#: core/templates/core/base.jinja:203 +#: core/templates/core/base.jinja:202 msgid "Help" msgstr "Aide" -#: core/templates/core/base.jinja:207 +#: core/templates/core/base.jinja:206 msgid "FAQ" msgstr "FAQ" -#: core/templates/core/base.jinja:208 core/templates/core/base.jinja:250 +#: core/templates/core/base.jinja:207 core/templates/core/base.jinja:249 msgid "Contacts" msgstr "Contacts" -#: core/templates/core/base.jinja:209 +#: core/templates/core/base.jinja:208 msgid "Wiki" msgstr "Wiki" -#: core/templates/core/base.jinja:251 +#: core/templates/core/base.jinja:250 msgid "Legal notices" msgstr "Mentions légales" -#: core/templates/core/base.jinja:252 +#: core/templates/core/base.jinja:251 msgid "Intellectual property" msgstr "Propriété intellectuelle" -#: core/templates/core/base.jinja:253 +#: core/templates/core/base.jinja:252 msgid "Help & Documentation" msgstr "Aide & Documentation" -#: core/templates/core/base.jinja:254 +#: core/templates/core/base.jinja:253 msgid "R&D" msgstr "R&D" -#: core/templates/core/base.jinja:256 +#: core/templates/core/base.jinja:255 msgid "Site made by good people" msgstr "Site réalisé par des gens bons" @@ -2688,6 +2688,7 @@ msgstr "Éditer le groupe" #: core/templates/core/group_edit.jinja:9 #: core/templates/core/user_edit.jinja:37 #: core/templates/core/user_group.jinja:8 +#: pedagogy/templates/pedagogy/uv_create.jinja:36 msgid "Update" msgstr "Mettre à jour" @@ -3520,7 +3521,7 @@ msgstr "Ajouter un nouveau dossier" msgid "Error creating folder %(folder_name)s: %(msg)s" msgstr "Erreur de création du dossier %(folder_name)s : %(msg)s" -#: core/views/files.py:121 core/views/forms.py:323 core/views/forms.py:330 +#: core/views/files.py:121 core/views/forms.py:305 core/views/forms.py:312 #: sas/views.py:94 #, python-format msgid "Error uploading file %(file_name)s: %(msg)s" @@ -3530,91 +3531,91 @@ msgstr "Erreur d'envoi du fichier %(file_name)s : %(msg)s" msgid "Apply rights recursively" msgstr "Appliquer les droits récursivement" -#: core/views/forms.py:105 +#: core/views/forms.py:87 msgid "Heading" msgstr "Titre" -#: core/views/forms.py:106 +#: core/views/forms.py:88 msgid "Italic" msgstr "Italique" -#: core/views/forms.py:107 +#: core/views/forms.py:89 msgid "Bold" msgstr "Gras" -#: core/views/forms.py:108 +#: core/views/forms.py:90 msgid "Strikethrough" msgstr "Barré" -#: core/views/forms.py:109 +#: core/views/forms.py:91 msgid "Underline" msgstr "Souligné" -#: core/views/forms.py:110 +#: core/views/forms.py:92 msgid "Superscript" msgstr "Exposant" -#: core/views/forms.py:111 +#: core/views/forms.py:93 msgid "Subscript" msgstr "Indice" -#: core/views/forms.py:113 +#: core/views/forms.py:95 msgid "Quote" msgstr "Citation" -#: core/views/forms.py:114 +#: core/views/forms.py:96 msgid "Unordered list" msgstr "Liste non ordonnée" -#: core/views/forms.py:115 +#: core/views/forms.py:97 msgid "Ordered list" msgstr "Liste ordonnée" -#: core/views/forms.py:116 +#: core/views/forms.py:98 msgid "Insert image" msgstr "Insérer image" -#: core/views/forms.py:117 +#: core/views/forms.py:99 msgid "Insert link" msgstr "Insérer lien" -#: core/views/forms.py:118 +#: core/views/forms.py:100 msgid "Insert table" msgstr "Insérer tableau" -#: core/views/forms.py:119 +#: core/views/forms.py:101 msgid "Clean block" msgstr "Nettoyer bloc" -#: core/views/forms.py:120 +#: core/views/forms.py:102 msgid "Toggle preview" msgstr "Activer la prévisualisation" -#: core/views/forms.py:121 +#: core/views/forms.py:103 msgid "Toggle side by side" msgstr "Activer la vue côte à côte" -#: core/views/forms.py:122 +#: core/views/forms.py:104 msgid "Toggle fullscreen" msgstr "Activer le plein écran" -#: core/views/forms.py:123 +#: core/views/forms.py:105 msgid "Markdown guide" msgstr "Guide markdown" -#: core/views/forms.py:139 core/views/forms.py:147 +#: core/views/forms.py:121 core/views/forms.py:129 msgid "Choose file" msgstr "Choisir un fichier" -#: core/views/forms.py:163 core/views/forms.py:171 +#: core/views/forms.py:145 core/views/forms.py:153 msgid "Choose user" msgstr "Choisir un utilisateur" -#: core/views/forms.py:203 +#: core/views/forms.py:185 msgid "Username, email, or account number" msgstr "Nom d'utilisateur, email, ou numéro de compte AE" -#: core/views/forms.py:269 +#: core/views/forms.py:251 msgid "" "Profile: you need to be visible on the picture, in order to be recognized (e." "g. by the barmen)" @@ -3622,36 +3623,36 @@ msgstr "" "Photo de profil: vous devez être visible sur la photo afin d'être reconnu " "(par exemple par les barmen)" -#: core/views/forms.py:271 +#: core/views/forms.py:253 msgid "Avatar: used on the forum" msgstr "Avatar : utilisé sur le forum" -#: core/views/forms.py:272 +#: core/views/forms.py:254 msgid "Scrub: let other know how your scrub looks like!" msgstr "Blouse : montrez aux autres à quoi ressemble votre blouse !" -#: core/views/forms.py:334 +#: core/views/forms.py:316 msgid "Bad image format, only jpeg, png, and gif are accepted" msgstr "Mauvais format d'image, seuls les jpeg, png, et gif sont acceptés" -#: core/views/forms.py:354 +#: core/views/forms.py:336 msgid "Godfather" msgstr "Parrain" -#: core/views/forms.py:354 +#: core/views/forms.py:336 msgid "Godchild" msgstr "Fillot" -#: core/views/forms.py:358 counter/views.py:154 trombi/views.py:156 +#: core/views/forms.py:340 counter/views.py:154 trombi/views.py:156 msgid "Select user" msgstr "Choisir un utilisateur" -#: core/views/forms.py:371 core/views/forms.py:389 election/models.py:24 +#: core/views/forms.py:353 core/views/forms.py:371 election/models.py:24 #: election/views.py:154 msgid "edit groups" msgstr "groupe d'édition" -#: core/views/forms.py:374 core/views/forms.py:392 election/models.py:31 +#: core/views/forms.py:356 core/views/forms.py:374 election/models.py:31 #: election/views.py:157 msgid "view groups" msgstr "groupe de vue" @@ -3742,7 +3743,7 @@ msgstr "groupe d'achat" msgid "archived" msgstr "archivé" -#: counter/models.py:185 counter/models.py:738 +#: counter/models.py:185 counter/models.py:754 msgid "product" msgstr "produit" @@ -3770,7 +3771,7 @@ msgstr "vendeurs" msgid "token" msgstr "jeton" -#: counter/models.py:237 counter/models.py:613 counter/models.py:643 +#: counter/models.py:237 counter/models.py:629 counter/models.py:659 #: launderette/models.py:41 stock/models.py:43 msgid "counter" msgstr "comptoir" @@ -3791,7 +3792,7 @@ msgstr "rechargement" msgid "unit price" msgstr "prix unitaire" -#: counter/models.py:442 counter/models.py:723 eboutic/models.py:155 +#: counter/models.py:442 counter/models.py:739 eboutic/models.py:155 msgid "quantity" msgstr "quantité" @@ -3808,16 +3809,16 @@ msgstr "Carte bancaire" msgid "selling" msgstr "vente" -#: counter/models.py:490 +#: counter/models.py:494 msgid "Unknown event" msgstr "Événement inconnu" -#: counter/models.py:491 +#: counter/models.py:495 #, python-format msgid "Eticket bought for the event %(event)s" msgstr "Eticket acheté pour l'événement %(event)s" -#: counter/models.py:493 counter/models.py:508 +#: counter/models.py:497 counter/models.py:520 #, python-format msgid "" "You bought an eticket for the event %(event)s.\n" @@ -3829,59 +3830,59 @@ msgstr "" "Vous pouvez également retrouver tous vos e-tickets sur votre page de compte " "%(url)s." -#: counter/models.py:618 +#: counter/models.py:634 msgid "last activity date" msgstr "dernière activité" -#: counter/models.py:621 +#: counter/models.py:637 msgid "permanency" msgstr "permanence" -#: counter/models.py:648 +#: counter/models.py:664 msgid "emptied" msgstr "coffre vidée" -#: counter/models.py:651 +#: counter/models.py:667 msgid "cash register summary" msgstr "relevé de caisse" -#: counter/models.py:719 +#: counter/models.py:735 msgid "cash summary" msgstr "relevé" -#: counter/models.py:722 +#: counter/models.py:738 msgid "value" msgstr "valeur" -#: counter/models.py:724 +#: counter/models.py:740 msgid "check" msgstr "chèque" -#: counter/models.py:727 +#: counter/models.py:743 msgid "cash register summary item" msgstr "élément de relevé de caisse" -#: counter/models.py:742 +#: counter/models.py:758 msgid "banner" msgstr "bannière" -#: counter/models.py:744 +#: counter/models.py:760 msgid "event date" msgstr "date de l'événement" -#: counter/models.py:746 +#: counter/models.py:762 msgid "event title" msgstr "titre de l'événement" -#: counter/models.py:748 +#: counter/models.py:764 msgid "secret" msgstr "secret" -#: counter/models.py:804 +#: counter/models.py:820 msgid "uid" msgstr "uid" -#: counter/models.py:809 +#: counter/models.py:825 msgid "student cards" msgstr "cartes étudiante" @@ -4291,7 +4292,7 @@ msgstr "Montant du chèque" msgid "Check quantity" msgstr "Nombre de chèque" -#: counter/views.py:1802 +#: counter/views.py:1806 msgid "people(s)" msgstr "personne(s)" @@ -4987,6 +4988,19 @@ msgstr "Supprimer commentaire" msgid "Delete report" msgstr "Supprimer signalement" +#: pedagogy/templates/pedagogy/uv_create.jinja:4 +#: pedagogy/templates/pedagogy/uv_create.jinja:8 +#, fuzzy +#| msgid "Edit" +msgid "Edit UV" +msgstr "Éditer" + +#: pedagogy/templates/pedagogy/uv_create.jinja:57 +#, fuzzy +#| msgid "Unknown event" +msgid "Unknown UV code" +msgstr "Code d'UV inconnu" + #: pedagogy/templates/pedagogy/uv_detail.jinja:6 msgid "UV Details" msgstr "Détails d'UV" diff --git a/pedagogy/templates/pedagogy/uv_create.jinja b/pedagogy/templates/pedagogy/uv_create.jinja index a648799b..7f00598c 100644 --- a/pedagogy/templates/pedagogy/uv_create.jinja +++ b/pedagogy/templates/pedagogy/uv_create.jinja @@ -52,7 +52,11 @@ year-- } const url = "{{ url('api:uv_endpoint') }}?year=" + year + "&code=" + codeInput.value - $.getJSON(url, function(data) { + $.getJSON(url, function(data, _, xhr) { + if (xhr.status != 200) { + alert('{% trans %}Unknown UV code{% endtrans %}') + return + } for (let key in data) { if (data.hasOwnProperty(key)) { const el = document.querySelector('[name="' + key + '"]')