Skip to content

Commit

Permalink
feat(cli): Expose the CLI and fix several things about it
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswmackey committed Nov 15, 2024
1 parent 41f67b8 commit 4e431fa
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 43 deletions.
1 change: 1 addition & 0 deletions docs/_templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
{% endif %}

{%- block extrahead %}
<link rel="icon" type="image/x-icon" href="https://github.com/ladybug-tools/artwork/raw/refs/heads/master/icons_bugs/ico/ladybug.ico">
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
Expand Down
29 changes: 23 additions & 6 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Welcome to ladybug-vtk's documentation!
===================================

.. image:: https://raw.githubusercontent.com/devngc/honeybee-vtk/master/images/vtk.png
.. image:: http://www.ladybug.tools/assets/img/ladybug.png
.. image:: https://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Visualization_Toolkit_logo.svg/320px-Visualization_Toolkit_logo.svg.png

Ladybug extension for translating ladybug-geometry objects to VTK PolyData.

Expand All @@ -10,16 +11,32 @@ Installation

``pip install -U ladybug-vtk``

To check if the command line interface is installed correctly use ``ladybug-vtk --help``


CLI Docs
=============

For command line interface documentation see the pages below.


.. toctree::
:maxdepth: 4
:caption: Contents:
:maxdepth: 2

.. include:: modules.rst
cli/index


ladybug_vtk
===============

.. toctree::
:maxdepth: 4

modules

Indices and tables
==================
------------------

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
* :ref:`search`
92 changes: 60 additions & 32 deletions ladybug_vtk/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,56 +26,84 @@ def vtk():
@click.option(
'--output-format', '-of', help='Text for the output format of the resulting '
'file. Choose from: vtkjs, html. Note that the html format refers to a web page '
'with the vtkjs file embedded within it. ',
'with the vtkjs file embedded within it.',
type=str, default='vtkjs', show_default=True)
@click.option(
'--output-file', help='Optional file to output the JSON string of '
'the config object. By default, it will be printed out to stdout.',
type=click.File('w'), default='-', show_default=True)
def vis_set_to_vtk(vis_file, output_format, output_file):
def vis_set_to_vtk_cli(vis_file, output_format, output_file):
"""Translate a VisualizationSet file (.vsf) to VTK formats.
\b
Args:
vis_file: Full path to a Ladybug Display Visualization Set (VSF) file.
"""
try:
# load the visualization set from the file
vis_set = VisualizationSet.from_file(vis_file)
output_format = output_format.lower()
# set up the output folder and file
if output_file.name == '<stdout>': # get a temporary file
out_file = str(uuid.uuid4())[:6]
out_folder = tempfile.gettempdir()
else:
out_folder, out_file = os.path.split(output_file.name)
if out_file.lower().endswith('.vtkjs'):
out_file = out_file[:-6]
elif out_file.lower().endswith('.html'):
out_file = out_file[:-5]
# create the output file
if output_format == 'vtkjs':
vis_set.to_vtkjs(output_folder=out_folder, file_name=out_file)
if output_format == 'html':
vis_set.to_html(output_folder=out_folder, file_name=out_file)
if output_file.name == '<stdout>': # load file contents to stdout
out_file_ext = out_file + '.' + output_format
out_file_path = os.path.join(out_folder, out_file_ext)
if output_format == 'html':
with open(out_file_path, encoding='utf-8') as of:
f_contents = of.read()
else: # vtkjs can only be read as binary
with open(out_file_path, 'rb') as of:
f_contents = of.read()
b = base64.b64encode(f_contents)
base64_string = b.decode('utf-8')
output_file.write(base64_string)
vis_set_to_vtk(vis_file, output_format, output_file)
except Exception as e:
_logger.exception('Failed to translate VisualizationSet to VTK.\n{}'.format(e))
sys.exit(1)
else:
sys.exit(0)


def vis_set_to_vtk(vis_file, output_format='vtkjs', output_file=None):
"""Translate a VisualizationSet file (.vsf) to VTK formats.
Args:
vis_file: Full path to a Ladybug Display Visualization Set (VSF) file.
output_format: Text for the output format of the resulting file.
Choose from: vtkjs, html. Note that the html format refers to a
web page with the vtkjs file embedded within it.
output_file: Optional file to output the string of the visualization
file contents. If None, the string will simply be returned from
this method.
"""
# load the visualization set from the file
vis_set = VisualizationSet.from_file(vis_file)
output_format = output_format.lower()
if output_format not in ('vtkjs', 'html'):
raise ValueError('Unrecognized output-format "{}".'.format(output_format))

# setup the working directory
if output_file is None or (not isinstance(output_file, str)
and output_file.name == '<stdout>'):
# get a temporary file
out_file = str(uuid.uuid4())[:6]
out_folder = tempfile.gettempdir()
else:
f_path = output_file if isinstance(output_file, str) else output_file.name
out_folder, out_file = os.path.split(f_path)
if out_file.endswith('.vtkjs'):
out_file = out_file[:-6]
elif out_file.endswith('.html'):
out_file = out_file[:-5]

# create the output file
if output_format == 'vtkjs':
vis_set.to_vtkjs(output_folder=out_folder, file_name=out_file)
if output_format == 'html':
vis_set.to_html(output_folder=out_folder, file_name=out_file)

# load file contents if need be
if output_file is None or (not isinstance(output_file, str)
and output_file.name == '<stdout>'):
# load file contents
out_file_ext = out_file + '.' + output_format
out_file_path = os.path.join(out_folder, out_file_ext)
if output_format == 'html':
with open(out_file_path, encoding='utf-8') as of:
f_contents = of.read()
else: # vtkjs can only be read as binary
with open(out_file_path, 'rb') as of:
f_contents = of.read()
b = base64.b64encode(f_contents)
f_contents = b.decode('utf-8')
if output_file is None:
return f_contents
output_file.write(f_contents)


# add vtk sub-group to ladybug CLI
main.add_command(vtk)
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
packages=setuptools.find_packages(exclude=["tests*"]),
install_requires=requirements,
include_package_data=True,
entry_points={
"console_scripts": ["ladybug-vtk = ladybug_vtk.cli:vtk"]
},
classifiers=[
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.10",
Expand Down
10 changes: 5 additions & 5 deletions tests/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
import os
from click.testing import CliRunner

from ladybug_vtk.cli import vis_set_to_vtk
from ladybug_vtk.cli import vis_set_to_vtk_cli


def test_vis_set_to_vtk():
"""Test the vis_set_to_vtk command."""
def test_vis_set_to_vtk_cli():
"""Test the vis_set_to_vtk_cli command."""
runner = CliRunner()
input_vsf = './tests/assets/daylight_factor.vsf'
output_vtkjs = './tests/assets/daylight_factor.vtkjs'
output_html = './tests/assets/daylight_factor.html'

in_args = [input_vsf, '--output-format', 'vtkjs', '--output-file', output_vtkjs]
result = runner.invoke(vis_set_to_vtk, in_args)
result = runner.invoke(vis_set_to_vtk_cli, in_args)
assert result.exit_code == 0
assert os.path.isfile(output_vtkjs)
os.remove(output_vtkjs)

in_args = [input_vsf, '--output-format', 'html', '--output-file', output_html]
result = runner.invoke(vis_set_to_vtk, in_args)
result = runner.invoke(vis_set_to_vtk_cli, in_args)
assert result.exit_code == 0
assert os.path.isfile(output_html)
os.remove(output_html)

0 comments on commit 4e431fa

Please sign in to comment.