15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Creates a directory with with the unpacked contents of the remoting webapp.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The directory will contain a copy-of or a link-to to all remoting webapp
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)resources.  This includes HTML/JS and any plugin binaries. The script also
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)massages resulting files appropriately with host plugin data. Finally,
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)a zip archive for all of the above is produced.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Python 2.5 compatibility
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from __future__ import with_statement
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import io
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import platform
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import shutil
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import zipfile
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Update the module path, assuming that this script is in src/remoting/webapp,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# and that the google_api_keys module is in src/google_apis. Note that
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# sys.path[0] refers to the directory containing this script.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sys.path.append(
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      os.path.abspath(os.path.join(sys.path[0], '../../google_apis')))
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import google_api_keys
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def findAndReplace(filepath, findString, replaceString):
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Does a search and replace on the contents of a file."""
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  oldFilename = os.path.basename(filepath) + '.old'
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  oldFilepath = os.path.join(os.path.dirname(filepath), oldFilename)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  os.rename(filepath, oldFilepath)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  with open(oldFilepath) as input:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    with open(filepath, 'w') as output:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for s in input:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output.write(s.replace(findString, replaceString))
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  os.remove(oldFilepath)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def createZip(zip_path, directory):
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Creates a zipfile at zip_path for the given directory."""
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zipfile_base = os.path.splitext(os.path.basename(zip_path))[0]
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zip = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (root, dirs, files) in os.walk(directory):
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for f in files:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      full_path = os.path.join(root, f)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rel_path = os.path.relpath(full_path, directory)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zip.write(full_path, os.path.join(zipfile_base, rel_path))
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zip.close()
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)def replaceString(destination, placeholder, value):
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  findAndReplace(os.path.join(destination, 'plugin_settings.js'),
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 "'" + placeholder + "'", "'" + value + "'")
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)def processJinjaTemplate(input_file, output_file, context):
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  jinja2_path = os.path.normpath(
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      os.path.join(os.path.abspath(__file__),
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   '../../../third_party/jinja2'))
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  sys.path.append(os.path.split(jinja2_path)[0])
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  import jinja2
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  (template_path, template_name) = os.path.split(input_file)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_path))
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template = env.get_template(template_name)
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  rendered = template.render(context)
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  io.open(output_file, 'w', encoding='utf-8').write(rendered)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)def buildWebApp(buildtype, version, destination, zip_path,
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                manifest_template, webapp_type, files, locales):
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Does the main work of building the webapp directory and zipfile.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Args:
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    buildtype: the type of build ("Official" or "Dev").
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destination: A string with path to directory where the webapp will be
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 written.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zipfile: A string with path to the zipfile to create containing the
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             contents of |destination|.
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    manifest_template: jinja2 template file for manifest.
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    webapp_type: webapp type ("v1", "v2" or "v2_pnacl").
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    files: An array of strings listing the paths for resources to include
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           in this webapp.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    locales: An array of strings listing locales, which are copied, along
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             with their directory structure from the _locales directory down.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Ensure a fresh directory.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  try:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shutil.rmtree(destination)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  except OSError:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if os.path.exists(destination):
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pass
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  os.mkdir(destination, 0775)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Use symlinks on linux and mac for faster compile/edit cycle.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # On Windows Vista platform.system() can return 'Microsoft' with some
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # versions of Python, see http://bugs.python.org/issue1082
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # should_symlink = platform.system() not in ['Windows', 'Microsoft']
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # TODO(ajwong): Pending decision on http://crbug.com/27185 we may not be
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # able to load symlinked resources.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  should_symlink = False
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Copy all the files.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for current_file in files:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destination_file = os.path.join(destination, os.path.basename(current_file))
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destination_dir = os.path.dirname(destination_file)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not os.path.exists(destination_dir):
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      os.makedirs(destination_dir, 0775)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if should_symlink:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # TODO(ajwong): Detect if we're vista or higher.  Then use win32file
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # to create a symlink in that case.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      targetname = os.path.relpath(os.path.realpath(current_file),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   os.path.realpath(destination_file))
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      os.symlink(targetname, destination_file)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shutil.copy2(current_file, destination_file)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Copy all the locales, preserving directory structure
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destination_locales = os.path.join(destination, "_locales")
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  os.mkdir(destination_locales , 0775)
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  remoting_locales = os.path.join(destination, "remoting_locales")
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  os.mkdir(remoting_locales , 0775)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for current_locale in locales:
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extension = os.path.splitext(current_locale)[1]
138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if extension == '.json':
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      locale_id = os.path.split(os.path.split(current_locale)[0])[1]
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      destination_dir = os.path.join(destination_locales, locale_id)
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      destination_file = os.path.join(destination_dir,
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                      os.path.split(current_locale)[1])
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      os.mkdir(destination_dir, 0775)
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      shutil.copy2(current_locale, destination_file)
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    elif extension == '.pak':
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      destination_file = os.path.join(remoting_locales,
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                      os.path.split(current_locale)[1])
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      shutil.copy2(current_locale, destination_file)
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    else:
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      raise Exception("Unknown extension: " + current_locale);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  # Set client plugin type.
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client_plugin = 'pnacl' if webapp_type == 'v2_pnacl' else 'native'
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  findAndReplace(os.path.join(destination, 'plugin_settings.js'),
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 "'CLIENT_PLUGIN_TYPE'", "'" + client_plugin + "'")
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # Allow host names for google services/apis to be overriden via env vars.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2AccountsHost = os.environ.get(
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'OAUTH2_ACCOUNTS_HOST', 'https://accounts.google.com')
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2ApiHost = os.environ.get(
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'OAUTH2_API_HOST', 'https://www.googleapis.com')
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  directoryApiHost = os.environ.get(
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'DIRECTORY_API_HOST', 'https://www.googleapis.com')
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2BaseUrl = oauth2AccountsHost + '/o/oauth2'
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2ApiBaseUrl = oauth2ApiHost + '/oauth2'
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  directoryApiBaseUrl = directoryApiHost + '/chromoting/v1'
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, 'OAUTH2_BASE_URL', oauth2BaseUrl)
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, 'OAUTH2_API_BASE_URL', oauth2ApiBaseUrl)
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, 'DIRECTORY_API_BASE_URL', directoryApiBaseUrl)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # Substitute hosts in the manifest's CSP list.
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # Ensure we list the API host only once if it's the same for multiple APIs.
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  googleApiHosts = ' '.join(set([oauth2ApiHost, directoryApiHost]))
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # WCS and the OAuth trampoline are both hosted on talkgadget. Split them into
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # separate suffix/prefix variables to allow for wildcards in manifest.json.
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  talkGadgetHostSuffix = os.environ.get(
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'TALK_GADGET_HOST_SUFFIX', 'talkgadget.google.com')
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  talkGadgetHostPrefix = os.environ.get(
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'TALK_GADGET_HOST_PREFIX', 'https://chromoting-client.')
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2RedirectHostPrefix = os.environ.get(
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'OAUTH2_REDIRECT_HOST_PREFIX', 'https://chromoting-oauth.')
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # Use a wildcard in the manifest.json host specs if the prefixes differ.
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  talkGadgetHostJs = talkGadgetHostPrefix + talkGadgetHostSuffix
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  talkGadgetBaseUrl = talkGadgetHostJs + '/talkgadget/'
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if talkGadgetHostPrefix == oauth2RedirectHostPrefix:
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    talkGadgetHostJson = talkGadgetHostJs
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else:
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    talkGadgetHostJson = 'https://*.' + talkGadgetHostSuffix
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Set the correct OAuth2 redirect URL.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2RedirectHostJs = oauth2RedirectHostPrefix + talkGadgetHostSuffix
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2RedirectHostJson = talkGadgetHostJson
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2RedirectPath = '/talkgadget/oauth/chrome-remote-desktop'
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2RedirectBaseUrlJs = oauth2RedirectHostJs + oauth2RedirectPath
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  oauth2RedirectBaseUrlJson = oauth2RedirectHostJson + oauth2RedirectPath
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if buildtype == 'Official':
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oauth2RedirectUrlJs = ("'" + oauth2RedirectBaseUrlJs +
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           "/rel/' + chrome.i18n.getMessage('@@extension_id')")
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oauth2RedirectUrlJson = oauth2RedirectBaseUrlJson + '/rel/*'
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else:
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oauth2RedirectUrlJs = "'" + oauth2RedirectBaseUrlJs + "/dev'"
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    oauth2RedirectUrlJson = oauth2RedirectBaseUrlJson + '/dev*'
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  thirdPartyAuthUrlJs = oauth2RedirectBaseUrlJs + "/thirdpartyauth"
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  thirdPartyAuthUrlJson = oauth2RedirectBaseUrlJson + '/thirdpartyauth*'
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, "TALK_GADGET_URL", talkGadgetBaseUrl)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  findAndReplace(os.path.join(destination, 'plugin_settings.js'),
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 "'OAUTH2_REDIRECT_URL'", oauth2RedirectUrlJs)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # Configure xmpp server and directory bot settings in the plugin.
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  xmppServerAddress = os.environ.get(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'XMPP_SERVER_ADDRESS', 'talk.google.com:5222')
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  xmppServerUseTls = os.environ.get('XMPP_SERVER_USE_TLS', 'true')
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  directoryBotJid = os.environ.get(
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'DIRECTORY_BOT_JID', 'remoting@bot.talk.google.com')
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  findAndReplace(os.path.join(destination, 'plugin_settings.js'),
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 "Boolean('XMPP_SERVER_USE_TLS')", xmppServerUseTls)
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, "XMPP_SERVER_ADDRESS", xmppServerAddress)
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, "DIRECTORY_BOT_JID", directoryBotJid)
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, "THIRD_PARTY_AUTH_REDIRECT_URL",
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                thirdPartyAuthUrlJs)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Set the correct API keys.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  # For overriding the client ID/secret via env vars, see google_api_keys.py.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  apiClientId = google_api_keys.GetClientID('REMOTING')
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  apiClientSecret = google_api_keys.GetClientSecret('REMOTING')
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  apiClientIdV2 = google_api_keys.GetClientID('REMOTING_IDENTITY_API')
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, "API_CLIENT_ID", apiClientId)
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replaceString(destination, "API_CLIENT_SECRET", apiClientSecret)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  # Use a consistent extension id for unofficial builds.
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if buildtype != 'Official':
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    manifestKey = '"key": "remotingdevbuild",'
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else:
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    manifestKey = ''
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # Generate manifest.
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  context = {
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'webapp_type': webapp_type,
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'FULL_APP_VERSION': version,
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'MANIFEST_KEY_FOR_UNOFFICIAL_BUILD': manifestKey,
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'OAUTH2_REDIRECT_URL': oauth2RedirectUrlJson,
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'TALK_GADGET_HOST': talkGadgetHostJson,
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'THIRD_PARTY_AUTH_REDIRECT_URL': thirdPartyAuthUrlJson,
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'REMOTING_IDENTITY_API_CLIENT_ID': apiClientIdV2,
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'OAUTH2_BASE_URL': oauth2BaseUrl,
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'OAUTH2_API_BASE_URL': oauth2ApiBaseUrl,
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'DIRECTORY_API_BASE_URL': directoryApiBaseUrl,
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'OAUTH2_ACCOUNTS_HOST': oauth2AccountsHost,
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    'GOOGLE_API_HOSTS': googleApiHosts,
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  processJinjaTemplate(manifest_template,
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       os.path.join(destination, 'manifest.json'),
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       context)
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Make the zipfile.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  createZip(zip_path, destination)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def main():
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if len(sys.argv) < 6:
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print ('Usage: build-webapp.py '
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)           '<build-type> <version> <dst> <zip-path> <manifest_template> '
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)           '<webapp_type> <other files...> '
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)           '[--locales <locales...>]')
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  arg_type = ''
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  files = []
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  locales = []
2756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for arg in sys.argv[7:]:
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if arg in ['--locales']:
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      arg_type = arg
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    elif arg_type == '--locales':
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      locales.append(arg)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      files.append(arg)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return buildWebApp(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4],
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     sys.argv[5], sys.argv[6], files, locales)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sys.exit(main())
289