From 3567a4cfb09b84421fa427802f9edc082c1e15cf Mon Sep 17 00:00:00 2001 From: SomberNight Date: Tue, 8 Apr 2025 15:56:35 +0000 Subject: [PATCH] mv git submodule electrum-locale from contrib to electrum/locale - this merges `contrib/deterministic-build/locale` and `electrum/locale` - it is now once again possible have translations when running from a local git clone - which was already possible in the past before crowdin removed their unauthenticated APIs - see https://github.com/spesmilo/electrum/issues/9531 - however, the translations available are the often-old frozen strings from electrum-locale - while previously one could just download the latest strings from crowdin --- .gitignore | 1 - .gitmodules | 4 +-- MANIFEST.in | 6 ++-- README.md | 4 +-- contrib/android/make_apk.sh | 15 +++++----- contrib/build-linux/appimage/make_appimage.sh | 7 +++-- contrib/build-linux/sdist/make_sdist.sh | 15 ++++++---- contrib/build-wine/build-electrum-git.sh | 23 ++++++++++----- contrib/build_locale.sh | 3 ++ contrib/deterministic-build/electrum-locale | 1 - contrib/osx/make_osx.sh | 21 +++++++++----- contrib/pull_locale | 21 -------------- contrib/push_locale | 29 ++++++++++++------- electrum/i18n.py | 2 +- electrum/locale | 1 + 15 files changed, 81 insertions(+), 72 deletions(-) delete mode 160000 contrib/deterministic-build/electrum-locale delete mode 100755 contrib/pull_locale create mode 160000 electrum/locale diff --git a/.gitignore b/.gitignore index d9c375536..9f013f3c7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ build/ dist/ *.egg/ Electrum.egg-info/ -electrum/locale/ .devlocaltmp/ *_trial_temp packages diff --git a/.gitmodules b/.gitmodules index ce9f6968f..5d001cd4a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ -[submodule "contrib/deterministic-build/electrum-locale"] - path = contrib/deterministic-build/electrum-locale +[submodule "electrum/locale"] + path = electrum/locale url = https://github.com/spesmilo/electrum-locale [submodule "electrum/www"] path = electrum/plugins/payserver/www diff --git a/MANIFEST.in b/MANIFEST.in index abc5aaba8..2288c739e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -26,6 +26,6 @@ global-exclude *.py.orig global-exclude *.py.rej global-exclude .git -# Maybe we should exclude the compiled locale files? see https://askubuntu.com/a/144139 -# We include both source (.po) and compiled (.mo) locale files atm (if present). -# exclude electrum/locale/*/LC_MESSAGES/electrum.mo +# We include both source (.po) and compiled (.mo) locale files (if present). +# When building the "sourceonly" tar.gz, the build script explicitly deletes the compiled files. +# exclude electrum/locale/locale/*/LC_MESSAGES/electrum.mo diff --git a/README.md b/README.md index 6fd01380f..77b18c68d 100644 --- a/README.md +++ b/README.md @@ -109,8 +109,8 @@ $ python3 -m pip install --user -e . Create translations (optional): ``` -$ sudo apt-get install python3-requests gettext qt6-l10n-tools -$ ./contrib/pull_locale +$ sudo apt-get install gettext +$ ./contrib/build_locale.sh electrum/locale/locale electrum/locale/locale ``` Finally, to start Electrum: diff --git a/contrib/android/make_apk.sh b/contrib/android/make_apk.sh index 49a65fbf1..72b6bc4dc 100755 --- a/contrib/android/make_apk.sh +++ b/contrib/android/make_apk.sh @@ -6,7 +6,6 @@ CONTRIB_ANDROID="$(dirname "$(readlink -e "$0")")" CONTRIB="$CONTRIB_ANDROID"/.. PROJECT_ROOT="$CONTRIB"/.. PACKAGES="$PROJECT_ROOT"/packages/ -LOCALE="$PROJECT_ROOT"/electrum/locale/ . "$CONTRIB"/build_tools_util.sh @@ -20,17 +19,19 @@ if [ ! -d "$PACKAGES" ]; then "$CONTRIB"/make_packages.sh || fail "make_packages failed" fi -pushd "$PROJECT_ROOT" -git submodule update --init -popd - # update locale info "preparing electrum-locale." ( + cd "$PROJECT_ROOT" + git submodule update --init + LOCALE="$PROJECT_ROOT/electrum/locale/" + cd "$LOCALE" + git clean -ffxd + git reset --hard + "$CONTRIB/build_locale.sh" "$LOCALE/locale" "$LOCALE/locale" # we want the binary to have only compiled (.mo) locale files; not source (.po) files - rm -rf "$LOCALE" - "$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE" + rm -r locale/*/electrum.po ) pushd "$CONTRIB_ANDROID" diff --git a/contrib/build-linux/appimage/make_appimage.sh b/contrib/build-linux/appimage/make_appimage.sh index 0ed8be67f..e302ca38c 100755 --- a/contrib/build-linux/appimage/make_appimage.sh +++ b/contrib/build-linux/appimage/make_appimage.sh @@ -140,9 +140,12 @@ info "preparing electrum-locale." git submodule update --init LOCALE="$PROJECT_ROOT/electrum/locale/" + cd "$LOCALE" + git clean -ffxd + git reset --hard + "$CONTRIB/build_locale.sh" "$LOCALE/locale" "$LOCALE/locale" # we want the binary to have only compiled (.mo) locale files; not source (.po) files - rm -rf "$LOCALE" - "$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE" + rm -r locale/*/electrum.po ) diff --git a/contrib/build-linux/sdist/make_sdist.sh b/contrib/build-linux/sdist/make_sdist.sh index 66e91bee7..9c2469747 100755 --- a/contrib/build-linux/sdist/make_sdist.sh +++ b/contrib/build-linux/sdist/make_sdist.sh @@ -7,7 +7,6 @@ CONTRIB="$PROJECT_ROOT/contrib" CONTRIB_SDIST="$CONTRIB/build-linux/sdist" DISTDIR="$PROJECT_ROOT/dist" BUILDDIR="$CONTRIB_SDIST/build" -LOCALE="$PROJECT_ROOT/electrum/locale" . "$CONTRIB"/build_tools_util.sh @@ -25,16 +24,20 @@ if ([ "$OMIT_UNCLEAN_FILES" != 1 ]); then "$CONTRIB"/make_packages.sh || fail "make_packages failed" fi -git submodule update --init - +info "preparing electrum-locale." ( + cd "$PROJECT_ROOT" + git submodule update --init + + LOCALE="$PROJECT_ROOT/electrum/locale/" + cd "$LOCALE" + git clean -ffxd + git reset --hard # By default, include both source (.po) and compiled (.mo) locale files in the source dist. # Set option OMIT_UNCLEAN_FILES=1 to exclude the compiled locale files # see https://askubuntu.com/a/144139 (also see MANIFEST.in) - rm -rf "$LOCALE" - cp -r "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE/" if ([ "$OMIT_UNCLEAN_FILES" != 1 ]); then - "$CONTRIB/build_locale.sh" "$LOCALE" "$LOCALE" + "$CONTRIB/build_locale.sh" "$LOCALE/locale" "$LOCALE/locale" fi ) diff --git a/contrib/build-wine/build-electrum-git.sh b/contrib/build-wine/build-electrum-git.sh index f797417b6..449eb17bf 100755 --- a/contrib/build-wine/build-electrum-git.sh +++ b/contrib/build-wine/build-electrum-git.sh @@ -1,6 +1,7 @@ #!/bin/bash NAME_ROOT=electrum +PROJECT_ROOT="$WINEPREFIX/drive_c/electrum" export PYTHONDONTWRITEBYTECODE=1 # don't create __pycache__/ folders with .pyc files @@ -10,18 +11,24 @@ set -e . "$CONTRIB"/build_tools_util.sh -pushd $WINEPREFIX/drive_c/electrum +pushd "$PROJECT_ROOT" VERSION=$(git describe --tags --dirty --always) info "Last commit: $VERSION" -# Load electrum-locale for this release -git submodule update --init +info "preparing electrum-locale." +( + cd "$PROJECT_ROOT" + git submodule update --init -LOCALE="$WINEPREFIX/drive_c/electrum/electrum/locale/" -# we want the binary to have only compiled (.mo) locale files; not source (.po) files -rm -rf "$LOCALE" -"$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE" + LOCALE="$PROJECT_ROOT/electrum/locale/" + cd "$LOCALE" + git clean -ffxd + git reset --hard + "$CONTRIB/build_locale.sh" "$LOCALE/locale" "$LOCALE/locale" + # we want the binary to have only compiled (.mo) locale files; not source (.po) files + rm -r locale/*/electrum.po +) find -exec touch -h -d '2000-11-11T11:11:11+00:00' {} + popd @@ -48,7 +55,7 @@ $WINE_PYTHON -m pip install --no-build-isolation --no-dependencies --no-warn-scr --no-binary :all: --only-binary cffi,cryptography,hidapi \ --cache-dir "$WINE_PIP_CACHE_DIR" -r "$CONTRIB"/deterministic-build/requirements-hw.txt -pushd $WINEPREFIX/drive_c/electrum +pushd "$PROJECT_ROOT" # see https://github.com/pypa/pip/issues/2195 -- pip makes a copy of the entire directory info "Pip installing Electrum. This might take a long time if the project folder is large." $WINE_PYTHON -m pip install --no-build-isolation --no-dependencies --no-warn-script-location . diff --git a/contrib/build_locale.sh b/contrib/build_locale.sh index a50f0eca4..8439489cc 100755 --- a/contrib/build_locale.sh +++ b/contrib/build_locale.sh @@ -1,10 +1,13 @@ #!/bin/bash +# +# This script converts human-readable (.po) locale files to compiled (.mo) locale files. set -e if [[ ! -d "$1" || -z "$2" ]]; then echo "usage: $0 locale_source_dir locale_dest_dir" echo " The dirs can match, to build in place." + # ^ note: these are the paths to the "inner" locale/ dir exit 1 fi diff --git a/contrib/deterministic-build/electrum-locale b/contrib/deterministic-build/electrum-locale deleted file mode 160000 index 39132e772..000000000 --- a/contrib/deterministic-build/electrum-locale +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 39132e77229bf9bc7b1a617b58deab855060d732 diff --git a/contrib/osx/make_osx.sh b/contrib/osx/make_osx.sh index 249f5f4fd..68e50831e 100755 --- a/contrib/osx/make_osx.sh +++ b/contrib/osx/make_osx.sh @@ -128,18 +128,23 @@ pyinstaller --version rm -rf ./dist -git submodule update --init +if ! which msgfmt > /dev/null 2>&1; then + brew install gettext + brew link --force gettext +fi -info "generating locale" +info "preparing electrum-locale." ( - if ! which msgfmt > /dev/null 2>&1; then - brew install gettext - brew link --force gettext - fi + cd "$PROJECT_ROOT" + git submodule update --init + LOCALE="$PROJECT_ROOT/electrum/locale/" + cd "$LOCALE" + git clean -ffxd + git reset --hard + "$CONTRIB/build_locale.sh" "$LOCALE/locale" "$LOCALE/locale" # we want the binary to have only compiled (.mo) locale files; not source (.po) files - rm -rf "$LOCALE" - "$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE" + rm -r locale/*/electrum.po ) || fail "failed generating locale" diff --git a/contrib/pull_locale b/contrib/pull_locale deleted file mode 100755 index 8d056e022..000000000 --- a/contrib/pull_locale +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 -import os -import subprocess -import importlib.util - -project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) -locale_path = os.path.join(project_root, "electrum", "locale") - -# download latest .po files from crowdin -locale_update = os.path.join(project_root, "contrib", "deterministic-build", "electrum-locale", "update.py") -assert os.path.exists(locale_update) -# load update.py; needlessly complicated alternative to "imp.load_source": -lu_spec = importlib.util.spec_from_file_location('update', locale_update) -lu_module = importlib.util.module_from_spec(lu_spec) -lu_spec.loader.exec_module(lu_module) - -lu_module.pull_locale(locale_path) - -# Convert .po to .mo -subprocess.check_output([f"{project_root}/contrib/build_locale.sh", locale_path, locale_path]) - diff --git a/contrib/push_locale b/contrib/push_locale index 53cb17f97..bf1229a4b 100755 --- a/contrib/push_locale +++ b/contrib/push_locale @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# +# This script extracts "raw" strings from the codebase, +# and uploads them to crowdin, for the community to translate them. +# # Dependencies: # $ sudo apt-get install python3-requests gettext qt6-l10n-tools @@ -15,6 +19,10 @@ except ImportError as e: project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) os.chdir(project_root) +locale_dir = os.path.join(project_root, "electrum", "locale") +if not os.path.exists(os.path.join(locale_dir, "locale")): + raise Exception(f"missing git submodule for locale? {locale_dir}") + # check dependencies are available try: subprocess.check_output(["xgettext", "--version"]) @@ -46,33 +54,34 @@ with open("app.fil", "wb") as f: print("Found {} files to translate".format(len(files.splitlines()))) # Generate fresh translation template -if not os.path.exists('electrum/locale'): - os.mkdir('electrum/locale') +build_dir = os.path.join(locale_dir, "build") +if not os.path.exists(build_dir): + os.mkdir(build_dir) print('Generating template...') -cmd = 'xgettext -s --from-code UTF-8 --language Python --no-wrap -f app.fil --output=electrum/locale/messages_gettext.pot' -subprocess.check_output(cmd, shell=True) +cmd = ["xgettext", "-s", "--from-code", "UTF-8", "--language", "Python", "--no-wrap", "-f", "app.fil", f"--output={build_dir}/messages_gettext.pot"] +subprocess.check_output(cmd) # add QML translations cmd = "find electrum/gui/qml -type f -name '*.qml'" files = subprocess.check_output(cmd, shell=True) -with open("electrum/locale/qml.lst", "wb") as f: +with open(f"{build_dir}/qml.lst", "wb") as f: f.write(files) print("Found {} QML files to translate".format(len(files.splitlines()))) -cmd = [QT_LUPDATE, "@electrum/locale/qml.lst","-ts", "electrum/locale/qml.ts"] +cmd = [QT_LUPDATE, f"@{build_dir}/qml.lst","-ts", f"{build_dir}/qml.ts"] print('Collecting strings') subprocess.check_output(cmd) -cmd = [QT_LCONVERT, "-of", "po", "-o", "electrum/locale/messages_qml.pot", "electrum/locale/qml.ts"] +cmd = [QT_LCONVERT, "-of", "po", "-o", f"{build_dir}/messages_qml.pot", f"{build_dir}/qml.ts"] print('Convert to gettext') subprocess.check_output(cmd) -cmd = "msgcat -u -o electrum/locale/messages.pot electrum/locale/messages_gettext.pot electrum/locale/messages_qml.pot" +cmd = ["msgcat", "-u", "-o", f"{build_dir}/messages.pot", f"{build_dir}/messages_gettext.pot", f"{build_dir}/messages_qml.pot"] print('Generate template') -subprocess.check_output(cmd, shell=True) +subprocess.check_output(cmd) # prepare uploading to crowdin @@ -91,7 +100,7 @@ if not crowdin_api_key: print('Found crowdin_api_key. Will push updated source-strings to crowdin.') crowdin_project_id = 20482 # for "Electrum" project on crowdin -locale_file_name = "locale/messages.pot" +locale_file_name = os.path.join(build_dir, "messages.pot") crowdin_file_name = "messages.pot" crowdin_file_id = 68 # for "/electrum-client/messages.pot" global_headers = {"Authorization": "Bearer {}".format(crowdin_api_key)} diff --git a/electrum/i18n.py b/electrum/i18n.py index 1ccebc337..a1a1678cd 100644 --- a/electrum/i18n.py +++ b/electrum/i18n.py @@ -31,7 +31,7 @@ from .logging import get_logger _logger = get_logger(__name__) -LOCALE_DIR = os.path.join(os.path.dirname(__file__), 'locale') +LOCALE_DIR = os.path.join(os.path.dirname(__file__), 'locale', 'locale') # Set initial default language to None. i.e. translations explicitly disabled. # The main script or GUIs can call set_language to enable translations. diff --git a/electrum/locale b/electrum/locale new file mode 160000 index 000000000..eb7298f8d --- /dev/null +++ b/electrum/locale @@ -0,0 +1 @@ +Subproject commit eb7298f8dd32eb998fd73c0806098717b7010083