Comment UV API and fix little bugs

This commit is contained in:
tleb 2019-10-18 18:13:53 +02:00
parent dbe44a9c1c
commit bddb88d97f
5 changed files with 247 additions and 205 deletions

View File

@ -77,3 +77,4 @@ from .user import *
from .club import * from .club import *
from .group import * from .group import *
from .launderette import * from .launderette import *
from .uv import *

View File

@ -24,15 +24,9 @@
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import api_view, renderer_classes from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import StaticHTMLRenderer, JSONRenderer from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.views import APIView
from django.core.exceptions import PermissionDenied
from rest_framework import serializers
import urllib.request
import json
from core.templatetags.renderer import markdown from core.templatetags.renderer import markdown
from pedagogy.views import CanCreateUVFunctionMixin
@api_view(["POST"]) @api_view(["POST"])
@ -46,94 +40,3 @@ def RenderMarkdown(request):
except: except:
data = "Error" data = "Error"
return Response(data) 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)

120
api/views/uv.py Normal file
View File

@ -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

View File

@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "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" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Skia <skia@libskia.so>\n" "Last-Translator: Skia <skia@libskia.so>\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@ -88,12 +88,12 @@ msgstr "Compte club"
msgid "%(club_account)s on %(bank_account)s" msgid "%(club_account)s on %(bank_account)s"
msgstr "%(club_account)s sur %(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 #: election/models.py:18 launderette/models.py:194
msgid "start date" msgid "start date"
msgstr "date de début" 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 #: election/models.py:19
msgid "end date" msgid "end date"
msgstr "date de fin" msgstr "date de fin"
@ -129,13 +129,13 @@ msgstr "classeur"
#: accounting/models.py:290 core/models.py:825 core/models.py:1363 #: accounting/models.py:290 core/models.py:825 core/models.py:1363
#: core/models.py:1411 core/models.py:1440 counter/models.py:364 #: 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 #: eboutic/models.py:93 forum/models.py:311 forum/models.py:408
#: stock/models.py:104 #: stock/models.py:104
msgid "date" msgid "date"
msgstr "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 #: pedagogy/models.py:219 stock/models.py:107
msgid "comment" msgid "comment"
msgstr "commentaire" msgstr "commentaire"
@ -654,7 +654,7 @@ msgid "Target"
msgstr "Cible" msgstr "Cible"
#: accounting/templates/accounting/journal_details.jinja:38 #: accounting/templates/accounting/journal_details.jinja:38
#: core/views/forms.py:112 #: core/views/forms.py:94
msgid "Code" msgid "Code"
msgstr "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" msgid "A club with that unix_name already exists"
msgstr "Un club avec ce nom UNIX existe déjà." 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 #: eboutic/models.py:42 eboutic/models.py:89 election/models.py:192
#: launderette/models.py:145 launderette/models.py:213 sas/models.py:244 #: launderette/models.py:145 launderette/models.py:213 sas/models.py:244
#: trombi/models.py:213 #: 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." msgstr "Il n'y a pas de membres dans ce club."
#: club/templates/club/club_members.jinja:78 #: 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 #: launderette/views.py:226 trombi/templates/trombi/detail.jinja:19
msgid "Add" msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
@ -1363,7 +1363,7 @@ msgstr "Anciens membres"
msgid "History" msgid "History"
msgstr "Historique" 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 #: sas/templates/sas/picture.jinja:95 trombi/views.py:61
msgid "Tools" msgid "Tools"
msgstr "Outils" msgstr "Outils"
@ -1651,7 +1651,7 @@ msgid "Calls to moderate"
msgstr "Appels à modérer" msgstr "Appels à modérer"
#: com/templates/com/news_admin_list.jinja:242 #: com/templates/com/news_admin_list.jinja:242
#: core/templates/core/base.jinja:171 #: core/templates/core/base.jinja:170
msgid "Events" msgid "Events"
msgstr "Événements" msgstr "Événements"
@ -1930,23 +1930,23 @@ msgstr "Jusqu'à"
msgid "Automoderation" msgid "Automoderation"
msgstr "Automodération" 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." msgid "This field is required."
msgstr "Ce champ est obligatoire." 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." 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." 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" msgid "Delete and save to regenerate"
msgstr "Supprimer et sauver pour regénérer" msgstr "Supprimer et sauver pour regénérer"
#: com/views.py:481 #: com/views.py:485
msgid "Weekmail of the " msgid "Weekmail of the "
msgstr "Weekmail du " msgstr "Weekmail du "
#: com/views.py:591 #: com/views.py:595
msgid "" msgid ""
"You must be a board member of the selected club to post in the Weekmail." "You must be a board member of the selected club to post in the Weekmail."
msgstr "" msgstr ""
@ -2372,24 +2372,24 @@ msgstr "500, Erreur Serveur"
msgid "Welcome!" msgid "Welcome!"
msgstr "Bienvenue !" msgstr "Bienvenue !"
#: core/templates/core/base.jinja:49 #: core/templates/core/base.jinja:48
msgid "Username" msgid "Username"
msgstr "Nom d'utilisateur" msgstr "Nom d'utilisateur"
#: core/templates/core/base.jinja:51 #: core/templates/core/base.jinja:50
msgid "Password" msgid "Password"
msgstr "Mot de passe" 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 #: core/templates/core/password_reset_complete.jinja:5
msgid "Login" msgid "Login"
msgstr "Connexion" 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" msgid "Register"
msgstr "S'enregister" 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:171
#: forum/templates/forum/macros.jinja:175 #: forum/templates/forum/macros.jinja:175
#: matmat/templates/matmat/search_form.jinja:37 #: matmat/templates/matmat/search_form.jinja:37
@ -2399,64 +2399,64 @@ msgstr "S'enregister"
msgid "Search" msgid "Search"
msgstr "Recherche" msgstr "Recherche"
#: core/templates/core/base.jinja:108 #: core/templates/core/base.jinja:107
msgid "View more" msgid "View more"
msgstr "Voir plus" msgstr "Voir plus"
#: core/templates/core/base.jinja:112 #: core/templates/core/base.jinja:111
#: forum/templates/forum/last_unread.jinja:17 #: forum/templates/forum/last_unread.jinja:17
msgid "Mark all as read" msgid "Mark all as read"
msgstr "Marquer tout commme lu" msgstr "Marquer tout commme lu"
#: core/templates/core/base.jinja:122 #: core/templates/core/base.jinja:121
msgid "Logout" msgid "Logout"
msgstr "Déconnexion" msgstr "Déconnexion"
#: core/templates/core/base.jinja:155 #: core/templates/core/base.jinja:154
msgid "Main" msgid "Main"
msgstr "Accueil" msgstr "Accueil"
#: core/templates/core/base.jinja:157 #: core/templates/core/base.jinja:156
msgid "Associations & Clubs" msgid "Associations & Clubs"
msgstr "Associations & Clubs" msgstr "Associations & Clubs"
#: core/templates/core/base.jinja:161 #: core/templates/core/base.jinja:160
msgid "AE" msgid "AE"
msgstr "L'AE" msgstr "L'AE"
#: core/templates/core/base.jinja:162 #: core/templates/core/base.jinja:161
msgid "AE's clubs" msgid "AE's clubs"
msgstr "Les clubs de L'AE" msgstr "Les clubs de L'AE"
#: core/templates/core/base.jinja:163 #: core/templates/core/base.jinja:162
msgid "BdF" msgid "BdF"
msgstr "Le BdF" msgstr "Le BdF"
#: core/templates/core/base.jinja:164 #: core/templates/core/base.jinja:163
msgid "BDS" msgid "BDS"
msgstr "Le BDS" msgstr "Le BDS"
#: core/templates/core/base.jinja:165 #: core/templates/core/base.jinja:164
msgid "CETU" msgid "CETU"
msgstr "Le CETU" msgstr "Le CETU"
#: core/templates/core/base.jinja:166 #: core/templates/core/base.jinja:165
msgid "Doceo" msgid "Doceo"
msgstr "Doceo" msgstr "Doceo"
#: core/templates/core/base.jinja:167 #: core/templates/core/base.jinja:166
msgid "Positions" msgid "Positions"
msgstr "Postes à pourvoir" msgstr "Postes à pourvoir"
#: core/templates/core/base.jinja:175 #: core/templates/core/base.jinja:174
msgid "Calendar" msgid "Calendar"
msgstr "Calendrier" msgstr "Calendrier"
#: core/templates/core/base.jinja:176 #: core/templates/core/base.jinja:175
msgid "Big event" msgid "Big event"
msgstr "Grandes Activités" 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/favorite_topics.jinja:14
#: forum/templates/forum/last_unread.jinja:14 #: forum/templates/forum/last_unread.jinja:14
#: forum/templates/forum/macros.jinja:90 forum/templates/forum/main.jinja:6 #: forum/templates/forum/macros.jinja:90 forum/templates/forum/main.jinja:6
@ -2465,11 +2465,11 @@ msgstr "Grandes Activités"
msgid "Forum" msgid "Forum"
msgstr "Forum" msgstr "Forum"
#: core/templates/core/base.jinja:180 #: core/templates/core/base.jinja:179
msgid "Gallery" msgid "Gallery"
msgstr "Photos" 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 #: counter/templates/counter/counter_list.jinja:11
#: eboutic/templates/eboutic/eboutic_main.jinja:4 #: eboutic/templates/eboutic/eboutic_main.jinja:4
#: eboutic/templates/eboutic/eboutic_main.jinja:24 #: eboutic/templates/eboutic/eboutic_main.jinja:24
@ -2479,75 +2479,75 @@ msgstr "Photos"
msgid "Eboutic" msgid "Eboutic"
msgstr "Eboutic" msgstr "Eboutic"
#: core/templates/core/base.jinja:183 #: core/templates/core/base.jinja:182
msgid "Services" msgid "Services"
msgstr "Services" msgstr "Services"
#: core/templates/core/base.jinja:187 #: core/templates/core/base.jinja:186
msgid "Matmatronch" msgid "Matmatronch"
msgstr "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.jinja:5
#: launderette/templates/launderette/launderette_book_choose.jinja:4 #: launderette/templates/launderette/launderette_book_choose.jinja:4
#: launderette/templates/launderette/launderette_main.jinja:4 #: launderette/templates/launderette/launderette_main.jinja:4
msgid "Launderette" msgid "Launderette"
msgstr "Laverie" 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 #: core/views/files.py:84
msgid "Files" msgid "Files"
msgstr "Fichiers" 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" msgid "Pedagogy"
msgstr "Pédagogie" msgstr "Pédagogie"
#: core/templates/core/base.jinja:194 #: core/templates/core/base.jinja:193
msgid "My Benefits" msgid "My Benefits"
msgstr "Mes Avantages" msgstr "Mes Avantages"
#: core/templates/core/base.jinja:198 #: core/templates/core/base.jinja:197
msgid "Sponsors" msgid "Sponsors"
msgstr "Partenaires" msgstr "Partenaires"
#: core/templates/core/base.jinja:199 #: core/templates/core/base.jinja:198
msgid "Subscriber benefits" msgid "Subscriber benefits"
msgstr "Les avantages cotisants" msgstr "Les avantages cotisants"
#: core/templates/core/base.jinja:203 #: core/templates/core/base.jinja:202
msgid "Help" msgid "Help"
msgstr "Aide" msgstr "Aide"
#: core/templates/core/base.jinja:207 #: core/templates/core/base.jinja:206
msgid "FAQ" msgid "FAQ"
msgstr "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" msgid "Contacts"
msgstr "Contacts" msgstr "Contacts"
#: core/templates/core/base.jinja:209 #: core/templates/core/base.jinja:208
msgid "Wiki" msgid "Wiki"
msgstr "Wiki" msgstr "Wiki"
#: core/templates/core/base.jinja:251 #: core/templates/core/base.jinja:250
msgid "Legal notices" msgid "Legal notices"
msgstr "Mentions légales" msgstr "Mentions légales"
#: core/templates/core/base.jinja:252 #: core/templates/core/base.jinja:251
msgid "Intellectual property" msgid "Intellectual property"
msgstr "Propriété intellectuelle" msgstr "Propriété intellectuelle"
#: core/templates/core/base.jinja:253 #: core/templates/core/base.jinja:252
msgid "Help & Documentation" msgid "Help & Documentation"
msgstr "Aide & Documentation" msgstr "Aide & Documentation"
#: core/templates/core/base.jinja:254 #: core/templates/core/base.jinja:253
msgid "R&D" msgid "R&D"
msgstr "R&D" msgstr "R&D"
#: core/templates/core/base.jinja:256 #: core/templates/core/base.jinja:255
msgid "Site made by good people" msgid "Site made by good people"
msgstr "Site réalisé par des gens bons" 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/group_edit.jinja:9
#: core/templates/core/user_edit.jinja:37 #: core/templates/core/user_edit.jinja:37
#: core/templates/core/user_group.jinja:8 #: core/templates/core/user_group.jinja:8
#: pedagogy/templates/pedagogy/uv_create.jinja:36
msgid "Update" msgid "Update"
msgstr "Mettre à jour" msgstr "Mettre à jour"
@ -3520,7 +3521,7 @@ msgstr "Ajouter un nouveau dossier"
msgid "Error creating folder %(folder_name)s: %(msg)s" msgid "Error creating folder %(folder_name)s: %(msg)s"
msgstr "Erreur de création du dossier %(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 #: sas/views.py:94
#, python-format #, python-format
msgid "Error uploading file %(file_name)s: %(msg)s" 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" msgid "Apply rights recursively"
msgstr "Appliquer les droits récursivement" msgstr "Appliquer les droits récursivement"
#: core/views/forms.py:105 #: core/views/forms.py:87
msgid "Heading" msgid "Heading"
msgstr "Titre" msgstr "Titre"
#: core/views/forms.py:106 #: core/views/forms.py:88
msgid "Italic" msgid "Italic"
msgstr "Italique" msgstr "Italique"
#: core/views/forms.py:107 #: core/views/forms.py:89
msgid "Bold" msgid "Bold"
msgstr "Gras" msgstr "Gras"
#: core/views/forms.py:108 #: core/views/forms.py:90
msgid "Strikethrough" msgid "Strikethrough"
msgstr "Barré" msgstr "Barré"
#: core/views/forms.py:109 #: core/views/forms.py:91
msgid "Underline" msgid "Underline"
msgstr "Souligné" msgstr "Souligné"
#: core/views/forms.py:110 #: core/views/forms.py:92
msgid "Superscript" msgid "Superscript"
msgstr "Exposant" msgstr "Exposant"
#: core/views/forms.py:111 #: core/views/forms.py:93
msgid "Subscript" msgid "Subscript"
msgstr "Indice" msgstr "Indice"
#: core/views/forms.py:113 #: core/views/forms.py:95
msgid "Quote" msgid "Quote"
msgstr "Citation" msgstr "Citation"
#: core/views/forms.py:114 #: core/views/forms.py:96
msgid "Unordered list" msgid "Unordered list"
msgstr "Liste non ordonnée" msgstr "Liste non ordonnée"
#: core/views/forms.py:115 #: core/views/forms.py:97
msgid "Ordered list" msgid "Ordered list"
msgstr "Liste ordonnée" msgstr "Liste ordonnée"
#: core/views/forms.py:116 #: core/views/forms.py:98
msgid "Insert image" msgid "Insert image"
msgstr "Insérer image" msgstr "Insérer image"
#: core/views/forms.py:117 #: core/views/forms.py:99
msgid "Insert link" msgid "Insert link"
msgstr "Insérer lien" msgstr "Insérer lien"
#: core/views/forms.py:118 #: core/views/forms.py:100
msgid "Insert table" msgid "Insert table"
msgstr "Insérer tableau" msgstr "Insérer tableau"
#: core/views/forms.py:119 #: core/views/forms.py:101
msgid "Clean block" msgid "Clean block"
msgstr "Nettoyer bloc" msgstr "Nettoyer bloc"
#: core/views/forms.py:120 #: core/views/forms.py:102
msgid "Toggle preview" msgid "Toggle preview"
msgstr "Activer la prévisualisation" msgstr "Activer la prévisualisation"
#: core/views/forms.py:121 #: core/views/forms.py:103
msgid "Toggle side by side" msgid "Toggle side by side"
msgstr "Activer la vue côte à côte" msgstr "Activer la vue côte à côte"
#: core/views/forms.py:122 #: core/views/forms.py:104
msgid "Toggle fullscreen" msgid "Toggle fullscreen"
msgstr "Activer le plein écran" msgstr "Activer le plein écran"
#: core/views/forms.py:123 #: core/views/forms.py:105
msgid "Markdown guide" msgid "Markdown guide"
msgstr "Guide markdown" 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" msgid "Choose file"
msgstr "Choisir un fichier" 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" msgid "Choose user"
msgstr "Choisir un utilisateur" msgstr "Choisir un utilisateur"
#: core/views/forms.py:203 #: core/views/forms.py:185
msgid "Username, email, or account number" msgid "Username, email, or account number"
msgstr "Nom d'utilisateur, email, ou numéro de compte AE" msgstr "Nom d'utilisateur, email, ou numéro de compte AE"
#: core/views/forms.py:269 #: core/views/forms.py:251
msgid "" msgid ""
"Profile: you need to be visible on the picture, in order to be recognized (e." "Profile: you need to be visible on the picture, in order to be recognized (e."
"g. by the barmen)" "g. by the barmen)"
@ -3622,36 +3623,36 @@ msgstr ""
"Photo de profil: vous devez être visible sur la photo afin d'être reconnu " "Photo de profil: vous devez être visible sur la photo afin d'être reconnu "
"(par exemple par les barmen)" "(par exemple par les barmen)"
#: core/views/forms.py:271 #: core/views/forms.py:253
msgid "Avatar: used on the forum" msgid "Avatar: used on the forum"
msgstr "Avatar : utilisé sur le 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!" msgid "Scrub: let other know how your scrub looks like!"
msgstr "Blouse : montrez aux autres à quoi ressemble votre blouse !" 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" 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" 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" msgid "Godfather"
msgstr "Parrain" msgstr "Parrain"
#: core/views/forms.py:354 #: core/views/forms.py:336
msgid "Godchild" msgid "Godchild"
msgstr "Fillot" 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" msgid "Select user"
msgstr "Choisir un utilisateur" 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 #: election/views.py:154
msgid "edit groups" msgid "edit groups"
msgstr "groupe d'édition" 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 #: election/views.py:157
msgid "view groups" msgid "view groups"
msgstr "groupe de vue" msgstr "groupe de vue"
@ -3742,7 +3743,7 @@ msgstr "groupe d'achat"
msgid "archived" msgid "archived"
msgstr "archivé" msgstr "archivé"
#: counter/models.py:185 counter/models.py:738 #: counter/models.py:185 counter/models.py:754
msgid "product" msgid "product"
msgstr "produit" msgstr "produit"
@ -3770,7 +3771,7 @@ msgstr "vendeurs"
msgid "token" msgid "token"
msgstr "jeton" 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 #: launderette/models.py:41 stock/models.py:43
msgid "counter" msgid "counter"
msgstr "comptoir" msgstr "comptoir"
@ -3791,7 +3792,7 @@ msgstr "rechargement"
msgid "unit price" msgid "unit price"
msgstr "prix unitaire" 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" msgid "quantity"
msgstr "quantité" msgstr "quantité"
@ -3808,16 +3809,16 @@ msgstr "Carte bancaire"
msgid "selling" msgid "selling"
msgstr "vente" msgstr "vente"
#: counter/models.py:490 #: counter/models.py:494
msgid "Unknown event" msgid "Unknown event"
msgstr "Événement inconnu" msgstr "Événement inconnu"
#: counter/models.py:491 #: counter/models.py:495
#, python-format #, python-format
msgid "Eticket bought for the event %(event)s" msgid "Eticket bought for the event %(event)s"
msgstr "Eticket acheté pour l'événement %(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 #, python-format
msgid "" msgid ""
"You bought an eticket for the event %(event)s.\n" "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 " "Vous pouvez également retrouver tous vos e-tickets sur votre page de compte "
"%(url)s." "%(url)s."
#: counter/models.py:618 #: counter/models.py:634
msgid "last activity date" msgid "last activity date"
msgstr "dernière activité" msgstr "dernière activité"
#: counter/models.py:621 #: counter/models.py:637
msgid "permanency" msgid "permanency"
msgstr "permanence" msgstr "permanence"
#: counter/models.py:648 #: counter/models.py:664
msgid "emptied" msgid "emptied"
msgstr "coffre vidée" msgstr "coffre vidée"
#: counter/models.py:651 #: counter/models.py:667
msgid "cash register summary" msgid "cash register summary"
msgstr "relevé de caisse" msgstr "relevé de caisse"
#: counter/models.py:719 #: counter/models.py:735
msgid "cash summary" msgid "cash summary"
msgstr "relevé" msgstr "relevé"
#: counter/models.py:722 #: counter/models.py:738
msgid "value" msgid "value"
msgstr "valeur" msgstr "valeur"
#: counter/models.py:724 #: counter/models.py:740
msgid "check" msgid "check"
msgstr "chèque" msgstr "chèque"
#: counter/models.py:727 #: counter/models.py:743
msgid "cash register summary item" msgid "cash register summary item"
msgstr "élément de relevé de caisse" msgstr "élément de relevé de caisse"
#: counter/models.py:742 #: counter/models.py:758
msgid "banner" msgid "banner"
msgstr "bannière" msgstr "bannière"
#: counter/models.py:744 #: counter/models.py:760
msgid "event date" msgid "event date"
msgstr "date de l'événement" msgstr "date de l'événement"
#: counter/models.py:746 #: counter/models.py:762
msgid "event title" msgid "event title"
msgstr "titre de l'événement" msgstr "titre de l'événement"
#: counter/models.py:748 #: counter/models.py:764
msgid "secret" msgid "secret"
msgstr "secret" msgstr "secret"
#: counter/models.py:804 #: counter/models.py:820
msgid "uid" msgid "uid"
msgstr "uid" msgstr "uid"
#: counter/models.py:809 #: counter/models.py:825
msgid "student cards" msgid "student cards"
msgstr "cartes étudiante" msgstr "cartes étudiante"
@ -4291,7 +4292,7 @@ msgstr "Montant du chèque"
msgid "Check quantity" msgid "Check quantity"
msgstr "Nombre de chèque" msgstr "Nombre de chèque"
#: counter/views.py:1802 #: counter/views.py:1806
msgid "people(s)" msgid "people(s)"
msgstr "personne(s)" msgstr "personne(s)"
@ -4987,6 +4988,19 @@ msgstr "Supprimer commentaire"
msgid "Delete report" msgid "Delete report"
msgstr "Supprimer signalement" 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 #: pedagogy/templates/pedagogy/uv_detail.jinja:6
msgid "UV Details" msgid "UV Details"
msgstr "Détails d'UV" msgstr "Détails d'UV"

View File

@ -52,7 +52,11 @@
year-- year--
} }
const url = "{{ url('api:uv_endpoint') }}?year=" + year + "&code=" + codeInput.value 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) { for (let key in data) {
if (data.hasOwnProperty(key)) { if (data.hasOwnProperty(key)) {
const el = document.querySelector('[name="' + key + '"]') const el = document.querySelector('[name="' + key + '"]')