diff --git a/tools/localazy/README.md b/tools/localazy/README.md index 54ee857242..ea60a1743b 100644 --- a/tools/localazy/README.md +++ b/tools/localazy/README.md @@ -6,7 +6,7 @@ Localazy is used to host the source strings and their translations. To add new strings, or to translate existing strings, go the the Localazy project: [https://localazy.com/p/element](https://localazy.com/p/element). -Never edit manually the files `localazy.xml`!. +Never edit manually the files `localazy.xml` or `translations.xml`!. ## CLI Installation @@ -17,7 +17,13 @@ To install the Localazy client, follow the instructions from [here](https://loca In the root folder of the project, run: ```shell -localazy download --config ./tools/localazy/localazy.json +./tools/localazy/downloadStrings.sh ``` -It will update all the `localazy.xml` resource files. In case of merge conflicts, just erase the files and download again using the Localazy client. +It will update all the `localazy.xml` and `translations.xml` resource files. In case of merge conflicts, just erase the files and download again using the script. + +## Add translations to a specific module + +Edit the file [config.json](./config.json) to add a new module, or add a new item in `includeRegex` arrays, then run the script again to see the effect. + +[generateLocalazyConfig.py](generateLocalazyConfig.py) is the Python script that convert `config.json` to a localazy configuration file. Generally should not edit this file. diff --git a/tools/localazy/config.json b/tools/localazy/config.json new file mode 100644 index 0000000000..8061d126a9 --- /dev/null +++ b/tools/localazy/config.json @@ -0,0 +1,62 @@ +{ + "modules": [ + { + "name": ":features:rageshake:impl", + "includeRegex": [ + "screen_bug_report_.*" + ] + }, + { + "name": ":features:rageshake:api", + "includeRegex": [ + "crash_detection_.*", + "rageshake_detection_.*" + ] + }, + { + "name": ":features:logout:api", + "includeRegex": [ + "screen_signout_.*" + ] + }, + { + "name": ":features:onboarding:impl", + "includeRegex": [ + "screen_onboarding_.*" + ] + }, + { + "name": ":features:createroom:impl", + "includeRegex": [ + "screen_create_room_.*" + ] + }, + { + "name": ":features:verifysession:impl", + "includeRegex": [ + "screen_session_verification_.*" + ] + }, + { + "name": ":libraries:textcomposer", + "includeRegex": [ + "rich_text_editor_.*" + ] + }, + { + "name": ":features:login:impl", + "includeRegex": [ + "screen_login_.*", + "screen_change_server_.*" + ] + }, + { + "name": ":features:roomlist:impl", + "includeRegex": [ + "state_event_.*", + "screen_roomlist_.*", + "session_verification_banner_.*" + ] + } + ] +} diff --git a/tools/localazy/downloadStrings.sh b/tools/localazy/downloadStrings.sh new file mode 100755 index 0000000000..163aab8e31 --- /dev/null +++ b/tools/localazy/downloadStrings.sh @@ -0,0 +1,34 @@ +#! /bin/bash + +# +# Copyright (c) 2023 New Vector Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -e + +echo "Generating the configuration file for localazy..." +./tools/localazy/generateLocalazyConfig.py + +echo "Deleting all existing localazy.xml and translations.xml files..." +find . -name 'localazy.xml' -delete +find . -name 'translations.xml' -delete + +echo "Importing the strings..." +localazy download --config ./tools/localazy/localazy.json + +echo "Removing the generated config" +rm ./tools/localazy/localazy.json + +echo "Success!" diff --git a/tools/localazy/generateLocalazyConfig.py b/tools/localazy/generateLocalazyConfig.py new file mode 100755 index 0000000000..829541462e --- /dev/null +++ b/tools/localazy/generateLocalazyConfig.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +import json + +# Read the config.json file +with open('./tools/localazy/config.json', 'r') as f: + config = json.load(f) + + +# Convert a module name to a path +# Ex: ":features:verifysession:impl" => "features/verifysession/impl" +def convertModuleToPath(name): + return name[1:].replace(":", "/") + +# Regex that will be excluded from the Android project, you may add items here if necessary. +regexToAlwaysExclude = [ + "Notification", + ".*_ios" +] + +# Store all regex specific to module, to eclude the corresponding keyx from the common string module +allRegexToExcludeFromMainModule = [] +# All actions that will be serialized in the localazy config +allActions = [] + +# Iterating on the config +for entry in config["modules"]: + # Create action for the default language + action = { + "type": "android", + "output": convertModuleToPath(entry["name"]) + "/src/main/res/values/localazy.xml", + "includeKeys": list(map(lambda i: "REGEX:" + i, entry["includeRegex"])), + "excludeKeys": list(map(lambda i: "REGEX:" + i, regexToAlwaysExclude)), + "conditions": [ + "equals: ${languageCode}, en" + ] + } + # Create action for the translations + actionTranslation = { + "type": "android", + "output": convertModuleToPath(entry["name"]) + "/src/main/res/values-${langAndroidResNoScript}/translations.xml", + "includeKeys": list(map(lambda i: "REGEX:" + i, entry["includeRegex"])), + "excludeKeys": list(map(lambda i: "REGEX:" + i, regexToAlwaysExclude)), + "conditions": [ + "!equals: ${languageCode}, en" + ] + } + # print(action) + allRegexToExcludeFromMainModule.extend(entry["includeRegex"]) + allActions.append(action) + allActions.append(actionTranslation) + +# Append configuration for the main string module: default language +mainAction = { + "type": "android", + "output": "libraries/ui-strings/src/main/res/values/localazy.xml", + "excludeKeys": list(map(lambda i: "REGEX:" + i, allRegexToExcludeFromMainModule + regexToAlwaysExclude)), + "conditions": [ + "equals: ${languageCode}, en" + ] +} +# print(mainAction) +allActions.append(mainAction) + +# Append configuration for the main string module: translations +mainActionTranslation = { + "type": "android", + "output": "libraries/ui-strings/src/main/res/values-${langAndroidResNoScript}/translations.xml", + "excludeKeys": list(map(lambda i: "REGEX:" + i, allRegexToExcludeFromMainModule + regexToAlwaysExclude)), + "conditions": [ + "!equals: ${languageCode}, en" + ] +} +allActions.append(mainActionTranslation) + +# Generate the configuration for localazy +result = { + "readKey": "a7876306080832595063-aa37154bb3772f6146890fca868d155b2228b492c56c91f67abdcdfb74d6142d", + "conversion": { + "actions": allActions + } +} + +# Json serialization +with open('./tools/localazy/localazy.json', 'w') as json_file: + json.dump(result, json_file, indent=4, sort_keys=True) diff --git a/tools/localazy/localazy.json b/tools/localazy/localazy.json deleted file mode 100644 index 5052584986..0000000000 --- a/tools/localazy/localazy.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "readKey": "a7876306080832595063-aa37154bb3772f6146890fca868d155b2228b492c56c91f67abdcdfb74d6142d", - - "conversion": { - "actions": [ - { - "type": "android", - "output": "libraries/ui-strings/src/main/res/values/localazy.xml", - "conditions": [ "equals: ${languageCode}, en" ] - }, - { - "type": "android", - "output": "libraries/ui-strings/src/main/res/values-${langAndroidResNoScript}/localazy.xml", - "conditions": [ "!equals: ${languageCode}, en" ] - } - ] - } -}