diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-20 13:57:39 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-20 13:57:39 +0200 |
commit | c288ba14fd475a03ef148769ffb4146669a34de9 (patch) | |
tree | 17c1e66f3f5a42242d19501fbcf039c195f43b1e | |
parent | 2e95bd9f19797bc4d19c284c793ff98aaeb99d4f (diff) | |
download | auditor-c288ba14fd475a03ef148769ffb4146669a34de9.tar.gz auditor-c288ba14fd475a03ef148769ffb4146669a34de9.tar.bz2 auditor-c288ba14fd475a03ef148769ffb4146669a34de9.zip |
fixing #5063, also adding i18n, with help by Torsten
-rw-r--r-- | Makefile | 70 | ||||
-rw-r--r-- | config.mk | 7 | ||||
-rw-r--r-- | i18nfix.py | 34 | ||||
-rw-r--r-- | index.html.j2 | 35 | ||||
-rw-r--r-- | locale/babel.map | 12 | ||||
m--------- | static/web-common | 0 | ||||
-rwxr-xr-x | template.py | 60 |
7 files changed, 183 insertions, 35 deletions
@@ -1,3 +1,67 @@ -.PHONY: all -all: - ./template.py +# This file is in the public domain. + +# Hardly anyone seems to read README files anymore, so keep this note here: +# Don't remove the variables for python etc. They exist +# because one system sticks with PEPs, and others opt +# for installing every version side-by-side, +# Same goes for babel. + +include config.mk + +# All: build HTML pages in all languages and compile the +# TypeScript logic in web-common. +all: locale template +# cd web-common && $(TSC) + +# Extract translateable strings from jinja2 templates. +locale/messages.pot: *.j2 # common/*.j2 common/*.j2.inc + env PYTHONPATH="." $(BABEL) extract -F locale/babel.map -o locale/messages.pot . + +# Update translation (.po) files with new strings. +locale-update: locale/messages.pot + msgmerge -U -m --previous locale/en/LC_MESSAGES/messages.po locale/messages.pot + + if grep -nA1 '#-#-#-#-#' locale/*/LC_MESSAGES/messages.po; then echo -e "\nERROR: Conflicts encountered in PO files.\n"; exit 1; fi + +# Compile translation files for use. +locale-compile: + $(BABEL) compile -d locale -l en --use-fuzzy + +# Process everything related to gettext translations. +locale: locale-update locale-compile + +# Run the jinja2 templating engine to expand templates to HTML +# incorporating translations. +template: locale-compile + $(PYTHON) ./template.py + +run: all + @[ "$(BROWSER)" ] || ( echo "You need to export the environment variable 'BROWSER' to run this."; exit 1 ) + $(RUN_BROWSER) http://0.0.0.0:8000 & + # cd rendered && $(PYTHON) -m http.server + $(PYTHON) -m http.server + +clean: + rm -rf __pycache__ + rm -rf en/ de/ fr/ it/ es/ ru/ + rm -rf rendered/ + +submodules/init: + git submodule update --init --recursive + +submodules/update: + git submodule update --recursive --remote + +.SILENT: show-help + +show-help: + printf "all:\t\t\tBuild the website\n" + printf "locale/messages.pot:\tExtract translateable strings from jinja2 templates.\n" + printf "locale-update:\t\tUpdate translation files with new strings.\n" + printf "locale-compile:\t\tCompile translation files for use.\n" + printf "locale:\t\t\tProcess everything related to gettext translations.\n" + printf "template:\t\texpand jinja2 templates to html.\n" + printf "run:\t\t\tspawn python webserver and open the current directory.\n" + printf "clean:\t\t\tclean.\n" + printf "submodules/init:\tinit git submodules\n" + printf "submodules/update:\tupdate git submodules\n" diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..6d0dae0 --- /dev/null +++ b/config.mk @@ -0,0 +1,7 @@ +# config.mk Makefile fragment to set custom variables. + +TSC=tsc +PYTHON=python3 +BABEL=pybabel + +RUN_BROWSER=$(BROWSER) diff --git a/i18nfix.py b/i18nfix.py new file mode 100644 index 0000000..9e4b26b --- /dev/null +++ b/i18nfix.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# This file is in the public domain. + +""" +Extract translations from a Jinja2 template, stripping leading newlines. + +@author Florian Dold +""" + +import jinja2.ext +import re + +def normalize(message): + if isinstance(message, str): + message = message.strip() + # collapse whitespaces (including newlines) into one space. + message = re.sub("\s+", " ", message) + return message + + +def babel_extract(fileobj, keywords, comment_tags, options): + res = jinja2.ext.babel_extract(fileobj, keywords, comment_tags, options) + for lineno, funcname, message, comments in res: + message = normalize(message) + yield lineno, funcname, message, comments + +def wrap_gettext(f): + """ + Call gettext with whitespace normalized. + """ + def wrapper(message): + message = normalize(message) + return f(message) + return wrapper diff --git a/index.html.j2 b/index.html.j2 index 0dcdead..6945479 100644 --- a/index.html.j2 +++ b/index.html.j2 @@ -2,7 +2,7 @@ <html lang="en" data-taler-nojs="true"> <head profile="http://www.w3.org/2005/10/profile"> <meta charset="utf-8"/> - <title>Taler Demo - Auditor</title> + <title>{{ _("Taler Demo - Auditor") }}</title> <link rel="stylesheet" type="text/css" href="{{ url('static/web-common/pure.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ url('static/web-common/demo.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ url('static/web-common/taler-fallback.css') }}" id="taler-presence-stylesheet" /> @@ -50,19 +50,42 @@ <body> <div class="demobar"> - <h1><span class="tt adorn-brackets">Taler Demo</span></h1> - <h1><span class="it"><a href="#">Auditor</a></span></h1> - <p>This is an auditor for the currency "{{ currency }}".</p> + <h1><span class="tt adorn-brackets">{{ _("Taler Demo") }}</span></h1> + <h1><span class="it"><a href="#">{{ _("Auditor") }}</a></span></h1> + <p> + {{ _("This is an auditor for the %(curr)s currency.", curr=currency) }} + </p> <ul> <li><a href="{{ intro_url }}">Introduction</a></li> <li><a href="{{ bank_url }}">Bank</a></li> <li><a href="{{ merchant_blog_url }}">Essay Shop</a></li> <li><a href="{{ merchant_donations_url }}">Donations</a></li> </ul> - <p>You can learn more about Taler on our main <a href="https://taler.net">website</a>.</p> + <p> + {% trans %} + You can learn more about Taler on our main <a href="https://taler.net/">website</a>. + {% endtrans %} + </p> </div> <section id="main" class="content"> - <button class="pure-button pure-button-primary" onclick="addAuditor()">Add Auditor</button> + <h1>{{ _("%(curr)s Auditor", curr=currency) }} </h1> + <p style="color: black;"> + {{ _("This is the Web site of the auditor for the %(curr)s currency.",curr=currency) }} + {% trans %} + In the GNU Taler system, an auditor is responsible for verifying + that an exchange operates correctly. If you trust us to do a good + job auditing, please click here: + {% endtrans %} + </p> + <div style="text-align: center;"> + <button class="pure-button pure-button-primary" style="text-allign: center;" click="addAuditor()">{{ _("Add Auditor") }}</button> + </div> + <p> + {% trans %} + This will tell your wallet that you are willing to trust exchanges that + we audit to handle the TESTKUDOS currency properly. + {% endtrans %} + </p> </section> </body> </html> diff --git a/locale/babel.map b/locale/babel.map new file mode 100644 index 0000000..72b6f99 --- /dev/null +++ b/locale/babel.map @@ -0,0 +1,12 @@ +[extractors] +jinja2 = i18nfix:babel_extract + +[jinja2: **.j2] +encoding = utf-8 +lstrip_blocks = True +trim_blocks = True + +[jinja2: **.j2.inc] +encoding = utf-8 +lstrip_blocks = True +ltrim_blocks = True diff --git a/static/web-common b/static/web-common -Subproject d7e013594d15388b1a7342a44a0e9c8d4ecca82 +Subproject 68cb09ce78e261dbcddc69b174b8766f9679497 diff --git a/template.py b/template.py index bd67d3f..c8153cc 100755 --- a/template.py +++ b/template.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # This file is in the public domain. # -# This script runs the jinga2 templating engine on an input template-file +# This script runs the jinja2 templating engine on an input template-file # using the specified locale for gettext translations, and outputs # the resulting (HTML) ouptut-file. # @@ -12,19 +12,19 @@ import os.path import sys import re import gettext +import subprocess import jinja2 import glob import codecs import os -import os.path -import subprocess +sys.path.append(os.getcwd()) +import i18nfix env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), - extensions=["jinja2.ext.i18n"], - lstrip_blocks=True, - trim_blocks=True, - - undefined=jinja2.StrictUndefined, + extensions=["jinja2.ext.i18n"], + lstrip_blocks=True, + trim_blocks=True, + undefined=jinja2.StrictUndefined, autoescape=False) default_ctx = {} @@ -38,6 +38,8 @@ auditor_priv_file = os.path.expanduser("~/.local/share/taler/auditor/offline-key default_ctx["auditor_pub"] = subprocess.check_output(["gnunet-ecc", "-p", auditor_priv_file]).decode("utf-8").strip() +langs_full = {"en": "English" } + for in_file in glob.glob("*.j2"): name, ext = re.match(r"(.*)\.([^.]+)$", in_file.rstrip(".j2")).groups() tmpl = env.get_template(in_file) @@ -51,34 +53,40 @@ for in_file in glob.glob("*.j2"): def url_localized(filename): return "../" + locale + "/" + filename + def svg_localized(filename): + lf = filename + "." + locale + ".svg" + if "en" == locale or not os.path.isfile (lf): + return "../" + filename + ".svg" + else: + return "../" + lf + def url(x): # TODO: look at the app root environment variable # TODO: check if file exists return "../" + x - for l in ("en", "de", "it", "es"): - locale = os.path.basename(l) + for l in glob.glob("locale/*/"): + locale = os.path.basename(l[:-1]) - if os.path.isdir(os.path.join("./locale/", locale)): - tr = gettext.translation("messages", - localedir="locale", - languages=[locale]) + tr = gettext.translation("messages", + localedir="locale", + languages=[locale]) - env.install_gettext_translations(tr, newstyle=True) - else: - print("warning: locale {} not found".format(locale)) - - ctx = dict( - lang=locale, - url=url, - self_localized=self_localized, - url_localized=url_localized, - filename=name + "." + ext) - ctx.update(default_ctx) + tr.gettext = i18nfix.wrap_gettext(tr.gettext) + + env.install_gettext_translations(tr, newstyle=True) + ctx = dict(lang=locale, + lang_full=langs_full[locale], + url=url, + self_localized=self_localized, + url_localized=url_localized, + svg_localized=svg_localized, + filename=name + "." + ext) + ctx.update(default_ctx) content = tmpl.render(**ctx) + out_name = "./" + locale + "/" + in_file.rstrip(".j2") os.makedirs("./" + locale, exist_ok=True) - with codecs.open(out_name, "w", "utf-8") as f: f.write(content) |