Пример #1
0
    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()
Пример #2
0
    def __init__(self):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = os.path.join(g.folder, c.DEFAULT_CONFIG_DIR)
        self.filename = os.path.join(self.folder,
                                     'config' + c.CONFIG_EXTENSION)

        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

        # try:

        self.load_config()
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)

        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters[
            'fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units_metric = 0 if self.vars.General[
            'tool_units'] == 'in' else 1
Пример #3
0
    def load_config(self):
        """Load Config File"""
        print(self.file_name)
        if os.path.isfile(self.file_name):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.file_name,
                                          configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)
            except self.var_dict == None:  #rw
                logger.error(
                    "reading values from postprocessorconfig file error")  #rw

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
    def create_default_config(self):
        """
        If no postprocessor config file exists this function is called
        to generate the config file based on its specification.
        """
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        logger.debug(POSTPRO_SPEC)

        self.var_dict = ConfigObj(configspec=POSTPRO_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()
Пример #5
0
    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.file_name. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.file_name, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)
        except self.var_dict == None: #rw
            logger.error("reading values from postprocessorconfig file error") #rw

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.update_config()
Пример #6
0
    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()
Пример #7
0
class MyPostProConfig(object):
    """
    This class hosts all functions related to the PostProConfig File.
    """
    def __init__(self, file_name='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param file_name: The file_name for the creation of a new config
        file and the file_name of the file to read config from.
        """
        self.folder = os.path.join('C:\\PythonScripts\\1.Programming\\dxf2g\\config')
        self.file_name = os.path.join(self.folder, file_name)

        self.version_mismatch = '' # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC, interpolation=False, list_values=False, _inspec=True)

    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.file_name. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.file_name, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)
        except self.var_dict == None: #rw
            logger.error("reading values from postprocessorconfig file error") #rw

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.update_config()

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the postprocessor configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)
        # add here any update needed for the internal variables of this class

    def make_settings_folder(self):
        """
        This method creates the postprocessor settings folder if necessary
        """
        try:
            os.mkdir(self.folder)
        except OSError:
            pass
Пример #8
0
    def __init__(self, file_name='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param file_name: The file_name for the creation of a new config
        file and the file_name of the file to read config from.
        """
        self.folder = os.path.join('C:\\PythonScripts\\1.Programming\\dxf2g\\config')
        self.file_name = os.path.join(self.folder, file_name)

        self.version_mismatch = '' # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC, interpolation=False, list_values=False, _inspec=True)
Пример #9
0
    def create_default_config(self):
        """
        If no postprocessor config file exists this function is called
        to generate the config file based on its specification.
        """
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        logger.debug(POSTPRO_SPEC)

        self.var_dict = ConfigObj(configspec=POSTPRO_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()
    def __init__(self, filename='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param filename: The filename for the creation of a new config
        file and the filename of the file to read config from.
        """
        self.folder = os.path.join(g.folder, c.DEFAULT_POSTPRO_DIR)
        self.filename = os.path.join(self.folder, filename)

        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)
Пример #11
0
    def __init__(self, script_dir):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = script_dir + '\\config'
        self.file_name = os.path.join(self.folder,
                                      'config' + c.CONFIG_EXTENSION)

        self.version_mismatch = ''  # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

        # try:

        self.load_config()
        self.update_config()

        # The following settings won't be modified after a change in the configuration window.
        # If a setting need to be updated when the configuration changes, move it to the update_config() function
        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters[
            'fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units = self.vars.General[
            'tool_units']  # store the initial tool_units (we don't want it to change until software restart)
        self.tool_units_metric = 0 if self.vars.General[
            'tool_units'] == 'in' else 1
Пример #12
0
class MyConfig(object):
    """
    This class hosts all functions related to the Config File.
    """
    def __init__(self):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = os.path.join(g.folder, c.DEFAULT_CONFIG_DIR)
        self.filename = os.path.join(self.folder, 'config' + c.CONFIG_EXTENSION)

        self.version_mismatch = '' # no problem for now
        self.default_config = False # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC, interpolation=False, list_values=False, _inspec=True)

        # try:

        self.load_config()
        self.update_config()

        # The following settings won't be modified after a change in the configuration window.
        # If a setting need to be updated when the configuration changes, move it to the update_config() function
        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters['fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units = self.vars.General['tool_units'] # store the initial tool_units (we don't want it to change until software restart)
        self.tool_units_metric = 0 if self.vars.General['tool_units'] == 'in' else 1

        # except Exception, msg:
        #     logger.warning(self.tr("Config loading failed: %s") % msg)
        #     return False

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(QtCore.QCoreApplication.translate('MyConfig',
                                                           string_to_translate))

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)
        # add here any update needed for the internal variables of this class
        

    def make_settings_folder(self):
        """Create settings folder if necessary"""
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename, configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version']['config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                #raise VersionMismatchError(fileversion, CONFIG_VERSION)
                # version mismatch flag, it will be used to display an error.
                self.version_mismatch = self.tr("The configuration file version ({0}) doesn't match the software expected version ({1}).\n\nYou have to delete (or carefully edit) the configuration file \"{2}\" to solve the problem.").format(fileversion, CONFIG_VERSION, self.filename)

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(self.tr("trying to rename bad cfg %s to %s") % (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(self.tr("rename(%s,%s) failed: %s") % (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(self.tr("renamed bad varspace %s to '%s'") % (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(self.tr("created default varspace '%s'") % self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever

    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def _save_varspace(self):
        """Saves Variables space"""
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """Prints Variables"""
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)

    def makeConfigWindgets(self):
        """
        Build the configuration widgets and store them into a dictionary.
        The structure of the dictionnary must match the structure of the configuration file. The names of the keys must be identical to those used in the configfile.
        If a name is declared in the configfile but not here, it simply won't appear in the config window (the config_version for example must not be modified by the user, so it is not declared here)
        """
        self.cfg_widget_def = \
        {
            '__section_title__':
            {
                # This section is only used for assigning titles to the keys of the dictionnary (= name of the sections used in the config file).
                # This name is displayed in the tabs of the configuration window ; if no name is provided, the key name is used. A same title may be used for several keys : in this case, all the items that belongs to this section are regrouped into the same tab.
                # Note: the title may be specified in the section itselt too, using special entry "'__section_title__': Title to use"
                'Tool_Parameters': self.tr("Tools table"),
                'Custom_Actions' : self.tr("Custom actions"),
            },
            'Paths':
            {
                '__section_title__': self.tr("Software config"),
                'import_dir': CfgLineEdit(self.tr('Default look for DXF files in:')),
                'output_dir': CfgLineEdit(self.tr('Default export generated GCODE to:')),
            },
            'Filters':
            {
                '__section_title__': self.tr("Software config"),
                'pstoedit_cmd': CfgLineEdit(self.tr('pstoedit command location:')),
                'pstoedit_opt': CfgListEdit(self.tr('pstoedit options:'), ','),
            },
            'Axis_letters':
            {
                '__section_title__': self.tr("Machine config"),
                'ax1_letter': CfgLineEdit(self.tr('Letter used for first axis:')),
                'ax2_letter': CfgLineEdit(self.tr('Letter used for second axis:')),
                'ax3_letter': CfgLineEdit(self.tr('Letter used for third axis:')),
            },
            'Plane_Coordinates':
            {
                '__section_title__': self.tr("Machine config"),
                'axis1_start_end': CfgDoubleSpinBox(self.tr('Start/End coordinate for first axis:')),
                'axis2_start_end': CfgDoubleSpinBox(self.tr('Start/End coordinate for second axis:')),
            },
            'Depth_Coordinates':
            {
                '__section_title__': self.tr("Machine config"),
                'axis3_retract': CfgDoubleSpinBox(self.tr('Third axis default retraction coordinate:')),
                'axis3_safe_margin': CfgDoubleSpinBox(self.tr('Third axis default safe coordinate:')),
                'axis3_start_mill_depth': CfgDoubleSpinBox(self.tr('Third axis default workpiece origin:')),
                'axis3_slice_depth': CfgDoubleSpinBox(self.tr('Third axis default slice depth:')),
                'axis3_mill_depth': CfgDoubleSpinBox(self.tr('Third axis default final mill depth:')),
            },
            'Feed_Rates':
            {
                '__section_title__': self.tr("Machine config"),
                'f_g1_plane': CfgDoubleSpinBox(self.tr('G1 feed rate for first and second axis (2D plane):'), ' mm/min'),
                'f_g1_depth': CfgDoubleSpinBox(self.tr('G1 feed rate for third axis:'), ' mm/min'),
            },
            'General':
            {
                '__section_title__': self.tr("Software config"),
                'mode3d': CfgCheckBox(self.tr('3D mode (requires OpenGL - Needs a software restart)')),
                'write_to_stdout': CfgCheckBox(self.tr('Export GCODE to stdout (instead of a file)')),
                'show_disabled_paths': CfgCheckBox(self.tr('Default enable "Show Disabled Paths"')),
                'live_update_export_route': CfgCheckBox(self.tr('Default enable "Live Update Export Route"')),
                'split_line_segments': CfgCheckBox(self.tr('Default enable "Split Line Segments" (create tabs on last slices)')),
                'automatic_cutter_compensation': CfgCheckBox(self.tr('Default enable "Automatic Cutter Compensation"')),
                'machine_type': CfgComboBox(self.tr('Default machine type at startup:')),
                'tool_units': CfgComboBox(self.tr('Units for tools (needs a software restart):')),
                #'test':
                #{
                #   'test_niveau_2': CfgCheckBox('Pour test'),
                #   'test2_niveau_2': CfgComboBox('Pour test', ('milling', 'lathe', 'drag_knife'), 'milling'),
                #},
            },
            'Cutter_Compensation':
            {
                '__section_title__': self.tr("Output settings"),
                'done_by_machine': CfgCheckBox(self.tr('Cutter compensation is done by machine (check this box if the machine reconizes G41 and G42 commands / uncheck it otherwise)')),
            },
            'Drag_Knife_Options':
            {
                'drag_angle': CfgDoubleSpinBox(self.tr('Angle above which the tool retracts to slice depth (see "Third axis slice depth parameter"):'), u'°'), #u for unicode
            },
            'Route_Optimisation':
            {
                '__section_title__': self.tr("Output settings"),
                'default_TSP': CfgCheckBox(self.tr('Default enable the TSP output path optimisation for each shape (TSP = Travelling Salesman Problem method)')),
                'TSP_shape_order': CfgComboBox(self.tr('"Constrain order only" mixes fixed and optimized shapes\n"Constrain place after" always place optimized shapes after fixed shapes:')),
                'mutation_rate': CfgDoubleSpinBox(self.tr('Mutation rate for TSP optimizer:')),
                'max_population': CfgSpinBox(self.tr('Max population for the TSP optimizer:')),
                'max_iterations': CfgSpinBox(self.tr('Max iterations for the TSP optimizer:')),
                'begin_art': CfgComboBox(self.tr('TSP start method:')),
            },
            'Import_Parameters':
            {
                '__section_title__': self.tr("Output settings"),
                'point_tolerance': CfgDoubleSpinBox(self.tr('DXF default import point tolerance:'), '', None, None, 5),
                'spline_check': CfgSpinBox(self.tr('DXF import spline check:')),
                'fitting_tolerance': CfgDoubleSpinBox(self.tr('DXF default import fit tolerance:'), '', None, None, 5),
                'insert_at_block_layer': CfgCheckBox(self.tr('insert elements which are part of a block to layer where the block is inserted')),
            },
            'Layer_Options':
            {
                '__section_title__': self.tr("Automatic tool config"),
                'id_float_separator': CfgLineEdit(self.tr('Separator between identifier and value:')),
                'mill_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Final mill depth:'), ','),
                'slice_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Infeed depth:'), ','),
                'start_mill_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Workpiece top:'), ','),
                'retract_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Z Retraction area:'), ','),
                'safe_margin_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Z Safety margin:'), ','),
                'f_g1_plane_identifiers': CfgListEdit(self.tr('Identifiers that can be used for G1 feed rate of XY plane:'), ','),
                'f_g1_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for G1 feed rate of Z:'), ','),
                'tool_nr_identifiers': CfgListEdit(self.tr('Identifiers that can be used for tool number selection:'), ','),
                'tool_diameter_identifiers': CfgListEdit(self.tr('Identifiers that can be used for tool diameter setting:'), ','),
                'spindle_speed_identifiers': CfgListEdit(self.tr('Identifiers that can be used for spindle speed:'), ','),
                'start_radius_identifiers': CfgListEdit(self.tr('Identifiers that can be used for start radius:'), ','),
            },
            'Tool_Parameters': CfgTableToolParameters(self.tr('Define the tools here:')),
            'Custom_Actions': CfgTableCustomActions(self.tr('Define here custom GCODE that can be inserted anywhere in the program:')),
            'Logging':
            {
                '__section_title__': self.tr("Software config"),
                'logfile': CfgLineEdit(self.tr('File used for logging (software restart needed):')),
                'console_loglevel': CfgComboBox(self.tr('Log any message with importance >= to log level on stderr console (software restart needed):')),
                'file_loglevel': CfgComboBox(self.tr('Log any message with importance >= to log level in logfile (software restart needed):')),
                'window_loglevel': CfgComboBox(self.tr('Log any message with importance >= to log level on the message window (software restart needed):')),
            },
        }
        
        return self.cfg_widget_def
    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.filename. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.filename, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)

            if validate_errors:
                g.logger.logger.error(
                    self.tr("errors reading %s:") % self.filename)
            for entry in validate_errors:
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = self.tr('Missing value or section.')
                g.logger.logger.error(section_string + ' = ' + error)

            if validate_errors:
                raise BadConfigFileError(
                    self.tr("syntax errors in postpro_config file"))

            # check config file version against internal version

            if POSTPRO_VERSION:
                fileversion = self.var_dict['Version'][
                    'config_version']  # this could raise KeyError

                if fileversion != POSTPRO_VERSION:
                    raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except VersionMismatchError:
            raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except Exception as inst:
            logger.error(inst)
            (base, ext) = os.path.splitext(self.filename)
            badfilename = base + c.BAD_CONFIG_EXTENSION
            logger.debug(
                self.tr("trying to rename bad cfg %s to %s") %
                (self.filename, badfilename))
            try:
                os.rename(self.filename, badfilename)
            except OSError as e:
                logger.error(
                    self.tr("rename(%s,%s) failed: %s") %
                    (self.filename, badfilename, e.strerror))
                raise
            else:
                logger.debug(
                    self.tr("renamed bad varspace %s to '%s'") %
                    (self.filename, badfilename))
                self.create_default_config()
                self.default_config = True
                logger.debug(
                    self.tr("created default varspace '%s'") % self.filename)
        else:
            self.default_config = False
            logger.debug(
                self.tr("read existing varspace '%s'") % self.filename)

        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.vars = DictDotLookup(self.var_dict)
class MyPostProConfig(object):
    """
    This class hosts all functions related to the PostProConfig File.
    """
    def __init__(self, filename='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param filename: The filename for the creation of a new config
        file and the filename of the file to read config from.
        """
        self.folder = os.path.join(g.folder, c.DEFAULT_POSTPRO_DIR)
        self.filename = os.path.join(self.folder, filename)

        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param: string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(
            QtCore.QCoreApplication.translate("MyPostProConfig",
                                              string_to_translate))

    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.filename. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.filename, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)

            if validate_errors:
                g.logger.logger.error(
                    self.tr("errors reading %s:") % self.filename)
            for entry in validate_errors:
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = self.tr('Missing value or section.')
                g.logger.logger.error(section_string + ' = ' + error)

            if validate_errors:
                raise BadConfigFileError(
                    self.tr("syntax errors in postpro_config file"))

            # check config file version against internal version

            if POSTPRO_VERSION:
                fileversion = self.var_dict['Version'][
                    'config_version']  # this could raise KeyError

                if fileversion != POSTPRO_VERSION:
                    raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except VersionMismatchError:
            raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except Exception as inst:
            logger.error(inst)
            (base, ext) = os.path.splitext(self.filename)
            badfilename = base + c.BAD_CONFIG_EXTENSION
            logger.debug(
                self.tr("trying to rename bad cfg %s to %s") %
                (self.filename, badfilename))
            try:
                os.rename(self.filename, badfilename)
            except OSError as e:
                logger.error(
                    self.tr("rename(%s,%s) failed: %s") %
                    (self.filename, badfilename, e.strerror))
                raise
            else:
                logger.debug(
                    self.tr("renamed bad varspace %s to '%s'") %
                    (self.filename, badfilename))
                self.create_default_config()
                self.default_config = True
                logger.debug(
                    self.tr("created default varspace '%s'") % self.filename)
        else:
            self.default_config = False
            logger.debug(
                self.tr("read existing varspace '%s'") % self.filename)

        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.vars = DictDotLookup(self.var_dict)

    def make_settings_folder(self):
        """
        This method creates the postprocessor settings folder if necessary
        """
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def create_default_config(self):
        """
        If no postprocessor config file exists this function is called
        to generate the config file based on its specification.
        """
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        logger.debug(POSTPRO_SPEC)

        self.var_dict = ConfigObj(configspec=POSTPRO_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()


#    def _save_varspace(self):
#        self.var_dict.filename = self.filename
#        self.var_dict.write()
#

    def print_vars(self):
        """
        Print all the variables with their values
        """
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)
Пример #15
0
    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename,
                                          configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version'][
                        'config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                #raise VersionMismatchError(fileversion, CONFIG_VERSION)
                # version mismatch flag, it will be used to display an error.
                self.version_mismatch = self.tr(
                    "The configuration file version ({0}) doesn't match the software expected version ({1}).\n\nYou have to delete (or carefully edit) the configuration file \"{2}\" to solve the problem."
                ).format(fileversion, CONFIG_VERSION, self.filename)

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(
                    self.tr("trying to rename bad cfg %s to %s") %
                    (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(
                        self.tr("rename(%s,%s) failed: %s") %
                        (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(
                        self.tr("renamed bad varspace %s to '%s'") %
                        (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(
                        self.tr("created default varspace '%s'") %
                        self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(
                self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
Пример #16
0
class MyPostProConfig(object):
    """
    This class hosts all functions related to the PostProConfig File.
    """
    def __init__(self, filename='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param filename: The filename for the creation of a new config
        file and the filename of the file to read config from.
        """
        self.folder = os.path.join(g.folder, c.DEFAULT_POSTPRO_DIR)
        self.filename = os.path.join(self.folder, filename)

        self.version_mismatch = ''  # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.filename. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.filename, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)

            if validate_errors:
                logger.error(self.tr("errors reading %s:") % self.filename)
            for entry in validate_errors:
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = self.tr('Missing value or section.')
                logger.error(section_string + ' = ' + error)

            if validate_errors:
                raise BadConfigFileError(
                    self.tr("syntax errors in postpro_config file"))

            # check config file version against internal version

            if POSTPRO_VERSION:
                fileversion = self.var_dict['Version'][
                    'config_version']  # this could raise KeyError

                if fileversion != POSTPRO_VERSION:
                    raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except VersionMismatchError:
            # version mismatch flag, it will be used to display an error.
            self.version_mismatch = self.tr(
                "The postprocessor configuration file version ({0}) doesn't match the software expected version ({1}).\n\nYou have to delete (or carefully edit) the configuration file \"{2}\" to solve the problem."
            ).format(fileversion, POSTPRO_VERSION, self.filename)

        except Exception as inst:
            #logger.error(inst)
            (base, ext) = os.path.splitext(self.filename)
            badfilename = base + c.BAD_CONFIG_EXTENSION
            logger.debug(
                self.tr("trying to rename bad cfg %s to %s") %
                (self.filename, badfilename))
            try:
                os.rename(self.filename, badfilename)
            except OSError as e:
                logger.error(
                    self.tr("rename(%s,%s) failed: %s") %
                    (self.filename, badfilename, e.strerror))
                raise
            else:
                logger.debug(
                    self.tr("renamed bad varspace %s to '%s'") %
                    (self.filename, badfilename))
                self.create_default_config()
                self.default_config = True
                logger.debug(
                    self.tr("created default varspace '%s'") % self.filename)
        else:
            self.default_config = False
            logger.debug(
                self.tr("read existing varspace '%s'") % self.filename)

        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.update_config()

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the postprocessor configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        # print  self.var_dict;
        self.vars = DictDotLookup(self.var_dict)
        # print self.vars.General["abs_export"];
        # add here any update needed for the internal variables of this class

    def make_settings_folder(self):
        """
        This method creates the postprocessor settings folder if necessary
        """
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def create_default_config(self):
        """
        If no postprocessor config file exists this function is called
        to generate the config file based on its specification.
        """
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        logger.debug(POSTPRO_SPEC)

        self.var_dict = ConfigObj(configspec=POSTPRO_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def save_varspace(self):
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """
        Print all the variables with their values
        """
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)

    @staticmethod
    def tr(string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(string_to_translate)

    @staticmethod
    def makeConfigWidgets():
        """
        Build the postprocessor configuration widgets and store them into a dictionary.
        The structure of the dictionnary must match the structure of the postprocessor configuration file. The names of the keys must be identical to those used in the configfile.
        If a name is declared in the configfile but not here, it simply won't appear in the config window (the config_version for example must not be modified by the user, so it is not declared here)
        """
        cfg_widget_def = OrderedDict([])
        return cfg_widget_def
Пример #17
0
class MyConfig(object):
    """
    This class hosts all functions related to the Config File.
    """
    def __init__(self):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = os.path.join(g.folder, c.DEFAULT_CONFIG_DIR)
        self.filename = os.path.join(self.folder,
                                     'config' + c.CONFIG_EXTENSION)

        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

        # try:

        self.load_config()
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)

        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters[
            'fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units_metric = 0 if self.vars.General[
            'tool_units'] == 'in' else 1

        # except Exception, msg:
        #     logger.warning(self.tr("Config loading failed: %s") % msg)
        #     return False

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(
            QtCore.QCoreApplication.translate('MyConfig', string_to_translate))

    def make_settings_folder(self):
        """Create settings folder if necessary"""
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename,
                                          configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version'][
                        'config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                raise VersionMismatchError(
                    fileversion, CONFIG_VERSION)  # TODO pop-up error?

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(
                    self.tr("trying to rename bad cfg %s to %s") %
                    (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(
                        self.tr("rename(%s,%s) failed: %s") %
                        (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(
                        self.tr("renamed bad varspace %s to '%s'") %
                        (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(
                        self.tr("created default varspace '%s'") %
                        self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(
                self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever

    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def _save_varspace(self):
        """Saves Variables space"""
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """Prints Variables"""
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)
Пример #18
0
class MyConfig(object):
    """
    This class hosts all functions related to the Config File.
    """
    def __init__(self):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = os.path.join(g.folder, c.DEFAULT_CONFIG_DIR)
        self.filename = os.path.join(self.folder,
                                     'config' + c.CONFIG_EXTENSION)

        self.version_mismatch = ''  # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

        # try:

        self.load_config()
        self.update_config()

        # The following settings won't be modified after a change in the configuration window.
        # If a setting need to be updated when the configuration changes, move it to the update_config() function

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters[
            'fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units = self.vars.General[
            'tool_units']  # store the initial tool_units (we don't want it to change until software restart)
        self.tool_units_metric = 0 if self.vars.General[
            'tool_units'] == 'in' else 1

        # except Exception, msg:
        #     logger.warning(self.tr("Config loading failed: %s") % msg)
        #     return False

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(string_to_translate)

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)
        # add here any update needed for the internal variables of this class

    def make_settings_folder(self):
        """Create settings folder if necessary"""
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename,
                                          configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version'][
                        'config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                #raise VersionMismatchError(fileversion, CONFIG_VERSION)
                # version mismatch flag, it will be used to display an error.
                self.version_mismatch = self.tr(
                    "The configuration file version ({0}) doesn't match the software expected version ({1}).\n\nYou have to delete (or carefully edit) the configuration file \"{2}\" to solve the problem."
                ).format(fileversion, CONFIG_VERSION, self.filename)

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(
                    self.tr("trying to rename bad cfg %s to %s") %
                    (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(
                        self.tr("rename(%s,%s) failed: %s") %
                        (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(
                        self.tr("renamed bad varspace %s to '%s'") %
                        (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(
                        self.tr("created default varspace '%s'") %
                        self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(
                self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever

    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def save_varspace(self):
        """Saves Variables space"""
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """Prints Variables"""
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)

    def makeConfigWidgets(self):
        """
        Build the configuration widgets and store them into a dictionary.
        The structure of the dictionnary must match the structure of the configuration file. The names of the keys must be identical to those used in the configfile.
        If a name is declared in the configfile but not here, it simply won't appear in the config window (the config_version for example must not be modified by the user, so it is not declared here)
        """
        coordinate_unit = self.tr(
            " mm") if self.tool_units_metric else self.tr(" in")
        speed_unit = self.tr(" mm/min") if self.tool_units_metric else self.tr(
            " IPS")
        cfg_widget_def = OrderedDict([])

        return cfg_widget_def
Пример #19
0
    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.filename. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.filename, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)

            if validate_errors:
                g.logger.logger.error(self.tr("errors reading %s:") % self.filename)
            for entry in validate_errors:
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = self.tr('Missing value or section.')
                g.logger.logger.error( section_string + ' = ' + error)

            if validate_errors:
                raise BadConfigFileError(self.tr("syntax errors in postpro_config file"))

            # check config file version against internal version

            if POSTPRO_VERSION:
                fileversion = self.var_dict['Version']['config_version'] # this could raise KeyError

                if fileversion != POSTPRO_VERSION:
                    raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except VersionMismatchError:
            raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except Exception as inst:
            logger.error(inst)
            (base, ext) = os.path.splitext(self.filename)
            badfilename = base + c.BAD_CONFIG_EXTENSION
            logger.debug(self.tr("trying to rename bad cfg %s to %s") % (self.filename, badfilename))
            try:
                os.rename(self.filename, badfilename)
            except OSError as e:
                logger.error(self.tr("rename(%s,%s) failed: %s") % (self.filename, badfilename, e.strerror))
                raise
            else:
                logger.debug(self.tr("renamed bad varspace %s to '%s'") % (self.filename, badfilename))
                self.create_default_config()
                self.default_config = True
                logger.debug(self.tr("created default varspace '%s'") % self.filename)
        else:
            self.default_config = False
            logger.debug(self.tr("read existing varspace '%s'") % self.filename)

        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.vars = DictDotLookup(self.var_dict)
Пример #20
0
class MyConfig(object):
    """
    This class hosts all functions related to the Config File.
    """
    def __init__(self):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = os.path.join(g.folder, c.DEFAULT_CONFIG_DIR)
        self.filename = os.path.join(self.folder,
                                     'config' + c.CONFIG_EXTENSION)

        self.version_mismatch = ''  # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

        # try:

        self.load_config()
        self.update_config()

        # The following settings won't be modified after a change in the configuration window.
        # If a setting need to be updated when the configuration changes, move it to the update_config() function
        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters[
            'fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units = self.vars.General[
            'tool_units']  # store the initial tool_units (we don't want it to change until software restart)
        self.tool_units_metric = 0 if self.vars.General[
            'tool_units'] == 'in' else 1

        # except Exception, msg:
        #     logger.warning(self.tr("Config loading failed: %s") % msg)
        #     return False

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(
            QtCore.QCoreApplication.translate('MyConfig', string_to_translate))

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)
        # add here any update needed for the internal variables of this class

    def make_settings_folder(self):
        """Create settings folder if necessary"""
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename,
                                          configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version'][
                        'config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                #raise VersionMismatchError(fileversion, CONFIG_VERSION)
                # version mismatch flag, it will be used to display an error.
                self.version_mismatch = self.tr(
                    "The configuration file version ({0}) doesn't match the software expected version ({1}).\n\nYou have to delete (or carefully edit) the configuration file \"{2}\" to solve the problem."
                ).format(fileversion, CONFIG_VERSION, self.filename)

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(
                    self.tr("trying to rename bad cfg %s to %s") %
                    (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(
                        self.tr("rename(%s,%s) failed: %s") %
                        (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(
                        self.tr("renamed bad varspace %s to '%s'") %
                        (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(
                        self.tr("created default varspace '%s'") %
                        self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(
                self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever

    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def _save_varspace(self):
        """Saves Variables space"""
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """Prints Variables"""
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)

    def makeConfigWindgets(self):
        """
        Build the configuration widgets and store them into a dictionary.
        The structure of the dictionnary must match the structure of the configuration file. The names of the keys must be identical to those used in the configfile.
        If a name is declared in the configfile but not here, it simply won't appear in the config window (the config_version for example must not be modified by the user, so it is not declared here)
        """
        self.cfg_widget_def = \
        {
            '__section_title__':
            {
                # This section is only used for assigning titles to the keys of the dictionnary (= name of the sections used in the config file).
                # This name is displayed in the tabs of the configuration window ; if no name is provided, the key name is used. A same title may be used for several keys : in this case, all the items that belongs to this section are regrouped into the same tab.
                # Note: the title may be specified in the section itselt too, using special entry "'__section_title__': Title to use"
                'Tool_Parameters': self.tr("Tools table"),
                'Custom_Actions' : self.tr("Custom actions"),
            },
            'Paths':
            {
                '__section_title__': self.tr("Software config"),
                'import_dir': CfgLineEdit(self.tr('Default look for DXF files in:')),
                'output_dir': CfgLineEdit(self.tr('Default export generated GCODE to:')),
            },
            'Filters':
            {
                '__section_title__': self.tr("Software config"),
                'pstoedit_cmd': CfgLineEdit(self.tr('pstoedit command location:')),
                'pstoedit_opt': CfgListEdit(self.tr('pstoedit options:'), ','),
            },
            'Axis_letters':
            {
                '__section_title__': self.tr("Machine config"),
                'ax1_letter': CfgLineEdit(self.tr('Letter used for first axis:')),
                'ax2_letter': CfgLineEdit(self.tr('Letter used for second axis:')),
                'ax3_letter': CfgLineEdit(self.tr('Letter used for third axis:')),
            },
            'Plane_Coordinates':
            {
                '__section_title__': self.tr("Machine config"),
                'axis1_start_end': CfgDoubleSpinBox(self.tr('Start/End coordinate for first axis:')),
                'axis2_start_end': CfgDoubleSpinBox(self.tr('Start/End coordinate for second axis:')),
            },
            'Depth_Coordinates':
            {
                '__section_title__': self.tr("Machine config"),
                'axis3_retract': CfgDoubleSpinBox(self.tr('Third axis default retraction coordinate:')),
                'axis3_safe_margin': CfgDoubleSpinBox(self.tr('Third axis default safe coordinate:')),
                'axis3_start_mill_depth': CfgDoubleSpinBox(self.tr('Third axis default workpiece origin:')),
                'axis3_slice_depth': CfgDoubleSpinBox(self.tr('Third axis default slice depth:')),
                'axis3_mill_depth': CfgDoubleSpinBox(self.tr('Third axis default final mill depth:')),
            },
            'Feed_Rates':
            {
                '__section_title__': self.tr("Machine config"),
                'f_g1_plane': CfgDoubleSpinBox(self.tr('G1 feed rate for first and second axis (2D plane):'), ' mm/min'),
                'f_g1_depth': CfgDoubleSpinBox(self.tr('G1 feed rate for third axis:'), ' mm/min'),
            },
            'General':
            {
                '__section_title__': self.tr("Software config"),
                'mode3d': CfgCheckBox(self.tr('3D mode (requires OpenGL - Needs a software restart)')),
                'write_to_stdout': CfgCheckBox(self.tr('Export GCODE to stdout (instead of a file)')),
                'show_disabled_paths': CfgCheckBox(self.tr('Default enable "Show Disabled Paths"')),
                'live_update_export_route': CfgCheckBox(self.tr('Default enable "Live Update Export Route"')),
                'split_line_segments': CfgCheckBox(self.tr('Default enable "Split Line Segments" (create tabs on last slices)')),
                'automatic_cutter_compensation': CfgCheckBox(self.tr('Default enable "Automatic Cutter Compensation"')),
                'machine_type': CfgComboBox(self.tr('Default machine type at startup:')),
                'tool_units': CfgComboBox(self.tr('Units for tools (needs a software restart):')),
                #'test':
                #{
                #   'test_niveau_2': CfgCheckBox('Pour test'),
                #   'test2_niveau_2': CfgComboBox('Pour test', ('milling', 'lathe', 'drag_knife'), 'milling'),
                #},
            },
            'Cutter_Compensation':
            {
                '__section_title__': self.tr("Output settings"),
                'done_by_machine': CfgCheckBox(self.tr('Cutter compensation is done by machine (check this box if the machine reconizes G41 and G42 commands / uncheck it otherwise)')),
            },
            'Drag_Knife_Options':
            {
                'drag_angle': CfgDoubleSpinBox(self.tr('Angle above which the tool retracts to slice depth (see "Third axis slice depth parameter"):'), u'°'), #u for unicode
            },
            'Route_Optimisation':
            {
                '__section_title__': self.tr("Output settings"),
                'default_TSP': CfgCheckBox(self.tr('Default enable the TSP output path optimisation for each shape (TSP = Travelling Salesman Problem method)')),
                'TSP_shape_order': CfgComboBox(self.tr('"Constrain order only" mixes fixed and optimized shapes\n"Constrain place after" always place optimized shapes after fixed shapes:')),
                'mutation_rate': CfgDoubleSpinBox(self.tr('Mutation rate for TSP optimizer:')),
                'max_population': CfgSpinBox(self.tr('Max population for the TSP optimizer:')),
                'max_iterations': CfgSpinBox(self.tr('Max iterations for the TSP optimizer:')),
                'begin_art': CfgComboBox(self.tr('TSP start method:')),
            },
            'Import_Parameters':
            {
                '__section_title__': self.tr("Output settings"),
                'point_tolerance': CfgDoubleSpinBox(self.tr('DXF default import point tolerance:'), '', None, None, 5),
                'spline_check': CfgSpinBox(self.tr('DXF import spline check:')),
                'fitting_tolerance': CfgDoubleSpinBox(self.tr('DXF default import fit tolerance:'), '', None, None, 5),
                'insert_at_block_layer': CfgCheckBox(self.tr('insert elements which are part of a block to layer where the block is inserted')),
            },
            'Layer_Options':
            {
                '__section_title__': self.tr("Automatic tool config"),
                'id_float_separator': CfgLineEdit(self.tr('Separator between identifier and value:')),
                'mill_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Final mill depth:'), ','),
                'slice_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Infeed depth:'), ','),
                'start_mill_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Workpiece top:'), ','),
                'retract_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Z Retraction area:'), ','),
                'safe_margin_identifiers': CfgListEdit(self.tr('Identifiers that can be used for Z Safety margin:'), ','),
                'f_g1_plane_identifiers': CfgListEdit(self.tr('Identifiers that can be used for G1 feed rate of XY plane:'), ','),
                'f_g1_depth_identifiers': CfgListEdit(self.tr('Identifiers that can be used for G1 feed rate of Z:'), ','),
                'tool_nr_identifiers': CfgListEdit(self.tr('Identifiers that can be used for tool number selection:'), ','),
                'tool_diameter_identifiers': CfgListEdit(self.tr('Identifiers that can be used for tool diameter setting:'), ','),
                'spindle_speed_identifiers': CfgListEdit(self.tr('Identifiers that can be used for spindle speed:'), ','),
                'start_radius_identifiers': CfgListEdit(self.tr('Identifiers that can be used for start radius:'), ','),
            },
            'Tool_Parameters': CfgTableToolParameters(self.tr('Define the tools here:')),
            'Custom_Actions': CfgTableCustomActions(self.tr('Define here custom GCODE that can be inserted anywhere in the program:')),
            'Logging':
            {
                '__section_title__': self.tr("Software config"),
                'logfile': CfgLineEdit(self.tr('File used for logging (software restart needed):')),
                'console_loglevel': CfgComboBox(self.tr('Log any message with importance >= to log level on stderr console (software restart needed):')),
                'file_loglevel': CfgComboBox(self.tr('Log any message with importance >= to log level in logfile (software restart needed):')),
                'window_loglevel': CfgComboBox(self.tr('Log any message with importance >= to log level on the message window (software restart needed):')),
            },
        }

        return self.cfg_widget_def
Пример #21
0
class MyConfig(object):
    """
    This class hosts all functions related to the Config File.
    """
    def __init__(self, script_dir):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = script_dir + '\\config'
        self.file_name = os.path.join(self.folder,
                                      'config' + c.CONFIG_EXTENSION)

        self.version_mismatch = ''  # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

        # try:

        self.load_config()
        self.update_config()

        # The following settings won't be modified after a change in the configuration window.
        # If a setting need to be updated when the configuration changes, move it to the update_config() function
        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters[
            'fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units = self.vars.General[
            'tool_units']  # store the initial tool_units (we don't want it to change until software restart)
        self.tool_units_metric = 0 if self.vars.General[
            'tool_units'] == 'in' else 1

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)
        # add here any update needed for the internal variables of this class

    def make_settings_folder(self):
        """Create settings folder if necessary"""
        try:
            os.makedirs(self.folder)
        except OSError:
            pass

    def load_config(self):
        """Load Config File"""
        print(self.file_name)
        if os.path.isfile(self.file_name):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.file_name,
                                          configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)
            except self.var_dict == None:  #rw
                logger.error(
                    "reading values from postprocessorconfig file error")  #rw

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
Пример #22
0
    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename, configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version']['config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                raise VersionMismatchError(fileversion, CONFIG_VERSION)  # TODO pop-up error?

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(self.tr("trying to rename bad cfg %s to %s") % (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(self.tr("rename(%s,%s) failed: %s") % (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(self.tr("renamed bad varspace %s to '%s'") % (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(self.tr("created default varspace '%s'") % self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
Пример #23
0
class MyConfig(object):
    """
    This class hosts all functions related to the Config File.
    """
    def __init__(self):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        """

        self.folder = os.path.join(g.folder, c.DEFAULT_CONFIG_DIR)
        self.filename = os.path.join(self.folder, 'config' + c.CONFIG_EXTENSION)

        self.default_config = False # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(CONFIG_SPEC, interpolation=False, list_values=False, _inspec=True)

        # try:

        self.load_config()
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)

        self.mode3d = self.vars.General['mode3d']

        self.machine_type = self.vars.General['machine_type']
        self.fitting_tolerance = self.vars.Import_Parameters['fitting_tolerance']
        self.point_tolerance = self.vars.Import_Parameters['point_tolerance']

        self.metric = 1  # true unit is determined while importing
        self.tool_units_metric = 0 if self.vars.General['tool_units'] == 'in' else 1

        # except Exception, msg:
        #     logger.warning(self.tr("Config loading failed: %s") % msg)
        #     return False

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(QtCore.QCoreApplication.translate('MyConfig',
                                                           string_to_translate))

    def make_settings_folder(self):
        """Create settings folder if necessary"""
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def load_config(self):
        """Load Config File"""
        if os.path.isfile(self.filename):
            try:
                # file exists, read & validate it
                self.var_dict = ConfigObj(self.filename, configspec=CONFIG_SPEC)
                _vdt = Validator()
                result = self.var_dict.validate(_vdt, preserve_errors=True)
                validate_errors = flatten_errors(self.var_dict, result)

                if validate_errors:
                    logger.error(self.tr("errors reading %s:") % self.filename)

                for entry in validate_errors:
                    section_list, key, error = entry
                    if key is not None:
                        section_list.append(key)
                    else:
                        section_list.append('[missing section]')
                    section_string = ', '.join(section_list)
                    if not error:
                        error = self.tr('Missing value or section.')
                    logger.error(section_string + ' = ' + error)

                if validate_errors:
                    raise BadConfigFileError("syntax errors in config file")

                # check config file version against internal version
                if CONFIG_VERSION:
                    fileversion = self.var_dict['Version']['config_version']  # this could raise KeyError

                    if fileversion != CONFIG_VERSION:
                        raise VersionMismatchError(fileversion, CONFIG_VERSION)

            except VersionMismatchError:
                raise VersionMismatchError(fileversion, CONFIG_VERSION)  # TODO pop-up error?

            except Exception as inst:
                logger.error(inst)
                (base, ext) = os.path.splitext(self.filename)
                badfilename = base + c.BAD_CONFIG_EXTENSION
                logger.debug(self.tr("trying to rename bad cfg %s to %s") % (self.filename, badfilename))
                try:
                    os.rename(self.filename, badfilename)
                except OSError as e:
                    logger.error(self.tr("rename(%s,%s) failed: %s") % (self.filename, badfilename, e.strerror))
                    raise
                else:
                    logger.debug(self.tr("renamed bad varspace %s to '%s'") % (self.filename, badfilename))
                    self.create_default_config()
                    self.default_config = True
                    logger.debug(self.tr("created default varspace '%s'") % self.filename)
            else:
                self.default_config = False
                # logger.debug(self.dir())
                # logger.debug(self.tr("created default varspace '%s'") % self.filename)
                # logger.debug(self.tr("read existing varspace '%s'") % self.filename)
        else:
            self.create_default_config()
            self.default_config = True
            logger.debug(self.tr("created default varspace '%s'") % self.filename)

        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever

    def create_default_config(self):
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        self.var_dict = ConfigObj(configspec=CONFIG_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def _save_varspace(self):
        """Saves Variables space"""
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """Prints Variables"""
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)
Пример #24
0
class MyPostProConfig(object):
    """
    This class hosts all functions related to the PostProConfig File.
    """
    def __init__(self, filename='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param filename: The filename for the creation of a new config
        file and the filename of the file to read config from.
        """
        self.folder = os.path.join(g.folder, c.DEFAULT_POSTPRO_DIR)
        self.filename = os.path.join(self.folder, filename)

        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC, interpolation=False, list_values=False, _inspec=True)

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param: string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(QtCore.QCoreApplication.translate("MyPostProConfig",
                                                           string_to_translate))

    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.filename. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.filename, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)

            if validate_errors:
                g.logger.logger.error(self.tr("errors reading %s:") % self.filename)
            for entry in validate_errors:
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = self.tr('Missing value or section.')
                g.logger.logger.error( section_string + ' = ' + error)

            if validate_errors:
                raise BadConfigFileError(self.tr("syntax errors in postpro_config file"))

            # check config file version against internal version

            if POSTPRO_VERSION:
                fileversion = self.var_dict['Version']['config_version'] # this could raise KeyError

                if fileversion != POSTPRO_VERSION:
                    raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except VersionMismatchError:
            raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except Exception as inst:
            logger.error(inst)
            (base, ext) = os.path.splitext(self.filename)
            badfilename = base + c.BAD_CONFIG_EXTENSION
            logger.debug(self.tr("trying to rename bad cfg %s to %s") % (self.filename, badfilename))
            try:
                os.rename(self.filename, badfilename)
            except OSError as e:
                logger.error(self.tr("rename(%s,%s) failed: %s") % (self.filename, badfilename, e.strerror))
                raise
            else:
                logger.debug(self.tr("renamed bad varspace %s to '%s'") % (self.filename, badfilename))
                self.create_default_config()
                self.default_config = True
                logger.debug(self.tr("created default varspace '%s'") % self.filename)
        else:
            self.default_config = False
            logger.debug(self.tr("read existing varspace '%s'") % self.filename)

        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.vars = DictDotLookup(self.var_dict)

    def make_settings_folder(self):
        """
        This method creates the postprocessor settings folder if necessary
        """
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def create_default_config(self):
        """
        If no postprocessor config file exists this function is called
        to generate the config file based on its specification.
        """
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        logger.debug(POSTPRO_SPEC)

        self.var_dict = ConfigObj(configspec=POSTPRO_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()


#    def _save_varspace(self):
#        self.var_dict.filename = self.filename
#        self.var_dict.write()
#
    def print_vars(self):
        """
        Print all the variables with their values
        """
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)
Пример #25
0
class MyPostProConfig(object):
    """
    This class hosts all functions related to the PostProConfig File.
    """
    def __init__(self, filename='postpro_config' + c.CONFIG_EXTENSION):
        """
        initialize the varspace of an existing plugin instance
        init_varspace() is a superclass method of plugin
        @param filename: The filename for the creation of a new config
        file and the filename of the file to read config from.
        """
        self.folder = os.path.join(g.folder, c.DEFAULT_POSTPRO_DIR)
        self.filename = os.path.join(self.folder, filename)

        self.version_mismatch = ''  # no problem for now
        self.default_config = False  # whether a new name was generated
        self.var_dict = dict()
        self.spec = ConfigObj(POSTPRO_SPEC,
                              interpolation=False,
                              list_values=False,
                              _inspec=True)

    def load_config(self):
        """
        This method tries to load the defined postprocessor file given in
        self.filename. If this fails it will create a new one
        """

        try:
            # file exists, read & validate it
            self.var_dict = ConfigObj(self.filename, configspec=POSTPRO_SPEC)
            _vdt = Validator()
            result = self.var_dict.validate(_vdt, preserve_errors=True)
            validate_errors = flatten_errors(self.var_dict, result)

            if validate_errors:
                logger.error(self.tr("errors reading %s:") % self.filename)
            for entry in validate_errors:
                section_list, key, error = entry
                if key is not None:
                    section_list.append(key)
                else:
                    section_list.append('[missing section]')
                section_string = ', '.join(section_list)
                if error == False:
                    error = self.tr('Missing value or section.')
                logger.error(section_string + ' = ' + error)

            if validate_errors:
                raise BadConfigFileError(
                    self.tr("syntax errors in postpro_config file"))

            # check config file version against internal version

            if POSTPRO_VERSION:
                fileversion = self.var_dict['Version'][
                    'config_version']  # this could raise KeyError

                if fileversion != POSTPRO_VERSION:
                    raise VersionMismatchError(fileversion, POSTPRO_VERSION)

        except VersionMismatchError:
            # version mismatch flag, it will be used to display an error.
            self.version_mismatch = self.tr(
                "The postprocessor configuration file version ({0}) doesn't match the software expected version ({1}).\n\nYou have to delete (or carefully edit) the configuration file \"{2}\" to solve the problem."
            ).format(fileversion, POSTPRO_VERSION, self.filename)

        except Exception as inst:
            #logger.error(inst)
            (base, ext) = os.path.splitext(self.filename)
            badfilename = base + c.BAD_CONFIG_EXTENSION
            logger.debug(
                self.tr("trying to rename bad cfg %s to %s") %
                (self.filename, badfilename))
            try:
                os.rename(self.filename, badfilename)
            except OSError as e:
                logger.error(
                    self.tr("rename(%s,%s) failed: %s") %
                    (self.filename, badfilename, e.strerror))
                raise
            else:
                logger.debug(
                    self.tr("renamed bad varspace %s to '%s'") %
                    (self.filename, badfilename))
                self.create_default_config()
                self.default_config = True
                logger.debug(
                    self.tr("created default varspace '%s'") % self.filename)
        else:
            self.default_config = False
            logger.debug(
                self.tr("read existing varspace '%s'") % self.filename)

        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.var_dict.main.interpolation = False  # avoid ConfigObj getting too clever
        self.update_config()

    def update_config(self):
        """
        Call this function each time the self.var_dict is updated (eg when the postprocessor configuration window changes some settings)
        """
        # convenience - flatten nested config dict to access it via self.config.sectionname.varname
        self.vars = DictDotLookup(self.var_dict)
        # add here any update needed for the internal variables of this class

    def make_settings_folder(self):
        """
        This method creates the postprocessor settings folder if necessary
        """
        try:
            os.mkdir(self.folder)
        except OSError:
            pass

    def create_default_config(self):
        """
        If no postprocessor config file exists this function is called
        to generate the config file based on its specification.
        """
        # check for existing setting folder or create one
        self.make_settings_folder()

        # derive config file with defaults from spec
        logger.debug(POSTPRO_SPEC)

        self.var_dict = ConfigObj(configspec=POSTPRO_SPEC)
        _vdt = Validator()
        self.var_dict.validate(_vdt, copy=True)
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def save_varspace(self):
        self.var_dict.filename = self.filename
        self.var_dict.write()

    def print_vars(self):
        """
        Print all the variables with their values
        """
        print("Variables:")
        for k, v in self.var_dict['Variables'].items():
            print(k, "=", v)

    @staticmethod
    def tr(string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(
            QtCore.QCoreApplication.translate('MyPostProConfig',
                                              string_to_translate))

    @staticmethod
    def makeConfigWidgets():
        """
        Build the postprocessor configuration widgets and store them into a dictionary.
        The structure of the dictionnary must match the structure of the postprocessor configuration file. The names of the keys must be identical to those used in the configfile.
        If a name is declared in the configfile but not here, it simply won't appear in the config window (the config_version for example must not be modified by the user, so it is not declared here)
        """
        cfg_widget_def = OrderedDict([
            ('General',
             OrderedDict([
                 ('__section_title__', MyPostProConfig.tr("Software config")),
                 ('__subtitle__',
                  CfgSubtitle(MyPostProConfig.tr("Output specifications"))),
                 ('output_text',
                  CfgLineEdit(
                      MyPostProConfig.tr('Output format description:'))),
                 ('output_format',
                  CfgLineEdit(MyPostProConfig.tr('Output file extension:'))),
                 ('output_type',
                  CfgComboBox(MyPostProConfig.tr('Output type:'))),
                 ('__subtitle2__',
                  CfgSubtitle(MyPostProConfig.tr("Output options"))),
                 ('abs_export',
                  CfgCheckBox(
                      MyPostProConfig.tr('Export absolute coordinates'))),
                 ('cancel_cc_for_depth',
                  CfgCheckBox(
                      MyPostProConfig.tr(
                          'Cancel cutter compensation at each slice'))),
                 ('cc_outside_the_piece',
                  CfgCheckBox(
                      MyPostProConfig.tr(
                          'Perform cutter compensation outside the piece'))),
                 ('export_ccw_arcs_only',
                  CfgCheckBox(
                      MyPostProConfig.tr('Export only counter clockwise arcs'))
                  ),
                 ('max_arc_radius',
                  CfgDoubleSpinBox(MyPostProConfig.tr('Maximum arc radius:'))),
                 ('__subtitle3__',
                  CfgSubtitle(MyPostProConfig.tr("G-code constants"))),
                 ('code_begin_units_mm',
                  CfgLineEdit(MyPostProConfig.tr('Units in millimeters:'))),
                 ('code_begin_units_in',
                  CfgLineEdit(MyPostProConfig.tr('Units in inch:'))),
                 ('code_begin_prog_abs',
                  CfgLineEdit(MyPostProConfig.tr('Absolute programming:'))),
                 ('code_begin_prog_inc',
                  CfgLineEdit(MyPostProConfig.tr('Incremental programming:'))),
                 ('code_begin', CfgTextEdit(MyPostProConfig.tr('Startup:'))),
                 ('code_end', CfgTextEdit(MyPostProConfig.tr('End:')))
             ])),
            ('Number_Format',
             OrderedDict([
                 ('__section_title__',
                  MyPostProConfig.tr("Output formatting")),
                 ('__subtitle__',
                  CfgSubtitle(MyPostProConfig.tr("Output formatting"))),
                 ('signed_values',
                  CfgCheckBox(
                      MyPostProConfig.
                      tr("Prepend numbers with the '+' sign for positive values"
                         ))),
                 ('pre_decimals',
                  CfgSpinBox(
                      MyPostProConfig.tr(
                          'Number of digits before the decimal separator:'))),
                 ('pre_decimal_zero_padding',
                  CfgCheckBox(
                      MyPostProConfig.tr(
                          "Padding with '0' digit before the decimal separator"
                      ))),
                 ('post_decimals',
                  CfgSpinBox(
                      MyPostProConfig.tr(
                          'Number of digits after the decimal separator:'))),
                 ('post_decimal_zero_padding',
                  CfgCheckBox(
                      MyPostProConfig.
                      tr("Padding with '0' digit after the decimal separator"))
                  ),
                 ('decimal_separator',
                  CfgLineEdit(MyPostProConfig.tr('Decimal separator:')))
             ])),
            ('Line_Numbers',
             OrderedDict([
                 ('__section_title__',
                  MyPostProConfig.tr("Output formatting")),
                 ('__subtitle__',
                  CfgSubtitle(MyPostProConfig.tr("Line numbers"))),
                 ('use_line_nrs',
                  CfgCheckBox(MyPostProConfig.tr('Export line numbers'))),
                 ('line_nrs_begin',
                  CfgSpinBox(MyPostProConfig.tr('Line number starts at:'))),
                 ('line_nrs_step',
                  CfgSpinBox(MyPostProConfig.tr('Line number step:')))
             ])),
            ('Program',
             OrderedDict([
                 ('__section_title__', MyPostProConfig.tr("G-code codes")),
                 ('tool_change',
                  CfgLineEdit(MyPostProConfig.tr('Tool change:'))),
                 ('feed_change',
                  CfgLineEdit(MyPostProConfig.tr('Feed rate change:'))),
                 ('rap_pos_plane',
                  CfgLineEdit(
                      MyPostProConfig.tr('Rapid positioning for XY plane:'))),
                 ('rap_pos_depth',
                  CfgLineEdit(
                      MyPostProConfig.tr('Rapid positioning for Z plane:'))),
                 ('lin_mov_plane',
                  CfgLineEdit(
                      MyPostProConfig.tr('Linear feed move for XY plane:'))),
                 ('lin_mov_depth',
                  CfgLineEdit(
                      MyPostProConfig.tr('Linear feed move for Z plane:'))),
                 ('arc_int_cw',
                  CfgLineEdit(MyPostProConfig.tr('Clockwise feed move:'))),
                 ('arc_int_ccw',
                  CfgLineEdit(
                      MyPostProConfig.tr('Counter clockwise feed move:'))),
                 ('cutter_comp_off',
                  CfgLineEdit(
                      MyPostProConfig.tr('Disable cutter compensation:'))),
                 ('cutter_comp_left',
                  CfgLineEdit(
                      MyPostProConfig.tr('Left cutter compensation:'))),
                 ('cutter_comp_right',
                  CfgLineEdit(
                      MyPostProConfig.tr('Right cutter compensation:'))),
                 ('pre_shape_cut',
                  CfgLineEdit(
                      MyPostProConfig.tr('Placed in front of any shape:'))),
                 ('post_shape_cut',
                  CfgLineEdit(MyPostProConfig.tr('Placed after any shape:'))),
                 ('comment',
                  CfgLineEdit(
                      MyPostProConfig.tr('Comment for current shape:')))
             ]))
        ])

        return cfg_widget_def