"""A tool to upload translation screenshots to Google Cloud Storage.
This tool searches the current repo for .png files associated with .grd or
.grdp files. It uploads the images to a Cloud Storage bucket and generates .sha1
files. Finally, it asks the user if they want to add the .sha1 files to their
CL.
Images must be named the same as the UI strings they represent
(e.g. IDS_HELLO.png for IDS_HELLO). The tool does NOT try to parse .grd/.grdp
files, so it doesn't know whether an image file corresponds to a message or not.
It will attempt to upload the image anyways.
"""
from __future__ import print_function
try:
input = raw_input
except NameError:
pass
import argparse
import sys
import os
import subprocess
import helper.translation_helper as translation_helper
import helper.git_helper as git_helper
here = os.path.dirname(os.path.realpath(__file__))
src_path = os.path.normpath(os.path.join(here, '..', '..'))
if (
here.startswith('/google/cog/cloud')
and not os.environ.get('PYTHONPYCACHEPREFIX')
):
os.environ.setdefault('PYTHONDONTWRITEBYTECODE', '1')
INTERNAL_TRANSLATION_EXPECTATIONS_PATH = os.path.join(
'clank', 'tools', 'translation_expectations.pyl')
TRANSLATION_EXPECTATIONS_PATH = os.path.join('tools', 'gritsettings',
'translation_expectations.pyl')
BUCKET_URL = 'gs://chromium-translation-screenshots'
if sys.platform.startswith('win'):
GIT = 'git.bat'
else:
GIT = 'git'
def query_yes_no(question, default='no'):
"""Ask a yes/no question via input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
"""
if default is None:
prompt = '[y/n] '
elif default == 'yes':
prompt = '[Y/n] '
elif default == 'no':
prompt = '[y/N] '
else:
raise ValueError("invalid default answer: '%s'" % default)
valid = {'yes': True, 'y': True, 'ye': True, 'no': False, 'n': False}
while True:
print(question, prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
if choice in valid:
return valid[choice]
print("Please respond with 'yes' or 'no' (or 'y' or 'n').")
def find_screenshots(repo_root, translation_expectations, is_cog):
"""Returns a list of translation related .png files in the repository."""
all_grds = []
if not is_cog:
all_grds = git_helper.list_grds_in_repository(repo_root)
translatable_grds = translation_helper.get_translatable_grds(
repo_root, all_grds, translation_expectations, is_cog)
src_paths = []
for grd in translatable_grds:
src_paths.append(grd.path)
src_paths.extend(grd.grdp_paths)
src_paths.extend(grd.structure_paths)
screenshots = []
rename_to_lowercase_png = None
for grd_path in src_paths:
name, ext = os.path.splitext(os.path.basename(grd_path))
relative_screenshots_dir = os.path.relpath(
os.path.dirname(grd_path), repo_root)
screenshots_dir = os.path.realpath(
os.path.join(repo_root,
os.path.join(relative_screenshots_dir,
name + ext.replace('.', '_'))))
if not os.path.exists(screenshots_dir):
continue
for f in os.listdir(screenshots_dir):
if f in ('OWNERS', 'README.md', 'DIR_METADATA') or f.endswith('.sha1'):
continue
if f.endswith('.PNG'):
if rename_to_lowercase_png is None:
rename_to_lowercase_png = query_yes_no(
'.PNG file(s) found, rename to .png for upload?')
if rename_to_lowercase_png:
f_path = os.path.join(screenshots_dir, f)
f = os.path.splitext(f)[0] + '.png'
f_path_lowercase_png = os.path.join(screenshots_dir, f)
os.rename(f_path, f_path_lowercase_png)
if not f.endswith('.png'):
print('File with unexpected extension: %s in %s' % (f, screenshots_dir))
continue
screenshots.append(os.path.join(screenshots_dir, f))
return screenshots
def main():
default_depot_tools_path = os.path.normpath(
os.path.join(src_path, 'third_party', 'depot_tools'))
parser = argparse.ArgumentParser(
description='Upload translation screenshots to Google Cloud Storage')
parser.add_argument(
'-n',
'--dry-run',
action='store_true',
help='Don\'t actually upload the images')
parser.add_argument(
'-c',
'--clank_internal',
action='store_true',
help='Upload screenshots for strings in the downstream clank directory')
parser.add_argument(
'--depot_tools_path',
default=default_depot_tools_path,
help='Path to the depot_tools directory.')
args = parser.parse_args()
sys.path.insert(0, args.depot_tools_path)
import upload_to_google_storage
import download_from_google_storage
import gclient_utils
sys.path.remove(args.depot_tools_path)
is_cog = gclient_utils.IsEnvCog()
if is_cog and args.depot_tools_path == default_depot_tools_path:
if not query_yes_no(
"WARNING: uploading screenshots with third_party/depot_tools "
"in a cog environment may add extraneous files to the cog workspace. "
"You can specify a local depot_tools version with "
"`--depot_tools_path`. Continue anyway?"):
sys.exit(1)
if args.clank_internal:
screenshots = find_screenshots(
os.path.join(src_path, "clank"),
os.path.join(src_path, INTERNAL_TRANSLATION_EXPECTATIONS_PATH),
is_cog)
else:
screenshots = find_screenshots(
src_path, os.path.join(src_path, TRANSLATION_EXPECTATIONS_PATH),
is_cog)
if not screenshots:
print ("No screenshots found.\n\n"
"- Screenshots must be located in the correct directory.\n"
" E.g. For IDS_HELLO_WORLD message in path/to/file.grd, save the "
"screenshot at path/to/file_grd/IDS_HELLO_WORLD.png.\n"
"- If you added a new, uncommitted .grd file, `git add` it so that "
"this script can pick up its screenshot directory.")
sys.exit(0)
print('Found %d updated screenshot(s): ' % len(screenshots))
for s in screenshots:
print(' %s' % s)
print()
if not query_yes_no('Do you want to upload these to Google Cloud Storage?\n\n'
'FILES WILL BE VISIBLE TO A LARGE NUMBER OF PEOPLE. '
'DO NOT UPLOAD ANYTHING CONFIDENTIAL.'):
sys.exit(0)
gsutil_path = os.path.abspath(os.path.join(args.depot_tools_path,
'gsutil.py'))
gsutil = download_from_google_storage.Gsutil(gsutil_path, boto_path=None)
if not args.dry_run:
if upload_to_google_storage.upload_to_google_storage(
input_filenames=screenshots,
base_url=BUCKET_URL,
gsutil=gsutil,
force=False,
use_md5=False,
num_threads=10,
skip_hashing=False,
gzip=None) != 0:
print ('Error uploading screenshots. Try running '
'`download_from_google_storage --config`.')
sys.exit(1)
print()
print('Images are uploaded and their signatures are calculated:')
signatures = ['%s.sha1' % s for s in screenshots]
for s in signatures:
print(' %s' % s)
print()
if not query_yes_no('Do you want to add these files to your CL?',
default='yes'):
sys.exit(0)
if not args.dry_run:
git_helper.git_add(signatures, src_path)
print('DONE.')
if __name__ == '__main__':
main()