diff options
| author | cyberta <cyberta@riseup.net> | 2026-07-03 15:19:03 +0200 |
|---|---|---|
| committer | cyberta <cyberta@riseup.net> | 2026-07-03 15:19:03 +0200 |
| commit | 5186251010419535fa706686ae89c4305f9a260b (patch) | |
| tree | b24375493fd7cd78e25defddfcceccced61241b4 | |
| parent | a7a4154854eff96dac3c85e8bba7dbb99f8c6f28 (diff) | |
replace pullTranslations.py, which is deprecated and still relied on Transifex with a simple bash script that expcets that the l10s git reposotory is on the same directory level as bitmasks root directory
| -rw-r--r-- | scripts/pullTranslations.py | 273 | ||||
| -rwxr-xr-x | scripts/pull_metadata.sh | 29 |
2 files changed, 29 insertions, 273 deletions
diff --git a/scripts/pullTranslations.py b/scripts/pullTranslations.py deleted file mode 100644 index 2a929256..00000000 --- a/scripts/pullTranslations.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/env python3 -""" -Pull store metadata translations from the l10n git repo and split into -fastlane-compatible files. Creates a MR against bitmask_android. -""" -__author__ = "kwadronaut, cyberta" -__copyright__ = "Copyright 2026, LEAP" -__license__ = "GPL3 or later" -__version__ = "3" - -import os -import re -import json -import shutil -import subprocess -import sys -import argparse -import tempfile -import urllib.request -import urllib.error - -def get_script_path(): - return os.path.dirname(os.path.realpath(sys.argv[0])) - - -# --------------------------------------------------------------------------- -# Config -# --------------------------------------------------------------------------- - -APP_CONFIG = { - "main": { - "l10n_branch": "bitmask-playstore", - "metadata_dir": "src/normalProductionFat/fastlane/metadata/android", - }, - "custom": { - "l10n_branch": "bitmask.riseupvpn-playstore-metadata", - "metadata_dir": "src/customProductionFat/fastlane/metadata/android", - }, -} - -L10N_REPO = "https://0xacab.org/leap/l10n.git" -GITLAB_API = "https://0xacab.org/api/v4" -BITMASK_ANDROID_PROJECT_ID = "leap%2Fbitmask_android" - -# Play Store doesn't support Cuban Spanish, but maybe other store do -SKIP_LOCALES = {"es_CU"} - -# Explicit locale mappings: l10n filename stem -> Play Store / fastlane dir name -# Only entries that differ from the default (underscore->dash) need to be here -LOCALE_MAP = { - "en": "en-US", - "zh_Hans": "zh-CN", - "zh_Hant": "zh-TW", - "pt_BR": "pt-BR", -} - - -# --------------------------------------------------------------------------- -# Locale helpers -# --------------------------------------------------------------------------- - -def stem(filename): - """Return filename without .json extension.""" - return filename.replace(".json", "") - - -def to_fastlane_locale(locale_stem): - """Map a l10n locale stem to a Play Store / fastlane directory.""" - if locale_stem in SKIP_LOCALES: - return None - if locale_stem in LOCALE_MAP: - return LOCALE_MAP[locale_stem] - # default: replace underscore with dash - return locale_stem.replace("_", "-") - - -# --------------------------------------------------------------------------- -# Cloning the l10n repo -# --------------------------------------------------------------------------- - -def clone_l10n_repo(branch, token=None): - """ - Shallow-clone the l10n repo at branch into a temp directory. - Returns the path to the cloned directory. - """ - tmpdir = tempfile.mkdtemp(prefix="l10n_") - repo_url = L10N_REPO - if token: - # token into URL - repo_url = repo_url.replace("https://", f"https://l10n-lab-weblate:{token}@") - - cmd = [ - "git", "clone", - "--depth", "1", - "--branch", branch, - repo_url, - tmpdir, - ] - print(f"Cloning l10n repo (branch: {branch}) ...") - subprocess.run(cmd, check=True) - return tmpdir - - -# --------------------------------------------------------------------------- -# Processing JSON files -# --------------------------------------------------------------------------- - -def process_locale_files(l10n_dir, metadata_dir): - """ - Read each <locale>.json from l10n_dir, map to fastlane locale name, - write title.txt / full_description.txt / short_description.txt. - """ - processed = [] - skipped = [] - - for filename in sorted(os.listdir(l10n_dir)): - if not filename.endswith(".json"): - continue - - locale_stem = stem(filename) - fastlane_locale = to_fastlane_locale(locale_stem) - - if fastlane_locale is None: - skipped.append(locale_stem) - continue - - json_path = os.path.join(l10n_dir, filename) - with open(json_path, "r", encoding="utf-8") as f: - try: - data = json.load(f) - except json.JSONDecodeError as e: - print(f" WARNING: skipping {filename}: {e}") - continue - - if not data: - skipped.append(locale_stem) - continue - - locale_dir = os.path.join(metadata_dir, fastlane_locale) - os.makedirs(locale_dir, exist_ok=True) - - wrote_any = False - for key, out_filename in [ - ("title", "title.txt"), - ("full_description", "full_description.txt"), - ("short_description", "short_description.txt"), - ]: - value = data.get(key) - if value: - out_path = os.path.join(locale_dir, out_filename) - with open(out_path, "w", encoding="utf-8") as f: - f.write(value) - wrote_any = True - - if wrote_any: - processed.append(f"{locale_stem} -> {fastlane_locale}") - else: - skipped.append(locale_stem) - - print(f"\nProcessed: {', '.join(processed)}") - if skipped: - print(f"Skipped: {', '.join(skipped)}") - - -# --------------------------------------------------------------------------- -# GitLab MR -# --------------------------------------------------------------------------- - -def create_mr(token, source_branch, target_branch="master", app_type="main"): - """Open a merge request on bitmask_android via the GitLab API.""" - url = f"{GITLAB_API}/projects/{BITMASK_ANDROID_PROJECT_ID}/merge_requests" - payload = json.dumps({ - "source_branch": source_branch, - "target_branch": target_branch, - "title": f"chore: update {app_type} Play Store translations", - "description": "Automated update from the l10n repo (Weblate).", - "remove_source_branch": True, - }).encode("utf-8") - - req = urllib.request.Request( - url, - data=payload, - headers={ - "Content-Type": "application/json", - "PRIVATE-TOKEN": token, - }, - method="POST", - ) - try: - with urllib.request.urlopen(req) as resp: - mr = json.loads(resp.read()) - print(f"\nMR created: {mr['web_url']}") - except urllib.error.HTTPError as e: - body = e.read().decode() - print(f"\nFailed to create MR: {e.code} {body}", file=sys.stderr) - - -def commit_and_push(repo_root, source_branch, app_type): - """Stage changes, commit, push to a new branch.""" - def git(*args): - subprocess.run(["git", "-C", repo_root] + list(args), check=True) - - git("checkout", "-b", source_branch) - git("add", APP_CONFIG[app_type]["metadata_dir"]) - - result = subprocess.run( - ["git", "-C", repo_root, "diff", "--cached", "--quiet"], - capture_output=True, - ) - if result.returncode == 0: - print("No changes to commit.") - return False - - git("commit", "-m", f"chore: update {app_type} Play Store translations from Weblate") - git("push", "origin", source_branch) - return True - - -# --------------------------------------------------------------------------- -# Main -# --------------------------------------------------------------------------- - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="Pull Play Store translations from l10n repo and create MR." - ) - parser.add_argument( - "app_type", - choices=["main", "custom"], - help="'main' for Bitmask, 'custom' for RiseupVPN", - ) - parser.add_argument( - "--token", - default=os.environ.get("L10N_GITLAB_TOKEN"), - help="GitLab token for l10n-lab-weblate (or set L10N_GITLAB_TOKEN env var)", - ) - parser.add_argument( - "--target-branch", - default="master", - help="Target branch for the MR (default: master)", - ) - parser.add_argument( - "--mr-branch", - default=None, - help="Source branch name for the MR (default: auto-generated)", - ) - args = parser.parse_args() - - config = APP_CONFIG[args.app_type] - repo_root = os.path.abspath(os.path.join(get_script_path(), "..")) - metadata_dir = os.path.join(repo_root, config["metadata_dir"]) - mr_branch = args.mr_branch or f"translations/{args.app_type}-playstore-update" - - # 1. Clone l10n repo - l10n_dir = clone_l10n_repo(config["l10n_branch"], token=args.token) - - try: - # 2. Process JSON files -> fastlane txt files - print(f"\nWriting fastlane metadata to: {metadata_dir}") - process_locale_files(l10n_dir, metadata_dir) - - # 3. Commit & push - pushed = commit_and_push(repo_root, mr_branch, args.app_type) - - # 4. Open MR - if pushed: - if args.token: - create_mr(args.token, mr_branch, args.target_branch, args.app_type) - else: - print("\nNo token provided — skipping MR creation.") - print(f"Push branch '{mr_branch}' and open MR manually.") - finally: - shutil.rmtree(l10n_dir, ignore_errors=True) diff --git a/scripts/pull_metadata.sh b/scripts/pull_metadata.sh new file mode 100755 index 00000000..a9156a8c --- /dev/null +++ b/scripts/pull_metadata.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +L10N_DIR="$(cd "$PROJECT_ROOT/../l10n" && pwd)" + +MODE="${1:-normal}" # normal|custom +case "$MODE" in + normal|custom) ;; + *) echo "Usage: $0 [normal|custom]"; exit 1 ;; +esac + +SRC_GLOB="$L10N_DIR/bitmask-playstore-metadata/*.json" +OUT_BASE="$PROJECT_ROOT/src/${MODE}ProductionFat/fastlane/metadata/android" + +command -v jq >/dev/null 2>&1 || { echo "Missing jq"; exit 1; } + +for json in $SRC_GLOB; do + [ -e "$json" ] || break + lang="$(basename "$json" .json)" + echo "updating meta data for langauge $lang" + out_dir="$OUT_BASE/$lang" + mkdir -p "$out_dir" + + jq -r '.full_description' "$json" > "$out_dir/full_description.txt" + jq -r '.short_description' "$json" > "$out_dir/short_description.txt" + jq -r '.title' "$json" > "$out_dir/title.txt" +done |
