summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--o3d/build/all.gyp3
-rw-r--r--o3d/build/file_exists.py10
-rw-r--r--o3d/documentation/build.scons3
-rwxr-xr-xo3d/documentation/build_docs.py89
-rw-r--r--o3d/documentation/get_docs_files.py114
-rw-r--r--o3d/plugin/version_info.py4
-rw-r--r--o3d/samples/interactive_samples.js6
-rw-r--r--o3d/samples/picking.html2
-rw-r--r--o3d/samples/samples.gyp26
-rw-r--r--o3d/samples/samples_gen.py52
-rw-r--r--o3d/samples/split_samples.py183
11 files changed, 434 insertions, 58 deletions
diff --git a/o3d/build/all.gyp b/o3d/build/all.gyp
index bda0373..775dc0b 100644
--- a/o3d/build/all.gyp
+++ b/o3d/build/all.gyp
@@ -21,14 +21,15 @@
'../converter/converter.gyp:o3dConverter',
'../core/core.gyp:o3dCore',
'../core/core.gyp:o3dCorePlatform',
+ '../documentation/documentation.gyp:*',
'../import/archive.gyp:o3dArchive',
'../import/import.gyp:o3dImport',
'../plugin/idl/idl.gyp:o3dPluginIdl',
'../plugin/plugin.gyp:add_version',
'../plugin/plugin.gyp:npo3dautoplugin',
'../plugin/plugin.gyp:o3dPluginLogging',
- '../serializer/serializer.gyp:o3dSerializer',
'../samples/samples.gyp:*',
+ '../serializer/serializer.gyp:o3dSerializer',
'../statsreport/statsreport.gyp:o3dStatsReport',
'../tests/tests.gyp:unit_tests',
'../utils/utils.gyp:o3dUtils',
diff --git a/o3d/build/file_exists.py b/o3d/build/file_exists.py
new file mode 100644
index 0000000..6f6abb2
--- /dev/null
+++ b/o3d/build/file_exists.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os.path
+import sys
+
+sys.stdout.write(str(os.path.exists(sys.argv[1])))
+sys.exit(0)
diff --git a/o3d/documentation/build.scons b/o3d/documentation/build.scons
index 7bc998a..953490a 100644
--- a/o3d/documentation/build.scons
+++ b/o3d/documentation/build.scons
@@ -51,7 +51,8 @@ LOCAL_IDL_SOURCES = [IDL_DIR + i for i in O3D_IDL_SOURCES]
JS_DIR = '$SCONSTRUCT_DIR/samples/o3djs/'
LOCAL_JS_SOURCES = [JS_DIR + i for i in O3D_JS_SOURCES]
-DOCSGEN_ARGS = ['$JSDOC_DIR/build_docs.py $JAVA_EXE']
+DOCSGEN_ARGS = ['$JSDOC_DIR/build_docs.py $JAVA_EXE '
+ '$THIRD_PARTY $TARGET_ROOT/obj']
env["BUILDERS"]["JSDocs"] = Builder(action=env.Python(DOCSGEN_ARGS))
diff --git a/o3d/documentation/build_docs.py b/o3d/documentation/build_docs.py
index c309996..3c96852 100755
--- a/o3d/documentation/build_docs.py
+++ b/o3d/documentation/build_docs.py
@@ -44,6 +44,8 @@ import re
_java_exe = ''
+_output_dir = ''
+_third_party_dir = ''
_script_path = os.path.dirname(os.path.realpath(__file__))
_js_copyright = """
/*
@@ -81,9 +83,9 @@ _js_copyright = """
GlobalsDict = { }
-def MakePath(file_path):
- """Makes a path absolute given a path relativel to this script."""
- return os.path.join(_script_path, file_path)
+def MakePath(*file_paths):
+ """Makes a path absolute given a path relative to this script."""
+ return os.path.join(_script_path, *file_paths)
def UpdateGlobals(dict):
@@ -160,11 +162,10 @@ def AppendBasePath(folder, filenames):
def RunNixysa(idl_files, generate, output_dir, nixysa_options):
"""Executes Nixysa."""
- python_exe = 'python'
Execute([
- python_exe,
- MakePath('../third_party/nixysa/codegen.py'),
- '--binding-module=o3d:%s' % MakePath('../plugin/o3d_binding.py'),
+ sys.executable,
+ MakePath(_third_party_dir, 'nixysa', 'codegen.py'),
+ '--binding-module=o3d:%s' % MakePath('..', 'plugin', 'o3d_binding.py'),
'--generate=' + generate,
'--force',
'--output-dir=' + output_dir] +
@@ -175,7 +176,7 @@ def RunNixysa(idl_files, generate, output_dir, nixysa_options):
def RunJSDocToolkit(js_files, ezt_output_dir, html_output_dir, prefix, mode,
baseURL, topURL, exports_file):
"""Executes the JSDocToolkit."""
- list_filename = MakePath('../scons-out/docs/obj/doclist.conf')
+ list_filename = MakePath(_output_dir, 'doclist.conf')
f = open(list_filename, 'w')
f.write('{\nD:{\n')
f.write('prefix: "%s",\n' % prefix)
@@ -192,21 +193,24 @@ def RunJSDocToolkit(js_files, ezt_output_dir, html_output_dir, prefix, mode,
f.write(']\n}\n')
f.close()
+ files_dir = MakePath(_third_party_dir, 'jsdoctoolkit', 'files')
Execute([
_java_exe,
- '-Djsdoc.dir=%s' % MakePath('../third_party/jsdoctoolkit/files'),
+ '-Djsdoc.dir=%s' % files_dir,
'-jar',
- MakePath('../third_party/jsdoctoolkit/files/jsrun.jar'),
- MakePath('../third_party/jsdoctoolkit/files/app/run.js'),
+ MakePath(files_dir, 'jsrun.jar'),
+ MakePath(files_dir, 'app', 'run.js'),
'-v',
- '-t=%s' % MakePath('./jsdoc-toolkit-templates//'),
+ '-t=%s' % MakePath('jsdoc-toolkit-templates'),
'-d=' + ezt_output_dir,
'-c=' + list_filename])
def DeleteOldDocs(docs_js_outpath):
- shutil.rmtree(docs_js_outpath);
-
+ try:
+ shutil.rmtree(docs_js_outpath);
+ except:
+ pass
def BuildJavaScriptForDocsFromIDLs(idl_files, output_dir):
RunNixysa(idl_files, 'jsheader', output_dir, ['--properties-equal-undefined'])
@@ -226,7 +230,7 @@ def BuildO3DDocsFromJavaScript(js_files, ezt_output_dir, html_output_dir):
def BuildO3DJSDocs(js_files, ezt_output_dir, html_output_dir, exports_file):
RunJSDocToolkit(js_files, ezt_output_dir, html_output_dir, 'js_0_1_', 'o3djs',
- 'jsdocs/', '../', exports_file)
+ 'jsdocs', '..', exports_file)
def BuildO3DExternsFile(js_files_dir, extra_externs_file, externs_file):
@@ -261,7 +265,7 @@ def BuildCompiledO3DJS(o3djs_files,
Execute([
_java_exe,
'-jar',
- MakePath('../../o3d-internal/jscomp/JSCompiler_deploy.jar'),
+ MakePath('..', '..', 'o3d-internal', 'jscomp', 'JSCompiler_deploy.jar'),
'--property_renaming', 'OFF',
'--variable_renaming', 'LOCAL',
'--strict',
@@ -294,35 +298,48 @@ def CopyStaticFiles(o3d_docs_ezt_outpath, o3d_docs_html_outpath):
'tab_r.gif',
'tab_b.gif']
for file in files:
- shutil.copyfile(MakePath('jsdoc-toolkit-templates/static/' + file),
+ shutil.copyfile(MakePath('jsdoc-toolkit-templates', 'static', file),
MakePath(os.path.join(o3d_docs_ezt_outpath, file)))
- shutil.copyfile(MakePath('jsdoc-toolkit-templates/static/' + file),
+ shutil.copyfile(MakePath('jsdoc-toolkit-templates', 'static', file),
MakePath(os.path.join(o3d_docs_html_outpath, file)))
-def main():
+def main(argv):
"""Builds the O3D API docs and externs and the o3djs docs."""
global _java_exe
- _java_exe = sys.argv[1]
+ _java_exe = argv[0]
+ global _third_party_dir
+ _third_party_dir = argv[1]
+
+ # Fix up the python path of subprocesses by setting PYTHONPATH.
+ pythonpath = os.pathsep.join([MakePath(_third_party_dir, 'gflags', 'python'),
+ MakePath(_third_party_dir, 'ply')])
+
+ orig_pythonpath = os.environ.get('PYTHONPATH')
+ if orig_pythonpath:
+ pythonpath = os.pathsep.join([pythonpath, orig_pythonpath])
+
+ os.environ['PYTHONPATH'] = pythonpath
- js_list_filename = MakePath('../samples/o3djs/js_list.scons')
- idl_list_filename = MakePath('../plugin/idl_list.scons')
+ js_list_filename = MakePath('..', 'samples', 'o3djs', 'js_list.scons')
+ idl_list_filename = MakePath('..', 'plugin', 'idl_list.scons')
js_list_basepath = os.path.dirname(js_list_filename)
idl_list_basepath = os.path.dirname(idl_list_filename)
- outpath = '../scons-out/docs/obj/'
- docs_outpath = '../scons-out/docs/obj/documentation/'
- docs_js_outpath = MakePath(docs_outpath + 'apijs')
- externs_js_outpath = MakePath(outpath + '/externs')
- o3d_docs_ezt_outpath = MakePath(docs_outpath + 'reference')
- o3d_docs_html_outpath = MakePath(docs_outpath + 'local_html')
- o3djs_docs_ezt_outpath = MakePath(docs_outpath + 'reference/jsdocs')
- o3djs_docs_html_outpath = MakePath(docs_outpath + 'local_html/jsdocs')
- o3d_externs_path = MakePath(outpath + 'o3d-externs.js')
- o3djs_exports_path = MakePath(outpath + 'o3d-exports.js')
- compiled_o3djs_outpath = MakePath(docs_outpath + 'base.js')
- externs_path = MakePath('externs/externs.js')
- o3d_extra_externs_path = MakePath('externs/o3d-extra-externs.js')
+ global _output_dir
+ _output_dir = argv[2]
+ docs_outpath = os.path.join(_output_dir, 'documentation')
+ docs_js_outpath = MakePath(docs_outpath, 'apijs')
+ externs_js_outpath = MakePath(_output_dir, 'externs')
+ o3d_docs_ezt_outpath = MakePath(docs_outpath, 'reference')
+ o3d_docs_html_outpath = MakePath(docs_outpath, 'local_html')
+ o3djs_docs_ezt_outpath = MakePath(docs_outpath, 'reference', 'jsdocs')
+ o3djs_docs_html_outpath = MakePath(docs_outpath, 'local_html', 'jsdocs')
+ o3d_externs_path = MakePath(_output_dir, 'o3d-externs.js')
+ o3djs_exports_path = MakePath(_output_dir, 'o3d-exports.js')
+ compiled_o3djs_outpath = MakePath(docs_outpath, 'base.js')
+ externs_path = MakePath('externs', 'externs.js')
+ o3d_extra_externs_path = MakePath('externs', 'o3d-extra-externs.js')
Import(js_list_filename)
Import(idl_list_filename)
@@ -358,4 +375,4 @@ def main():
if __name__ == '__main__':
- main()
+ main(sys.argv[1:])
diff --git a/o3d/documentation/get_docs_files.py b/o3d/documentation/get_docs_files.py
new file mode 100644
index 0000000..f4bc31d
--- /dev/null
+++ b/o3d/documentation/get_docs_files.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Helper script to generate file lists for documentation.gyp."""
+
+import os
+import sys
+import types
+
+
+GlobalsDict = { }
+
+
+def UpdateGlobals(dict):
+ """Copies pairs from dict into GlobalDict."""
+ for i, v in dict.items():
+ GlobalsDict.__setitem__(i, v)
+
+
+def AppendBasePath(folder, filenames):
+ """Appends a base path to a ist of files"""
+ return [os.path.join(folder, filename) for filename in filenames]
+
+
+def GetCallingNamespaces():
+ """Return the locals and globals for the function that called
+ into this module in the current call stack."""
+ try: 1/0
+ except ZeroDivisionError:
+ # Don't start iterating with the current stack-frame to
+ # prevent creating reference cycles (f_back is safe).
+ frame = sys.exc_info()[2].tb_frame.f_back
+
+ # Find the first frame that *isn't* from this file
+ while frame.f_globals.get("__name__") == __name__:
+ frame = frame.f_back
+
+ return frame.f_locals, frame.f_globals
+
+
+def ComputeExports(exports):
+ """Compute a dictionary of exports given one of the parameters
+ to the Export() function or the exports argument to SConscript()."""
+
+ loc, glob = GetCallingNamespaces()
+
+ retval = {}
+ try:
+ for export in exports:
+ if isinstance(export, types.DictType):
+ retval.update(export)
+ else:
+ try:
+ retval[export] = loc[export]
+ except KeyError:
+ retval[export] = glob[export]
+ except KeyError, x:
+ raise Error, "Export of non-existent variable '%s'"%x
+
+ return retval
+
+
+def Export(*vars):
+ """Copies the named variables to GlobalDict."""
+ for var in vars:
+ UpdateGlobals(ComputeExports(vars))
+
+
+def Import(filename):
+ """Imports a python file in a scope with 'Export' defined."""
+ scope = {'__builtins__': globals()['__builtins__'],
+ 'Export': Export}
+ file = open(filename, 'r')
+ exec file in scope
+ file.close()
+
+
+def GetIdlFiles():
+ idl_list_filename = os.path.join('..', 'plugin', 'idl_list.scons')
+ idl_list_basepath = os.path.dirname(idl_list_filename)
+ Import(idl_list_filename)
+ idl_files = AppendBasePath(idl_list_basepath, GlobalsDict['O3D_IDL_SOURCES'])
+ return idl_files
+
+
+def GetJsFiles():
+ js_list_filename = os.path.join('..', 'samples', 'o3djs', 'js_list.scons')
+ js_list_basepath = os.path.dirname(js_list_filename)
+ Import(js_list_filename)
+ o3djs_files = AppendBasePath(js_list_basepath, GlobalsDict['O3D_JS_SOURCES'])
+ return o3djs_files
+
+
+# Read in the scons files (which are just really simple python files),
+# and scrape out the file lists.
+# TODO(gspencer): Once we no longer use the scons build, rework this
+# so that the lists are just python lists so we can just do a simple
+# eval instead of having to emulate scons import.
+def main(argv):
+ files = []
+ if argv[0] == '--js':
+ files = GetJsFiles()
+ if argv[0] == '--idl':
+ files = GetIdlFiles()
+ files.sort()
+ for file in files:
+ # gyp wants paths with slashes, not backslashes.
+ print file.replace("\\", "/")
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/o3d/plugin/version_info.py b/o3d/plugin/version_info.py
index fe92026..cebfa57 100644
--- a/o3d/plugin/version_info.py
+++ b/o3d/plugin/version_info.py
@@ -20,7 +20,9 @@ import os.path
import re
import sys
-gflags_dir = os.path.join('..', '..', 'third_party', 'gflags', 'python')
+gflags_dir = os.path.normpath(
+ os.path.join(os.path.dirname(sys.argv[0]),
+ '..', '..', 'third_party', 'gflags', 'python'))
sys.path.append(gflags_dir)
import gflags
diff --git a/o3d/samples/interactive_samples.js b/o3d/samples/interactive_samples.js
index d5e818d..eb30c85 100644
--- a/o3d/samples/interactive_samples.js
+++ b/o3d/samples/interactive_samples.js
@@ -29,6 +29,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// From here on down, please keep the format consistent. This file
+// will be read by the split_samples.py script to determine which files
+// will be split, and it reads all lines below "var codeArray = [" as
+// a python list, which just happens to match the syntax of a
+// javascript list, so please don't violate that assumption.
+// Leave this next line as it is...
var codeArray = [
{
'category': 'Basic',
diff --git a/o3d/samples/picking.html b/o3d/samples/picking.html
index ae62ebd..24a652f 100644
--- a/o3d/samples/picking.html
+++ b/o3d/samples/picking.html
@@ -56,7 +56,7 @@ O3D Picking Example.
<!-- Include default javascript library functions-->
<script type="text/javascript" src="o3djs/base.js"></script>
<!-- Our javascript code -->
-<script type="text/javascript" id="o3d">
+<script type="text/javascript" id="o3dscript">
o3djs.require('o3djs.util');
o3djs.require('o3djs.math');
o3djs.require('o3djs.rendergraph');
diff --git a/o3d/samples/samples.gyp b/o3d/samples/samples.gyp
index 5c5a195..27d96f1 100644
--- a/o3d/samples/samples.gyp
+++ b/o3d/samples/samples.gyp
@@ -11,9 +11,35 @@
],
'targets': [
{
+ 'target_name': 'split_samples',
+ 'type': 'none',
+ 'rules': [
+ {
+ 'rule_name': 'split_sample',
+ 'extension': 'html',
+ 'inputs': [
+ 'split_samples.py',
+ ],
+ 'outputs': [
+ '<(PRODUCT_DIR)/samples/<(RULE_INPUT_NAME)',
+ '<(PRODUCT_DIR)/samples/<(RULE_INPUT_ROOT).js',
+ ],
+ 'action': ['python', '<@(_inputs)',
+ '--products', '<(PRODUCT_DIR)/samples',
+ '--samples', '.',
+ '<(RULE_INPUT_PATH)',
+ ],
+ },
+ ],
+ 'sources': [
+ '<!@(python split_samples.py --samples . --find_candidates)',
+ ],
+ },
+ {
'target_name': 'samples',
'type': 'none',
'dependencies': [
+ 'split_samples',
'<!(python samples_gen.py):build_samples',
],
},
diff --git a/o3d/samples/samples_gen.py b/o3d/samples/samples_gen.py
index 783565c..00fe45c 100644
--- a/o3d/samples/samples_gen.py
+++ b/o3d/samples/samples_gen.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
import os.path
import sys
@@ -21,16 +24,28 @@ names = {
}
assets = [
- {'path': 'beachdemo/convert_assets/beachdemo.zip', 'up': z_up},
- {'path': 'beachdemo/convert_assets/beach-low-poly.dae', 'up': z_up},
{'path': 'GoogleIO-2009/convert_assets/background.zip', 'up': y_up},
{'path': 'GoogleIO-2009/convert_assets/character.zip', 'up': y_up},
- {'path': 'home-configurators/convert_cbassets/House_Roofless.kmz', 'up': z_up},
+ {'path': 'beachdemo/convert_assets/beach-low-poly.dae', 'up': z_up},
+ {'path': 'beachdemo/convert_assets/beachdemo.zip', 'up': z_up},
+ {'path': 'convert_assets/dome1.zip', 'up': y_up},
+ {'path': 'convert_assets/dome2.zip', 'up': y_up},
+ {'path': 'convert_assets/dome3.zip', 'up': y_up},
+ {'path': 'convert_assets/dome4.zip', 'up': y_up},
+ {'path': 'convert_assets/kitty_151_idle_stand05_cff1.zip', 'up': y_up},
+ {'path': 'convert_assets/part1.zip', 'up': y_up},
+ {'path': 'convert_assets/part2.zip', 'up': y_up},
+ {'path': 'convert_assets/part3.zip', 'up': y_up},
+ {'path': 'convert_assets/seven_shapes.zip', 'up': y_up},
+ {'path': 'convert_assets/stencil_frame.zip', 'up': y_up},
+ {'path': 'convert_assets/teapot.zip', 'up': y_up},
+ {'path': 'convert_assets/yard.zip', 'up': y_up},
{'path': 'home-configurators/convert_cbassets/Agra_Rug.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Asimi_Rug.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Camden_Chair.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Elements_Bookshelf.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Ferrara_Rug.kmz', 'up': z_up},
+ {'path': 'home-configurators/convert_cbassets/House_Roofless.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Lounge_Chair.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Lounge_Chaise.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Lounge_Sofa.kmz', 'up': z_up},
@@ -47,22 +62,9 @@ assets = [
{'path': 'home-configurators/convert_cbassets/Troy_Sofa.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Troy_Storage_Ottoman.kmz', 'up': z_up},
{'path': 'home-configurators/convert_cbassets/Troy_Twin_Sleeper.kmz', 'up': z_up},
-
{'path': 'io/convert_levels/all_actors.kmz', 'up': y_up},
{'path': 'io/convert_levels/map1.kmz', 'up': y_up},
{'path': 'simpleviewer/convert_assets/cube.zip', 'up': y_up},
- {'path': 'convert_assets/dome1.zip', 'up': y_up},
- {'path': 'convert_assets/dome2.zip', 'up': y_up},
- {'path': 'convert_assets/dome3.zip', 'up': y_up},
- {'path': 'convert_assets/dome4.zip', 'up': y_up},
- {'path': 'convert_assets/kitty_151_idle_stand05_cff1.zip', 'up': y_up},
- {'path': 'convert_assets/part1.zip', 'up': y_up},
- {'path': 'convert_assets/part2.zip', 'up': y_up},
- {'path': 'convert_assets/part3.zip', 'up': y_up},
- {'path': 'convert_assets/seven_shapes.zip', 'up': y_up},
- {'path': 'convert_assets/stencil_frame.zip', 'up': y_up},
- {'path': 'convert_assets/teapot.zip', 'up': y_up},
- {'path': 'convert_assets/yard.zip', 'up': y_up},
{'path': 'waterdemo/convert_assets/bamboo.zip', 'up': y_up},
{'path': 'waterdemo/convert_assets/coconuts.zip', 'up': y_up},
{'path': 'waterdemo/convert_assets/driftwood.zip', 'up': y_up},
@@ -121,17 +123,31 @@ for asset in assets:
output_file.write(" ],\n")
-# coalesce copies.
+# Coalesce copies by directory so we don't have tons of copies rules
+# to parse.
copies = {}
for asset in assets:
output = asset['path'].replace('convert_', '')
output = os.path.splitext(output)[0] + ".o3dtgz"
output_dir = os.path.dirname(output)
if output_dir in copies:
- copies[output_dir] += [output]
+ # Make sure we don't add any twice.
+ if not output in copies[output_dir]:
+ copies[output_dir] += [output]
else:
copies[output_dir] = [output]
+# Add in all the MANIFEST files to be copied,
+# Skipping the ones in the assets above (if any).
+manifest = open("MANIFEST", "r")
+for item in manifest.read().splitlines():
+ item_dir = os.path.dirname(item)
+ if item_dir in copies:
+ if not item in copies[item_dir]:
+ copies[item_dir] += [item]
+ else:
+ copies[item_dir] = [item]
+
output_file.write(" 'copies': [\n")
for (dir, paths) in copies.items():
output_file.write(" {\n")
diff --git a/o3d/samples/split_samples.py b/o3d/samples/split_samples.py
new file mode 100644
index 0000000..c101fdc
--- /dev/null
+++ b/o3d/samples/split_samples.py
@@ -0,0 +1,183 @@
+#!/usr/bin/env python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""This script takes the samples and splits out the code and the HTML
+into separate files for the unified sample browser."""
+
+import datetime
+import os.path
+import re
+import sys
+
+gflags_dir = os.path.normpath(
+ os.path.join(os.path.dirname(sys.argv[0]),
+ '..', '..', 'third_party', 'gflags', 'python'))
+sys.path.append(gflags_dir)
+
+import gflags
+
+year = datetime.date.today().year
+copyright_header = """/*
+ * Copyright %d, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+""" % year
+
+FLAGS = gflags.FLAGS
+gflags.DEFINE_string('products', None,
+ 'Sets the output directory for products.')
+
+gflags.DEFINE_string('samples', None,
+ 'Sets the directory for samples..')
+
+gflags.DEFINE_boolean('find_candidates', False,
+ 'Tells the script to just output a list of '
+ 'candidate samples.')
+
+def FindCandidates():
+ contents = GetFileContents(
+ os.path.join(FLAGS.samples, "interactive_samples.js")).splitlines()
+ start_re = re.compile("var codeArray.*")
+ end_re = re.compile("];")
+ keepers = []
+ inside = False
+ for line in contents:
+ if end_re.match(line):
+ inside = False
+ if inside:
+ keepers.append(line)
+ if start_re.match(line):
+ inside = True
+ keepers = ["["] + keepers + ["]"]
+ candidate_data = eval("\n".join(keepers),
+ {'__builtins__': None, 'true': 1, 'false': 0}, None)
+
+ # Put them into a dict to make sure they're unique
+ candidates = {}
+ for category in candidate_data:
+ for samples in category['samples']:
+ candidates[samples['files'][0]] = 1
+ candidates_array = candidates.keys()
+ candidates_array.sort()
+ for candidate in candidates_array:
+ print candidate
+
+def GetFileContents(filename):
+ try:
+ fd = open(filename, "r")
+ output = fd.read()
+ fd.close()
+ except IOError:
+ print "Unable to read file '%s'" % (filename)
+ return None
+ return output
+
+def SetFileContentsIfDifferent(filename, contents):
+ try:
+ fd = open(filename, "r")
+ old_contents = fd.read()
+ fd.close()
+ except IOError:
+ old_contents = None
+ pass
+
+ # If nothing changed, then don't re-write anything.
+ if old_contents == contents:
+ return True
+
+ try:
+ fd = open(filename, "wb")
+ except IOError:
+ print "Unable to write file '%s'" % (filename)
+ return False
+ output = fd.write(contents)
+ fd.close()
+ return True
+
+def SplitSample(sample_file, output_html, output_js):
+ script_re = re.compile(r'(.*)<script(\s+type="text/javascript")' +
+ r'(\s+charset="utf-8")?(\s+id="o3dscript")?' +
+ r'\s*>(.*)</script>(.*)',
+ re.DOTALL)
+
+ content = GetFileContents(sample_file)
+ m = script_re.match(content)
+ if not m:
+ raise Exception('Script regexp failed on input file %s' % sample_file)
+ (html_start, type, charset, id, script, html_end) = m.groups()
+ if not type:
+ raise Exception('Found a script (%s) that lacked the javascript tag!'
+ % sample_file)
+ if not charset:
+ charset = ''
+
+ html_content = (
+ '%(html_start)s<script %(type)s%(id)s%(charset)s '
+ 'src="%(js_path)s"></script>%(html_end)s' %
+ {
+ 'html_start' : html_start,
+ 'type' : type,
+ 'id' : id,
+ 'charset' : charset,
+ 'js_path' : os.path.basename(output_js),
+ 'html_end' : html_end
+ })
+
+ if not SetFileContentsIfDifferent(output_html, html_content):
+ return False
+ if not SetFileContentsIfDifferent(output_js, copyright_header + script):
+ return False
+ return True
+
+def main(argv):
+ try:
+ files = FLAGS(argv) # Parse flags
+ except gflags.FlagsError, e:
+ print '%s.\nUsage: %s [<options>]\n%s' % \
+ (e, sys.argv[0], FLAGS)
+ sys.exit(2)
+
+ # Strip off argv[0] to leave a list of html files to split.
+ files = files[1:]
+
+ if FLAGS.find_candidates:
+ return FindCandidates()
+
+ for file in files:
+ basename = os.path.basename(file)
+ output_html = os.path.join(FLAGS.products, basename)
+ output_js = os.path.splitext(output_html)[0] + '.js'
+ print "Splitting sample %s into %s and %s" % (file, output_html, output_js)
+ if not SplitSample(file, output_html, output_js):
+ sys.exit(2)
+
+if __name__ == "__main__":
+ main(sys.argv)