1
0

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
This commit is contained in:
SomberNight
2025-04-08 15:56:35 +00:00
parent bd0085e680
commit 3567a4cfb0
15 changed files with 81 additions and 72 deletions

1
.gitignore vendored
View File

@@ -6,7 +6,6 @@ build/
dist/ dist/
*.egg/ *.egg/
Electrum.egg-info/ Electrum.egg-info/
electrum/locale/
.devlocaltmp/ .devlocaltmp/
*_trial_temp *_trial_temp
packages packages

4
.gitmodules vendored
View File

@@ -1,5 +1,5 @@
[submodule "contrib/deterministic-build/electrum-locale"] [submodule "electrum/locale"]
path = contrib/deterministic-build/electrum-locale path = electrum/locale
url = https://github.com/spesmilo/electrum-locale url = https://github.com/spesmilo/electrum-locale
[submodule "electrum/www"] [submodule "electrum/www"]
path = electrum/plugins/payserver/www path = electrum/plugins/payserver/www

View File

@@ -26,6 +26,6 @@ global-exclude *.py.orig
global-exclude *.py.rej global-exclude *.py.rej
global-exclude .git 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 (if present).
# We include both source (.po) and compiled (.mo) locale files atm (if present). # When building the "sourceonly" tar.gz, the build script explicitly deletes the compiled files.
# exclude electrum/locale/*/LC_MESSAGES/electrum.mo # exclude electrum/locale/locale/*/LC_MESSAGES/electrum.mo

View File

@@ -109,8 +109,8 @@ $ python3 -m pip install --user -e .
Create translations (optional): Create translations (optional):
``` ```
$ sudo apt-get install python3-requests gettext qt6-l10n-tools $ sudo apt-get install gettext
$ ./contrib/pull_locale $ ./contrib/build_locale.sh electrum/locale/locale electrum/locale/locale
``` ```
Finally, to start Electrum: Finally, to start Electrum:

View File

@@ -6,7 +6,6 @@ CONTRIB_ANDROID="$(dirname "$(readlink -e "$0")")"
CONTRIB="$CONTRIB_ANDROID"/.. CONTRIB="$CONTRIB_ANDROID"/..
PROJECT_ROOT="$CONTRIB"/.. PROJECT_ROOT="$CONTRIB"/..
PACKAGES="$PROJECT_ROOT"/packages/ PACKAGES="$PROJECT_ROOT"/packages/
LOCALE="$PROJECT_ROOT"/electrum/locale/
. "$CONTRIB"/build_tools_util.sh . "$CONTRIB"/build_tools_util.sh
@@ -20,17 +19,19 @@ if [ ! -d "$PACKAGES" ]; then
"$CONTRIB"/make_packages.sh || fail "make_packages failed" "$CONTRIB"/make_packages.sh || fail "make_packages failed"
fi fi
pushd "$PROJECT_ROOT"
git submodule update --init
popd
# update locale # update locale
info "preparing electrum-locale." info "preparing electrum-locale."
( (
cd "$PROJECT_ROOT"
git submodule update --init
LOCALE="$PROJECT_ROOT/electrum/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 # we want the binary to have only compiled (.mo) locale files; not source (.po) files
rm -rf "$LOCALE" rm -r locale/*/electrum.po
"$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE"
) )
pushd "$CONTRIB_ANDROID" pushd "$CONTRIB_ANDROID"

View File

@@ -140,9 +140,12 @@ info "preparing electrum-locale."
git submodule update --init git submodule update --init
LOCALE="$PROJECT_ROOT/electrum/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 # we want the binary to have only compiled (.mo) locale files; not source (.po) files
rm -rf "$LOCALE" rm -r locale/*/electrum.po
"$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE"
) )

View File

@@ -7,7 +7,6 @@ CONTRIB="$PROJECT_ROOT/contrib"
CONTRIB_SDIST="$CONTRIB/build-linux/sdist" CONTRIB_SDIST="$CONTRIB/build-linux/sdist"
DISTDIR="$PROJECT_ROOT/dist" DISTDIR="$PROJECT_ROOT/dist"
BUILDDIR="$CONTRIB_SDIST/build" BUILDDIR="$CONTRIB_SDIST/build"
LOCALE="$PROJECT_ROOT/electrum/locale"
. "$CONTRIB"/build_tools_util.sh . "$CONTRIB"/build_tools_util.sh
@@ -25,16 +24,20 @@ if ([ "$OMIT_UNCLEAN_FILES" != 1 ]); then
"$CONTRIB"/make_packages.sh || fail "make_packages failed" "$CONTRIB"/make_packages.sh || fail "make_packages failed"
fi 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. # 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 # Set option OMIT_UNCLEAN_FILES=1 to exclude the compiled locale files
# see https://askubuntu.com/a/144139 (also see MANIFEST.in) # 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 if ([ "$OMIT_UNCLEAN_FILES" != 1 ]); then
"$CONTRIB/build_locale.sh" "$LOCALE" "$LOCALE" "$CONTRIB/build_locale.sh" "$LOCALE/locale" "$LOCALE/locale"
fi fi
) )

View File

@@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
NAME_ROOT=electrum NAME_ROOT=electrum
PROJECT_ROOT="$WINEPREFIX/drive_c/electrum"
export PYTHONDONTWRITEBYTECODE=1 # don't create __pycache__/ folders with .pyc files export PYTHONDONTWRITEBYTECODE=1 # don't create __pycache__/ folders with .pyc files
@@ -10,18 +11,24 @@ set -e
. "$CONTRIB"/build_tools_util.sh . "$CONTRIB"/build_tools_util.sh
pushd $WINEPREFIX/drive_c/electrum pushd "$PROJECT_ROOT"
VERSION=$(git describe --tags --dirty --always) VERSION=$(git describe --tags --dirty --always)
info "Last commit: $VERSION" info "Last commit: $VERSION"
# Load electrum-locale for this release info "preparing electrum-locale."
git submodule update --init (
cd "$PROJECT_ROOT"
git submodule update --init
LOCALE="$WINEPREFIX/drive_c/electrum/electrum/locale/" LOCALE="$PROJECT_ROOT/electrum/locale/"
# we want the binary to have only compiled (.mo) locale files; not source (.po) files cd "$LOCALE"
rm -rf "$LOCALE" git clean -ffxd
"$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE" 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' {} + find -exec touch -h -d '2000-11-11T11:11:11+00:00' {} +
popd 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 \ --no-binary :all: --only-binary cffi,cryptography,hidapi \
--cache-dir "$WINE_PIP_CACHE_DIR" -r "$CONTRIB"/deterministic-build/requirements-hw.txt --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 # 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." 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 . $WINE_PYTHON -m pip install --no-build-isolation --no-dependencies --no-warn-script-location .

View File

@@ -1,10 +1,13 @@
#!/bin/bash #!/bin/bash
#
# This script converts human-readable (.po) locale files to compiled (.mo) locale files.
set -e set -e
if [[ ! -d "$1" || -z "$2" ]]; then if [[ ! -d "$1" || -z "$2" ]]; then
echo "usage: $0 locale_source_dir locale_dest_dir" echo "usage: $0 locale_source_dir locale_dest_dir"
echo " The dirs can match, to build in place." echo " The dirs can match, to build in place."
# ^ note: these are the paths to the "inner" locale/ dir
exit 1 exit 1
fi fi

View File

@@ -128,18 +128,23 @@ pyinstaller --version
rm -rf ./dist 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 cd "$PROJECT_ROOT"
brew install gettext git submodule update --init
brew link --force gettext
fi
LOCALE="$PROJECT_ROOT/electrum/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 # we want the binary to have only compiled (.mo) locale files; not source (.po) files
rm -rf "$LOCALE" rm -r locale/*/electrum.po
"$CONTRIB/build_locale.sh" "$CONTRIB/deterministic-build/electrum-locale/locale/" "$LOCALE"
) || fail "failed generating locale" ) || fail "failed generating locale"

View File

@@ -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])

View File

@@ -1,4 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
#
# This script extracts "raw" strings from the codebase,
# and uploads them to crowdin, for the community to translate them.
#
# Dependencies: # Dependencies:
# $ sudo apt-get install python3-requests gettext qt6-l10n-tools # $ 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__))) project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
os.chdir(project_root) 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 # check dependencies are available
try: try:
subprocess.check_output(["xgettext", "--version"]) 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()))) print("Found {} files to translate".format(len(files.splitlines())))
# Generate fresh translation template # Generate fresh translation template
if not os.path.exists('electrum/locale'): build_dir = os.path.join(locale_dir, "build")
os.mkdir('electrum/locale') if not os.path.exists(build_dir):
os.mkdir(build_dir)
print('Generating template...') print('Generating template...')
cmd = 'xgettext -s --from-code UTF-8 --language Python --no-wrap -f app.fil --output=electrum/locale/messages_gettext.pot' 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, shell=True) subprocess.check_output(cmd)
# add QML translations # add QML translations
cmd = "find electrum/gui/qml -type f -name '*.qml'" cmd = "find electrum/gui/qml -type f -name '*.qml'"
files = subprocess.check_output(cmd, shell=True) 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) f.write(files)
print("Found {} QML files to translate".format(len(files.splitlines()))) 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') print('Collecting strings')
subprocess.check_output(cmd) 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') print('Convert to gettext')
subprocess.check_output(cmd) 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') print('Generate template')
subprocess.check_output(cmd, shell=True) subprocess.check_output(cmd)
# prepare uploading to crowdin # 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.') print('Found crowdin_api_key. Will push updated source-strings to crowdin.')
crowdin_project_id = 20482 # for "Electrum" project on 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_name = "messages.pot"
crowdin_file_id = 68 # for "/electrum-client/messages.pot" crowdin_file_id = 68 # for "/electrum-client/messages.pot"
global_headers = {"Authorization": "Bearer {}".format(crowdin_api_key)} global_headers = {"Authorization": "Bearer {}".format(crowdin_api_key)}

View File

@@ -31,7 +31,7 @@ from .logging import get_logger
_logger = get_logger(__name__) _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. # Set initial default language to None. i.e. translations explicitly disabled.
# The main script or GUIs can call set_language to enable translations. # The main script or GUIs can call set_language to enable translations.

1
electrum/locale Submodule

Submodule electrum/locale added at eb7298f8dd