summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-04-20 13:57:39 +0200
committerChristian Grothoff <christian@grothoff.org>2019-04-20 13:57:39 +0200
commitc288ba14fd475a03ef148769ffb4146669a34de9 (patch)
tree17c1e66f3f5a42242d19501fbcf039c195f43b1e
parent2e95bd9f19797bc4d19c284c793ff98aaeb99d4f (diff)
downloadauditor-c288ba14fd475a03ef148769ffb4146669a34de9.tar.gz
auditor-c288ba14fd475a03ef148769ffb4146669a34de9.tar.bz2
auditor-c288ba14fd475a03ef148769ffb4146669a34de9.zip
fixing #5063, also adding i18n, with help by Torsten
-rw-r--r--Makefile70
-rw-r--r--config.mk7
-rw-r--r--i18nfix.py34
-rw-r--r--index.html.j235
-rw-r--r--locale/babel.map12
m---------static/web-common0
-rwxr-xr-xtemplate.py60
7 files changed, 183 insertions, 35 deletions
diff --git a/Makefile b/Makefile
index 72460df..e6f461f 100644
--- a/Makefile
+++ b/Makefile
@@ -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)