Beispiel #1
0
def install_userobjects(source):
    """Installs Grasshopper user objects.

    Parameters
    ----------
    source : str
        Folder where the ghuser files to install are located.

    Returns
    -------
    list
        List of tuples (name, success) indicating whether each of the user objects was successfully installed.
    """
    version = get_version_from_args()

    dstdir = get_grasshopper_userobjects_path(version)
    userobjects = glob.glob(os.path.join(source, '*.ghuser'))

    symlinks_to_remove = []
    symlinks_to_add = []
    for src in userobjects:
        dst = os.path.join(dstdir, os.path.basename(src))
        symlinks_to_remove.append(dst)
        symlinks_to_add.append((src, dst))

    # Remove existing links first
    remove_symlinks(symlinks_to_remove)

    # And the create new ones
    created = create_symlinks(symlinks_to_add)

    return list(zip(symlinks_to_add, created))
Beispiel #2
0
def install():
    """Installs the Grasshopper components library."""
    results = []

    try:
        version = get_version_from_args()
        grasshopper_library_path = get_grasshopper_library_path(version)

        for f in _remove_old_ghpy_components(grasshopper_library_path):
            results.append(
                ('compas_fab', 'Uninstalled old GHPY component: {}'.format(f),
                 True))

        dstdir = get_grasshopper_userobjects_path(version)
        srcdir = os.path.join(os.path.dirname(__file__), 'ghuser')
        userobjects = glob.glob(os.path.join(srcdir, '*.ghuser'))

        symlinks_to_remove = []
        symlinks_to_add = []
        for src in userobjects:
            dst = os.path.join(dstdir, os.path.basename(src))
            symlinks_to_remove.append(dst)
            symlinks_to_add.append((src, dst))

        remove_symlinks(symlinks_to_remove)
        create_symlinks(symlinks_to_add)

        results.append(
            ('compas_fab',
             'Installed {} GH User Objects'.format(len(userobjects)), True))
    except PermissionError:
        raise Exception(
            'Please close first all instances of Rhino and then rerun the command'
        )

    return results
Beispiel #3
0
def install(blender_path):
    """Install COMPAS for Blender.

    Parameters
    ----------
    blender_path : str
        The path to the folder with the version number of Blender.
        For example, on Mac: ``'/Applications/blender.app/Contents/Resources/2.80'``.
        On Windows: ``'%PROGRAMFILES%\\Blender Foundation\\Blender\\2.80'``.

    Examples
    --------
    .. code-block:: bash

        $ python -m compas_blender.install /Applications/blender.app/Contents/Resources/2.80

    """
    if not os.environ.get('CONDA_PREFIX'):
        print(
            'Conda environment not found. The installation into Blender requires an active conda environment with a matching Python version to continue.'
        )
        sys.exit(-1)

    path, version = os.path.split(blender_path)

    print('Installing COMPAS for Blender {}'.format(version))

    startup = os.path.join(blender_path, 'scripts', 'startup')

    blenderpython_src = os.path.join(blender_path, 'python')
    blenderpython_dst = os.path.join(blender_path, 'original_python')
    compas_bootstrapper = os.path.join(startup, 'compas_bootstrapper.py')

    if os.path.exists(blenderpython_dst):
        print(
            'Found existing installation, restoring bundled python installation...'
        )
        if os.path.exists(blenderpython_src):
            remove_symlink(blenderpython_src)

        print(
            '  Renaming original_python back to bundled python folder: {} => {}'
            .format(blenderpython_dst, blenderpython_src))
        rename(blenderpython_dst, blenderpython_src)

    if os.path.exists(compas_bootstrapper):
        print('  Removing compas bootstrapper...')
        remove(compas_bootstrapper)

    print('Installing current conda environment into Blender...')
    print(
        '  Renaming bundled python folder to original_python: {} => {}'.format(
            blenderpython_src, blenderpython_dst))
    rename(blenderpython_src, blenderpython_dst)
    create_symlinks([(os.environ['CONDA_PREFIX'], blenderpython_src)])

    # Take either the CONDA environment directory or the current Python executable's directory
    python_directory = os.environ.get('CONDA_PREFIX', None) or os.path.dirname(
        sys.executable)
    environment_name = os.environ.get('CONDA_DEFAULT_ENV', '')

    # Get current sys.version value, we will override it inside Blender
    # because it seems Blender overrides it as well, but doing so breaks many things after having replaced the Python interpreter
    sys_version = "\\n".join(sys.version.split("\n"))

    _handle, bootstrapper_temp_path = tempfile.mkstemp(suffix='.py', text=True)

    with open(bootstrapper_temp_path, 'w') as f:
        f.write(
            BOOTSTRAPPER_TEMPLATE.format(environment_name, python_directory,
                                         sys_version))

    print('  Creating bootstrap script: {}'.format(compas_bootstrapper))
    copy(bootstrapper_temp_path, compas_bootstrapper)

    print()
    print('COMPAS for Blender {} has been installed.'.format(version))
Beispiel #4
0
def install(blender_path, version=None):
    """Install COMPAS for Blender.

    Parameters
    ----------
    blender_path : str
        The path to the folder with the version number of Blender.
        For example, on Mac: ``'/Applications/Blender.app/Contents/Resources/2.83'``.
        On Windows: ``'%PROGRAMFILES%/Blender Foundation/Blender 2.83/2.83'``.
    version : {'2.83', '2.93'}, optional
        The version number of Blender.
        Default is ``'2.93'``.

    Examples
    --------
    .. code-block:: bash

        $ python -m compas_blender.install

    .. code-block:: bash

        $ python -m compas_blender.install -v 2.93

    .. code-block:: bash

        $ python -m compas_blender.install /Applications/Blender.app/Contents/Resources/2.93

    """
    if not os.environ.get('CONDA_PREFIX'):
        print('Conda environment not found. The installation into Blender requires an active conda environment with a matching Python version to continue.')
        sys.exit(-1)

    if not version and not blender_path:
        version = '2.93'

    if version and blender_path:
        print('Both options cannot be provided simultaneously. Provide the full installation path, or the version with flag -v.')
        sys.exit(-1)

    if version:
        if compas.LINUX:
            print('Version-based installs are currently not supported for Linux. Please provide the full installation path with the -p option.')
            sys.exit(-1)

        blender_path = compas_blender._get_default_blender_installation_path(version)

    if not os.path.exists(blender_path):
        raise FileNotFoundError('Blender version folder not found.')

    path, version = os.path.split(blender_path)

    print('Installing COMPAS for Blender {}'.format(version))

    startup = os.path.join(blender_path, 'scripts', 'startup')

    blenderpython_src = os.path.join(blender_path, 'python')
    blenderpython_dst = os.path.join(blender_path, 'original_python')
    compas_bootstrapper = os.path.join(startup, 'compas_bootstrapper.py')

    if os.path.exists(blenderpython_dst):
        print('Found existing installation, restoring bundled python installation...')
        if os.path.exists(blenderpython_src):
            remove_symlink(blenderpython_src)

        print('  Renaming original_python back to bundled python folder: {} => {}'.format(blenderpython_dst, blenderpython_src))
        rename(blenderpython_dst, blenderpython_src)

    if os.path.exists(compas_bootstrapper):
        print('  Removing compas bootstrapper...')
        remove(compas_bootstrapper)

    print('Installing current conda environment into Blender...')
    print('  Renaming bundled python folder to original_python: {} => {}'.format(blenderpython_src, blenderpython_dst))
    rename(blenderpython_src, blenderpython_dst)
    create_symlinks([(os.environ['CONDA_PREFIX'], blenderpython_src)])

    # Take either the CONDA environment directory or the current Python executable's directory
    python_directory = os.environ.get('CONDA_PREFIX', None) or os.path.dirname(sys.executable)
    environment_name = os.environ.get('CONDA_DEFAULT_ENV', '')

    # Get current sys.version value, we will override it inside Blender
    # because it seems Blender overrides it as well, but doing so breaks many things after having replaced the Python interpreter
    sys_version = "\\n".join(sys.version.split("\n"))

    _handle, bootstrapper_temp_path = tempfile.mkstemp(suffix='.py', text=True)

    with open(bootstrapper_temp_path, 'w') as f:
        f.write(BOOTSTRAPPER_TEMPLATE.format(environment_name, python_directory, sys_version))

    print('  Creating bootstrap script: {}'.format(compas_bootstrapper))
    copy(bootstrapper_temp_path, compas_bootstrapper)

    print()
    print('COMPAS for Blender {} has been installed.'.format(version))
Beispiel #5
0
def install_plugin(plugin, version=None):
    """Install a Rhino Python Command Plugin.

    Parameters
    ----------
    plugin : str
        The path to the plugin folder.
    version : {'5.0', '6.0', '7.0', '8.0'}, optional
        The version of Rhino for which the plugin should be installed.
        Default is ``'6.0'``.

    Notes
    -----
    The version info is only relevant for Rhino on Windows.

    The function creates an *editable install*, which means that the plugin
    folder is *symlinked* into the correct location so Rhino can find and load it.
    The contents of the source folder can still be edited and next time you start
    Rhino those canges will be reflected in the loaded plugin.

    Examples
    --------
    Assuming the plugin folder is at the following location on your computer

    .. code-block:: none

        ~/Code/compas_xxx/ui/Rhino/XXX

    and contains at least a "dev" folder with a ``__plugin__.py`` file with

    * the GUID of the tool: ``id={...}``, and
    * the name of the tool: ``title="..."``,

    it can be installed with the following command,

    .. code-block:: bash

        cd ~/Code/compas_xxx
        python -m compas_rhino.install_plugin ui/Rhino/XXX

    or the following, if the plugin should be installed for Rhino 7.

    .. code-block:: bash

        cd ~/Code/compas_xxx
        python -m compas_rhino.install_plugin -v 7.0 ui/Rhino/XXX

    """
    if not os.path.isdir(plugin):
        raise Exception('Cannot find the plugin: {}'.format(plugin))

    version = compas_rhino._check_rhino_version(version)

    plugin_dir = os.path.abspath(plugin)

    # Clean up the plugin directory
    # by removing all broken symlinks
    # because ... they're broken!

    symlinks_to_remove = []

    for name in os.listdir(plugin_dir):
        path = os.path.join(plugin_dir, name)
        if os.path.islink(path):
            if not os.path.exists(path):
                symlinks_to_remove.append(dict(name=name, link=path))

    symlinks_removed = []
    symlinks_unremoved = []

    if symlinks_to_remove:
        symlinks = [link['link'] for link in symlinks_to_remove]
        removal_results = remove_symlinks(symlinks)
        for uninstall_data, success in zip(symlinks_to_remove, removal_results):
            if success:
                symlinks_removed.append(uninstall_data['name'])
            else:
                symlinks_unremoved.append(uninstall_data['name'])

    if symlinks_removed:
        print('\nThe following package symlinks are broken and were removed:\n')
        for name in symlinks_removed:
            print('   {}'.format(name.ljust(20)))

    if symlinks_unremoved:
        print('\nThe following package symlinks are broken but could not be removed:\n')
        for name in symlinks_unremoved:
            print('   {}'.format(name.ljust(20)))

    # -----------------------------
    # proceed with the installation
    # -----------------------------

    plugin_path, plugin_name = os.path.split(plugin_dir)
    plugin_path = plugin_path or os.getcwd()

    plugin_dev = os.path.join(plugin_dir, 'dev')

    if not os.path.isdir(plugin_dev):
        raise Exception('The plugin does not contain a dev folder.')

    plugin_info = os.path.join(plugin_dev, '__plugin__.py')

    if not os.path.isfile(plugin_info):
        raise Exception('The plugin does not contain plugin info.')

    __plugin__ = imp.load_source('__plugin__', plugin_info)

    if not __plugin__.id:
        raise Exception('Plugin id is not set.')

    if not __plugin__.title:
        raise Exception('Plugin title is not set.')

    plugin_fullname = "{}{}".format(__plugin__.title, __plugin__.id)

    python_plugins_path = compas_rhino._get_rhino_pythonplugins_path(version)

    if not os.path.exists(python_plugins_path):
        os.mkdir(python_plugins_path)

    source = plugin_dir
    destination = os.path.join(python_plugins_path, plugin_fullname)

    print('\nInstalling PlugIn {} to Rhino PythonPlugIns.'.format(plugin_name))

    remove_symlinks([destination])
    create_symlinks([(source, destination)])

    print('\nPlugIn {} Installed.'.format(plugin_name))
    print('\nRestart Rhino and open the Python editor at least once to make it available.')
Beispiel #6
0
def install(version=None, packages=None):
    """Install COMPAS for Rhino.

    Parameters
    ----------
    version : {'5.0', '6.0'}, optional
        The version number of Rhino.
        Default is ``'6.0'``.
    packages : list of str, optional
        List of packages to install or None to use default package list.
        Default is ``['compas', 'compas_rhino', 'compas_ghpython']``.

    Examples
    --------
    .. code-block:: python

        >>> import compas_rhino
        >>> compas_rhino.install('6.0')

    .. code-block:: python

        $ python -m compas_rhino.install -v 6.0

    """
    if version not in ('5.0', '6.0'):
        version = '6.0'

    if system == 'win32':
        print('Installing COMPAS packages to Rhino {0} IronPython lib:'.format(
            version))
    elif system == 'darwin':
        print('Installing COMPAS packages to Rhino IronPython lib.')

    if not packages:
        packages = INSTALLABLE_PACKAGES

    ipylib_path = compas_rhino._get_ironpython_lib_path(version)
    print('IronPython location: {}'.format(ipylib_path))
    print()

    results = []
    symlinks = []
    exit_code = 0

    for package in packages:
        package_path = _get_package_path(importlib.import_module(package))
        symlink_path = os.path.join(ipylib_path, package)
        symlinks.append((package_path, symlink_path))

    removal_results = remove_symlinks([link[1] for link in symlinks])

    for package, success in zip(packages, removal_results):
        if not success:
            results.append(
                (package,
                 'ERROR: Cannot remove symlink, try to run as administrator.'))

    create_results = create_symlinks(symlinks)

    for package, success in zip(packages, create_results):
        result = 'OK' if success else 'ERROR: Cannot create symlink, try to run as administrator.'
        results.append((package, result))

    if not all(create_results):
        exit_code = -1

    if exit_code == -1:
        results.append((
            'compas_bootstrapper',
            'WARNING: One or more packages failed, will not install bootstrapper, try uninstalling first'
        ))
    else:
        # Take either the CONDA environment directory or the current Python executable's directory
        python_directory = os.environ.get(
            'CONDA_PREFIX', None) or os.path.dirname(sys.executable)
        environment_name = os.environ.get('CONDA_DEFAULT_ENV', '')
        compas_bootstrapper = os.path.join(ipylib_path,
                                           'compas_bootstrapper.py')

        try:
            bootstrapper_data = _get_bootstrapper_data(compas_bootstrapper)
            installed_packages = bootstrapper_data.get('INSTALLED_PACKAGES',
                                                       [])
            installed_packages = list(set(installed_packages + list(packages)))

            with open(compas_bootstrapper, 'w') as f:
                f.write('ENVIRONMENT_NAME = r"{}"\n'.format(environment_name))
                f.write('PYTHON_DIRECTORY = r"{}"\n'.format(python_directory))
                f.write('INSTALLED_PACKAGES = {}'.format(
                    repr(installed_packages)))
                results.append(('compas_bootstrapper', 'OK'))
        except:  # noqa: E722
            results.append((
                'compas_bootstrapper',
                'ERROR: Could not create compas_bootstrapper to auto-determine Python environment'
            ))

    for package, status in results:
        print('   {} {}'.format(package.ljust(20), status))

        if status != 'OK':
            exit_code = -1

    print('\nCompleted.')
    sys.exit(exit_code)
Beispiel #7
0
def install_plugin(plugin, version=None):
    """Install a Rhino Python Command Plugin.

    Parameters
    ----------
    plugin : str
        The path to the plugin folder.
    version : {'5.0', '6.0', '7.0'}, optional
        The version of Rhino for which the plugin should be installed.
        Default is ``'6.0'``.

    Notes
    -----
    The version info is only relevant for Rhino on Windows.

    The function creates an *editable install*, which means that the plugin
    folder is *symlinked* into the correct location so Rhino can find and load it.
    The contents of the source folder can still be edited and next time you start
    Rhino those canges will be reflected in the loaded plugin.

    Examples
    --------
    Assuming the plugin folder is at the following location on your computer

    .. code-block:: none

        ~/Code/compas_xxx/ui/Rhino/XXX

    and contains at least a "dev" folder with a ``__plugin__.py`` file with

    * the GUID of the tool: ``id={...}``, and
    * the name of the tool: ``title="..."``,

    it can be installed with the following command,

    .. code-block:: bash

        cd ~/Code/compas_xxx
        python -m compas_rhino.install_plugin ui/Rhino/XXX

    or the following, if the plugin should be installed for Rhino 7.

    .. code-block:: bash

        cd ~/Code/compas_xxx
        python -m compas_rhino.install_plugin -v 7.0 ui/Rhino/XXX

    """
    if version not in ('5.0', '6.0', '7.0'):
        version = '6.0'

    if not os.path.isdir(plugin):
        raise Exception('Cannot find the plugin: {}'.format(plugin))

    plugin_dir = os.path.abspath(plugin)

    plugin_path, plugin_name = os.path.split(plugin_dir)
    if not plugin_path:
        plugin_path = os.getcwd()

    plugin_dev = os.path.join(plugin_dir, 'dev')

    if not os.path.isdir(plugin_dev):
        raise Exception('The plugin does not contain a dev folder.')

    plugin_info = os.path.join(plugin_dev, '__plugin__.py')

    if not os.path.isfile(plugin_info):
        raise Exception('The plugin does not contain plugin info.')

    __plugin__ = imp.load_source('__plugin__', plugin_info)

    if not __plugin__.id:
        raise Exception('Plugin id is not set.')

    if not __plugin__.title:
        raise Exception('Plugin title is not set.')

    plugin_fullname = "{}{}".format(__plugin__.title, __plugin__.id)

    python_plugins_path = compas_rhino._get_python_plugins_path(version)

    if not os.path.exists(python_plugins_path):
        os.mkdir(python_plugins_path)

    source = plugin_dir
    destination = os.path.join(python_plugins_path, plugin_fullname)

    print('Installing PlugIn {} to Rhino PythonPlugIns.'.format(plugin_name))

    remove_symlinks([destination])
    create_symlinks([(source, destination)])

    print()
    print('PlugIn {} Installed.'.format(plugin_name))
    print()
    print(
        'Restart Rhino and open the Python editor at least once to make it available.'
    )