def create_workspace(self, workspace_name: str) -> Workspace:
     """
     :param workspace_name: new workspace name
     :raise: WorkspaceError: when workspace already exists
     """
     if not workspace_name:
         raise WorkspaceError('no workspace name is specified')
     workspace_dir = self.get_workspace_path(workspace_name)
     if os.path.isdir(workspace_dir) and os.listdir(workspace_dir):
         raise WorkspaceError('workspace "%s" already exists' %
                              workspace_name)
     self._ensure_dir_exists(workspace_dir)
     return Workspace(workspace_dir, workspace_name)
 def _ensure_dir_exists(cls, dir_path):
     if not os.path.exists(dir_path):
         try:
             os.makedirs(dir_path, exist_ok=True)
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
     return dir_path
def _readline(file_path: str) -> str or None:
    if os.path.exists(file_path) and os.path.isfile(file_path):
        try:
            with open(file_path, 'r') as fp:
                return fp.readline()
        except (IOError, OSError) as e:
            raise WorkspaceError(str(e))
    return None
 def rename_workspace(self, workspace_name: str, new_workspace_name: str):
     """
     :param workspace_name: workspace name to be renamed
     :param new_workspace_name: new workspace name
     :raise: WorkspaceError
     """
     self._assert_workspace_exists(workspace_name)
     if not new_workspace_name:
         raise WorkspaceError("missing the new workspace name")
     dir_path = self.get_workspace_path('')
     if os.path.exists(dir_path):
         try:
             shutil.move(os.path.join(dir_path, workspace_name),
                         os.path.join(dir_path, new_workspace_name))
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
     workspace_dir = self.get_workspace_path(new_workspace_name)
     return Workspace(workspace_dir, new_workspace_name)
 def remove_outputs(self, workspace_name, config_name):
     """
     :param workspace_name: the workspace name in which the output files are located
     :param config_name: the config name with which the output files were created
     """
     output_dir = self.get_outputs_path(workspace_name, config_name)
     if not os.path.exists(output_dir):
         raise WorkspaceError('output directory does not exist')
     output_names = os.listdir(output_dir)
     output_paths = [
         os.path.join(output_dir, output_name)
         for output_name in output_names
     ]
     for output_path in output_paths:
         if os.path.exists(output_path):
             try:
                 os.remove(output_path)
             except (IOError, OSError) as e:
                 raise WorkspaceError(str(e))
    def open_file(cls, path):
        launch_editor_command_template = get_config_value(
            'launch_editor_command', None)
        if launch_editor_command_template:
            if isinstance(launch_editor_command_template,
                          str) and launch_editor_command_template.strip():
                launch_editor_command_template = launch_editor_command_template.strip(
                )
            else:
                launch_editor_command_template = None
            if not launch_editor_command_template:
                raise WorkspaceError(
                    'configuration parameter "launch_editor_command" must be a non-empty string'
                )
        else:
            try:
                # Windows:
                # Start a file with its associated application.
                os.startfile(path)
                return
            except AttributeError:
                if shutil.which('xdg-open'):
                    # Unix Desktops
                    # xdg-open opens a file or URL in the user's preferred application.
                    launch_editor_command_template = 'xdg-open "{file}"'
                elif shutil.which('open'):
                    # Mac OS X
                    # Open a file or folder. The open command opens a file (or a folder or URL), just as
                    # if you had double-clicked the file's icon.
                    launch_editor_command_template = 'open "{file}"'
                else:
                    print('warning: don\'t know how to open %s' % path)
                    return

        launch_editor_command = launch_editor_command_template.format(
            file=path)
        try:
            # print('launch_editor_command:', launch_editor_command)
            subprocess.call(launch_editor_command, shell=True)
        except (IOError, OSError) as error:
            raise WorkspaceError(str(error))
 def delete_workspace(self, workspace_name: str):
     """
     :param workspace_name: workspace name to be deleted
     :raise: WorkspaceError: thrown when workspace not found or cannot delete the workspace
     """
     self._assert_workspace_exists(workspace_name)
     dir_path = self.get_workspace_path(workspace_name)
     if os.path.exists(dir_path):
         try:
             shutil.rmtree(dir_path)
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
 def delete_config(self, workspace_name: str, config_name: str):
     """
     :param workspace_name: the workspace name where the config is to be removed
     :param config_name: the name of the configuration to be removed
     :return:
     """
     self._assert_workspace_exists(workspace_name)
     self._assert_config_exists(workspace_name, config_name)
     dir_path = self.get_workspace_path(workspace_name, _CONFIGS_DIR_NAME,
                                        config_name)
     if os.path.exists(dir_path):
         try:
             shutil.rmtree(dir_path)
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
 def copy_workspace(self, workspace_name: str, new_workspace_name: str):
     """
     :param workspace_name: workspace name to be copied
     :param new_workspace_name: new workspace name
     :raise: WorkspaceError
     """
     self._assert_workspace_exists(workspace_name)
     dir_path = self.get_workspace_path('')
     if os.path.exists(dir_path):
         try:
             shutil.copytree(os.path.join(dir_path, workspace_name),
                             os.path.join(dir_path, new_workspace_name))
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
     workspace_dir = self.get_workspace_path(new_workspace_name)
     return Workspace(workspace_dir, new_workspace_name)
 def add_inputs(self, workspace_name: str, input_paths, monitor):
     """
     :param workspace_name: workspace name to add the input
     :param input_paths: path to the input files to be added
     :param monitor: to monitor the progress
     """
     inputs_dir = self._ensure_dir_exists(
         self.get_inputs_path(workspace_name))
     with monitor.starting('adding inputs', len(input_paths)):
         for input_path in input_paths:
             try:
                 shutil.copy(
                     input_path,
                     os.path.join(inputs_dir, os.path.basename(input_path)))
             except (IOError, OSError) as e:
                 raise WorkspaceError(str(e))
             monitor.progress(1)
 def remove_inputs(self, workspace_name, input_names, monitor):
     """
     :param workspace_name: workspace name in which the inputs are to be removed
     :param input_names: name of input files to be removed
     :param monitor: to monitor the progress
     """
     input_paths = [
         self.get_inputs_path(workspace_name, input_name)
         for input_name in input_names
     ]
     with monitor.starting('removing inputs', len(input_paths)):
         for input_path in input_paths:
             if os.path.exists(input_path):
                 try:
                     os.remove(input_path)
                 except (IOError, OSError) as e:
                     raise WorkspaceError(str(e))
             monitor.progress(1)
 def rename_config(self, workspace_name: str, config_name: str,
                   new_config_name: str):
     """
     :param workspace_name: the workspace name where the config is to be renamed
     :param config_name: the name of the configuration to be renamed
     :param new_config_name: the name of the new configuration
     :raise: WorkspaceError
     """
     self._assert_workspace_exists(workspace_name)
     self._assert_config_exists(workspace_name, config_name)
     dir_path = self.get_workspace_path(workspace_name, _CONFIGS_DIR_NAME,
                                        config_name)
     dir_path_new = self.get_workspace_path(workspace_name,
                                            _CONFIGS_DIR_NAME,
                                            new_config_name)
     if os.path.exists(dir_path):
         try:
             os.rename(dir_path, dir_path_new)
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
 def create_config(self,
                   workspace_name: str,
                   config_name: str,
                   cryosat: bool = False):
     """
     :param cryosat: True to create a config based on cryosat template
     :param workspace_name: the workspace name where the config is to be created
     :param config_name: the name of the configuration to be added
     """
     self._assert_workspace_exists(workspace_name)
     if self.config_exists(workspace_name, config_name):
         raise WorkspaceError(
             'workspace "%s" already contains a configuration "%s"' %
             (workspace_name, config_name))
     config_dir = self.get_config_path(workspace_name, config_name)
     dir_path = self._ensure_dir_exists(config_dir)
     package = _CRYOSAT_CONFIG_PACKAGE_NAME if cryosat else _DEFAULT_CONFIG_PACKAGE_NAME
     # TODO (forman, 20160727): copy text files so that '\n' is replaced by OS-specific line separator
     self._copy_resource(package, 'CHD.json', dir_path)
     self._copy_resource(package, 'CNF.json', dir_path)
     self._copy_resource(package, 'CST.json', dir_path)
 def delete_all_workspaces(self) -> str:
     if os.path.isdir(self._workspaces_dir):
         try:
             shutil.rmtree(self._workspaces_dir)
         except (IOError, OSError) as e:
             raise WorkspaceError(str(e))
 def _assert_config_exists(self, workspace_name, config_name):
     if not os.path.exists(self.get_config_path(workspace_name,
                                                config_name)):
         raise WorkspaceError(
             'DDP configuration "%s" of workspace "%s" does not exist' %
             (config_name, workspace_name))
 def _assert_workspace_exists(self, workspace_name):
     if not os.path.exists(self.get_workspace_path(workspace_name)):
         raise WorkspaceError('workspace "%s" does not exist' %
                              workspace_name)
 def _copy_resource(cls, package, file_name, dir_path):
     try:
         with open(os.path.join(dir_path, file_name), 'wb') as fp:
             fp.write(pkgutil.get_data(package, file_name))
     except (IOError, OSError) as e:
         raise WorkspaceError(str(e))
    def launch_notebook(cls,
                        title: str,
                        notebook_dir: str,
                        notebook_path: str = None):

        # we start a new terminal/command window here so that non-expert users can close the Notebook session easily
        # by closing the newly created window.

        terminal_title = 'DeDop - %s' % title

        notebook_command = 'jupyter notebook --notebook-dir "%s"' % notebook_dir
        notebook_command_with_prefix = '{prefix}/bin/{notebook_command}'.format(
            prefix=sys.prefix, notebook_command=notebook_command)
        if notebook_path:
            notebook_command += ' "%s"' % notebook_path
            notebook_command_with_prefix += ' "%s"' % notebook_path

        launch_notebook_command_template = get_config_value(
            'launch_notebook_command', None)
        launch_notebook_in_new_terminal = True
        if launch_notebook_command_template:
            if isinstance(launch_notebook_command_template,
                          str) and launch_notebook_command_template.strip():
                launch_notebook_command_template = launch_notebook_command_template.strip(
                )
            else:
                launch_notebook_command_template = None
            if not launch_notebook_command_template:
                raise WorkspaceError(
                    'configuration parameter "launch_notebook_command" must be a non-empty string'
                )
            launch_notebook_in_new_terminal = get_config_value(
                'launch_notebook_in_new_terminal', False)
        else:
            if sys.platform.startswith('win'):
                # Windows
                # launch_notebook_command_template = 'start "{title}" /Min {command}'
                launch_notebook_command_template = 'start "{title}" /Min "{command_file}"'
            elif sys.platform == 'darwin':
                # Mac OS X
                launch_notebook_command_template = 'open -a Terminal "{command_file}"'
            elif shutil.which("konsole"):
                # KDE
                launch_notebook_command_template = 'konsole -p tabtitle="{title}" -e \'{command}\' & disown'
            elif shutil.which("gnome-terminal"):
                # GNOME / Ubuntu
                launch_notebook_command_template = 'gnome-terminal -e \'{command}\''
            elif shutil.which("xterm"):
                launch_notebook_command_template = 'xterm  -T "{title}" -e \'{command}\''
            else:
                launch_notebook_command_template = notebook_command_with_prefix
                launch_notebook_in_new_terminal = False

        command_file = ''
        if '{command_file}' in launch_notebook_command_template:
            try:
                if not os.path.exists(DEFAULT_TEMP_DIR):
                    os.makedirs(DEFAULT_TEMP_DIR)

                command_basename = 'dedop-notebook-server'
                if sys.platform.startswith('win'):
                    command_file = os.path.join(DEFAULT_TEMP_DIR,
                                                command_basename + '.bat')
                    with open(command_file, 'w') as fp:
                        fp.write(
                            'call "{prefix}/Scripts/activate.bat" "{prefix}"\n'
                            'call {command}\n'.format(
                                prefix=sys.prefix, command=notebook_command))
                else:
                    import stat
                    command_file = os.path.join(DEFAULT_TEMP_DIR,
                                                command_basename)
                    with open(command_file, 'w') as fp:
                        fp.write('#!/bin/bash\n'
                                 'source "{prefix}/bin/activate" "{prefix}"\n'
                                 '{command}\n'.format(
                                     prefix=sys.prefix,
                                     command=notebook_command))
                    os.chmod(command_file,
                             stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE)
            except (OSError, IOError) as error:
                raise WorkspaceError(str(error))

        launch_notebook_command = launch_notebook_command_template.format(
            title=terminal_title,
            command=notebook_command_with_prefix,
            command_file=command_file,
            prefix=sys.prefix)
        try:
            print('calling:', launch_notebook_command)
            subprocess.check_call(launch_notebook_command, shell=True)
            if launch_notebook_in_new_terminal:
                print('A terminal window titled "%s" has been opened.' %
                      cls._limit_title(terminal_title, 30, mode='l'))
                print(
                    'Close that window or press CTRL+C within it to terminate the Notebook session.'
                )
        except (subprocess.CalledProcessError, IOError, OSError) as error:
            raise WorkspaceError('failed to launch Jupyter Notebook: %s' %
                                 str(error))
def _writeline(file_path: str, text: str):
    try:
        with open(file_path, 'w') as fp:
            fp.write(text)
    except (IOError, OSError) as e:
        raise WorkspaceError(str(e))