|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
#!/bin/python3
|
|
|
|
|
import re
|
|
|
|
|
from typing import List, Tuple
|
|
|
|
|
|
|
|
|
|
OUTPUT_FILE = "./ts/localization/locales.ts"
|
|
|
|
|
|
|
|
|
@ -49,6 +50,100 @@ def generate_js_object(data):
|
|
|
|
|
return js_object
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extract_vars(text):
|
|
|
|
|
# Use a regular expression to find all strings inside curly braces
|
|
|
|
|
vars = re.findall(r'\{(.*?)\}', text)
|
|
|
|
|
return vars
|
|
|
|
|
|
|
|
|
|
def extract_plurals(text: str) -> List[Tuple[str, str]]:
|
|
|
|
|
pattern = r'(\b\w+\b)\s*(\[[^\]]+\])'
|
|
|
|
|
|
|
|
|
|
matches = re.findall(pattern, text)
|
|
|
|
|
|
|
|
|
|
return matches
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def vars_to_record(vars):
|
|
|
|
|
arr = []
|
|
|
|
|
for var in vars:
|
|
|
|
|
to_append = '"' + var + '": ' + ('number' if var == 'count' else 'string')
|
|
|
|
|
if to_append not in arr:
|
|
|
|
|
arr.append(to_append)
|
|
|
|
|
|
|
|
|
|
# print(arr)
|
|
|
|
|
if not arr:
|
|
|
|
|
return ''
|
|
|
|
|
return "{" + ', '.join(arr) + "}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def replace_static_strings(str):
|
|
|
|
|
|
|
|
|
|
# todo make those come from the glossary
|
|
|
|
|
replaced = str.replace("{app_name}", "Session")\
|
|
|
|
|
.replace("{session_download_url}", "https://getsession.org/download")\
|
|
|
|
|
.replace("{session_download_url}", "GIF")\
|
|
|
|
|
.replace("{oxen_foundation}", "Oxen Foundation")\
|
|
|
|
|
.replace("\"", "\\\"")
|
|
|
|
|
return replaced
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_type_object(locales):
|
|
|
|
|
"""
|
|
|
|
|
Generate a JavaScript type from a dictionary.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
data (dict): The dictionary containing key-value pairs.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
str: A string representation of the JavaScript object.
|
|
|
|
|
"""
|
|
|
|
|
js_object = "{\n"
|
|
|
|
|
|
|
|
|
|
for key, value_en in locales['en'].items():
|
|
|
|
|
# print('value',value)
|
|
|
|
|
if value_en.startswith("{count, plural, "):
|
|
|
|
|
continue
|
|
|
|
|
# plurals = extract_plurals(value)
|
|
|
|
|
# print(plurals)
|
|
|
|
|
# js_plural_object = "{\n"
|
|
|
|
|
|
|
|
|
|
# for plural in plurals:
|
|
|
|
|
# plural_token = plural[0]
|
|
|
|
|
# plural_str = plural[1].replace('#', '{count}')
|
|
|
|
|
# extracted_vars = extract_vars(replace_static_strings(plural_str))
|
|
|
|
|
# if('count' not in extracted_vars):
|
|
|
|
|
# extracted_vars.append('count')
|
|
|
|
|
# print('extracted_vars',extracted_vars)
|
|
|
|
|
|
|
|
|
|
# as_record_type = vars_to_record(extracted_vars)
|
|
|
|
|
# js_plural_object += f" {wrapValue(plural_token)}: {as_record_type},\n"
|
|
|
|
|
# js_plural_object += " }"
|
|
|
|
|
# js_object += f" {wrapValue(key)}: {js_plural_object},\n"
|
|
|
|
|
else:
|
|
|
|
|
replaced_en = replace_static_strings(value_en)
|
|
|
|
|
extracted_vars = extract_vars(replaced_en)
|
|
|
|
|
as_record_type = vars_to_record(extracted_vars)
|
|
|
|
|
other_locales_replaced_values = [[locale, replace_static_strings(data.get(key, ""))] for locale, data in locales.items()]
|
|
|
|
|
|
|
|
|
|
filtered_values = []
|
|
|
|
|
# filter out strings that matches the english one (i.e. untranslated strings)
|
|
|
|
|
for locale, replaced_val in other_locales_replaced_values:
|
|
|
|
|
if replaced_val == replaced_en and not locale == 'en':
|
|
|
|
|
# print(f"{locale}: ${key} saved content is the same as english saved.")
|
|
|
|
|
filtered_values.append(f"{locale}: undefined")
|
|
|
|
|
else:
|
|
|
|
|
filtered_values.append(f"{locale}: \"{replaced_val}\"")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# print('key',key, " other_locales_replaced_values:", other_locales_replaced_values)
|
|
|
|
|
js_object += f" {wrapValue(key)}:{{\n {",\n ".join(filtered_values)},\n args: {as_record_type if as_record_type else 'undefined'}\n }},\n"
|
|
|
|
|
|
|
|
|
|
js_object += "}"
|
|
|
|
|
return js_object
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DISCLAIMER = """
|
|
|
|
|
// This file was generated by a script. Do not modify this file manually.
|
|
|
|
|
// To make changes, modify the corresponding JSON file and re-run the script.
|
|
|
|
@ -56,7 +151,7 @@ DISCLAIMER = """
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generateLocalesType(locale):
|
|
|
|
|
def generateLocalesType(locale, data):
|
|
|
|
|
"""
|
|
|
|
|
Generate the locales type and write it to a file.
|
|
|
|
|
|
|
|
|
@ -67,6 +162,35 @@ def generateLocalesType(locale):
|
|
|
|
|
with open(OUTPUT_FILE, "w", encoding='utf-8') as ts_file:
|
|
|
|
|
ts_file.write(
|
|
|
|
|
f"{DISCLAIMER}"
|
|
|
|
|
f"export const en = {generate_js_object(locale)} as const;\nexport type Dictionary = typeof en;"
|
|
|
|
|
)
|
|
|
|
|
ts_file.write(
|
|
|
|
|
f"export const {locale} = {generate_js_object(data)} as const;\n"
|
|
|
|
|
)
|
|
|
|
|
ts_file.write(
|
|
|
|
|
f"\nexport type Dictionary = typeof en;\n"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return f"Locales generated at: {OUTPUT_FILE}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generateLocalesMergedType(locales):
|
|
|
|
|
"""
|
|
|
|
|
Generate the locales type and write it to a file.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
locale: The locale dictionary containing the localization data.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# write the locale_dict to a file
|
|
|
|
|
with open(OUTPUT_FILE, "w", encoding='utf-8') as ts_file:
|
|
|
|
|
ts_file.write(
|
|
|
|
|
f"{DISCLAIMER}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
ts_file.write(
|
|
|
|
|
f"export const plop = {generate_type_object(locales)};\n"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return f"Locales generated at: {OUTPUT_FILE}"
|
|
|
|
|
|
|
|
|
|