Commit bf0f3cc0 authored by Julien Palard's avatar Julien Palard
Browse files

Start to translate exercises.

parent 850aab4a
Pipfile.lock
to_translate.py
exercises/
# Created by https://www.gitignore.io/api/python,django
......
......@@ -25,6 +25,27 @@ for_django branch of the moulinette, install firejail, and start it using:
./server.py http://127.0.0.1:8000/api/ --verbose --auth staff_login:staff_password
## Translations
```
$ django-admin makemessages -a
# Edit the .po files
$ django-admin compilemessages
```
To translate exercises you'll need to fetch them via the API first:
```
$ pip install requests
$ mkdir -p locale/fr/LC_MESSAGES/
$ python scripts/fetch.py --endpoint https://www.hackinscience.org/api/exercises/
$ python scripts/pygettext.py -o locale/fr/LC_MESSAGES/django.pot to_translate.py
$ cd locale/fr/LC_MESSAGES
$ if [ -f django.po ] ; then msgmerge -U django.po django.pot; else cp django.pot django.po; fi
# msgfmt django.po -o django.mo
```
# TODO
- In the exercise page, links to documentation should open in a new tab.
......@@ -193,6 +193,8 @@ CHANNEL_LAYERS = {
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTOCOL", "https")
LOCALE_PATHS = [BASE_DIR + "/locale/"]
try:
from local_settings import *
except ImportError:
......
"""Fetch exercises from hackinscience API.
"""
import requests
from getpass import getpass
from pathlib import Path
import json
import argparse
def parse_args():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--password")
parser.add_argument(
"--endpoint", default="https://www.hackinscience.org/api/exercises/"
)
return parser.parse_args()
def main():
args = parse_args()
username = input("Username: ")
password = getpass()
next_exercise_page = args.endpoint
root = Path("exercises")
while next_exercise_page:
exercises = requests.get(next_exercise_page, auth=(username, password)).json()
if "results" not in exercises:
print(exercises)
exit(1)
translatables = []
for exercise in exercises["results"]:
path = Path("exercises") / exercise["slug"]
path.mkdir(exist_ok=True, parents=True)
(path / "check.py").write_text(exercise["check"])
(path / "solution.py").write_text(exercise["solution"])
(path / "solution.py").write_text(exercise["solution"])
(path / "meta").write_text(json.dumps(exercise, indent=4))
(path / "wording.md").write_text(exercise["wording"])
translatables.append(exercise["wording"])
translatables.append(exercise["title"])
next_exercise_page = exercises["next"]
with open("to_translate.py", "w", encoding="UTF-8") as to_translate:
for string in translatables:
to_translate.write(f"_({string!r})\n")
if __name__ == "__main__":
main()
This diff is collapsed.
......@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-29 21:39+0200\n"
"PO-Revision-Date: 2020-06-29 21:43+0200\n"
"POT-Creation-Date: 2020-06-29 22:52+0200\n"
"PO-Revision-Date: 2020-06-29 22:53+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
......@@ -18,10 +18,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: templates/admin/base_site.html:3
msgid "Django site admin"
msgstr "Admin Django"
#: website/forms.py:26
msgid "E-mail (optional)"
msgstr "E-mail (facultatif)"
......@@ -32,10 +28,59 @@ msgstr "E-mail (facultatif)"
msgid "Submit"
msgstr "Envoyer"
#: website/templates/hkis/exercise.html:158
#: website/templates/hkis/exercise.html:70
msgid "Next"
msgstr "Suivant"
#: website/templates/hkis/exercise.html:75
msgid "Help"
msgstr "Aide"
#: website/templates/hkis/exercise.html:93
msgid "Waiting for correction"
msgstr "En attente de correction…"
#: website/templates/hkis/exercise.html:115
msgid "Waiting for test run"
msgstr "En attente d'exécution…"
#: website/templates/hkis/exercise.html:159
msgid "Your Code"
msgstr "Votre code"
#: website/templates/hkis/exercise.html:173
msgid "Run"
msgstr "Exécuter"
#: website/templates/hkis/exercise.html:183
msgid "Submit for validation"
msgstr "Envoi pour valiation"
#: website/templates/hkis/exercise.html:187
msgid "Other students solutions"
msgstr "Les solutions partagées"
#: website/templates/hkis/exercise.html:190
#, python-format
msgid "%(username)s on %(date)s"
msgstr "%(username)s le %(date)s"
#: website/templates/hkis/exercise.html:199
msgid "Results"
msgstr "Résultats"
#: website/templates/hkis/exercise.html:212
msgid "Solution shared!"
msgstr "Solution partagée ! Merci !"
#: website/templates/hkis/exercise.html:216
msgid "Share it with other students!"
msgstr "Partagez votre solution avec les autres !"
#: website/templates/hkis/exercise.html:220
msgid "View code"
msgstr "Voir le code"
#: website/templates/hkis/profile_update.html:21
#, python-format
msgid ""
......@@ -126,3 +171,9 @@ msgstr "S'enregistrer"
#: website/templates/registration/resend_activation_form.html:4
msgid "Resend Activation Email"
msgstr ""
#~ msgid "%(solution.user.username)s on %(solution.created_at.date)s"
#~ msgstr "%(solution.user.username)s le %(solution.created_at.date)s"
#~ msgid "Django site admin"
#~ msgstr "Admin Django"
......@@ -67,12 +67,12 @@
});
var button_next = document.createElement("a")
button_next.className = 'btn btn-primary btn-sm'
button_next.innerHTML = 'Next'
button_next.innerHTML = '{% trans "Next" %}'
button_next.href = "{% url "exercise" next %}"
var button_help = document.createElement("a")
button_help.className = 'btn btn-secondary btn-sm'
button_help.innerHTML = 'Help'
button_help.innerHTML = '{% trans "Help" %}'
button_help.href = "{% url 'help' %}"
div.className = "result-box";
......@@ -90,7 +90,7 @@
elem.appendChild(div);
document.getElementById('submit_answer').removeAttribute('disabled');
} else {
elem.innerHTML = '<img src="{% static "img/loading_anim.gif" %}" height=30> Waiting for correction';
elem.innerHTML = '<img src="{% static "img/loading_anim.gif" %}" height=30> {% trans "Waiting for correction" %}';
}
}
......@@ -112,7 +112,7 @@
elem.appendChild(pre);
document.getElementById("submit_snippet").removeAttribute('disabled');
} else {
elem.innerHTML = '<img src="{% static "img/loading_anim.gif" %}" height=30> Waiting for test run';
elem.innerHTML = '<img src="{% static "img/loading_anim.gif" %}" height=30> {% trans "Waiting for test run" %}';
}
}
......@@ -145,7 +145,7 @@
{% if next %}
<div class="float-right">
<a class="btn btn-secondary" href="{% url "exercise" next %}">
Next
{% trans "Next" %}
</a>
</div>
{% endif %}
......@@ -170,7 +170,7 @@
title="Use this to execute your code, so you can try things."
id="submit_snippet" class="btn btn-secondary"
onclick="AJAXSubmit(document.getElementById('answer_form'), '/api/snippets/'); this.setAttribute('disabled', true); return false;">
Run
{% trans "Run" %}
</button>
<button
id="submit_answer"
......@@ -180,14 +180,14 @@
title="This runs automated tests to verify your implementation (also saves your code)."
class="btn btn-primary"
type="submit">
Submit for validation
{% trans "Submit for validation" %}
</button>
</form>
{% if solutions %}
<h2 style="margin-top: 20px;">Other students solutions</h2>
<h2 style="margin-top: 20px;">{% trans "Other students solutions" %}</h2>
<div id="solutions">
{% for solution in solutions %}
<h3>{{ solution.user.username }} on {{ solution.created_at.date }}</h3>
<h3>{% blocktrans with username=solution.user.username date=solution.created_at.date %}{{ username }} on {{ date }}{% endblocktrans %}</h3>
<div class="django-ace-editor"><div class="django-ace-widget loading" data-fontsize="16px" data-mode="python" data-showinvisibles="false" data-showprintmargin="true" data-theme="twilight" data-usesofttabs="true" style="width:100%; height:400px"><div></div></div>
<textarea name="source_code" cols="40" rows="10" id="id_source_code_{{ forloop.counter }}">{{ solution.source_code }}</textarea>
</div>
......@@ -196,7 +196,7 @@
{% endif %}
</div>
<div class="col-md-6">
<h2>Results</h2>
<h2>{% trans "Results" %}</h2>
<div id="answers-result" class="result">
<table id="answer-table" class="table">
{% for answer in answers %}
......@@ -209,15 +209,15 @@
{% if answer.is_valid %}
{% if answer.is_shared %}
<button id="btn-{{ answer.id }}" type="button" class="btn btn-secondary btn-sm" disabled>
Solution shared!
{% trans "Solution shared!" %}
</button>
{% else %}
<button id="btn-{{ answer.id }}" type="button" class="btn btn-secondary btn-sm" onclick="shared_answer('{{ answer.id }}', true, '{{ csrf_token }}')">
Share it with other students!
{% trans "Share it with other students!" %}
</button>
{% endif %}
<button type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#modal-{{ answer.id }}">
View code
{% trans "View code" %}
</button>
<!-- Modal -->
<div class="modal fade" id="modal-{{ answer.id }}" tabindex="-1" role="dialog" aria-labelledby="{{ answer.name }} solution" aria-hidden="true">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment