1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-07-05 03:22:53 +00:00

Add script to download translations

Ideally this'd work per-branch, and be done as part of ./go4it build,
but this works for now.
This commit is contained in:
Jonathan Coates 2024-11-15 08:12:45 +00:00
parent 8bed862c38
commit 6bc161ac42
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
2 changed files with 74 additions and 22 deletions

10
.gitignore vendored
View File

@ -2,15 +2,5 @@
/mc-* /mc-*
/license-tools /license-tools
# Build output
/buildSrc
/.idea
/.gradle
/logs
/gradle*
/*.gradle
/*.gradle.kts
/build
# Misc # Misc
/.mailmap /.mailmap

86
go4it
View File

@ -12,8 +12,8 @@ We then build each branch, push changes, and upload all versions.
import argparse import argparse
import dataclasses import dataclasses
import enum import enum
import functools
import http.client import http.client
import itertools
import json import json
import os import os
import os.path import os.path
@ -24,6 +24,8 @@ import urllib.request
import urllib.response import urllib.response
from typing import Any, TypedDict, assert_never from typing import Any, TypedDict, assert_never
import yaml
@dataclasses.dataclass(frozen=True, slots=True) @dataclasses.dataclass(frozen=True, slots=True)
class Branch: class Branch:
@ -124,20 +126,32 @@ class StorageUploadResult(TypedDict):
id: int id: int
class _SkipErrorProcessor(urllib.request.HTTPErrorProcessor):
def http_response(self, request, response):
return response
https_response = http_response
@functools.lru_cache
def no_error_opener() -> urllib.request.OpenerDirector:
"""Create an opener that doesn't throw an error on HTTP errors."""
return urllib.request.build_opener(_SkipErrorProcessor())
def request_json(request: str | urllib.request.Request) -> Any: def request_json(request: str | urllib.request.Request) -> Any:
"""Make a HTTP request, and then decode the response as JSON.""" """Make a HTTP request, and then decode the response as JSON."""
response: http.client.HTTPResponse response: http.client.HTTPResponse
with urllib.request.urlopen(request) as response: with no_error_opener().open(request) as response:
if response.status not in (200, 201): if response.status not in (200, 201):
url = request if isinstance(request, str) else request.full_url url = request if isinstance(request, str) else request.full_url
print(response.read())
raise ValueError(f"Bad response to {url}: {response.status} {response.reason}") raise ValueError(f"Bad response to {url}: {response.status} {response.reason}")
return json.load(response) return json.load(response)
def request_crowdin[ def request_crowdin[T](
T
](
path: str, ty: type[T], *, method: str = "GET", body: str | None = None, headers: dict[str, str] | None = None path: str, ty: type[T], *, method: str = "GET", body: str | None = None, headers: dict[str, str] | None = None
) -> CrowdinResponse[T]: ) -> CrowdinResponse[T]:
"""Make a request to the Crowdin API""" """Make a request to the Crowdin API"""
@ -224,18 +238,24 @@ class TranslationLoader:
return current return current
def upload_translations() -> None: def get_translation_file() -> int:
""" """Get the translation file from Crowdin"""
Upload our en_us.json translations to Crowdin.
"""
# Fetch the current translations from Crowdin.
raw_files = request_crowdin(f"/projects/{CROWDIN_PROJECT}/files", list[CrowdinData[ProjectFile]])["data"] raw_files = request_crowdin(f"/projects/{CROWDIN_PROJECT}/files", list[CrowdinData[ProjectFile]])["data"]
files = [file["data"] for file in raw_files if file["data"]["name"] == "en_us.json"] files = [file["data"] for file in raw_files if file["data"]["name"] == "en_us.json"]
if len(files) != 1: if len(files) != 1:
log(f"Found {len(files)} matching translations") log(f"Found {len(files)} matching translations")
sys.exit(1) sys.exit(1)
remote_dl = request_crowdin(f"/projects/{CROWDIN_PROJECT}/files/{files[0]["id"]}/download", FileDownloadResult) return files[0]["id"]
def upload_translations() -> None:
"""
Upload our en_us.json translations to Crowdin.
"""
# Fetch the current translations from Crowdin.
file = get_translation_file()
remote_dl = request_crowdin(f"/projects/{CROWDIN_PROJECT}/files/{file}/download", FileDownloadResult)
remote_strings: dict[str, str] = request_json(remote_dl["data"]["url"]) remote_strings: dict[str, str] = request_json(remote_dl["data"]["url"])
# Compute our local translations across our branches. # Compute our local translations across our branches.
@ -280,7 +300,7 @@ def upload_translations() -> None:
)["data"]["id"] )["data"]["id"]
request_crowdin( request_crowdin(
f"/projects/{CROWDIN_PROJECT}/files/{files[0]["id"]}", f"/projects/{CROWDIN_PROJECT}/files/{file}",
object, object,
method="PUT", method="PUT",
body=json.dumps({"storageId": storage}), body=json.dumps({"storageId": storage}),
@ -290,6 +310,45 @@ def upload_translations() -> None:
log("Translations updated!") log("Translations updated!")
def download_translations() -> None:
"""
Upload our en_us.json translations to Crowdin.
"""
# Fetch the current translations from Crowdin.
file = get_translation_file()
branch = BRANCHES[0].name
with open(f"{branch}/crowdin.yml") as h:
crowdin_config = yaml.safe_load(h)["files"][0]
languages: dict[str, str] = crowdin_config["languages_mapping"]["locale_with_underscore"]
with open(f"{branch}/{crowdin_config["source"]}") as h:
local_strings: dict[str, str] = json.load(h)
for language, name in languages.items():
log(f"Fetching {language}")
remote_dl = request_crowdin(
f"/projects/{CROWDIN_PROJECT}/translations/exports",
FileDownloadResult,
method="POST",
headers={"Content-Type": "application/json"},
body=json.dumps(
{
"targetLanguageId": language,
"fileIds": [file],
}
),
)
remote_strings: dict[str, str] = request_json(remote_dl["data"]["url"])
dest = crowdin_config["translation"].replace("%locale_with_underscore%", name)
with open(f"{branch}/{dest}", "w") as h:
json.dump(
{k: remote_strings[k] for k in local_strings if k in remote_strings}, h, indent=4, ensure_ascii=False
)
h.write("\n")
################################################################################ ################################################################################
# Git and Gradle Commands # Git and Gradle Commands
################################################################################ ################################################################################
@ -410,6 +469,9 @@ def main() -> None:
) )
subparsers.add_parser("build", help="Merge and build all branches.").set_defaults(func=build) subparsers.add_parser("build", help="Merge and build all branches.").set_defaults(func=build)
subparsers.add_parser("release", help="Publish a release.").set_defaults(func=release) subparsers.add_parser("release", help="Publish a release.").set_defaults(func=release)
subparsers.add_parser("download-translations", help="Download crowdin translations.").set_defaults(
func=download_translations
)
subparsers.add_parser("upload-translations", help="Upload crowdin translations.").set_defaults( subparsers.add_parser("upload-translations", help="Upload crowdin translations.").set_defaults(
func=upload_translations func=upload_translations
) )