Example #1
0
    def _create_project_structure(self, directory):
        """Makes the given directory a Spine Toolbox project directory.
        Creates directories and files that are common to all projects.

        Args:
            directory (str): Abs. path to a directory that should be made into a project directory

        Returns:
            bool: True if project structure was created successfully, False otherwise
        """
        self.project_dir = directory
        self.config_dir = os.path.abspath(
            os.path.join(self.project_dir, ".spinetoolbox"))
        self.items_dir = os.path.abspath(os.path.join(self.config_dir,
                                                      "items"))
        self.specs_dir = os.path.abspath(
            os.path.join(self.config_dir, "specifications"))
        self.config_file = os.path.abspath(
            os.path.join(self.config_dir, PROJECT_FILENAME))
        for dir_ in (self.project_dir, self.config_dir, self.items_dir,
                     self.specs_dir):
            try:
                create_dir(dir_)
            except OSError:
                self._logger.msg_error.emit(
                    "Creating directory {0} failed".format(dir_))
                return False
        return True
Example #2
0
 def create_data_dir(self):
     try:
         create_dir(self.data_dir)
     except OSError:
         self._logger.msg_error.emit(
             f"[OSError] Creating directory {self.data_dir} failed. Check permissions."
         )
Example #3
0
    def __init__(self,
                 toolbox,
                 project,
                 logger,
                 name,
                 description,
                 x,
                 y,
                 cancel_on_error=False):
        """
        Combiner class.

        Args:
            toolbox (ToolboxUI): a toolbox instance
            project (SpineToolboxProject): the project this item belongs to
            logger (LoggerInterface): a logger instance
            name (str): Object name
            description (str): Object description
            x (float): Initial X coordinate of item icon
            y (float): Initial Y coordinate of item icon
            cancel_on_error (bool, optional): if True, changes will be reverted on errors
        """
        super().__init__(name, description, x, y, project, logger)
        self._toolbox = toolbox
        self.logs_dir = os.path.join(self.data_dir, "logs")
        try:
            create_dir(self.logs_dir)
        except OSError:
            self._logger.msg_error.emit(
                f"[OSError] Creating directory {self.logs_dir} failed. Check permissions."
            )
        self.cancel_on_error = cancel_on_error
        self._references = dict()
        self.reference_model = QStandardItemModel()  # References to databases
        self._spine_ref_icon = QIcon(QPixmap(":/icons/Spine_db_ref_icon.png"))
Example #4
0
    def __init__(self, name, description, mappings, x, y, toolbox, project, logger, cancel_on_error=True):
        """Importer class.

        Args:
            name (str): Project item name
            description (str): Project item description
            mappings (list): List where each element contains two dicts (path dict and mapping dict)
            x (float): Initial icon scene X coordinate
            y (float): Initial icon scene Y coordinate
            toolbox (ToolboxUI): QMainWindow instance
            project (SpineToolboxProject): the project this item belongs to
            logger (LoggerInterface): a logger instance
            cancel_on_error (bool): if True the item's execution will stop on import error
       """
        super().__init__(name, description, x, y, project, logger)
        # Make logs subdirectory for this item
        self._toolbox = toolbox
        self.logs_dir = os.path.join(self.data_dir, "logs")
        try:
            create_dir(self.logs_dir)
        except OSError:
            self._logger.msg_error.emit(f"[OSError] Creating directory {self.logs_dir} failed. Check permissions.")
        # Variables for saving selections when item is (de)activated
        if not mappings:
            mappings = list()
        # convert table_types and table_row_types keys to int since json always has strings as keys.
        for _, mapping in mappings:
            table_types = mapping.get("table_types", {})
            mapping["table_types"] = {
                table_name: {int(col): t for col, t in col_types.items()}
                for table_name, col_types in table_types.items()
            }
            table_row_types = mapping.get("table_row_types", {})
            mapping["table_row_types"] = {
                table_name: {int(row): t for row, t in row_types.items()}
                for table_name, row_types in table_row_types.items()
            }
        # Convert serialized paths to absolute in mappings
        self.settings = self.deserialize_mappings(mappings, self._project.project_dir)
        # self.settings is now a dictionary, where elements have the absolute path as the key and the mapping as value
        self.cancel_on_error = cancel_on_error
        self.resources_from_downstream = list()
        self.file_model = QStandardItemModel()
        self.importer_process = None
        self.all_files = []  # All source files
        self.unchecked_files = []  # Unchecked source files
        # connector class
        self._preview_widget = {}  # Key is the filepath, value is the ImportPreviewWindow instance
    def __init__(self,
                 name,
                 description,
                 x,
                 y,
                 toolbox,
                 project,
                 logger,
                 url=None):
        """Data Store class.

        Args:
            name (str): Object name
            description (str): Object description
            x (float): Initial X coordinate of item icon
            y (float): Initial Y coordinate of item icon
            toolbox (ToolboxUI): QMainWindow instance
            project (SpineToolboxProject): the project this item belongs to
            logger (LoggerInterface): a logger instance
            url (str or dict): SQLAlchemy url
        """
        super().__init__(name, description, x, y, project, logger)
        if url is None:
            url = dict()
        if url and not isinstance(url["database"], str):
            url["database"] = deserialize_path(url["database"],
                                               self._project.project_dir)
        self._toolbox = toolbox
        self._url = self.parse_url(url)
        self._sa_url = None
        self.ds_view = None
        self._for_spine_model_checkbox_state = Qt.Unchecked
        # Make logs directory for this Data Store
        self.logs_dir = os.path.join(self.data_dir, "logs")
        try:
            create_dir(self.logs_dir)
        except OSError:
            self._logger.msg_error.emit(
                f"[OSError] Creating directory {self.logs_dir} failed. Check permissions."
            )
 def test_upgrade(self):
     """Tests that reading an old project file (.proj) and
     upgrading it produces a valid project information dictionary."""
     old_project_file = os.path.abspath(
         os.path.join(os.curdir, "tests", "test_resources",
                      "unit_test_project.proj"))
     pu = ProjectUpgrader(self.toolbox)
     old_project_dict = pu.open_proj_json(old_project_file)
     with TemporaryDirectory() as old_project_dir:
         # Old project has four items which should have a data_dir
         a_dir = os.path.join(old_project_dir, "a")
         b_dir = os.path.join(old_project_dir, "b")
         c_dir = os.path.join(old_project_dir, "c")
         d_dir = os.path.join(old_project_dir, "d")
         create_dir(a_dir)
         create_dir(b_dir)
         create_dir(c_dir)
         create_dir(d_dir)
         udgraded_project_dict = pu.upgrade(old_project_dict,
                                            old_project_dir,
                                            "dummy_project_dir")
     retval = pu.is_valid(udgraded_project_dict)
     self.assertTrue(retval)
Example #7
0
    def __init__(self,
                 toolbox,
                 project,
                 logger,
                 name,
                 description,
                 mappings,
                 x,
                 y,
                 cancel_on_error=True,
                 mapping_selection=None):
        """Importer class.

        Args:
            toolbox (ToolboxUI): QMainWindow instance
            project (SpineToolboxProject): the project this item belongs to
            logger (LoggerInterface): a logger instance
            name (str): Project item name
            description (str): Project item description
            mappings (list): List where each element contains two dicts (path dict and mapping dict)
            x (float): Initial icon scene X coordinate
            y (float): Initial icon scene Y coordinate
            cancel_on_error (bool, optional): if True the item's execution will stop on import error
            mapping_selection (list, optional): serialized checked states for each file item
                either selected or unselected
       """
        super().__init__(name, description, x, y, project, logger)
        # Make logs subdirectory for this item
        self._toolbox = toolbox
        self.logs_dir = os.path.join(self.data_dir, "logs")
        try:
            create_dir(self.logs_dir)
        except OSError:
            self._logger.msg_error.emit(
                f"[OSError] Creating directory {self.logs_dir} failed. Check permissions."
            )
        # Variables for saving selections when item is (de)activated
        if not mappings:
            mappings = list()
        # convert table_types and table_row_types keys to int since json always has strings as keys.
        for _, mapping in mappings:
            table_types = mapping.get("table_types", {})
            mapping["table_types"] = {
                table_name: {int(col): t
                             for col, t in col_types.items()}
                for table_name, col_types in table_types.items()
            }
            table_row_types = mapping.get("table_row_types", {})
            mapping["table_row_types"] = {
                table_name: {int(row): t
                             for row, t in row_types.items()}
                for table_name, row_types in table_row_types.items()
            }
        # Convert serialized paths to absolute in mappings
        _fix_1d_array_to_array(mappings)
        self.settings = deserialize_mappings(mappings,
                                             self._project.project_dir)
        # self.settings is now a dictionary, where elements have the absolute path as the key and the mapping as value
        self.cancel_on_error = cancel_on_error
        self._file_model = FileListModel()
        if not mapping_selection or isinstance(mapping_selection[0], bool):
            # This is for legacy selections which either did not exist in the item dict
            # or were just a list of booleans which caused problems with empty mappings.
            # Consider removing this if in Toolbox 0.6
            mapping_selection = {}
        else:
            mapping_selection = deserialize_checked_states(
                mapping_selection, self._project.project_dir)
        self._file_model.set_initial_state(mapping_selection)
        self._file_model.selected_state_changed.connect(
            self._push_file_selection_change_to_undo_stack)
        # connector class
        self._preview_widget = {
        }  # Key is the filepath, value is the ImportEditorWindow instance