| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Creates a directory with with the unpacked contents of the remoting webapp. | 6 """Creates a directory with with the unpacked contents of the remoting webapp. |
| 7 | 7 |
| 8 The directory will contain a copy-of or a link-to to all remoting webapp | 8 The directory will contain a copy-of or a link-to to all remoting webapp |
| 9 resources. This includes HTML/JS and any plugin binaries. The script also | 9 resources. This includes HTML/JS and any plugin binaries. The script also |
| 10 massages resulting files appropriately with host plugin data. Finally, | 10 massages resulting files appropriately with host plugin data. Finally, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 sys.path.append(os.path.split(jinja2_path)[0]) | 100 sys.path.append(os.path.split(jinja2_path)[0]) |
| 101 import jinja2 | 101 import jinja2 |
| 102 (template_path, template_name) = os.path.split(input_file) | 102 (template_path, template_name) = os.path.split(input_file) |
| 103 include_paths = [template_path] + include_paths | 103 include_paths = [template_path] + include_paths |
| 104 env = jinja2.Environment(loader=jinja2.FileSystemLoader(include_paths)) | 104 env = jinja2.Environment(loader=jinja2.FileSystemLoader(include_paths)) |
| 105 template = env.get_template(template_name) | 105 template = env.get_template(template_name) |
| 106 rendered = template.render(context) | 106 rendered = template.render(context) |
| 107 io.open(output_file, 'w', encoding='utf-8').write(rendered) | 107 io.open(output_file, 'w', encoding='utf-8').write(rendered) |
| 108 | 108 |
| 109 def buildWebApp(buildtype, version, destination, zip_path, | 109 def buildWebApp(buildtype, version, destination, zip_path, |
| 110 manifest_template, webapp_type, appid, app_name, | 110 manifest_template, webapp_type, appid, app_client_id, app_name, |
| 111 app_description, app_capabilities, files, locales_listfile, | 111 app_description, app_capabilities, manifest_key, files, |
| 112 jinja_paths, service_environment, use_gcd): | 112 locales_listfile, jinja_paths, service_environment, use_gcd): |
| 113 """Does the main work of building the webapp directory and zipfile. | 113 """Does the main work of building the webapp directory and zipfile. |
| 114 | 114 |
| 115 Args: | 115 Args: |
| 116 buildtype: the type of build ("Official", "Release" or "Dev"). | 116 buildtype: the type of build ("Official", "Release" or "Dev"). |
| 117 destination: A string with path to directory where the webapp will be | 117 destination: A string with path to directory where the webapp will be |
| 118 written. | 118 written. |
| 119 zipfile: A string with path to the zipfile to create containing the | 119 zipfile: A string with path to the zipfile to create containing the |
| 120 contents of |destination|. | 120 contents of |destination|. |
| 121 manifest_template: jinja2 template file for manifest. | 121 manifest_template: jinja2 template file for manifest. |
| 122 webapp_type: webapp type ("v1", "v2", "v2_pnacl" or "app_remoting"). | 122 webapp_type: webapp type ("v1", "v2", "v2_pnacl" or "app_remoting"). |
| 123 appid: A string with the Remoting Application Id (only used for app | 123 appid: A string with the Remoting Application Id (only used for app |
| 124 remoting webapps). If supplied, it defaults to using the | 124 remoting webapps). If supplied, it defaults to using the |
| 125 test API server. | 125 test API server. |
| 126 app_client_id: The OAuth2 client ID for the webapp. |
| 126 app_name: A string with the name of the application. | 127 app_name: A string with the name of the application. |
| 127 app_description: A string with the description of the application. | 128 app_description: A string with the description of the application. |
| 128 app_capabilities: A set of strings naming the capabilities that should be | 129 app_capabilities: A set of strings naming the capabilities that should be |
| 129 enabled for this application. | 130 enabled for this application. |
| 131 manifest_key: The manifest key for the webapp. |
| 130 files: An array of strings listing the paths for resources to include | 132 files: An array of strings listing the paths for resources to include |
| 131 in this webapp. | 133 in this webapp. |
| 132 locales_listfile: The name of a file containing a list of locales, one per | 134 locales_listfile: The name of a file containing a list of locales, one per |
| 133 line, which are copied, along with their directory structure, from | 135 line, which are copied, along with their directory structure, from |
| 134 the _locales directory down. | 136 the _locales directory down. |
| 135 jinja_paths: An array of paths to search for {%include} directives in | 137 jinja_paths: An array of paths to search for {%include} directives in |
| 136 addition to the directory containing the manifest template. | 138 addition to the directory containing the manifest template. |
| 137 service_environment: Used to point the webApp to one of the | 139 service_environment: Used to point the webapp to one of the |
| 138 dev/test/staging/prod environments | 140 dev/test/staging/prod/prod-testing environments |
| 139 use_gcd: True if GCD support should be enabled. | 141 use_gcd: True if GCD support should be enabled. |
| 140 """ | 142 """ |
| 141 | 143 |
| 142 # Load the locales files from the locales_listfile. | 144 # Load the locales files from the locales_listfile. |
| 143 if not locales_listfile: | 145 if not locales_listfile: |
| 144 raise Exception('You must specify a locales_listfile') | 146 raise Exception('You must specify a locales_listfile') |
| 145 locales = [] | 147 locales = [] |
| 146 with open(locales_listfile) as input: | 148 with open(locales_listfile) as input: |
| 147 for s in input: | 149 for s in input: |
| 148 locales.append(s.rstrip()) | 150 locales.append(s.rstrip()) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 "'CLIENT_PLUGIN_TYPE'", "'" + client_plugin + "'") | 207 "'CLIENT_PLUGIN_TYPE'", "'" + client_plugin + "'") |
| 206 | 208 |
| 207 # Allow host names for google services/apis to be overriden via env vars. | 209 # Allow host names for google services/apis to be overriden via env vars. |
| 208 oauth2AccountsHost = os.environ.get( | 210 oauth2AccountsHost = os.environ.get( |
| 209 'OAUTH2_ACCOUNTS_HOST', 'https://accounts.google.com') | 211 'OAUTH2_ACCOUNTS_HOST', 'https://accounts.google.com') |
| 210 oauth2ApiHost = os.environ.get( | 212 oauth2ApiHost = os.environ.get( |
| 211 'OAUTH2_API_HOST', 'https://www.googleapis.com') | 213 'OAUTH2_API_HOST', 'https://www.googleapis.com') |
| 212 directoryApiHost = os.environ.get( | 214 directoryApiHost = os.environ.get( |
| 213 'DIRECTORY_API_HOST', 'https://www.googleapis.com') | 215 'DIRECTORY_API_HOST', 'https://www.googleapis.com') |
| 214 | 216 |
| 215 if webapp_type == 'app_remoting': | 217 is_app_remoting_webapp = webapp_type == 'app_remoting' |
| 218 is_prod_service_environment = service_environment == 'prod' or \ |
| 219 service_environment == 'prod-testing' |
| 220 if is_app_remoting_webapp: |
| 216 appRemotingApiHost = os.environ.get( | 221 appRemotingApiHost = os.environ.get( |
| 217 'APP_REMOTING_API_HOST', None) | 222 'APP_REMOTING_API_HOST', None) |
| 218 appRemotingApplicationId = os.environ.get( | 223 appRemotingApplicationId = os.environ.get( |
| 219 'APP_REMOTING_APPLICATION_ID', None) | 224 'APP_REMOTING_APPLICATION_ID', None) |
| 220 | 225 |
| 221 # Release/Official builds are special because they are what we will upload | 226 # Release/Official builds are special because they are what we will upload |
| 222 # to the web store. The checks below will validate that prod builds are | 227 # to the web store. The checks below will validate that prod builds are |
| 223 # being generated correctly (no overrides) and with the correct buildtype. | 228 # being generated correctly (no overrides) and with the correct buildtype. |
| 224 # They also verify that folks are not accidentally building dev/test/staging | 229 # They also verify that folks are not accidentally building dev/test/staging |
| 225 # apps for release (no impersonation) instead of dev. | 230 # apps for release (no impersonation) instead of dev. |
| 226 if service_environment == 'prod' and buildtype == 'Dev': | 231 if is_prod_service_environment and buildtype == 'Dev': |
| 227 raise Exception("Prod environment cannot be built for 'dev' builds") | 232 raise Exception("Prod environment cannot be built for 'dev' builds") |
| 228 | 233 |
| 229 if buildtype != 'Dev': | 234 if buildtype != 'Dev': |
| 230 if service_environment != 'prod': | 235 if not is_prod_service_environment: |
| 231 raise Exception('Invalid service_environment targeted for ' | 236 raise Exception('Invalid service_environment targeted for ' |
| 232 + buildtype + ': ' + service_environment) | 237 + buildtype + ': ' + service_environment) |
| 233 if 'out/Release' not in destination and 'out\Release' not in destination: | 238 if 'out/Release' not in destination and 'out\Release' not in destination: |
| 234 raise Exception('Prod builds must be placed in the out/Release folder') | 239 raise Exception('Prod builds must be placed in the out/Release folder') |
| 235 if appid != None: | 240 if appid != None: |
| 236 raise Exception('Cannot pass in an appid for ' | 241 raise Exception('Cannot pass in an appid for ' |
| 237 + buildtype + ' builds: ' + service_environment) | 242 + buildtype + ' builds: ' + service_environment) |
| 238 if appRemotingApiHost != None: | 243 if appRemotingApiHost != None: |
| 239 raise Exception('Cannot set APP_REMOTING_API_HOST env var for ' | 244 raise Exception('Cannot set APP_REMOTING_API_HOST env var for ' |
| 240 + buildtype + ' builds') | 245 + buildtype + ' builds') |
| 241 if appRemotingApplicationId != None: | 246 if appRemotingApplicationId != None: |
| 242 raise Exception('Cannot set APP_REMOTING_APPLICATION_ID env var for ' | 247 raise Exception('Cannot set APP_REMOTING_APPLICATION_ID env var for ' |
| 243 + buildtype + ' builds') | 248 + buildtype + ' builds') |
| 244 | 249 |
| 245 # If an Application ID was set (either from service_environment variable or | 250 # If an Application ID was set (either from service_environment variable or |
| 246 # from a command line argument), hardcode it, otherwise get it at runtime. | 251 # from a command line argument), hardcode it, otherwise get it at runtime. |
| 247 effectiveAppId = appRemotingApplicationId or appid | 252 effectiveAppId = appRemotingApplicationId or appid |
| 248 if effectiveAppId: | 253 if effectiveAppId: |
| 249 appRemotingApplicationId = "'" + effectiveAppId + "'" | 254 appRemotingApplicationId = "'" + effectiveAppId + "'" |
| 250 else: | 255 else: |
| 251 appRemotingApplicationId = "chrome.i18n.getMessage('@@extension_id')" | 256 appRemotingApplicationId = "chrome.i18n.getMessage('@@extension_id')" |
| 252 findAndReplace(os.path.join(destination, 'plugin_settings.js'), | 257 findAndReplace(os.path.join(destination, 'plugin_settings.js'), |
| 253 "'APP_REMOTING_APPLICATION_ID'", appRemotingApplicationId) | 258 "'APP_REMOTING_APPLICATION_ID'", appRemotingApplicationId) |
| 254 | 259 |
| 255 oauth2BaseUrl = oauth2AccountsHost + '/o/oauth2' | 260 oauth2BaseUrl = oauth2AccountsHost + '/o/oauth2' |
| 256 oauth2ApiBaseUrl = oauth2ApiHost + '/oauth2' | 261 oauth2ApiBaseUrl = oauth2ApiHost + '/oauth2' |
| 257 directoryApiBaseUrl = directoryApiHost + '/chromoting/v1' | 262 directoryApiBaseUrl = directoryApiHost + '/chromoting/v1' |
| 258 | 263 |
| 259 if webapp_type == 'app_remoting': | 264 if is_app_remoting_webapp: |
| 260 # Set the apiary endpoint and then set the endpoint version | 265 # Set the apiary endpoint and then set the endpoint version |
| 261 if not appRemotingApiHost: | 266 if not appRemotingApiHost: |
| 262 if service_environment == 'prod': | 267 if is_prod_service_environment: |
| 263 appRemotingApiHost = 'https://www.googleapis.com' | 268 appRemotingApiHost = 'https://www.googleapis.com' |
| 264 else: | 269 else: |
| 265 appRemotingApiHost = 'https://www-googleapis-test.sandbox.google.com' | 270 appRemotingApiHost = 'https://www-googleapis-test.sandbox.google.com' |
| 266 | 271 |
| 267 if service_environment == 'dev': | 272 if service_environment == 'dev': |
| 268 appRemotingServicePath = '/appremoting/v1beta1_dev' | 273 appRemotingServicePath = '/appremoting/v1beta1_dev' |
| 269 elif service_environment == 'test': | 274 elif service_environment == 'test': |
| 270 appRemotingServicePath = '/appremoting/v1beta1' | 275 appRemotingServicePath = '/appremoting/v1beta1' |
| 271 elif service_environment == 'staging': | 276 elif service_environment == 'staging': |
| 272 appRemotingServicePath = '/appremoting/v1beta1_staging' | 277 appRemotingServicePath = '/appremoting/v1beta1_staging' |
| 273 elif service_environment == 'prod': | 278 elif service_environment == 'prod': |
| 274 appRemotingServicePath = '/appremoting/v1beta1' | 279 appRemotingServicePath = '/appremoting/v1beta1' |
| 280 elif service_environment == 'prod-testing': |
| 281 appRemotingServicePath = '/appremoting/v1beta1_prod_testing' |
| 275 else: | 282 else: |
| 276 raise Exception('Unknown service environment: ' + service_environment) | 283 raise Exception('Unknown service environment: ' + service_environment) |
| 277 appRemotingApiBaseUrl = appRemotingApiHost + appRemotingServicePath | 284 appRemotingApiBaseUrl = appRemotingApiHost + appRemotingServicePath |
| 278 else: | 285 else: |
| 279 appRemotingApiBaseUrl = '' | 286 appRemotingApiBaseUrl = '' |
| 280 | 287 |
| 281 replaceBool(destination, 'USE_GCD', use_gcd) | 288 replaceBool(destination, 'USE_GCD', use_gcd) |
| 282 replaceString(destination, 'OAUTH2_BASE_URL', oauth2BaseUrl) | 289 replaceString(destination, 'OAUTH2_BASE_URL', oauth2BaseUrl) |
| 283 replaceString(destination, 'OAUTH2_API_BASE_URL', oauth2ApiBaseUrl) | 290 replaceString(destination, 'OAUTH2_API_BASE_URL', oauth2ApiBaseUrl) |
| 284 replaceString(destination, 'DIRECTORY_API_BASE_URL', directoryApiBaseUrl) | 291 replaceString(destination, 'DIRECTORY_API_BASE_URL', directoryApiBaseUrl) |
| 285 if webapp_type == 'app_remoting': | 292 if is_app_remoting_webapp: |
| 286 replaceString(destination, 'APP_REMOTING_API_BASE_URL', | 293 replaceString(destination, 'APP_REMOTING_API_BASE_URL', |
| 287 appRemotingApiBaseUrl) | 294 appRemotingApiBaseUrl) |
| 288 | 295 |
| 289 # Substitute hosts in the manifest's CSP list. | 296 # Substitute hosts in the manifest's CSP list. |
| 290 # Ensure we list the API host only once if it's the same for multiple APIs. | 297 # Ensure we list the API host only once if it's the same for multiple APIs. |
| 291 googleApiHosts = ' '.join(set([oauth2ApiHost, directoryApiHost])) | 298 googleApiHosts = ' '.join(set([oauth2ApiHost, directoryApiHost])) |
| 292 | 299 |
| 293 # WCS and the OAuth trampoline are both hosted on talkgadget. Split them into | 300 # WCS and the OAuth trampoline are both hosted on talkgadget. Split them into |
| 294 # separate suffix/prefix variables to allow for wildcards in manifest.json. | 301 # separate suffix/prefix variables to allow for wildcards in manifest.json. |
| 295 talkGadgetHostSuffix = os.environ.get( | 302 talkGadgetHostSuffix = os.environ.get( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 replaceString(destination, 'DIRECTORY_BOT_JID', | 343 replaceString(destination, 'DIRECTORY_BOT_JID', |
| 337 os.environ.get('DIRECTORY_BOT_JID', | 344 os.environ.get('DIRECTORY_BOT_JID', |
| 338 'remoting@bot.talk.google.com')) | 345 'remoting@bot.talk.google.com')) |
| 339 replaceString(destination, 'THIRD_PARTY_AUTH_REDIRECT_URL', | 346 replaceString(destination, 'THIRD_PARTY_AUTH_REDIRECT_URL', |
| 340 thirdPartyAuthUrlJs) | 347 thirdPartyAuthUrlJs) |
| 341 | 348 |
| 342 # Set the correct API keys. | 349 # Set the correct API keys. |
| 343 # For overriding the client ID/secret via env vars, see google_api_keys.py. | 350 # For overriding the client ID/secret via env vars, see google_api_keys.py. |
| 344 apiClientId = google_api_keys.GetClientID('REMOTING') | 351 apiClientId = google_api_keys.GetClientID('REMOTING') |
| 345 apiClientSecret = google_api_keys.GetClientSecret('REMOTING') | 352 apiClientSecret = google_api_keys.GetClientSecret('REMOTING') |
| 346 apiClientIdV2 = google_api_keys.GetClientID('REMOTING_IDENTITY_API') | 353 |
| 354 if is_app_remoting_webapp and buildtype != 'Dev': |
| 355 if not app_client_id: |
| 356 raise Exception('Invalid app_client_id passed in: "' + |
| 357 app_client_id + '"') |
| 358 apiClientIdV2 = app_client_id |
| 359 else: |
| 360 apiClientIdV2 = google_api_keys.GetClientID('REMOTING_IDENTITY_API') |
| 347 | 361 |
| 348 replaceString(destination, 'API_CLIENT_ID', apiClientId) | 362 replaceString(destination, 'API_CLIENT_ID', apiClientId) |
| 349 replaceString(destination, 'API_CLIENT_SECRET', apiClientSecret) | 363 replaceString(destination, 'API_CLIENT_SECRET', apiClientSecret) |
| 350 | 364 |
| 351 # Write the application capabilities. | 365 # Write the application capabilities. |
| 352 appCapabilities = ','.join( | 366 appCapabilities = ','.join( |
| 353 ['remoting.ClientSession.Capability.' + x for x in app_capabilities]) | 367 ['remoting.ClientSession.Capability.' + x for x in app_capabilities]) |
| 354 findAndReplace(os.path.join(destination, 'app_capabilities.js'), | 368 findAndReplace(os.path.join(destination, 'app_capabilities.js'), |
| 355 "'APPLICATION_CAPABILITIES'", appCapabilities) | 369 "'APPLICATION_CAPABILITIES'", appCapabilities) |
| 356 | 370 |
| 357 # Use a consistent extension id for dev builds. | 371 # Use a consistent extension id for dev builds. |
| 358 # AppRemoting builds always use the dev app id - the correct app id gets | 372 # AppRemoting builds always use the dev app id - the correct app id gets |
| 359 # written into the manifest later. | 373 # written into the manifest later. |
| 360 if buildtype != 'Official' or webapp_type == 'app_remoting': | 374 if is_app_remoting_webapp: |
| 375 if buildtype != 'Dev': |
| 376 if not manifest_key: |
| 377 raise Exception('Invalid manifest_key passed in: "' + |
| 378 manifest_key + '"') |
| 379 manifestKey = '"key": "' + manifest_key + '",' |
| 380 else: |
| 381 manifestKey = '"key": "remotingdevbuild",' |
| 382 elif buildtype != 'Official': |
| 383 # TODO(joedow): Update the chromoting webapp GYP entries to include keys. |
| 361 manifestKey = '"key": "remotingdevbuild",' | 384 manifestKey = '"key": "remotingdevbuild",' |
| 362 else: | 385 else: |
| 363 manifestKey = '' | 386 manifestKey = '' |
| 364 | 387 |
| 365 # Generate manifest. | 388 # Generate manifest. |
| 366 if manifest_template: | 389 if manifest_template: |
| 367 context = { | 390 context = { |
| 368 'webapp_type': webapp_type, | 391 'webapp_type': webapp_type, |
| 369 'FULL_APP_VERSION': version, | 392 'FULL_APP_VERSION': version, |
| 370 'MANIFEST_KEY_FOR_UNOFFICIAL_BUILD': manifestKey, | 393 'MANIFEST_KEY_FOR_UNOFFICIAL_BUILD': manifestKey, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 parser.add_argument('destination') | 428 parser.add_argument('destination') |
| 406 parser.add_argument('zip_path') | 429 parser.add_argument('zip_path') |
| 407 parser.add_argument('manifest_template') | 430 parser.add_argument('manifest_template') |
| 408 parser.add_argument('webapp_type') | 431 parser.add_argument('webapp_type') |
| 409 parser.add_argument('files', nargs='*', metavar='file', default=[]) | 432 parser.add_argument('files', nargs='*', metavar='file', default=[]) |
| 410 parser.add_argument('--app_name', metavar='NAME') | 433 parser.add_argument('--app_name', metavar='NAME') |
| 411 parser.add_argument('--app_description', metavar='TEXT') | 434 parser.add_argument('--app_description', metavar='TEXT') |
| 412 parser.add_argument('--app_capabilities', | 435 parser.add_argument('--app_capabilities', |
| 413 nargs='*', default=[], metavar='CAPABILITY') | 436 nargs='*', default=[], metavar='CAPABILITY') |
| 414 parser.add_argument('--appid') | 437 parser.add_argument('--appid') |
| 438 parser.add_argument('--app_client_id', default='') |
| 439 parser.add_argument('--manifest_key', default='') |
| 415 parser.add_argument('--locales_listfile', default='', metavar='PATH') | 440 parser.add_argument('--locales_listfile', default='', metavar='PATH') |
| 416 parser.add_argument('--jinja_paths', nargs='*', default=[], metavar='PATH') | 441 parser.add_argument('--jinja_paths', nargs='*', default=[], metavar='PATH') |
| 417 parser.add_argument('--service_environment', default='', metavar='ENV') | 442 parser.add_argument('--service_environment', default='', metavar='ENV') |
| 418 parser.add_argument('--use_gcd', choices=['0', '1'], default='0') | 443 parser.add_argument('--use_gcd', choices=['0', '1'], default='0') |
| 419 | 444 |
| 420 args = parser.parse_args() | 445 args = parser.parse_args() |
| 421 args.use_gcd = (args.use_gcd != '0') | 446 args.use_gcd = (args.use_gcd != '0') |
| 422 args.app_capabilities = set(args.app_capabilities) | 447 args.app_capabilities = set(args.app_capabilities) |
| 423 return buildWebApp(**vars(args)) | 448 return buildWebApp(**vars(args)) |
| 424 | 449 |
| 425 | 450 |
| 426 if __name__ == '__main__': | 451 if __name__ == '__main__': |
| 427 sys.exit(main()) | 452 sys.exit(main()) |
| OLD | NEW |