mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-14 15:56:38 +03:00
8320fb6937
- Make Java version explicit (11) in workflows - Update/sync required Java version (11) in all docs and scripts - Update/sync required Node version (18) in all docs and scripts - Update/sync required Python version (3.5) in all docs and scripts
265 lines
7.4 KiB
Python
Executable File
265 lines
7.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2018 Google LLC
|
|
#
|
|
# 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.
|
|
|
|
# cspell:words Merin haryalye alasse
|
|
|
|
"""Generates Javascript to load compile-time localization data.
|
|
|
|
This reads localization data at compile-time in a flat JSON-formatted
|
|
dictionary. The keys are message IDs, and the values are the translated
|
|
strings. For example:
|
|
{
|
|
"BEST_WISHES": "Merin sa haryalye alasse"
|
|
}
|
|
|
|
Each locale's translations are read from a separate file. For example, the path
|
|
the Arabic data would be ui/locales/ar.json.
|
|
"""
|
|
|
|
import argparse
|
|
import contextlib
|
|
import json
|
|
import os
|
|
import sys
|
|
import io
|
|
import shakaBuildHelpers
|
|
|
|
|
|
_INDENTATION = ' '
|
|
|
|
# These are Google's "Tier 1" languages as of April 2019.
|
|
DEFAULT_LOCALES = [
|
|
'ar',
|
|
'de',
|
|
'en',
|
|
'en-GB',
|
|
'es',
|
|
'es-419',
|
|
'fr',
|
|
'it',
|
|
'ja',
|
|
'ko',
|
|
'nl',
|
|
'pl',
|
|
'pt-BR',
|
|
'ru',
|
|
'th',
|
|
'tr',
|
|
'zh',
|
|
'zh-TW',
|
|
]
|
|
|
|
|
|
class Doc(object):
|
|
"""A string builder class used to build out a tab-sensitive document."""
|
|
|
|
def __init__(self):
|
|
# All the lines that make-up this document.
|
|
self._lines = []
|
|
|
|
# Track each tab we need to insert ahead of the next line.
|
|
self._tab_level = 0
|
|
|
|
@contextlib.contextmanager
|
|
def Block(self):
|
|
"""Starts a new tabbed block.
|
|
|
|
This should be used with |with| to ensure that the block closes.
|
|
"""
|
|
self._tab_level += 1
|
|
yield
|
|
self._tab_level -= 1
|
|
|
|
def Code(self, block):
|
|
"""Insert a block of code with the current tab level.
|
|
|
|
This will add the required leading white space to the line.
|
|
"""
|
|
# Break the code block into each line of code
|
|
lines = block.split('\n')
|
|
|
|
for line in lines:
|
|
# Right-strip the line to avoid trailing white space. We do this on the
|
|
# full string so that tabbing will be removed if a blank line was added.
|
|
new_line = (_INDENTATION * self._tab_level) + line
|
|
self._lines.append(new_line.rstrip())
|
|
|
|
def ToString(self):
|
|
return '\n'.join(self._lines) + '\n'
|
|
|
|
|
|
def AsQuotedString(input_string):
|
|
"""Convert |input_string| into a quoted string."""
|
|
subs = [
|
|
('\n', '\\n'),
|
|
('\t', '\\t'),
|
|
("'", "\\'")
|
|
]
|
|
|
|
# Go through each substitution and replace any occurrences.
|
|
output_string = input_string
|
|
for before, after in subs:
|
|
output_string = output_string.replace(before, after)
|
|
|
|
# Lastly wrap the string in quotes.
|
|
return "'%s'" % output_string
|
|
|
|
|
|
def GenerateLocalizations(localizations, class_name):
|
|
"""Generates JavaScript code to insert the localization data.
|
|
|
|
This creates a function called "addTo" in the class called |class_name| that,
|
|
when called, will insert the data from |localizations|.
|
|
|
|
Args:
|
|
localizations: A map of string locale name to a map of string tag to the
|
|
string localization.
|
|
class_name: A string name of the class to put generated code into.
|
|
|
|
Returns:
|
|
A string containing the generated code.
|
|
"""
|
|
doc = Doc()
|
|
|
|
doc.Code("""
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
// This file is auto-generated. DO NOT EDIT THIS FILE. If you need to:
|
|
// - change which locales are in this file, use the --locales option in
|
|
// "build/all.py" or "build/build.py"
|
|
// - change an entry for a specific locale, update "ui/locales/"
|
|
// - change anything else, update "build/generateLocalizations.py".
|
|
//
|
|
// To regenerate this file, run "build/generateLocalizations.py".
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
""")
|
|
|
|
# Insert a comment that the build scripts will read to determine the freshness
|
|
# of this output. This will be compared against a list of locales in the
|
|
# current build to decide if the output needs to be regenerated.
|
|
# DO NOT change the formatting here without also updating the "compiler.py"
|
|
# module and the "GenerateLocalizations" class's "_locales_changed" method.
|
|
locale_list_string = ', '.join(sorted(localizations.keys()))
|
|
doc.Code('// LOCALES: %s' % locale_list_string)
|
|
|
|
doc.Code("goog.provide('%s');" % class_name)
|
|
doc.Code("goog.require('shaka.ui.Localization');")
|
|
|
|
doc.Code("""
|
|
/**
|
|
* Insert all localization data for the UI into |localization|. This should be
|
|
* done BEFORE any listeners are added to the localization system (to avoid
|
|
* callbacks for each insert) and should be done BEFORE changing to the initial
|
|
* preferred locale (reduces the work needed to update the internal state after
|
|
* each insert).
|
|
*
|
|
* @param {!shaka.ui.Localization} localization
|
|
*/""")
|
|
|
|
doc.Code('%s.addTo = function(localization) {' % class_name)
|
|
|
|
message_ids = set()
|
|
|
|
# Go through the locales in sorted order so that we will be consistent between
|
|
# runs.
|
|
for locale in sorted(localizations.keys()):
|
|
localization = localizations[locale]
|
|
|
|
with doc.Block():
|
|
quoted_locale = AsQuotedString(locale)
|
|
doc.Code('localization.insert(%s, new Map([' % quoted_locale)
|
|
|
|
with doc.Block():
|
|
# Make sure that we sort by the localization keys so that they will
|
|
# always be in the same order.
|
|
for key, value in sorted(localization.items()):
|
|
message_ids.add(key)
|
|
quoted_key = AsQuotedString(key)
|
|
quoted_value = AsQuotedString(value)
|
|
doc.Code('[%s, %s],' % (quoted_key, quoted_value))
|
|
|
|
doc.Code(']));') # Close the call to insert.
|
|
|
|
doc.Code('};') # Close the function.
|
|
|
|
doc.Code("""
|
|
/**
|
|
* @enum {string}
|
|
* @const
|
|
*/
|
|
%s.Ids = {""" % class_name)
|
|
for message_id in message_ids:
|
|
doc.Code(' %s: %s,' % (message_id, AsQuotedString(message_id)))
|
|
doc.Code('};')
|
|
|
|
return doc.ToString()
|
|
|
|
|
|
def CreateParser():
|
|
"""Create the argument parser for this application."""
|
|
base = shakaBuildHelpers.get_source_base()
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
|
|
parser.add_argument(
|
|
'--locales',
|
|
type=str,
|
|
nargs='+',
|
|
default=DEFAULT_LOCALES,
|
|
help='The list of locales to compile in (default %(default)r)')
|
|
|
|
parser.add_argument(
|
|
'--source',
|
|
type=str,
|
|
default=os.path.join(base, 'ui', 'locales'),
|
|
help='The folder path for JSON inputs')
|
|
|
|
parser.add_argument(
|
|
'--output',
|
|
type=str,
|
|
default=os.path.join(base, 'dist', 'locales.js'),
|
|
help='The file path for JavaScript output')
|
|
|
|
parser.add_argument(
|
|
'--class-name',
|
|
type=str,
|
|
default='shaka.ui.Locales',
|
|
help='The fully qualified class name for the JavaScript output')
|
|
|
|
return parser
|
|
|
|
|
|
def main(args):
|
|
parser = CreateParser()
|
|
args = parser.parse_args(args)
|
|
|
|
combined_localizations = {}
|
|
for locale in args.locales:
|
|
path = os.path.join(args.source, locale + '.json')
|
|
with io.open(path, 'r', encoding='utf8') as f:
|
|
combined_localizations[locale] = json.load(f)
|
|
|
|
doc = GenerateLocalizations(combined_localizations, args.class_name)
|
|
with open(args.output, 'wb') as f:
|
|
f.write(doc.encode('utf-8'))
|
|
|
|
return args.output
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(sys.argv[1:])
|