Index: cms/bin/translate.py |
diff --git a/cms/bin/translate.py b/cms/bin/translate.py |
index 4a4e3d87dc0efff31bf0208b9d71e3c8337ccd15..5a855be517d056a698b5018f769ac6883708e011 100644 |
--- a/cms/bin/translate.py |
+++ b/cms/bin/translate.py |
@@ -22,6 +22,7 @@ import json |
import logging |
import os |
import posixpath |
+import shutil |
import sys |
import urllib |
import zipfile |
@@ -117,24 +118,36 @@ def extract_strings(source, defaultlocale): |
format=format, localized_string_callback=record_string) |
return page_strings |
-def configure_locales(crowdin_api, required_locales, enabled_locales, |
+def configure_locales(crowdin_api, local_locales, enabled_locales, |
defaultlocale): |
logger.info("Checking which locales are supported by Crowdin...") |
response = crowdin_api.request("GET", "supported-languages") |
supported_locales = {l["crowdin_code"] for l in response} |
- skipped_locales = required_locales - supported_locales |
- if skipped_locales: |
- logger.warning("Ignoring locales that Crowdin doesn't support: %s", |
- ", ".join(skipped_locales)) |
- required_locales -= skipped_locales |
- |
- if not required_locales.issubset(enabled_locales): |
+ # We need to map the locale names we use to the ones that Crowdin is expecting |
+ # and at the same time ensure that they are supported. |
+ required_locales = {} |
+ for locale in local_locales: |
+ if "_" in locale: |
+ crowdin_locale = locale.replace("_", "-") |
+ elif locale in supported_locales: |
+ crowdin_locale = locale |
+ else: |
+ crowdin_locale = "%s-%s" % (locale, locale.upper()) |
+ |
+ if crowdin_locale in supported_locales: |
+ required_locales[locale] = crowdin_locale |
+ else: |
+ logger.warning("Ignoring locale '%s', which Crowdin doesn't support", |
+ locale) |
+ |
+ required_crowdin_locales = set(required_locales.values()) |
+ if not required_crowdin_locales.issubset(enabled_locales): |
logger.info("Enabling the required locales for the Crowdin project...") |
crowdin_api.request( |
"POST", "edit-project", |
- data={"languages": enabled_locales | required_locales} |
+ data={"languages": enabled_locales | required_crowdin_locales} |
) |
return required_locales |
@@ -198,13 +211,13 @@ def upload_translations(crowdin_api, source_dir, new_files, required_locales): |
yield (file_name, f.read(), "application/json") |
if new_files: |
- for locale in required_locales: |
+ for locale, crowdin_locale in required_locales.iteritems(): |
for files in grouper(open_locale_files(locale, new_files), |
crowdin_api.FILES_PER_REQUEST): |
logger.info("Uploading %d existing translation " |
"files for locale %s...", len(files), locale) |
crowdin_api.request("POST", "upload-translation", files=files, |
- data={"language": locale}) |
+ data={"language": crowdin_locale}) |
def remove_old_files(crowdin_api, old_files): |
for file_name in old_files: |
@@ -226,6 +239,8 @@ def download_translations(crowdin_api, source_dir, required_locales): |
logger.info("Downloading translations archive...") |
response = crowdin_api.raw_request("GET", "download/all.zip") |
+ inverted_required_locales = {crowdin: local for local, crowdin in |
+ required_locales.iteritems()} |
logger.info("Extracting translations archive...") |
with zipfile.ZipFile(io.BytesIO(response.data), "r") as archive: |
locale_path = os.path.join(source_dir, "locales") |
@@ -240,9 +255,16 @@ def download_translations(crowdin_api, source_dir, required_locales): |
for member in archive.namelist(): |
path, file_name = posixpath.split(member) |
ext = posixpath.splitext(file_name)[1] |
- locale = path.split(posixpath.sep)[0] |
- if ext.lower() == ".json" and locale in required_locales: |
- archive.extract(member, locale_path) |
+ path_parts = path.split(posixpath.sep) |
+ locale, file_path = path_parts[0], path_parts[1:] |
+ if ext.lower() == ".json" and locale in inverted_required_locales: |
+ output_path = os.path.join( |
+ locale_path, inverted_required_locales[locale], |
+ *file_path + [file_name] |
+ ) |
+ with archive.open(member) as source_file, \ |
+ open(output_path, "wb") as target_file: |
+ shutil.copyfileobj(source_file, target_file) |
def crowdin_sync(source_dir, crowdin_api_key): |
with FileSource(source_dir) as source: |
@@ -256,10 +278,10 @@ def crowdin_sync(source_dir, crowdin_api_key): |
project_info = crowdin_api.request("GET", "info") |
page_strings = extract_strings(source, defaultlocale) |
- required_locales = {l for l in source.list_locales() if l != defaultlocale} |
+ local_locales = source.list_locales() - {defaultlocale} |
enabled_locales = {l["code"] for l in project_info["languages"]} |
- required_locales = configure_locales(crowdin_api, required_locales, |
+ required_locales = configure_locales(crowdin_api, local_locales, |
enabled_locales, defaultlocale) |
remote_files, remote_directories = list_remote_files(project_info) |