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
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." )
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"))
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)
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