gecko-dev/testing/mozharness/scripts/update_apk_description.py

262 lines
9.9 KiB
Python

#!/usr/bin/env python
""" update_apk_description.py
Update the descriptions of an application (multilang)
Example of beta update:
$ python update_apk_description.py --service-account foo@developer.gserviceaccount.com --package-name org.mozilla.firefox --credentials key.p12 --update-apk-description
"""
import sys
import os
import urllib2
import json
from oauth2client import client
# load modules from parent dir
sys.path.insert(1, os.path.dirname(sys.path[0]))
# import the guts
from mozharness.base.script import BaseScript
from mozharness.mozilla.googleplay import GooglePlayMixin
from mozharness.base.python import VirtualenvMixin
class UpdateDescriptionAPK(BaseScript, GooglePlayMixin, VirtualenvMixin):
all_actions = [
'create-virtualenv',
'update-apk-description',
'test',
]
default_actions = [
'create-virtualenv',
'test',
]
config_options = [
[["--service-account"], {
"dest": "service_account",
"help": "The service account email",
}],
[["--credentials"], {
"dest": "google_play_credentials_file",
"help": "The p12 authentication file",
"default": "key.p12"
}],
[["--package-name"], {
"dest": "package_name",
"help": "The Google play name of the app",
}],
[["--l10n-api-url"], {
"dest": "l10n_api_url",
"help": "The L10N URL",
"default": "https://l10n.mozilla-community.org/~pascalc/google_play_description/"
}],
[["--force-locale"], {
"dest": "force_locale",
"help": "Force a specific locale (instead of all)",
}],
]
# We have 3 apps. Make sure that their names are correct
package_name_values = ("org.mozilla.fennec_aurora",
"org.mozilla.firefox_beta",
"org.mozilla.firefox")
def __init__(self, require_config_file=False, config={},
all_actions=all_actions,
default_actions=default_actions):
# Default configuration
default_config = {
'debug_build': False,
'pip_index': True,
# this will pip install it automajically when we call the
# create-virtualenv action
'virtualenv_modules': ['google-api-python-client'],
"find_links": [
"http://pypi.pvt.build.mozilla.org/pub",
"http://pypi.pub.build.mozilla.org/pub",
],
'virtualenv_path': 'venv',
}
default_config.update(config)
BaseScript.__init__(
self,
config_options=self.config_options,
require_config_file=require_config_file,
config=default_config,
all_actions=all_actions,
default_actions=default_actions,
)
self.all_locales_url = self.config['l10n_api_url'] + "api/?done&channel={channel}"
self.locale_url = self.config['l10n_api_url'] + "api/?locale={locale}&channel={channel}"
self.mapping_url = self.config['l10n_api_url'] + "api/?locale_mapping&reverse"
def check_argument(self):
""" Check that the given values are correct,
files exists, etc
"""
if self.config['package_name'] not in self.package_name_values:
self.fatal("Unknown package name value " +
self.config['package_name'])
if not os.path.isfile(self.config['google_play_credentials_file']):
self.fatal("Could not find " + self.config['google_play_credentials_file'])
def get_list_locales(self, package_name):
""" Get all the translated locales supported by Google play
So, locale unsupported by Google play won't be downloaded
Idem for not translated locale
"""
try:
response = urllib2.urlopen(self.all_locales_url.format(channel=package_name))
except urllib2.HTTPError:
self.fatal("Could not download the locale list. Channel: '" + package_name + "', URL: '" + self.all_locales_url + "'")
return json.load(response)
def get_mapping(self):
""" Download and load the locale mapping
"""
try:
response = urllib2.urlopen(self.mapping_url)
except urllib2.HTTPError:
self.fatal("Could not download the locale mapping list. URL: '" + self.mapping_url + "'")
self.mappings = json.load(response)
def locale_mapping(self, locale):
""" Google play and Mozilla don't have the exact locale code
Translate them
"""
if locale in self.mappings:
return self.mappings[locale]
else:
return locale
def get_translation(self, package_name, locale):
""" Get the translation for a locale
"""
localeURL = self.locale_url.format(channel=package_name, locale=locale)
try:
response = urllib2.urlopen(localeURL)
except urllib2.HTTPError:
self.fatal("Could not download the locale translation. Locale: '" + locale + "', Channel: '" + package_name + "', URL: '" + localeURL + "'")
return json.load(response)
def update_desc(self, service, package_name):
""" Update the desc on google play
service -- The session to Google play
package_name -- The name of the package
locale -- The locale to update
description -- The new description
"""
edit_request = service.edits().insert(body={},
packageName=package_name)
result = edit_request.execute()
edit_id = result['id']
# Retrieve the mapping
self.get_mapping()
if self.config.get("force_locale"):
# The user forced a locale, don't need to retrieve the full list
locales = [self.config.get("force_locale")]
else:
# Get all the locales from the web interface
locales = self.get_list_locales(package_name)
nb_locales = 0
for locale in locales:
translation = self.get_translation(package_name, locale)
title = translation.get("title")
short_desc = translation.get("short_desc")
long_desc = translation.get("long_desc")
# Google play expects some locales codes (de-DE instead of de)
locale = self.locale_mapping(locale)
try:
self.log("Updating " + package_name + " for '" + locale +
"' / title: '" + title + "', short_desc: '" +
short_desc[0:20] + "'..., long_desc: '" +
long_desc[0:20] + "...'")
listing_response = service.edits().listings().update(
editId=edit_id, packageName=package_name, language=locale,
body={'fullDescription': long_desc,
'shortDescription': short_desc,
'title': title}).execute()
nb_locales += 1
except client.AccessTokenRefreshError:
self.log('The credentials have been revoked or expired,'
'please re-run the application to re-authorize')
# Commit our changes
commit_request = service.edits().commit(
editId=edit_id, packageName=package_name).execute()
self.log('Edit "%s" has been committed. %d locale(s) updated.' % (commit_request['id'], nb_locales))
def update_apk_description(self):
""" Update the description """
self.check_argument()
service = self.connect_to_play()
self.update_desc(service, self.config['package_name'])
def test(self):
"""
Test if the connexion can be done and if the various method
works as expected
"""
self.check_argument()
self.connect_to_play()
package_name = 'org.mozilla.fennec_aurora'
locales = self.get_list_locales(package_name)
if not locales:
self.fatal("get_list_locales() failed")
self.get_mapping()
if not self.mappings:
self.fatal("get_mapping() failed")
loca = self.locale_mapping("fr")
if loca != "fr-FR":
self.fatal("fr locale_mapping failed")
loca = self.locale_mapping("hr")
if loca != "hr":
self.fatal("hr locale_mapping failed")
translation = self.get_translation(package_name, 'cs')
if len(translation.get('title')) < 5:
self.fatal("get_translation title failed for the 'cs' locale")
if len(translation.get('short_desc')) < 5:
self.fatal("get_translation short_desc failed for the 'cs' locale")
if len(translation.get('long_desc')) < 5:
self.fatal("get_translation long_desc failed for the 'cs' locale")
package_name = "org.mozilla.firefox_beta"
translation = self.get_translation(package_name, 'fr')
if len(translation.get('title')) < 5:
self.fatal("get_translation title failed for the 'fr' locale")
if len(translation.get('short_desc')) < 5:
self.fatal("get_translation short_desc failed for the 'fr' locale")
if len(translation.get('long_desc')) < 5:
self.fatal("get_translation long_desc failed for the 'fr' locale")
package_name = "org.mozilla.firefox"
translation = self.get_translation(package_name, 'de')
if len(translation.get('title')) < 5:
self.fatal("get_translation title failed for the 'de' locale")
if len(translation.get('short_desc')) < 5:
self.fatal("get_translation short_desc failed for the 'de' locale")
if len(translation.get('long_desc')) < 5:
self.fatal("get_translation long_desc failed for the 'de' locale")
# main {{{1
if __name__ == '__main__':
myScript = UpdateDescriptionAPK()
myScript.run_and_exit()