release 1.18.9: FP domains default UI language fr globally

Workstation TALER_MON_LANG=en no longer locks English on *lefrancpaysan*;
only --lang / TALER_MON_LANG_SET=1 overrides. host-agent + HTML chrome.
This commit is contained in:
Hernâni Marques 2026-07-19 11:04:44 +02:00
parent 48d51e17be
commit 8c99e13af1
No known key found for this signature in database
GPG key ID: CB5738652768F7E9
5 changed files with 57 additions and 42 deletions

View file

@ -1 +1 @@
1.18.8 1.18.9

View file

@ -17,6 +17,7 @@ Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.8.0`). File `VERSION` omits the `v` pre
| Tag | Date (UTC) | Notes | | Tag | Date (UTC) | Notes |
|-----|------------|--------| |-----|------------|--------|
| **v1.18.9** | 2026-07-19 | **Bugfix:** UI lang — *lefrancpaysan*/*francpaysan* always default **fr** unless `TALER_MON_LANG_SET=1` / `--lang`; workstation `TALER_MON_LANG=en` no longer locks English (host-agent + console_to_html). |
| **v1.18.8** | 2026-07-19 | **Bugfix:** e2e wallet — require `taler-helper-sqlite3` on PATH; use absolute `node` + `timeout` instead of fragile `perl -e alarm` for wcli; clearer accept-uri errors (no raw alarm-shift noise). | | **v1.18.8** | 2026-07-19 | **Bugfix:** e2e wallet — require `taler-helper-sqlite3` on PATH; use absolute `node` + `timeout` instead of fragile `perl -e alarm` for wcli; clearer accept-uri errors (no raw alarm-shift noise). |
| **v1.18.7** | 2026-07-19 | **Bugfix:** mail/surface catalogs — TSA/Anastasis MX is **mail.anastasis.lu** (→ pixel), not non-resolving `anastasis.taler-systems.com`; add `anastasis.lu` + pixel host probes (fixes surface_err mail.*). **Also:** FP stage host-agent defaults include **e2e** + 1800s timeout; stagepaysan.env.example wires francpaysan-secrets + wallet-cli. | | **v1.18.7** | 2026-07-19 | **Bugfix:** mail/surface catalogs — TSA/Anastasis MX is **mail.anastasis.lu** (→ pixel), not non-resolving `anastasis.taler-systems.com`; add `anastasis.lu` + pixel host probes (fixes surface_err mail.*). **Also:** FP stage host-agent defaults include **e2e** + 1800s timeout; stagepaysan.env.example wires francpaysan-secrets + wallet-cli. |
| **v1.18.6** | 2026-07-19 | **Bugfix:** TESTS.md table cell for `e2e.bankwd-` markdown typo from rename. | | **v1.18.6** | 2026-07-19 | **Bugfix:** TESTS.md table cell for `e2e.bankwd-` markdown typo from rename. |

View file

@ -75,19 +75,25 @@ export CONTINUE_ON_ERROR="${CONTINUE_ON_ERROR:-1}"
export AUTH401_CONTINUE="${AUTH401_CONTINUE:-${CONTINUE_ON_ERROR}}" export AUTH401_CONTINUE="${AUTH401_CONTINUE:-${CONTINUE_ON_ERROR}}"
export RUN_TIMEOUT="${RUN_TIMEOUT:-600}" export RUN_TIMEOUT="${RUN_TIMEOUT:-600}"
export TALER_DOMAIN="${TALER_DOMAIN:-hacktivism.ch}" export TALER_DOMAIN="${TALER_DOMAIN:-hacktivism.ch}"
# UI language: selectable via TALER_MON_LANG / --lang (en|fr). # UI language: --lang / TALER_MON_LANG_SET=1 locks; otherwise auto by domain.
# If unset, auto: FrancPaysan domains → fr, else en. # Bare TALER_MON_LANG=en in workstation env (clementine) must NOT lock language —
if [ "${TALER_MON_LANG_SET:-0}" != "1" ] && [ -z "${TALER_MON_LANG:-}" ]; then # *lefrancpaysan* / *francpaysan* always default to fr when SET≠1 (global rule).
case "$TALER_DOMAIN" in if [ "${TALER_MON_LANG_SET:-0}" = "1" ]; then
*lefrancpaysan*|*francpaysan*) export TALER_MON_LANG=fr ;; case "${TALER_MON_LANG:-en}" in
*) export TALER_MON_LANG=en ;;
esac
elif [ -n "${TALER_MON_LANG:-}" ]; then
case "$TALER_MON_LANG" in
fr|FR|fra|french) export TALER_MON_LANG=fr ;; fr|FR|fra|french) export TALER_MON_LANG=fr ;;
*) export TALER_MON_LANG=en ;; *) export TALER_MON_LANG=en ;;
esac esac
export TALER_MON_LANG_SET=1 else
case "$TALER_DOMAIN" in
*lefrancpaysan*|*francpaysan*) export TALER_MON_LANG=fr ;;
*)
case "${TALER_MON_LANG:-}" in
fr|FR|fra|french) export TALER_MON_LANG=fr ;;
*) export TALER_MON_LANG=en ;;
esac
;;
esac
# leave TALER_MON_LANG_SET unset/0 so suite i18n_init can re-apply per -d domain
fi fi
export TALER_MON_LANG export TALER_MON_LANG

10
i18n.sh
View file

@ -2,11 +2,13 @@
# i18n.sh — language for taler-monitoring console + HTML chrome # i18n.sh — language for taler-monitoring console + HTML chrome
# #
# TALER_MON_LANG=en|fr # TALER_MON_LANG=en|fr
# TALER_MON_LANG_SET=1 → language is explicit (--lang or host-agent wrapper); do not override. # TALER_MON_LANG_SET=1 → language is explicit (--lang only); do not override.
# Auto (SET≠1): domain *lefrancpaysan* / *francpaysan* → fr, else keep env or en. # Auto (SET≠1): domain *lefrancpaysan* / *francpaysan* → fr always (global).
# else keep env or en.
# #
# Important: a bare TALER_MON_LANG=en in ~/.config/taler-monitoring/env must NOT lock # Important: a bare TALER_MON_LANG=en in ~/.config/taler-monitoring/env is only the
# language for FP domains (that used to force English on stage.monnaie…). # workstation default for non-FP domains. It must NEVER lock English on FP
# (*lefrancpaysan* / *francpaysan*) — local laptop and host-agent both follow this.
: "${TALER_MON_LANG:=}" : "${TALER_MON_LANG:=}"
: "${TALER_MON_LANG_SET:=0}" : "${TALER_MON_LANG_SET:=0}"

View file

@ -45,15 +45,35 @@ def atomic_write_text(path: Path, text: str, encoding: str = "utf-8") -> None:
except OSError: except OSError:
pass pass
def ui_lang(explicit: str = "") -> str: def ui_lang(explicit: str = "", host_hint: str = "") -> str:
"""en (default) or fr. Env: TALER_MON_LANG; auto fr for lefrancpaysan hosts.""" """en (default) or fr.
- TALER_MON_LANG_SET=1 honour TALER_MON_LANG / explicit only (no host auto).
- Else: any *lefrancpaysan* / *francpaysan* host or log hint fr
(workstation env TALER_MON_LANG=en must not force English on FP domains).
- Else: explicit / env / en.
"""
import os import os
lang = (explicit or os.environ.get("TALER_MON_LANG") or "").strip().lower()
if lang in ("fr", "fra", "french"): env_lang = (os.environ.get("TALER_MON_LANG") or "").strip().lower()
lang = (explicit or env_lang or "").strip().lower()
locked = (os.environ.get("TALER_MON_LANG_SET") or "").strip() == "1"
is_fp = bool(
re.search(r"lefrancpaysan|francpaysan", host_hint or "", re.I)
)
def _norm(v: str) -> str:
if v in ("fr", "fra", "french"):
return "fr"
if v in ("en", "eng", "english"):
return "en"
return ""
if locked:
return _norm(lang) or "en"
if is_fp:
return "fr" return "fr"
if lang in ("en", "eng", "english"): return _norm(lang) or "en"
return "en"
return "en"
def ui(lang: str, key: str, **kwargs) -> str: def ui(lang: str, key: str, **kwargs) -> str:
@ -709,11 +729,9 @@ def monitoring_scope(
label = (page_label or "monitoring").lower().replace("_", "-") label = (page_label or "monitoring").lower().replace("_", "-")
phases = extract_phases(log_text) phases = extract_phases(log_text)
host = hostname or "?" host = hostname or "?"
# Auto-fr for FrancPaysan hosts if lang not forced # Resolve lang again with host/log hint (*lefrancpaysan* → fr unless LANG_SET=1)
if lang == "en" and re.search(r"lefrancpaysan|francpaysan", host + " " + log_text, re.I): _ex = lang if lang in ("en", "fr") else ""
import os lang = ui_lang(explicit=_ex, host_hint=host + " " + log_text)
if not (os.environ.get("TALER_MON_LANG") or "").strip():
lang = "fr"
if "surface" in label: if "surface" in label:
items = [ items = [
@ -1079,10 +1097,7 @@ def sticky_bar_html(
if scope and scope.get("lang"): if scope and scope.get("lang"):
lang = str(scope.get("lang")) lang = str(scope.get("lang"))
else: else:
lang = ui_lang() lang = ui_lang(host_hint=hostname or "")
# auto-fr for FP hostnames
if lang == "en" and re.search(r"lefrancpaysan|francpaysan", hostname or "", re.I):
lang = "fr"
if level == "red": if level == "red":
status_txt = ui(lang, "errors") status_txt = ui(lang, "errors")
@ -1990,12 +2005,7 @@ def build_html(
page_label or "" page_label or ""
).lower() ).lower()
if _is_apt: if _is_apt:
_lang_board = ui_lang() _lang_board = ui_lang(host_hint=hostname + "\n" + log_text)
if re.search(r"lefrancpaysan|francpaysan", hostname + "\n" + log_text, re.I):
import os
if not (os.environ.get("TALER_MON_LANG") or "").strip():
_lang_board = "fr"
err_nav += aptdeploy_board_html(log_text, lang=_lang_board) err_nav += aptdeploy_board_html(log_text, lang=_lang_board)
if errors and mode == "err": if errors and mode == "err":
@ -2040,11 +2050,7 @@ def build_html(
first_err_href = "#first-error" if first_err_i is not None else None first_err_href = "#first-error" if first_err_i is not None else None
first_warn_href = "#first-warn" if first_warn_i is not None else None first_warn_href = "#first-warn" if first_warn_i is not None else None
lang = ui_lang() lang = ui_lang(host_hint=hostname + "\n" + log_text)
if re.search(r"lefrancpaysan|francpaysan", hostname + "\n" + log_text, re.I):
import os
if not (os.environ.get("TALER_MON_LANG") or "").strip():
lang = "fr"
scope = monitoring_scope(page_label, hostname, log_text, lang=lang) scope = monitoring_scope(page_label, hostname, log_text, lang=lang)
page_lang = lang page_lang = lang