diff --git a/.github/workflows/crowdin-commit.yml b/.github/workflows/crowdin-commit.yml new file mode 100644 index 0000000..ef02ae3 --- /dev/null +++ b/.github/workflows/crowdin-commit.yml @@ -0,0 +1,77 @@ +name: "Crowdin: Import translations" + +on: + schedule: + - cron: "0 0 1,15 * *" + workflow_dispatch: + +jobs: + import: + runs-on: ubuntu-latest + container: devkitpro/devkitarm + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: recursive + + - name: Setup environment + run: git config --global safe.directory '*' + + - name: Install tools + run: | + apt-get update + apt-get install python3 python3-pip -y + python3 -m pip install --upgrade pip setuptools --break-system-packages + python3 -m pip install cryptography git+https://github.com/TuxSH/firmtool.git --break-system-packages + + - uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Setup Crowdin CLI + run: | + npm i -g @crowdin/cli + + - name: Pull from Crowdin + shell: bash + env: + CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }} + run: | + crowdin pull + + set +e # continue on errors, we're using the exit code + for item in resources/languages/*.json; do + if ! [[ $item =~ (source|en).json$ ]]; then + # Check if the translation is over 30% translated + utils/transcheck.py resources/languages/source.json $item 30 + if [[ $? -ne 0 ]]; then + rm $item + fi + fi + done + + - name: Pull origin + run: git pull origin master --ff-only # Pull origin in case a commit has been done while updating + + # This makes sure that the app actually builds before pushing to master + - name: Build test + run: | + make release -j$(nproc) + + - name: Commit changes + continue-on-error: true + run: | + git config user.email "actions@github.com" + git config user.name "GitHub Actions" + + git checkout master + git stage resources/languages + git commit -m "Automatic translation import" + + - name: Push changes + uses: ad-m/github-push-action@master + with: + branch: master + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml new file mode 100644 index 0000000..432ca69 --- /dev/null +++ b/.github/workflows/crowdin-upload.yml @@ -0,0 +1,38 @@ +name: "Crowdin: Upload source" + +on: + push: + branches: [ master ] + paths: [ 'resources/languages/source.json' ] + +jobs: + upload: + runs-on: ubuntu-latest + container: devkitpro/devkitarm + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: recursive + + - name: Setup environment + run: git config --global safe.directory '*' + + - name: Install tools + run: | + apt-get update + apt-get -y install python3 python3-pip p7zip-full libarchive13 + python3 -m pip install --upgrade pip setuptools --break-system-packages + python3 -m pip install cryptography git+https://github.com/TuxSH/firmtool.git --break-system-packages + + - name: Build test + run: | + make release -j$(nproc) + + - name: Push to Crowdin + uses: crowdin/github-action@v2 + with: + upload_sources: true + env: + CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }} diff --git a/utils/transcheck.py b/utils/transcheck.py new file mode 100755 index 0000000..214a333 --- /dev/null +++ b/utils/transcheck.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser, FileType +import json + +# Special keys +LANGUAGE_NAME = "GM9_LANGUAGE" +VERSION = "GM9_TRANS_VER" + + +def check_translation(source, translation, threshold): + # Sanity check the versions + if source[VERSION] != translation[VERSION]: + raise Exception("Version mismatch (%d != %d)" % (source[VERSION], translation[VERSION])) + del source[VERSION] + + # Make sure the language has a name + if source[LANGUAGE_NAME] == translation[LANGUAGE_NAME]: + print("\x1B[33mError: Language name matches source (%s)\x1B[39m" % translation[LANGUAGE_NAME]) + return False + del source[LANGUAGE_NAME] + + # Check how many strings have been translated + translated_count = 0 + for item in source: + if item in translation and source[item] != translation[item]: + translated_count += 1 + + # Check if this translation meets the threshold percentage + percent_translated = translated_count / len(source) * 100 + valid = percent_translated >= threshold + print("\x1B[%om%s: %d of %d items translated (%.2f%%)\x1B[39m" % (0o32 if valid else 0o31, translation[LANGUAGE_NAME], translated_count, len(source), percent_translated)) + return valid + + +def main(): + parser = ArgumentParser(description="Checks if a translation is ready for use") + parser.add_argument("source", type=FileType("r", encoding="utf-8"), help="source.json") + parser.add_argument("translation", type=FileType("r", encoding="utf-8"), help="[LANG].json") + parser.add_argument("threshold", type=int, help="minimum translation percentage") + args = parser.parse_args() + + # Load the JSONs + source = json.load(args.source) + translation = json.load(args.translation) + + res = check_translation(source, translation, args.threshold) + exit(0 if res else 1) + + +if __name__ == "__main__": + main()