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
4 # found in the LICENSE file.
6 """Creates a directory with with the unpacked contents of the 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
10 massages resulting files appropriately with host plugin data. Finally,
11 a zip archive for all of the above is produced.
14 # Python 2.5 compatibility
15 from __future__
import with_statement
26 # Update the module path, assuming that this script is in src/remoting/webapp,
27 # and that the google_api_keys module is in src/google_apis. Note that
28 # sys.path[0] refers to the directory containing this script.
29 if __name__
== '__main__':
31 os
.path
.abspath(os
.path
.join(sys
.path
[0], '../../google_apis')))
32 import google_api_keys
34 def findAndReplace(filepath
, findString
, replaceString
):
35 """Does a search and replace on the contents of a file."""
36 oldFilename
= os
.path
.basename(filepath
) + '.old'
37 oldFilepath
= os
.path
.join(os
.path
.dirname(filepath
), oldFilename
)
38 os
.rename(filepath
, oldFilepath
)
39 with
open(oldFilepath
) as input:
40 with
open(filepath
, 'w') as output
:
42 output
.write(s
.replace(findString
, replaceString
))
43 os
.remove(oldFilepath
)
46 def createZip(zip_path
, directory
):
47 """Creates a zipfile at zip_path for the given directory."""
48 zipfile_base
= os
.path
.splitext(os
.path
.basename(zip_path
))[0]
49 zip = zipfile
.ZipFile(zip_path
, 'w', zipfile
.ZIP_DEFLATED
)
50 for (root
, dirs
, files
) in os
.walk(directory
):
52 full_path
= os
.path
.join(root
, f
)
53 rel_path
= os
.path
.relpath(full_path
, directory
)
54 zip.write(full_path
, os
.path
.join(zipfile_base
, rel_path
))
58 def buildWebApp(buildtype
, version
, mimetype
, destination
, zip_path
, plugin
,
60 """Does the main work of building the webapp directory and zipfile.
63 buildtype: the type of build ("Official" or "Dev")
64 mimetype: A string with mimetype of plugin.
65 destination: A string with path to directory where the webapp will be
67 zipfile: A string with path to the zipfile to create containing the
68 contents of |destination|.
69 plugin: A string with path to the binary plugin for this webapp.
70 files: An array of strings listing the paths for resources to include
72 locales: An array of strings listing locales, which are copied, along
73 with their directory structure from the _locales directory down.
75 # Ensure a fresh directory.
77 shutil
.rmtree(destination
)
79 if os
.path
.exists(destination
):
83 os
.mkdir(destination
, 0775)
85 # Use symlinks on linux and mac for faster compile/edit cycle.
87 # On Windows Vista platform.system() can return 'Microsoft' with some
88 # versions of Python, see http://bugs.python.org/issue1082
89 # should_symlink = platform.system() not in ['Windows', 'Microsoft']
91 # TODO(ajwong): Pending decision on http://crbug.com/27185 we may not be
92 # able to load symlinked resources.
93 should_symlink
= False
96 for current_file
in files
:
97 destination_file
= os
.path
.join(destination
, os
.path
.basename(current_file
))
98 destination_dir
= os
.path
.dirname(destination_file
)
99 if not os
.path
.exists(destination_dir
):
100 os
.makedirs(destination_dir
, 0775)
103 # TODO(ajwong): Detect if we're vista or higher. Then use win32file
104 # to create a symlink in that case.
105 targetname
= os
.path
.relpath(os
.path
.realpath(current_file
),
106 os
.path
.realpath(destination_file
))
107 os
.symlink(targetname
, destination_file
)
109 shutil
.copy2(current_file
, destination_file
)
111 # Copy all the locales, preserving directory structure
112 destination_locales
= os
.path
.join(destination
, "_locales")
113 os
.mkdir(destination_locales
, 0775)
114 locale_dir
= "/_locales/"
115 for current_locale
in locales
:
116 pos
= current_locale
.find(locale_dir
)
118 raise Exception("Missing locales directory in " + current_locale
)
119 subtree
= current_locale
[pos
+ len(locale_dir
):]
120 pos
= subtree
.find("/")
122 raise Exception("Malformed locale: " + current_locale
)
123 locale_id
= subtree
[:pos
]
124 messages
= subtree
[pos
+1:]
125 destination_dir
= os
.path
.join(destination_locales
, locale_id
)
126 destination_file
= os
.path
.join(destination_dir
, messages
)
127 os
.mkdir(destination_dir
, 0775)
128 shutil
.copy2(current_locale
, destination_file
)
130 # Create fake plugin files to appease the manifest checker.
131 # It requires that if there is a plugin listed in the manifest that
132 # there be a file in the plugin with that name.
134 'remoting_host_plugin.dll', # Windows
135 'remoting_host_plugin.plugin', # Mac
136 'libremoting_host_plugin.ia32.so', # Linux 32
137 'libremoting_host_plugin.x64.so' # Linux 64
139 pluginName
= os
.path
.basename(plugin
)
142 if name
!= pluginName
:
143 path
= os
.path
.join(destination
, name
)
145 f
.write("placeholder for %s" % (name
))
149 pluginName
= os
.path
.basename(plugin
)
150 newPluginPath
= os
.path
.join(destination
, pluginName
)
151 if os
.path
.isdir(plugin
):
152 # On Mac we have a directory.
153 shutil
.copytree(plugin
, newPluginPath
)
155 shutil
.copy2(plugin
, newPluginPath
)
157 # Strip the linux build.
158 if ((platform
.system() == 'Linux') and (buildtype
== 'Official')):
159 subprocess
.call(["strip", newPluginPath
])
161 # Set the version number in the manifest version.
162 findAndReplace(os
.path
.join(destination
, 'manifest.json'),
166 # Set the correct mimetype.
167 findAndReplace(os
.path
.join(destination
, 'plugin_settings.js'),
168 'HOST_PLUGIN_MIMETYPE',
171 # Set the correct OAuth2 redirect URL.
173 'https://chromoting-oauth.talkgadget.google.com/'
174 'talkgadget/oauth/chrome-remote-desktop')
175 if (buildtype
== 'Official'):
176 oauth2RedirectUrlJs
= (
177 "'" + baseUrl
+ "/rel/' + chrome.i18n.getMessage('@@extension_id')")
178 oauth2RedirectUrlJson
= baseUrl
+ '/rel/*'
180 oauth2RedirectUrlJs
= "'" + baseUrl
+ "/dev'"
181 oauth2RedirectUrlJson
= baseUrl
+ '/dev*'
182 findAndReplace(os
.path
.join(destination
, 'plugin_settings.js'),
183 "'OAUTH2_REDIRECT_URL'",
185 findAndReplace(os
.path
.join(destination
, 'manifest.json'),
186 "OAUTH2_REDIRECT_URL",
187 oauth2RedirectUrlJson
)
189 # Set the correct API keys.
190 apiClientId
= google_api_keys
.GetClientID('REMOTING')
191 apiClientSecret
= google_api_keys
.GetClientSecret('REMOTING')
193 findAndReplace(os
.path
.join(destination
, 'plugin_settings.js'),
195 "'" + apiClientId
+ "'")
196 findAndReplace(os
.path
.join(destination
, 'plugin_settings.js'),
197 "'API_CLIENT_SECRET'",
198 "'" + apiClientSecret
+ "'")
201 createZip(zip_path
, destination
)
205 if len(sys
.argv
) < 7:
206 print ('Usage: build-webapp.py '
207 '<build-type> <version> <mime-type> <dst> <zip-path> <plugin> '
208 '<other files...> --locales <locales...>')
211 reading_locales
= False
214 for arg
in sys
.argv
[7:]:
215 if arg
== "--locales":
216 reading_locales
= True;
217 elif reading_locales
:
222 buildWebApp(sys
.argv
[1], sys
.argv
[2], sys
.argv
[3], sys
.argv
[4], sys
.argv
[5],
223 sys
.argv
[6], files
, locales
)
227 if __name__
== '__main__':