Example #1
0
    def check(self, task):
        """Test all parameters evaluation.

        """
        traceback = {}
        i = 0
        kind = 'Analogical{}_'
        try:
            task.format_and_eval_string(self.active)
        except Exception:
            mess = 'Failed to eval active : {}'
            traceback['Channel'] = mess.format(format_exc())

        for p in chain(self.analogicals, self.logicals):
            if i == self.analogical:
                kind = 'Logical{}_'
            for n in tagged_members(p, 'check'):
                val = getattr(p, n)
                if not val:
                    continue
                try:
                    task.format_and_eval_string(val)
                except Exception:
                    mess = 'Failed to eval {} : {}'
                    traceback[kind.format(i) + n] = mess.format(
                        val, format_exc())

            i += 1

        return not bool(traceback), traceback
Example #2
0
    def check(self, *args, **kwargs):
        """Check that all the parameters are correct.

        """
        err_path = self.get_error_path()
        test, traceback = super(SaveFileHDF5Task, self).check(*args, **kwargs)
        try:
            full_folder_path = self.format_string(self.folder)
            filename = self.format_string(self.filename)
        except Exception:
            return test, traceback

        full_path = os.path.join(full_folder_path, filename)

        overwrite = False
        if os.path.isfile(full_path):
            overwrite = True
            traceback[err_path + '-file'] = \
                cleandoc('''File already exists, running the measure will
                override it.''')

        try:
            f = open(full_path, 'ab')
            f.close()
            if not overwrite:
                os.remove(full_path)
        except Exception as e:
            mess = 'Failed to open the specified file : {}'.format(e)
            traceback[err_path] = mess.format(e)
            return False, traceback

        labels = set()
        for i, (l, v) in enumerate(self.saved_values.items()):
            try:
                labels.add(self.format_string(l))
            except Exception:
                traceback[err_path + '-label_' + str(i)] = \
                    'Failed to evaluate label {}:\n{}'.format(l, format_exc())
                test = False
            try:
                self.format_and_eval_string(v)
            except Exception:
                traceback[err_path + '-entry_' + str(i)] = \
                    'Failed to evaluate entry {}:\n{}'.format(v, format_exc())
                test = False

        if not test:
            return test, traceback

        if len(labels) != len(self.saved_values):
            traceback[err_path] = "All labels must be different."
            return False, traceback

        return test, traceback
Example #3
0
    def evaluate_sequence(self, root_vars, sequence_locals, missings, errors):
        """Evaluate the entries of the items making the context.

        """
        # Check the channel mapping makes sense.
        if not self.context.prepare_compilation(errors):
            return False

        # Definition evaluation.
        self.eval_entries(root_vars, sequence_locals, missings, errors)

        prefix = '{}_'.format(self.index)
        # Template vars evaluation.
        for name, formula in self.template_vars.items():
            if name not in self._evaluated_vars:
                try:
                    val = eval_entry(formula, sequence_locals, missings)
                    self._evaluated_vars[name] = val
                except Exception:
                    errors[prefix + name] = format_exc()

        # Local vars computation.
        for name, formula in self.local_vars.items():
            if name not in self._evaluated_vars:
                try:
                    val = eval_entry(formula, sequence_locals, missings)
                    self._evaluated_vars[name] = val
                except Exception:
                    errors[prefix + name] = format_exc()

        local_namespace = self._evaluated_vars.copy()
        local_namespace['sequence_end'] = self.duration

        res = self._evaluate_items(local_namespace, local_namespace,
                                   missings, errors)

        if res:
            overtime = []
            self._update_times(self.items, errors, overtime)

            if overtime:
                msg = ('The stop time of the following items {} is larger '
                       'than the stop time of the sequence {}')
                ind = [p.index for p in overtime]
                errors[self.name + '-stop'] = msg.format(ind, self.index)

        if errors:
            return False

        return True
Example #4
0
    def load_sequence(self, mode='file'):
        """ Load an existing sequence to edit it.

        Parameters
        ----------
        mode : {'file', 'template'}
            - file : load a sequence from a file chosen by the user.
            - template : lod a sequence from a template chosen by the user.

        """
        if mode == 'file':
            factory = FileDialogEx.get_open_file_name
            path = ''
            if self.state.sequence_path:
                path = os.path.dirname(self.state.sequence_path)

            load_path = factory(self.content,
                                current_path=path,
                                name_filters=['*.pulse.ini'])
            if load_path:
                try:
                    seq = self._load_sequence_from_file(load_path)
                except Exception:
                    core = self.workbench.get_plugin('enaml.workbench.core')
                    cmd = 'exopy.app.errors.signal'
                    msg = 'Failed to rebuild sequence {} :\n\n{}'
                    core.invoke_command(
                        cmd,
                        dict(kind='error',
                             message=msg.format(load_path, format_exc())))
                else:
                    self.state.sequence = seq
                    self.state.sequence_type = 'Standard'
                    self.state.sequence_path = load_path
                    logger = logging.getLogger(__name__)
                    logger.debug('Sequence correctly loaded from %s.' %
                                 load_path)

#        elif mode == 'template':
#            dial = TemplateLoadDialog(self.content, manager=self.plugin)
#            dial.exec_()
#            if dial.result:
#                seq = self._load_sequence_from_template(dial.prefs)
#                self.state.sequence = seq
#                self.state.sequence_type = 'Template'
#                self.state.sequence_path = dial.t_infos.metadata['path']
#                self.state.sequence_doc = dial.t_infos.metadata['doc']
#                logger = logging.getLogger(__name__)
#                logger.info('Sequence correctly loaded from template.')

        else:
            mess = cleandoc('''Invalid mode for load sequence : {}. Admissible
                            values are 'file' and 'template'.''')
            raise ValueError(mess.format(mode))
Example #5
0
        def wrapper(self, *args, **kwargs):

            i = 0
            # Try at most `max_iter` times to excute method
            while i < max_iter + 1:
                try:
                    return method(self, *args, **kwargs)

                # Catch all the exception specified by the driver
                except self.secure_com_except:
                    if i == max_iter:
                        raise
                    else:
                        print(format_exc())
                        self.reopen_connection()
                        i += 1
    def check_infos(self, driver_cls, connection, settings):
        """Attempt to open the connection to the instrument.

        """
        c = self.format_connection_infos(connection)
        c.update(settings)
        driver = None
        try:
            driver = driver_cls(c)
            res = driver.connected
        except Exception:
            return False, format_exc()
        finally:
            if driver is not None:
                driver.close_connection()
        return res, ('Instrument does not appear to be connected but no '
                     'exception was raised.')
Example #7
0
    def check(self, *args, **kwargs):
        """Check that the sequence can be compiled.

        """
        test, traceback = super(TransferPulseSequenceTask,
                                self).check(*args, **kwargs)
        err_path = self.path + '/' + self.name + '-'

        if not self.sequence:
            traceback[err_path + 'sequence'] = 'There is no selected sequence.'
            return False, traceback

        msg = 'Failed to evaluate {} ({}): {}'
        seq = self.sequence
        for k, v in self.sequence_vars.items():
            try:
                seq.external_vars[k] = self.format_and_eval_string(v)
            except Exception:
                test = False
                traceback[err_path + k] = msg.format(k, v, format_exc())

        if not test:
            return test, traceback

        context = seq.context
        res, infos, errors = context.compile_and_transfer_sequence(seq)

        if not res:
            traceback[err_path + 'compil'] = errors
            return False, traceback

        for k, v in infos.items():
            self.write_in_database(k, v)

        if self.sequence_path:
            if not (self.sequence_timestamp == os.path.getmtime(
                    self.sequence_path)):
                msg = 'The sequence is outdated, consider refreshing it.'
                traceback[err_path + 'outdated'] = msg

        return test, traceback
Example #8
0
    def register(self, collector, traceback):
        """Collect shape and view and add infos to the DeclaratorCollector
        contributions member.

        The group declared by a parent if any is taken into account. All
        Interface children are also registered.

        """
        # Build the shape id by assembling the package name and the class
        # name.
        shape_id = self.id

        # If the shape only specifies a name update the matching infos.
        if ':' not in self.shape:
            if self.shape not in collector.contributions:
                collector._delayed.append(self)
                return

            infos = collector.contributions[shape_id]
            infos.metadata.update(self.metadata)
            self.is_registered = True
            return

        # Determine the path of shape and view
        path = self.get_path()
        try:
            s_path, shape = (path + '.' +
                             self.shape if path else self.shape).split(':')
            v_path, view = (path + '.' +
                            self.view if path else self.view).split(':')
        except ValueError:
            msg = 'Incorrect %s (%s), path must be of the form a.b.c:Class'
            err_id = s_path.split('.', 1)[0] + '.' + shape
            msg = msg % ('view', self.view)

            traceback[err_id] = msg
            return

        # Check that the shape does not already exist.
        if shape_id in collector.contributions or shape_id in traceback:
            i = 1
            while True:
                err_id = '%s_duplicate%d' % (shape_id, i)
                if err_id not in traceback:
                    break

            msg = 'Duplicate definition of {}, found in {}'
            traceback[err_id] = msg.format(shape, s_path)
            return

        infos = ShapeInfos(metadata=self.metadata)

        # Get the sequence class.
        s_cls = import_and_get(s_path, shape, traceback, shape_id)
        if s_cls is None:
            return

        try:
            infos.cls = s_cls
        except TypeError:
            msg = '{} should be a subclass of AbstractShape. \n{}'
            traceback[shape_id] = msg.format(s_cls, format_exc())
            return

        # Get the shape view.
        s_view = import_and_get(v_path, view, traceback, shape_id)
        if s_view is None:
            return

        try:
            infos.view = s_view
        except TypeError:
            msg = '{} should be a subclass of AbstractShapeView,.\n{}'
            traceback[shape_id] = msg.format(s_view, format_exc())
            return

        # Add group and add to collector
        infos.metadata['group'] = self.get_group()
        collector.contributions[shape_id] = infos

        self.is_registered = True
Example #9
0
    def register(self, collector, traceback):
        """Collect config and view and add infos to the DeclaratorCollector
        contributions member under the supported task name.

        """
        # Determine the path to the config and view.
        path = self.get_path()
        try:
            c_path, config = (path + '.' +
                              self.config if path else self.config).split(':')
            v_path, view = (path + '.' +
                            self.view if path else self.view).split(':')
        except ValueError:
            msg = 'Incorrect %s (%s), path must be of the form a.b.c:Class'
            if ':' in self.config:
                msg = msg % ('view', self.view)
            else:
                msg = msg % ('config', self.config)

            traceback[self.id] = msg
            return

        try:
            s_cls = self.get_sequence_class()
        except Exception:
            msg = 'Failed to get supported sequence : %s'
            traceback[self.id] = msg % format_exc()
            return

        # Check that the configurer does not already exist.
        if self.id in traceback:
            i = 1
            while True:
                err_id = '%s_duplicate%d' % (self.id, i)
                if err_id not in traceback:
                    break

            msg = 'Duplicate definition of {}, found in {}'
            traceback[err_id] = msg.format(s_cls, c_path)
            return

        if s_cls in collector.contributions:
            msg = 'Duplicate definition for {}, found in {}'
            traceback[self.id] = msg.format(s_cls, c_path)
            return

        infos = ConfigInfos()

        # Get the config class.
        c_cls = import_and_get(c_path, config, traceback, self.id)
        if c_cls is None:
            return

        try:
            infos.cls = c_cls
        except TypeError:
            msg = '{} should a subclass of AbstractConfig.\n{}'
            traceback[self.id] = msg.format(c_cls, format_exc())
            return

        # Get the config view.
        view = import_and_get(v_path, view, traceback, self.id)
        if view is None:
            return

        try:
            infos.view = view
        except TypeError:
            msg = '{} should a subclass of AbstractConfigView.\n{}'
            traceback[self.id] = msg.format(c_cls, format_exc())
            return

        collector.contributions[s_cls] = infos

        self.is_registered = True
Example #10
0
    def check(self, *args, **kwargs):
        """Check that the provided parameters make sense.

        """
        err_path = self.get_error_path()
        test, traceback = super(SaveTask, self).check(*args, **kwargs)

        if self.saving_target != 'Array':
            try:
                full_folder_path = self.format_string(self.folder)
            except Exception as e:
                mess = 'Failed to format the folder path: {}'
                traceback[err_path] = mess.format(e)
                return False, traceback

            try:
                filename = self.format_string(self.filename)
            except Exception as e:
                mess = 'Failed to format the filename: {}'
                traceback[err_path] = mess.format(e)
                return False, traceback

            full_path = os.path.join(full_folder_path, filename)

            overwrite = False
            if self.file_mode == 'New' and os.path.isfile(full_path):
                overwrite = True
                traceback[err_path + '-file'] = \
                    ('File already exists, running the measure will '
                     'override it.')

            try:
                f = open(full_path, 'ab')
                f.close()
                if self.file_mode == 'New' and not overwrite:
                    os.remove(full_path)
            except Exception as e:
                mess = 'Failed to open the specified file : {}'.format(e)
                traceback[err_path] = mess.format(e)
                return False, traceback

            try:
                self.format_string(self.header)
            except Exception as e:
                mess = 'Failed to format the header: {}'
                traceback[err_path] = mess.format(e)
                return False, traceback

        if self.array_size:
            try:
                self.format_and_eval_string(self.array_size)
            except Exception as e:
                mess = 'Failed to compute the array size: {}'
                traceback[err_path] = mess.format(e)
                return False, traceback

        elif self.saving_target != 'File':
            traceback[err_path] = 'A size for the array must be provided.'
            return False, traceback

        labels = list()
        for i, (l, v) in enumerate(self.saved_values.items()):
            try:
                labels.append(self.format_string(l))
            except Exception:
                traceback[err_path + '-label_' + str(i)] = \
                    'Failed to evaluate label {}:\n{}'.format(l, format_exc())
                test = False
            try:
                self.format_and_eval_string(v)
            except Exception:
                traceback[err_path + '-entry_' + str(i)] = \
                    'Failed to evaluate entry {}:\n{}'.format(v, format_exc())
                test = False

        if not test:
            return test, traceback

        if len(set(labels)) != len(self.saved_values):
            traceback[err_path] = "All labels must be different."
            return False, traceback

        if self.saving_target != 'File':
            data = [numpy.array([0.0, 1.0]) for s in self.saved_values]
            names = str(','.join([s for s in labels]))
            final_arr = numpy.rec.fromarrays(data, names=names)

            self.write_in_database('array', final_arr)

        return test, traceback
Example #11
0
    def eval_entries(self, global_vars, local_vars, missings, errors):
        """Evaluate and format all tagged members.

        The result of the evaluation is written to the _cache dictionary.

        Parameters
        ----------
        global_vars : dict
            Dictionary of global variables. This will be update will the valid
            values whose tag specify they should be stored as global.

        local_vars : dict
            Dictionary of variables used for evaluation. This will be update
            will the valid values whose tag specify they should be stored as
            global.

        missings : set
            Set of unfound local variables.

        errors : dict
            Dict of the errors which happened when performing the evaluation.

        Returns
        -------
        flag : bool
            Boolean indicating whether or not the evaluation succeeded.

        """
        res = True
        cache = self._cache

        for member, m in tagged_members(self, 'fmt').items():
            if member in cache:
                continue
            fmt_str = getattr(self, member)
            try:
                fmt = fmt_str.format(**local_vars)
                self._cache[member] = fmt
                if m.metadata['fmt']:
                    id_ = self.format_global_vars_id(member)
                    global_vars[id_] = fmt
                    local_vars[id_] = fmt
            # This can only occur if a {} field was found and an entry is
            # missing
            except KeyError:
                res = False
                aux_strings = fmt_str.split('{')
                elements = [el for aux in aux_strings for el in aux.split('}')]
                absent = [el for el in elements[1::2] if el not in local_vars]
                missings.update(absent)
            except Exception:
                res = False
                errors[self.format_error_id(member)] = format_exc()

        for member, m in tagged_members(self, 'feval').items():
            feval = m.metadata['feval']
            if member in cache:
                continue
            if not feval.should_test(self, member):
                continue
            try:
                val, store = feval.evaluate(self, member, local_vars)
                valid, msg = feval.validate(self, val)
                if not valid:
                    res = False
                    errors[self.format_error_id(member)] = msg
                else:
                    self._cache[member] = val
                    if store:
                        id_ = self.format_global_vars_id(member)
                        global_vars[id_] = val
                        local_vars[id_] = val
            except MissingLocalVars as e:
                res = False
                missings.update(e.missings)
            except Exception:
                res = False
                errors[self.format_error_id(member)] = format_exc()

        return res
Example #12
0
    def evaluate_sequence(self):
        """Evaluate the root sequence entries and all sub items.

        Returns
        -----------
        result : bool
            Flag indicating whether or not the compilation succeeded.

        missing : set
            Set of the entries whose values where never found and a dict of the
            errors which occured during compilation.

        errors : dict
            Dict describing the errors that occured during evaluation.

        """
        # First make sure the cache is clean
        self.clean_cached_values()

        missings = set()
        errors = {}
        root_vars = self.external_vars.copy()

        # Local vars computation.
        for name, formula in self.local_vars.items():
            if name not in self._cache:
                try:
                    val = eval_entry(formula, root_vars)
                    self._cache[name] = val
                except MissingLocalVars as e:
                    missings.update(e.missings)
                except Exception:
                    errors['root_' + name] = format_exc()

        root_vars.update(self._cache)

        if self.time_constrained:
            try:
                duration = eval_entry(self.sequence_duration, root_vars)
                self.stop = self.duration = duration
                root_vars['sequence_end'] = duration
            except MissingLocalVars as e:
                missings.update(e.missings)
            except Exception:
                errors['root_seq_duration'] = format_exc()

        res = self.context.eval_entries(root_vars, root_vars, missings, errors)

        res &= self._evaluate_items(root_vars, root_vars, missings, errors)

        if not res:
            return False, missings, errors

        if self.time_constrained:
            overtime = []
            self._validate_times(self.items, overtime)

            if overtime:
                mess = ('The stop time of the following pulses {} is larger '
                        'than the duration of the sequence.')
                ind = [p.index for p in overtime]
                errors['root-stop'] = mess.format(ind)
                return False, missings, errors

        return True, missings, errors
Example #13
0
    def evaluate_sequence(self, root_vars, sequence_locals, missings, errors):
        """ Evaluate the sequence vars and compile the list of pulses.

        Parameters
        ----------
        root_vars : dict
            Dictionary of global variables for the all items. This will
            tipically contains the i_start/stop/duration and the root vars.
            This dict must be updated with global new values but for
            evaluation sequence_locals must be used.

        sequence_locals : dict
            Dictionary of variables whose scope is limited to this sequence
            parent. This dict must be updated with global new values and
            must be used to perform evaluation (It always contains all the
            names defined in root_vars).

        missings : set
            Set of unfound local variables.

        errors : dict
            Dict of the errors which happened when performing the evaluation.

        Returns
        -------
        flag : bool
            Boolean indicating whether or not the evaluation succeeded.

        """
        prefix = '{}_'.format(self.index)

        # Definition evaluation.
        if self.time_constrained:
            self.eval_entries(root_vars, sequence_locals, missings, errors)

        # Local vars computation.
        for name, formula in self.local_vars.items():
            if name not in self._cache:
                try:
                    val = eval_entry(formula, sequence_locals)
                    self._cache[name] = val
                except MissingLocalVars as e:
                    missings.update(e.missings)
                except Exception:
                    errors[prefix + name] = format_exc()

        local_namespace = sequence_locals.copy()
        local_namespace.update(self._cache)

        res = self._evaluate_items(root_vars, local_namespace, missings,
                                   errors)
        if res:
            if self.time_constrained:
                # Check if start, stop and duration of sequence are compatible.
                start_err = [item for item in self.items
                             if item.start and item.stop and item.duration and
                             item.start < self.start]
                stop_err = [item for item in self.items
                            if item.start and item.stop and item.duration and
                            item.stop > self.stop]
                if start_err:
                    msg = ('The start time of the following items {} is '
                           'smaller than the start time of the sequence {}')
                    ind = [p.index for p in start_err]
                    errors[self.name + '-start'] = msg.format(ind, self.index)
                if stop_err:
                    msg = ('The stop time of the following items {} is '
                           'larger than  the stop time of the sequence {}')
                    ind = [p.index for p in stop_err]
                    errors[self.name + '-stop'] = msg.format(ind, self.index)

                if errors:
                    return False

            return True

        else:
            return False
Example #14
0
def main(cmd_line_args=None):
    """Main entry point of the Exopy application.

    """
    # Build parser from ArgParser and parse arguemnts
    parser = ArgParser()
    parser.add_choice('workspaces', 'exopy.measurement.workspace',
                      'measurement')
    parser.add_argument("-s",
                        "--nocapture",
                        help="Don't capture stdout/stderr",
                        action='store_true')
    parser.add_argument("-w",
                        "--workspace",
                        help='Select start-up workspace',
                        default='measurement',
                        choices='workspaces')
    parser.add_argument("-r",
                        "--reset-app-folder",
                        help='Reset the application startup folder.',
                        action='store_true')

    modifiers = []
    for i, ep in enumerate(iter_entry_points('exopy_cmdline_args')):

        try:
            modifier, priority = ep.load(require=False)
            modifiers.append((ep, modifier, priority, i))
        except Exception as e:
            text = 'Error loading extension %s' % ep.name
            content = ('The following error occurred when trying to load the '
                       'entry point {} :\n {}'.format(ep.name, e))
            details = format_exc()
            display_startup_error_dialog(text, content, details)

    modifiers.sort(key=itemgetter(1, 2))
    try:
        for m in modifiers:
            m[1](parser)
    except Exception as e:
        text = 'Error modifying cmd line arguments'
        content = ('The following error occurred when the entry point {} '
                   'tried to add cmd line options :\n {}'.format(ep.name, e))
        details = format_exc()
        display_startup_error_dialog(text, content, details)

    try:
        args = parser.parse_args(cmd_line_args)
    except BaseException as e:
        if e.args == (0, ):
            sys.exit(0)
        text = 'Failed to parse cmd line arguments'
        content = ('The following error occurred when trying to parse the '
                   'command line arguments :\n {}'.format(e))
        details = format_exc()
        display_startup_error_dialog(text, content, details)

    # Patch Thread to use sys.excepthook
    setup_thread_excepthook()

    workbench = Workbench()
    workbench.register(CoreManifest())
    workbench.register(UIManifest())
    workbench.register(AppManifest())
    workbench.register(StateManifest())
    workbench.register(ErrorsManifest())
    workbench.register(PreferencesManifest())
    workbench.register(IconManagerManifest())
    workbench.register(LogManifest())
    workbench.register(PackagesManifest())
    workbench.register(DependenciesManifest())
    workbench.register(InstrumentManagerManifest())
    workbench.register(TasksManagerManifest())
    workbench.register(MeasureManifest())
    workbench.register(TextMonitorManifest())

    ui = workbench.get_plugin(u'enaml.workbench.ui')  # Create the application

    try:
        app = workbench.get_plugin('exopy.app')
        app.run_app_startup(args)
    except Exception as e:
        text = 'Error starting plugins'
        content = ('The following error occurred when executing plugins '
                   'application start ups :\n {}'.format(e))
        details = format_exc()
        display_startup_error_dialog(text, content, details)

    core = workbench.get_plugin('enaml.workbench.core')

    # Install global except hook.
    if not args.nocapture:
        core.invoke_command('exopy.app.errors.install_excepthook', {})

    # Select workspace
    core.invoke_command('enaml.workbench.ui.select_workspace',
                        {'workspace': args.workspace}, workbench)

    ui = workbench.get_plugin(u'enaml.workbench.ui')
    ui.show_window()
    ui.window.maximize()
    ui.start_application()

    core.invoke_command('enaml.workbench.ui.close_workspace', {}, workbench)

    # Unregister all contributed packages
    workbench.unregister('exopy.app.packages')
    workbench.unregister('exopy.measurement.monitors.text_monitor')
    workbench.unregister('exopy.measurement')
    workbench.unregister('exopy.tasks')
    workbench.unregister('exopy.instruments')
    workbench.unregister('exopy.app.icons')
    workbench.unregister('exopy.app.preferences')
    workbench.unregister('exopy.app.states')
    workbench.unregister('exopy.app.dependencies')
    workbench.unregister('exopy.app.errors')
    workbench.unregister('exopy.app.logging')
    workbench.unregister('exopy.app')
    workbench.unregister(u'enaml.workbench.ui')
    workbench.unregister(u'enaml.workbench.core')
Example #15
0
    def register(self, collector, traceback):
        """Collect task and view and add infos to the DeclaratorCollector
        contributions member.

        The group declared by a parent if any is taken into account. All
        Interface children are also registered.

        """
        # Build the task id by assembling the package name and the class name
        task_id = self.id

        # If the task only specifies a name update the matching infos.
        if ':' not in self.task:
            if self.task not in collector.contributions:
                collector._delayed.append(self)
                return

            infos = collector.contributions[task_id]
            infos.instruments.update(self.instruments)
            infos.dependencies.update(self.dependencies)
            infos.metadata.update(self.metadata)

            check = check_children(self)
            if check:
                traceback[task_id] = check
                return

            for i in self.children:
                i.register(collector, traceback)
            self.is_registered = True
            return

        # Determine the path to the task and view.
        path = self.get_path()
        try:
            t_path, task = (path + '.' +
                            self.task if path else self.task).split(':')
            v_path, view = (path + '.' +
                            self.view if path else self.view).split(':')
        except ValueError:
            msg = 'Incorrect %s (%s), path must be of the form a.b.c:Class'
            err_id = t_path.split('.', 1)[0] + '.' + task
            msg = msg % ('view', self.view)

            traceback[err_id] = msg
            return

        # Check that the task does not already exist.
        if task_id in collector.contributions or task_id in traceback:
            i = 1
            while True:
                err_id = '%s_duplicate%d' % (task_id, i)
                if err_id not in traceback:
                    break

            msg = 'Duplicate definition of {}, found in {}'
            traceback[err_id] = msg.format(task, t_path)
            return

        infos = TaskInfos(metadata=self.metadata,
                          dependencies=self.dependencies,
                          instruments=self.instruments)

        # Get the task class.
        t_cls = import_and_get(t_path, task, traceback, task_id)
        if t_cls is None:
            return

        try:
            infos.cls = t_cls
        except TypeError:
            msg = '{} should a subclass of BaseTask.\n{}'
            traceback[task_id] = msg.format(t_cls, format_exc())
            return

        # Get the task view.
        t_view = import_and_get(v_path, view, traceback, task_id)
        if t_view is None:
            return

        try:
            infos.view = t_view
        except TypeError:
            msg = '{} should a subclass of BaseTaskView.\n{}'
            traceback[task_id] = msg.format(t_view, format_exc())
            return

        # Check children type.
        check = check_children(self)
        if check:
            traceback[task_id] = check
            return

        # Add group and add to collector
        infos.metadata['group'] = self.get_group()
        collector.contributions[task_id] = infos

        # Register children.
        for i in self.children:
            i.register(collector, traceback)

        self.is_registered = True
Example #16
0
def main(cmd_line_args=None):
    """Main entry point of the Exopy application.

    """
    # Build parser from ArgParser and parse arguemnts
    parser = ArgParser()
    parser.add_choice('workspaces', 'exopy.measurement.workspace',
                      'measurement')
    parser.add_argument("-s", "--nocapture",
                        help="Don't capture stdout/stderr",
                        action='store_true')
    parser.add_argument("-w", "--workspace",
                        help='Select start-up workspace',
                        default='measurement', choices='workspaces')
    parser.add_argument("-r", "--reset-app-folder",
                        help='Reset the application startup folder.',
                        action='store_true')

    modifiers = []
    for i, ep in enumerate(iter_entry_points('exopy_cmdline_args')):

        try:
            modifier, priority = ep.load(require=False)
            modifiers.append((ep, modifier, priority, i))
        except Exception as e:
            text = 'Error loading extension %s' % ep.name
            content = ('The following error occurred when trying to load the '
                       'entry point {} :\n {}'.format(ep.name, e))
            details = format_exc()
            display_startup_error_dialog(text, content, details)

    modifiers.sort(key=itemgetter(1, 2))
    try:
        for m in modifiers:
            m[1](parser)
    except Exception as e:
        text = 'Error modifying cmd line arguments'
        content = ('The following error occurred when the entry point {} '
                   'tried to add cmd line options :\n {}'.format(ep.name, e))
        details = format_exc()
        display_startup_error_dialog(text, content, details)

    try:
        args = parser.parse_args(cmd_line_args)
    except BaseException as e:
        if e.args == (0,):
            sys.exit(0)
        text = 'Failed to parse cmd line arguments'
        content = ('The following error occurred when trying to parse the '
                   'command line arguments :\n {}'.format(e))
        details = format_exc()
        display_startup_error_dialog(text, content, details)

    # Patch Thread to use sys.excepthook
    setup_thread_excepthook()

    workbench = Workbench()
    workbench.register(CoreManifest())
    workbench.register(UIManifest())
    workbench.register(AppManifest())
    workbench.register(StateManifest())
    workbench.register(ErrorsManifest())
    workbench.register(PreferencesManifest())
    workbench.register(IconManagerManifest())
    workbench.register(LogManifest())
    workbench.register(PackagesManifest())
    workbench.register(DependenciesManifest())
    workbench.register(InstrumentManagerManifest())
    workbench.register(TasksManagerManifest())
    workbench.register(MeasureManifest())
    workbench.register(TextMonitorManifest())

    ui = workbench.get_plugin(u'enaml.workbench.ui')  # Create the application

    try:
        app = workbench.get_plugin('exopy.app')
        app.run_app_startup(args)
    except Exception as e:
        text = 'Error starting plugins'
        content = ('The following error occurred when executing plugins '
                   'application start ups :\n {}'.format(e))
        details = format_exc()
        display_startup_error_dialog(text, content, details)

    core = workbench.get_plugin('enaml.workbench.core')

    # Install global except hook.
    if not args.nocapture:
        core.invoke_command('exopy.app.errors.install_excepthook', {})

    # Select workspace
    core.invoke_command('enaml.workbench.ui.select_workspace',
                        {'workspace': args.workspace}, workbench)

    ui = workbench.get_plugin(u'enaml.workbench.ui')
    ui.show_window()
    ui.window.maximize()
    ui.start_application()

    core.invoke_command('enaml.workbench.ui.close_workspace',
                        {}, workbench)

    # Unregister all contributed packages
    workbench.unregister('exopy.app.packages')
    workbench.unregister('exopy.measurement.monitors.text_monitor')
    workbench.unregister('exopy.measurement')
    workbench.unregister('exopy.tasks')
    workbench.unregister('exopy.instruments')
    workbench.unregister('exopy.app.icons')
    workbench.unregister('exopy.app.preferences')
    workbench.unregister('exopy.app.states')
    workbench.unregister('exopy.app.dependencies')
    workbench.unregister('exopy.app.errors')
    workbench.unregister('exopy.app.logging')
    workbench.unregister('exopy.app')
    workbench.unregister(u'enaml.workbench.ui')
    workbench.unregister(u'enaml.workbench.core')