diff --git a/src/unity/python/setup.py b/src/unity/python/setup.py index 00cc6908db..e97264b490 100644 --- a/src/unity/python/setup.py +++ b/src/unity/python/setup.py @@ -162,30 +162,35 @@ def run(self): 'Turi Create Visualization.app/Contents/Resources/*.dylib', 'Turi Create Visualization.app/Contents/PkgInfo', 'Turi Create Visualization.app/Contents/MacOS/Turi Create Visualization', - + # Linux visualization - 'Turi Create Visualization/icudtl.dat', - 'Turi Create Visualization/visualization_client', - 'Turi Create Visualization/snapshot_blob.bin', - 'Turi Create Visualization/cef_100_percent.pak', - 'Turi Create Visualization/locales/*.pak', - 'Turi Create Visualization/locales/*.info', - 'Turi Create Visualization/cef_200_percent.pak', - 'Turi Create Visualization/cef.pak', - 'Turi Create Visualization/devtools_resources.pak', - 'Turi Create Visualization/html/vega.min.js', - 'Turi Create Visualization/html/index.js', - 'Turi Create Visualization/html/vega_viz.html', - 'Turi Create Visualization/html/d3.v4.min.js', - 'Turi Create Visualization/html/vega-lite.min.js', - 'Turi Create Visualization/html/vega-tooltip.min.css', - 'Turi Create Visualization/html/vega-tooltip.min.js', - 'Turi Create Visualization/html/vega-embed.min.js', - 'Turi Create Visualization/html/table_view.css', - 'Turi Create Visualization/natives_blob.bin', - 'Turi Create Visualization/libcef.so', - 'Turi Create Visualization/v8_context_snapshot.bin', - 'Turi Create Visualization/cef_extensions.pak' + 'Turi Create Visualization/icudtl.dat', + 'Turi Create Visualization/visualization_client', + 'Turi Create Visualization/snapshot_blob.bin', + 'Turi Create Visualization/cef_100_percent.pak', + 'Turi Create Visualization/locales/*.pak', + 'Turi Create Visualization/locales/*.info', + 'Turi Create Visualization/cef_200_percent.pak', + 'Turi Create Visualization/cef.pak', + 'Turi Create Visualization/devtools_resources.pak', + 'Turi Create Visualization/html/vega.min.js', + 'Turi Create Visualization/html/index.js', + 'Turi Create Visualization/html/vega_viz.html', + 'Turi Create Visualization/html/d3.v4.min.js', + 'Turi Create Visualization/html/vega-lite.min.js', + 'Turi Create Visualization/html/vega-tooltip.min.css', + 'Turi Create Visualization/html/vega-tooltip.min.js', + 'Turi Create Visualization/html/vega-embed.min.js', + 'Turi Create Visualization/html/table_view.css', + 'Turi Create Visualization/natives_blob.bin', + 'Turi Create Visualization/libcef.so', + 'Turi Create Visualization/v8_context_snapshot.bin', + 'Turi Create Visualization/cef_extensions.pak', + + # Plot.save dependencies + 'visualization/vega_3.2.1.js', + 'visualization/vg2png', + 'visualization/vg2svg' ]}, packages=find_packages( exclude=["*.tests", "*.tests.*", "tests.*", "tests", "*.test", "*.test.*", "test.*", "test", diff --git a/src/unity/python/turicreate/CMakeLists.txt b/src/unity/python/turicreate/CMakeLists.txt index bbba8daaf8..510cc61371 100644 --- a/src/unity/python/turicreate/CMakeLists.txt +++ b/src/unity/python/turicreate/CMakeLists.txt @@ -52,7 +52,6 @@ set_property(DIRECTORY PROPERTY INSTALLATION_BINARY_FILES "${INSTALLATION_BINARY add_custom_target( visualization_vega ALL DEPENDS visualization_client - COMMAND npm install canvas-prebuilt COMMAND cp "${CMAKE_SOURCE_DIR}/src/unity/python/turicreate/visualization/vega_3.2.1.js" "${CMAKE_CURRENT_BINARY_DIR}" COMMAND cp "${CMAKE_SOURCE_DIR}/src/unity/python/turicreate/visualization/vg2png" "${CMAKE_CURRENT_BINARY_DIR}" COMMAND cp "${CMAKE_SOURCE_DIR}/src/unity/python/turicreate/visualization/vg2svg" "${CMAKE_CURRENT_BINARY_DIR}" diff --git a/src/unity/python/turicreate/visualization/_plot.py b/src/unity/python/turicreate/visualization/_plot.py index 6e4f717932..6255e9c6d6 100644 --- a/src/unity/python/turicreate/visualization/_plot.py +++ b/src/unity/python/turicreate/visualization/_plot.py @@ -5,12 +5,15 @@ import json as _json import os as _os from tempfile import mkstemp as _mkstemp -from subprocess import Popen as _Popen +from subprocess import Popen as _Popen from subprocess import PIPE as _PIPE _target = 'auto' +_SUCCESS = 0 +_CANVAS_PREBUILT_NOT_FOUND_ERROR = 1 _NODE_NOT_FOUND_ERROR_CODE = 127 +_PERMISSION_DENIED_ERROR_CODE = 243 def _run_cmdline(command): # runs a shell command @@ -122,7 +125,7 @@ def save(self, filepath): The destination filepath where the plot object must be saved as. The extension of this filepath determines what format the plot will be saved as. Currently supported formats are JSON, PNG, and SVG. - + Examples -------- Suppose 'plt' is an Plot Object @@ -160,24 +163,60 @@ def save(self, filepath): _json.dump(spec, fp) dirname = _os.path.dirname(__file__) relative_path_to_vg2png_vg2svg = "../vg2" + extension - absolute_path_to_vg2png_vg2svg = _os.path.join(dirname, + absolute_path_to_vg2png_vg2svg = _os.path.join(dirname, relative_path_to_vg2png_vg2svg) - (exitcode, stdout, stderr) = _run_cmdline("node " + - absolute_path_to_vg2png_vg2svg + " " + # try node vg2[png|svg] json_filepath out_filepath + (exitcode, stdout, stderr) = _run_cmdline("node " + + absolute_path_to_vg2png_vg2svg + " " + temp_file_path + " " + filepath) + if exitcode == _NODE_NOT_FOUND_ERROR_CODE: # user doesn't have node installed raise RuntimeError("Node.js not found. Saving as PNG and SVG" + " requires Node.js, please download and install Node.js " + "from here and try again: https://nodejs.org/en/download/") - elif exitcode == 0: - # success + elif exitcode == _CANVAS_PREBUILT_NOT_FOUND_ERROR: + # try to see if canvas-prebuilt is globally installed + # if it is, then link it + # if not, tell the user to install it + (is_installed_exitcode, + is_installed_stdout, + is_installed_stderr) = _run_cmdline( + "npm ls -g -json | grep canvas-prebuilt") + if is_installed_exitcode == _SUCCESS: + # npm link canvas-prebuilt + link_exitcode, link_stdout, link_stderr = _run_cmdline( + "npm link canvas-prebuilt") + if link_exitcode == _PERMISSION_DENIED_ERROR_CODE: + # They don't have permission, tell them. + raise RuntimeError(link_stderr + '\n\n' + + "`npm link canvas-prebuilt` failed, " + + "Permission Denied.") + elif link_exitcode == _SUCCESS: + # canvas-prebuilt link is now successful, so run the + # node vg2[png|svg] json_filepath out_filepath + # command again. + (exitcode, stdout, stderr) = _run_cmdline("node " + + absolute_path_to_vg2png_vg2svg + " " + + temp_file_path + " " + filepath) + if exitcode != _SUCCESS: + # something else that we have not identified yet + # happened. + raise RuntimeError(stderr) + else: + raise RuntimeError(link_stderr) + else: + raise RuntimeError("canvas-prebuilt not found. " + + "Saving as PNG and SVG requires canvas-prebuilt, " + + "please download and install canvas-prebuilt by " + + "running this command, and try again: " + + "`npm install -g canvas-prebuilt`") + elif exitcode == _SUCCESS: pass else: - # something else raise RuntimeError(stderr) # delete temp file that user didn't ask for - _run_cmdline("rm " + temp_file_path) + _run_cmdline("rm " + temp_file_path) else: raise NotImplementedError("filename must end in" + " .json, .svg, or .png") @@ -200,7 +239,7 @@ def _get_vega(self, include_data=True): def _repr_javascript_(self): from IPython.core.display import display, HTML - vega_spec = self._get_vega(True)["vega_spec"] + vega_spec = self._get_vega(True) vega_html = ' \ \ diff --git a/src/unity/python/turicreate/visualization/vg2png b/src/unity/python/turicreate/visualization/vg2png index b7e523535b..d398cfae3a 100755 --- a/src/unity/python/turicreate/visualization/vg2png +++ b/src/unity/python/turicreate/visualization/vg2png @@ -18,6 +18,7 @@ var path = require('path'), // set baseURL if provided on command line var base = null; +var _CANVAS_PREBUILT_NON_EXISTENT = 1; // input / output files var myArgs = process.argv.slice(2), @@ -47,5 +48,5 @@ function render(spec) { .initialize() .toCanvas() .then(function(canvas) { writePNG(canvas, outputFile); }) - .catch(function(err) { console.error(err); }); -} \ No newline at end of file + .catch(function(err) { console.error(err); process.exit(_CANVAS_PREBUILT_NON_EXISTENT); }); +} diff --git a/src/visualization/Turi Create Visualization/src/user_interface/package.json b/src/visualization/Turi Create Visualization/src/user_interface/package.json index 88d9526abe..79c3a14ed9 100644 --- a/src/visualization/Turi Create Visualization/src/user_interface/package.json +++ b/src/visualization/Turi Create Visualization/src/user_interface/package.json @@ -11,7 +11,6 @@ "element-resize-event": "^2.0.9", "react": "^16.2.0", "react-dom": "^16.2.0", - "react-fontawesome": "^1.6.1", "react-json-pretty": "^1.7.5", "vega": "^3.2.1", "vega-embed": "^3.2.0",