From 47bf716e0e6eea075b075fbb9071265fd643ce2c Mon Sep 17 00:00:00 2001 From: brgcode Date: Fri, 10 Dec 2021 16:32:52 +0100 Subject: [PATCH 1/3] simplify rhino path stuff --- src/compas_ghpython/__init__.py | 78 ++--- src/compas_ghpython/components/__init__.py | 1 + src/compas_rhino/__init__.py | 315 +++++++++++++-------- 3 files changed, 244 insertions(+), 150 deletions(-) diff --git a/src/compas_ghpython/__init__.py b/src/compas_ghpython/__init__.py index 96dceb91156..ee5ef3c3471 100644 --- a/src/compas_ghpython/__init__.py +++ b/src/compas_ghpython/__init__.py @@ -21,28 +21,52 @@ if compas.is_rhino(): from .utilities import * # noqa: F401 F403 +__all__ = [ + 'get_grasshopper_managedplugin_path', + 'get_grasshopper_library_path', + 'get_grasshopper_userobjects_path' +] +__all_plugins__ = [ + 'compas_ghpython.install', + 'compas_ghpython.uninstall', + 'compas_ghpython.artists', +] + + +# ============================================================================= +# General Helpers +# ============================================================================= -def get_grasshopper_plugin_path(version): + +def _get_grasshopper_special_folder(version, folder_name): + grasshopper = compas_rhino._get_grasshopper_plugin_path(version) + return os.path.join(grasshopper, folder_name) + + +# ============================================================================= +# Managed Plugin +# ============================================================================= + + +def get_grasshopper_managedplugin_path(version): version = compas_rhino._check_rhino_version(version) + managedplugins = compas_rhino._get_managedplugins_path(version) if compas.WINDOWS: - version = version.split('.')[0] # take the major only - grasshopper_plugin_path = os.path.join(os.getenv('ProgramFiles'), 'Rhino {}'.format(version), 'Plug-ins', 'Grasshopper') + gh_managedplugin_path = os.path.join(managedplugins, 'Grasshopper') + elif compas.OSX: - lib_paths = { - '6.0': ['/', 'Applications', 'Rhinoceros.app'], - '7.0': ['/', 'Applications', 'Rhino 7.app', ] - } + gh_managedplugin_path = os.path.join(managedplugins, 'GrasshopperPlugin.rhp') + + if not os.path.exists(gh_managedplugin_path): + raise Exception("The Grasshopper (managed) Plug-in folder does not exist in this location: {}".format(gh_managedplugin_path)) - if version not in lib_paths: - raise Exception('Unsupported Rhino version') + return gh_managedplugin_path - grasshopper_plugin_path = os.path.join(*lib_paths.get(version) + - ['Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A', - 'Resources', 'ManagedPlugIns', 'GrasshopperPlugin.rhp']) - else: - raise Exception('Unsupported platform') - return grasshopper_plugin_path + +# ============================================================================= +# GH Plugin Libraries path +# ============================================================================= def get_grasshopper_library_path(version): @@ -50,25 +74,11 @@ def get_grasshopper_library_path(version): return _get_grasshopper_special_folder(version, 'Libraries') +# ============================================================================= +# GH Plugin UserObjects path +# ============================================================================= + + def get_grasshopper_userobjects_path(version): """Retrieve Grasshopper's user objects path""" return _get_grasshopper_special_folder(version, 'UserObjects') - - -def _get_grasshopper_special_folder(version, folder_name): - if compas.WINDOWS: - grasshopper_library_path = os.path.join(os.getenv('APPDATA'), 'Grasshopper', folder_name) - elif compas.OSX: - grasshopper_library_path = os.path.join(os.getenv('HOME'), 'Library', 'Application Support', 'McNeel', 'Rhinoceros', '{}'.format(version), - 'Plug-ins', 'Grasshopper (b45a29b1-4343-4035-989e-044e8580d9cf)', folder_name) - else: - raise Exception('Unsupported platform') - return grasshopper_library_path - - -__all_plugins__ = [ - 'compas_ghpython.install', - 'compas_ghpython.uninstall', - 'compas_ghpython.artists', -] -__all__ = [name for name in dir() if not name.startswith('_')] diff --git a/src/compas_ghpython/components/__init__.py b/src/compas_ghpython/components/__init__.py index 5dd7788d941..003250ce352 100644 --- a/src/compas_ghpython/components/__init__.py +++ b/src/compas_ghpython/components/__init__.py @@ -66,6 +66,7 @@ def install_userobjects(source): """ version = get_version_from_args() + # this dstdir potentially doesn't exist dstdir = get_grasshopper_userobjects_path(version) userobjects = glob.glob(os.path.join(source, '*.ghuser')) diff --git a/src/compas_rhino/__init__.py b/src/compas_rhino/__init__.py index 8fa1d53b0e3..55f4bcbb115 100644 --- a/src/compas_rhino/__init__.py +++ b/src/compas_rhino/__init__.py @@ -39,6 +39,38 @@ SUPPORTED_VERSIONS = ['5.0', '6.0', '7.0', '8.0'] DEFAULT_VERSION = '7.0' +IRONPYTHON_PLUGIN_GUID = '814d908a-e25c-493d-97e9-ee3861957f49' +GRASSHOPPER_PLUGIN_GUID = 'b45a29b1-4343-4035-989e-044e8580d9cf' +RHINOCYCLES_PLUGIN_GUID = '9bc28e9e-7a6c-4b8f-a0c6-3d05e02d1b97' + + +__all__ = [ + 'PURGE_ON_DELETE', + 'INSTALLABLE_PACKAGES', + 'SUPPORTED_VERSIONS', + 'DEFAULT_VERSION', + 'IRONPYTHON_PLUGIN_GUID', + 'GRASSHOPPER_PLUGIN_GUID', + 'RHINOCYCLES_PLUGIN_GUID', + + 'clear', + 'redraw' +] + +__all_plugins__ = [ + 'compas_rhino.geometry.booleans', + 'compas_rhino.geometry.trimesh', + 'compas_rhino.install', + 'compas_rhino.uninstall', + 'compas_rhino.artists', + 'compas_rhino.geometry.curves', +] + + +# ============================================================================= +# General helpers +# ============================================================================= + def clear(): guids = get_objects() # noqa: F405 @@ -60,172 +92,223 @@ def _check_rhino_version(version): return version -def _get_ironpython_lib_path(version): - version = _check_rhino_version(version) +def _get_package_path(package): + return os.path.abspath(os.path.dirname(package.__file__)) - if compas.WINDOWS: - ironpython_lib_path = _get_ironpython_lib_path_win32(version) - elif compas.OSX: - ironpython_lib_path = _get_ironpython_lib_path_mac(version) +def _get_bootstrapper_path(install_path): + return os.path.join(install_path, 'compas_bootstrapper.py') - else: - raise Exception('Unsupported platform') - if not os.path.exists(ironpython_lib_path): - # This does not always work. - # Especially not on (new) macs. - # However, since it is only used to clean up potential old installations - # it does not seem crucial anymore. - ironpython_lib_path = None - # print("The lib folder for IronPython does not exist in this location: {}".format(ironpython_lib_path)) +def _get_bootstrapper_data(compas_bootstrapper): + data = {} - return ironpython_lib_path + if not os.path.exists(compas_bootstrapper): + return data + content = io.open(compas_bootstrapper, encoding='utf8').read() + exec(content, data) -def _get_ironpython_lib_path_win32(version): - appdata = os.getenv('APPDATA') - return os.path.join(appdata, - 'McNeel', - 'Rhinoceros', - '{}'.format(version), - 'Plug-ins', - 'IronPython (814d908a-e25c-493d-97e9-ee3861957f49)', - 'settings', - 'lib') + return data -def _get_ironpython_lib_path_mac(version): - lib_paths = { - '5.0': ['/', 'Applications', 'Rhinoceros.app', 'Contents'], - '6.0': ['/', 'Applications', 'Rhinoceros.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A'], - '7.0': ['/', 'Applications', 'Rhino7.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A'], - '8.0': ['/', 'Applications', 'Rhino8.app', 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A'], - } - return os.path.join(*lib_paths.get(version) + ['Resources', 'ManagedPlugIns', 'RhinoDLR_Python.rhp', 'Lib']) +def _try_remove_bootstrapper(path): + """Try to remove bootstrapper. + Returns + ------- + bool: ``True`` if the operation did not cause errors, ``False`` otherwise. + """ -def _get_python_plugins_path(version): + bootstrapper = _get_bootstrapper_path(path) + + if os.path.exists(bootstrapper): + try: + os.remove(bootstrapper) + return True + except: # noqa: E722 + return False + return True + + +# ============================================================================= +# Base Application folder (Program Files on Windows and Applications on Mac) +# ============================================================================= + + +def _get_app_folder(version): version = _check_rhino_version(version) + version = version.split('.')[0] # take the major only if compas.WINDOWS: - python_plugins_path = _get_python_plugins_path_win32(version) - + app = os.path.join(os.getenv('ProgramFiles'), 'Rhino {}'.format(version)) elif compas.OSX: - python_plugins_path = _get_python_plugins_path_mac(version) + paths = { + '5': ['/', 'Applications', 'Rhinoceros.app'], + '6': ['/', 'Applications', 'Rhinoceros.app'], + '7': ['/', 'Applications', 'Rhino 7.app', ], + '8': ['/', 'Applications', 'Rhino 8.app', ] + } + app = os.path.join(*paths[version]) else: raise Exception('Unsupported platform') - return python_plugins_path - - -def _get_python_plugins_path_win32(version): - return os.path.join( - os.getenv('APPDATA'), - 'McNeel', - 'Rhinoceros', - '{}'.format(version), - 'Plug-ins', - 'PythonPlugins') - - -def _get_python_plugins_path_mac(version): - if version == '5.0': - return os.path.join( - os.environ['HOME'], - 'Library', - 'Application Support', - 'McNeel', - 'Rhinoceros', - 'MacPlugIns', - 'PythonPlugIns') - - return os.path.join( - os.environ['HOME'], - 'Library', - 'Application Support', - 'McNeel', - 'Rhinoceros', - '{}'.format(version), - 'Plug-ins', - 'PythonPlugIns') + if not os.path.exists(app): + raise Exception("The application folder does not exist in this location: {}".format(app)) + return app + + +# ============================================================================= +# Base AppData folder (APPDATA on Windows and Application Support on Mac) +# ============================================================================= -def _get_scripts_path(version): - version = _check_rhino_version(version) +def _get_appdata_folder(): if compas.WINDOWS: - scripts_path = _get_scripts_path_win32(version) + app = os.path.join(os.getenv('APPDATA'), 'McNeel', 'Rhinoceros') elif compas.OSX: - scripts_path = _get_scripts_path_mac(version) + app = os.path.join(os.getenv('HOME'), 'Library', 'Application Support', 'McNeel', 'Rhinoceros') else: raise Exception('Unsupported platform') + if not os.path.exists(app): + raise Exception("The appdata folder does not exist in this location: {}".format(app)) + + return app + + +# ============================================================================= +# Scripts folder +# ============================================================================= + + +def _get_scripts_path(version): + appdata = _get_appdata_folder() + version = _check_rhino_version(version) + scripts_path = os.path.join(appdata, '{}'.format(version), 'scripts') + if not os.path.exists(scripts_path): - raise Exception("The folder for RhinoPython scripts does not exist in this location: {}".format(scripts_path)) + raise Exception("The scripts folder does not exist in this location: {}".format(scripts_path)) return scripts_path -def _get_scripts_path_win32(version): - return os.path.join( - os.getenv('APPDATA'), 'McNeel', 'Rhinoceros', '{}'.format(version), 'scripts') +# ============================================================================= +# Managed Plugins folder +# ============================================================================= -def _get_scripts_path_mac(version): - return os.path.join( - os.getenv('HOME'), 'Library', 'Application Support', 'McNeel', 'Rhinoceros', '{}'.format(version), 'scripts') +def _get_managedplugins_path(version): + app = _get_app_folder(version) + if compas.WINDOWS: + managedplugins_path = os.path.join(app, 'Plug-ins') -def _get_package_path(package): - return os.path.abspath(os.path.dirname(package.__file__)) + elif compas.OSX: + managedplugins_path = os.path.join(app, 'Contents', 'Frameworks', 'RhCore.framework', 'Versions', 'A', 'Resources', 'ManagedPlugIns') + if not os.path.exists(managedplugins_path): + raise Exception("The Managed Plug-ins folder does not exist in this location: {}".format(managedplugins_path)) -def _get_bootstrapper_path(install_path): - return os.path.join(install_path, 'compas_bootstrapper.py') + return managedplugins_path -def _get_bootstrapper_data(compas_bootstrapper): - data = {} +# ============================================================================= +# Plugins folder +# ============================================================================= - if not os.path.exists(compas_bootstrapper): - return data - content = io.open(compas_bootstrapper, encoding='utf8').read() - exec(content, data) +def _get_plugins_path(version): + appdata = _get_appdata_folder() + version = _check_rhino_version(version) - return data + if compas.WINDOWS: + plugins_path = os.path.join(appdata, '{}'.format(version), 'Plug-ins') + elif compas.OSX: + if version == '5.0': + plugins_path = os.path.join(appdata, 'MacPlugIns') + else: + plugins_path = os.path.join(appdata, '{}'.format(version), 'Plug-ins') -def _try_remove_bootstrapper(path): - """Try to remove bootstrapper. + if not os.path.exists(plugins_path): + raise Exception("The plugins folder does not exist in this location: {}".format(plugins_path)) - Returns - ------- - bool: ``True`` if the operation did not cause errors, ``False`` otherwise. - """ + return plugins_path - bootstrapper = _get_bootstrapper_path(path) - if os.path.exists(bootstrapper): - try: - os.remove(bootstrapper) - return True - except: # noqa: E722 - return False - return True +# ============================================================================= +# PythonPlugins folder +# ============================================================================= -__all__ = [name for name in dir() if not name.startswith('_')] +def _get_python_plugins_path(version): + version = _check_rhino_version(version) + return os.path.join(_get_plugins_path(version), 'PythonPlugins') -__all_plugins__ = [ - 'compas_rhino.geometry.booleans', - 'compas_rhino.geometry.trimesh', - 'compas_rhino.install', - 'compas_rhino.uninstall', - 'compas_rhino.artists', - 'compas_rhino.geometry.curves', -] + +# ============================================================================= +# IronPython Plugin +# ============================================================================= + + +def _get_ironpython_plugin_path(version): + version = _check_rhino_version(version) + return os.path.join(_get_plugins_path(version), 'IronPython ({})'.format(IRONPYTHON_PLUGIN_GUID)) + + +# ============================================================================= +# Grasshopper +# ============================================================================= + + +def _get_grasshopper_plugin_path(version): + appdata = _get_appdata_folder() + version = _check_rhino_version(version) + + if compas.WINDOWS: + gh_path = os.path.join(appdata, 'Grasshopper') + + elif compas.OSX: + gh_path = os.path.join(_get_plugins_path(version), 'Grasshopper ({})'.format(GRASSHOPPER_PLUGIN_GUID)) + + if not os.path.exists(gh_path): + raise Exception("The grasshopper folder does not exist in this location: {}".format(gh_path)) + + return gh_path + + +# ============================================================================= +# IronPython lib folder +# ============================================================================= + + +def _get_ironpython_lib_path(version): + version = _check_rhino_version(version) + + if compas.WINDOWS: + ipy_lib_path = _get_ironpython_lib_path_win32(version) + + elif compas.OSX: + ipy_lib_path = _get_ironpython_lib_path_mac(version) + + if not os.path.exists(ipy_lib_path): + ipy_lib_path = None + # print("The lib folder for IronPython does not exist in this location: {}".format(ipy_lib_path)) + + return ipy_lib_path + + +def _get_ironpython_lib_path_win32(version): + return os.path.join(_get_ironpython_plugin_path(version), 'settings', 'lib') + + +# For 5.0 this is correct +# For +6 we should switch to the same path as on windows +# which is not in the managed plugins but in the appdata plugins +def _get_ironpython_lib_path_mac(version): + return os.path.join(_get_managedplugins_path(version), 'RhinoDLR_Python.rhp', 'Lib') From d04edc9fcefabf974e50d23972eaca488ec4a99f Mon Sep 17 00:00:00 2001 From: brgcode Date: Fri, 10 Dec 2021 16:38:41 +0100 Subject: [PATCH 2/3] log --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11e015b7026..f90a09c8e4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Changed default Rhino version for installation to `7.0`. * Fixed bug in `compas_ghpython` related to importing `Grasshopper` prematurely. * Changed `compas.artists.Artist.ITAM_ARTIST` to context-based dict. +* Changed `compas_rhino.__init__.py` functions. +* Changed `compas_ghpython.__init__.py` functions. ### Removed From de039a7312fcb9241415fc72faa939637afd5a17 Mon Sep 17 00:00:00 2001 From: brgcode Date: Fri, 10 Dec 2021 16:50:21 +0100 Subject: [PATCH 3/3] update default versions everywhere --- src/compas_ghpython/components/__init__.py | 3 ++- src/compas_rhino/__init__.py | 2 +- src/compas_rhino/install.py | 6 +++--- src/compas_rhino/uninstall.py | 6 +++--- src/compas_rhino/uninstall_plugin.py | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/compas_ghpython/components/__init__.py b/src/compas_ghpython/components/__init__.py index 003250ce352..49418c935c6 100644 --- a/src/compas_ghpython/components/__init__.py +++ b/src/compas_ghpython/components/__init__.py @@ -31,6 +31,7 @@ from compas._os import remove_symlinks from compas_ghpython import get_grasshopper_userobjects_path from compas_rhino import _check_rhino_version +import compas_rhino def coerce_frame(plane): @@ -46,7 +47,7 @@ def coerce_frame(plane): def get_version_from_args(): parser = argparse.ArgumentParser() - parser.add_argument('-v', '--version', choices=['5.0', '6.0', '7.0'], default='6.0') + parser.add_argument('-v', '--version', choices=compas_rhino.SUPPORTED_VERSIONS, default=compas_rhino.DEFAULT_VERSION) args = parser.parse_args() return _check_rhino_version(args.version) diff --git a/src/compas_rhino/__init__.py b/src/compas_rhino/__init__.py index 55f4bcbb115..587a8076f9f 100644 --- a/src/compas_rhino/__init__.py +++ b/src/compas_rhino/__init__.py @@ -147,7 +147,7 @@ def _get_app_folder(version): '5': ['/', 'Applications', 'Rhinoceros.app'], '6': ['/', 'Applications', 'Rhinoceros.app'], '7': ['/', 'Applications', 'Rhino 7.app', ], - '8': ['/', 'Applications', 'Rhino 8.app', ] + '8': ['/', 'Applications', 'RhinoWIP.app', ] } app = os.path.join(*paths[version]) diff --git a/src/compas_rhino/install.py b/src/compas_rhino/install.py index 04bfc6e756c..e4cf45ab6e8 100644 --- a/src/compas_rhino/install.py +++ b/src/compas_rhino/install.py @@ -26,7 +26,7 @@ def install(version=None, packages=None, clean=False): ---------- version : {'5.0', '6.0', '7.0', '8.0'}, optional The version number of Rhino. - Default is ``'6.0'``. + Default is ``'7.0'``. packages : list of str, optional List of packages to install or None to use default package list. Default is the result of ``installable_rhino_packages``, @@ -40,11 +40,11 @@ def install(version=None, packages=None, clean=False): .. code-block:: python import compas_rhino.install - compas_rhino.install.install('6.0') + compas_rhino.install.install() .. code-block:: bash - python -m compas_rhino.install -v 6.0 + python -m compas_rhino.install """ version = compas_rhino._check_rhino_version(version) diff --git a/src/compas_rhino/uninstall.py b/src/compas_rhino/uninstall.py index efa1ca88a4c..6dc4e9b0478 100644 --- a/src/compas_rhino/uninstall.py +++ b/src/compas_rhino/uninstall.py @@ -25,7 +25,7 @@ def uninstall(version=None, packages=None): ---------- version : {'5.0', '6.0', '7.0', '8.0'}, optional The version number of Rhino. - Default is ``'6.0'``. + Default is ``'7.0'``. packages : list of str, optional List of packages to uninstall. Default is to uninstall all packages installed by the COMPAS installer. @@ -35,11 +35,11 @@ def uninstall(version=None, packages=None): .. code-block:: python import compas_rhino - compas_rhino.uninstall('6.0') + compas_rhino.uninstall() .. code-block:: bash - python -m compas_rhino.uninstall -v 6.0 + python -m compas_rhino.uninstall """ version = compas_rhino._check_rhino_version(version) diff --git a/src/compas_rhino/uninstall_plugin.py b/src/compas_rhino/uninstall_plugin.py index f740acfc8ed..339695741b0 100644 --- a/src/compas_rhino/uninstall_plugin.py +++ b/src/compas_rhino/uninstall_plugin.py @@ -21,7 +21,7 @@ def uninstall_plugin(plugin, version=None): The name of the plugin. version : {'5.0', '6.0', '7.0', '8.0'}, optional The version of Rhino for which the plugin should be uninstalled. - Default is ``'6.0'``. + Default is ``'7.0'``. Notes -----