Пример #1
0
def update_engine(engine, old, new):
    """Modify a StenoEngine using a before and after config object.
    
    Using the before and after allows this function to not make unnecessary 
    changes.
    """
    machine_type = new.get_machine_type()
    machine_options = new.get_machine_specific_options(machine_type)
    if (old.get_machine_type() != machine_type or
            old.get_machine_specific_options(machine_type) != machine_options):
        try:
            machine_class = machine_registry.get(machine_type)
        except NoSuchMachineException as e:
            raise InvalidConfigurationError(unicode(e))
        engine.set_machine(machine_class(machine_options))

    dictionary_file_names = new.get_dictionary_file_names()
    if old.get_dictionary_file_names() != dictionary_file_names:
        try:
            dicts = dict_manager.load(dictionary_file_names)
        except DictionaryLoaderException as e:
            raise InvalidConfigurationError(unicode(e))
        engine.get_dictionary().set_dicts(dicts)

    log_file_name = new.get_log_file_name()
    if old.get_log_file_name() != log_file_name:
        engine.set_log_file_name(log_file_name)

    enable_stroke_logging = new.get_enable_stroke_logging()
    if old.get_enable_stroke_logging() != enable_stroke_logging:
        engine.enable_stroke_logging(enable_stroke_logging)

    enable_translation_logging = new.get_enable_translation_logging()
    if old.get_enable_translation_logging() != enable_translation_logging:
        engine.enable_translation_logging(enable_translation_logging)
Пример #2
0
Файл: app.py Проект: gcr/plover
def check_steno_config(config_params):
    """This will do several check on the given configuration

    This method can be used in StenoEngine's __init__ method, but also when
    exiting the configuration dialog.

    @return: a tuple composed of:
        - a list of configuration errors
        - a tuple of the following values:
            * machine_type
            * user_dictionary
    """
    errors = []
    machine_type = config_params.get(conf.MACHINE_CONFIG_SECTION,
                                     conf.MACHINE_TYPE_OPTION)
    if machine_type not in SUPPORTED_MACHINES_DICT:
        # The machine isn't supported
        error = InvalidConfigurationError(
            'Invalid configuration value for %s: %s' %
            (conf.MACHINE_TYPE_OPTION, machine_type))
        errors.append(error)

    # Load the dictionary. The dictionary path can be either
    # absolute or relative to the configuration directory.
    dictionary_filename = config_params.get(conf.DICTIONARY_CONFIG_SECTION,
                                            conf.DICTIONARY_FILE_OPTION)
    dictionary_path = join(conf.CONFIG_DIR, dictionary_filename)
    if not isfile(dictionary_path):
        error = InvalidConfigurationError(
            'Invalid configuration value for %s: %s' %
            (conf.DICTIONARY_FILE_OPTION, dictionary_path))
        errors.append(error)

    dictionary_extension = splitext(dictionary_path)[1]
    if dictionary_extension != conf.JSON_EXTENSION:
        error = InvalidConfigurationError(
            'The value of %s must end with %s.' %
            (conf.DICTIONARY_FILE_OPTION, conf.JSON_EXTENSION))
        errors.append(error)

    # Load the dictionary. The dictionary path can be either
    # absolute or relative to the configuration directory.
    user_dictionary = None
    try:
        with open(dictionary_path, 'r') as f:
            user_dictionary = steno_dictionary.load_dictionary(f.read())
    except ValueError:
        error = InvalidConfigurationError(
            'The dictionary file contains incorrect json.')
        errors.append(error)

    return errors, (machine_type, user_dictionary)
Пример #3
0
 def load(self, fp):
     self._config = configparser.RawConfigParser()
     reader = codecs.getreader('utf8')(fp)
     try:
         self._config.readfp(reader)
     except configparser.Error as e:
         raise InvalidConfigurationError(str(e))
Пример #4
0
 def load(self):
     self.clear()
     with open(self.path, encoding='utf-8') as fp:
         try:
             self._config.read_file(fp)
         except configparser.Error as e:
             raise InvalidConfigurationError(str(e))
Пример #5
0
def get_dicts(config):
    """Initialize a StenoEngine from a config object."""
    dictionary_file_names = config.get_dictionary_file_names()
    try:
        dicts = dict_manager.load(dictionary_file_names)
    except DictionaryLoaderException as e:
        raise InvalidConfigurationError(unicode(e))
    return dicts
Пример #6
0
def reset_machine(engine, config):
    """Set the machine on the engine based on config."""
    machine_type = config.get_machine_type()
    machine_options = config.get_machine_specific_options(machine_type)
    try:
        instance = machine_registry.get(machine_type)(machine_options)
    except NoSuchMachineException as e:
        raise InvalidConfigurationError(unicode(e))
    engine.set_machine(instance)
Пример #7
0
def update_engine(engine, config, reset_machine=False):
    """Modify a StenoEngine using a before and after config object.
    
    Using the before and after allows this function to not make unnecessary 
    changes.
    """
    machine_type = config.get_machine_type()
    try:
        machine_class = machine_registry.get(machine_type)
    except NoSuchMachineException as e:
        raise InvalidConfigurationError(str(e))
    machine_options = config.get_machine_specific_options(machine_type)
    machine_mappings = config.get_system_keymap(machine_type)
    engine.set_machine(machine_class, machine_options, machine_mappings,
                       reset_machine=reset_machine)

    dictionary_file_names = config.get_dictionary_file_names()
    engine.set_dictionaries(dictionary_file_names)

    log_file_name = config.get_log_file_name()
    if log_file_name:
        # Older versions would use "plover.log" for logging strokes.
        if os.path.realpath(log_file_name) == os.path.realpath(log.LOG_FILENAME):
            log.warning('stroke logging must use a different file than %s, '
                        'renaming to %s', log.LOG_FILENAME, conf.DEFAULT_LOG_FILE)
            log_file_name = conf.DEFAULT_LOG_FILE
            config.set_log_file_name(log_file_name)
            with open(config.target_file, 'wb') as f:
                config.save(f)
    engine.set_log_file_name(log_file_name)

    enable_stroke_logging = config.get_enable_stroke_logging()
    engine.enable_stroke_logging(enable_stroke_logging)

    enable_translation_logging = config.get_enable_translation_logging()
    engine.enable_translation_logging(enable_translation_logging)

    space_placement = config.get_space_placement()
    engine.set_space_placement(space_placement)

    undo_levels = config.get_undo_levels()
    engine.set_undo_levels(undo_levels)

    start_capitalized = config.get_start_capitalized()
    start_attached = config.get_start_attached()
    engine.set_starting_stroke_state(attach=start_attached,
                                     capitalize=start_capitalized)
Пример #8
0
def init_engine(engine, config):
    """Initialize a StenoEngine from a config object."""
    reset_machine(engine, config)

    dictionary_file_names = config.get_dictionary_file_names()
    try:
        dicts = dict_manager.load(dictionary_file_names)
    except DictionaryLoaderException as e:
        raise InvalidConfigurationError(unicode(e))
    engine.get_dictionary().set_dicts(dicts)

    engine.set_log_file_name(config)
    engine.enable_stroke_logging(config.get_enable_stroke_logging())
    engine.enable_translation_logging(config.get_enable_translation_logging())
    engine.set_space_placement(config.get_space_placement())

    engine.set_is_running(config.get_auto_start())
Пример #9
0
 def _update(self, config_update=None, full=False, reset_machine=False):
     original_config = self._config.as_dict()
     # Update configuration.
     if config_update is not None:
         self._config.update(**config_update)
         config = self._config.as_dict()
     else:
         config = original_config
     # Create configuration update.
     if full:
         config_update = config
     else:
         config_update = {
             option: value
             for option, value in config.items()
             if value != original_config[option]
         }
         if 'machine_type' in config_update:
             for opt in (
                     'machine_specific_options',
                     'system_keymap',
             ):
                 config_update[opt] = config[opt]
     # Update logging.
     log.set_stroke_filename(config['log_file_name'])
     log.enable_stroke_logging(config['enable_stroke_logging'])
     log.enable_translation_logging(config['enable_translation_logging'])
     # Update output.
     self._formatter.set_space_placement(config['space_placement'])
     self._formatter.start_attached = config['start_attached']
     self._formatter.start_capitalized = config['start_capitalized']
     self._translator.set_min_undo_length(config['undo_levels'])
     # Update machine.
     update_keymap = False
     start_machine = False
     machine_params = MachineParams(config['machine_type'],
                                    config['machine_specific_options'],
                                    config['system_keymap'])
     if reset_machine or machine_params != self._machine_params:
         if self._machine is not None:
             self._machine.stop_capture()
             self._machine = None
         machine_type = config['machine_type']
         machine_options = config['machine_specific_options']
         try:
             machine_class = machine_registry.get(machine_type)
         except NoSuchMachineException as e:
             raise InvalidConfigurationError(str(e))
         self._machine = machine_class(machine_options)
         self._machine.set_suppression(self._is_running)
         self._machine.add_state_callback(self._machine_state_callback)
         self._machine.add_stroke_callback(self._machine_stroke_callback)
         self._machine_params = machine_params
         update_keymap = True
         start_machine = True
     elif self._machine is not None:
         update_keymap = 'system_keymap' in config_update
     if update_keymap:
         machine_keymap = config['system_keymap']
         if machine_keymap is not None:
             self._machine.set_keymap(machine_keymap)
     if start_machine:
         self._machine.start_capture()
     # Update dictionaries.
     dictionaries_files = config['dictionary_file_names']
     dictionaries = self._dictionaries_manager.load(dictionaries_files)
     self._dictionaries.set_dicts(dictionaries)
     # Trigger `config_changed` hook.
     if config_update:
         self._trigger_hook('config_changed', config_update)
Пример #10
0
Файл: app.py Проект: gcr/plover
    def __init__(self, engine_command_callback):
        """Creates and configures a single steno pipeline."""
        self.subscribers = []
        self.is_running = False
        self.machine = None
        self.machine_init = {}
        self.translator = None
        self.formatter = None
        self.output = None

        # Check and use configuration
        self.config = conf.get_config()
        config_errors, config_values = check_steno_config(self.config)
        for error in config_errors:
            # This will raise one of the configuration errors.
            raise error

        machine_type, user_dictionary = config_values

        # Set the machine module and any initialization variables.
        self.machine_module = conf.import_named_module(
            machine_type, SUPPORTED_MACHINES_DICT)
        if self.machine_module is None:
            raise InvalidConfigurationError(
                'Invalid configuration value for %s: %s' %
                (conf.MACHINE_TYPE_OPTION, machine_type))

        if issubclass(self.machine_module.Stenotype,
                      plover.machine.base.SerialStenotypeBase):
            serial_params = conf.get_serial_params(machine_type, self.config)
            self.machine_init.update(serial_params.__dict__)

        # Initialize the logger.
        log_file = join(
            conf.CONFIG_DIR,
            self.config.get(conf.LOGGING_CONFIG_SECTION, conf.LOG_FILE_OPTION))
        self.logger = logging.getLogger(conf.LOGGER_NAME)
        self.logger.setLevel(logging.DEBUG)
        handler = RotatingFileHandler(
            log_file,
            maxBytes=conf.LOG_MAX_BYTES,
            backupCount=conf.LOG_COUNT,
        )
        handler.setFormatter(logging.Formatter(conf.LOG_FORMAT))
        self.logger.addHandler(handler)

        # Construct the stenography capture-translate-format-display pipeline.
        self.machine = self.machine_module.Stenotype(**self.machine_init)
        self.translator = translation.Translator()
        self.translator.set_dictionary(user_dictionary)
        self.formatter = formatting.Formatter()

        # Add hooks for logging. Do this first so logs appear in order.
        if self.config.getboolean(conf.LOGGING_CONFIG_SECTION,
                                  conf.ENABLE_STROKE_LOGGING_OPTION):
            self.machine.add_callback(self._log_stroke)
        if self.config.getboolean(conf.LOGGING_CONFIG_SECTION,
                                  conf.ENABLE_TRANSLATION_LOGGING_OPTION):
            self.translator.add_listener(self._log_translation)

        self.machine.add_callback(
            lambda x: self.translator.translate(steno.Stroke(x)))
        self.translator.add_listener(self.formatter.format)
        # This seems like a reasonable number. If this becomes a problem it can
        # be parameterized.
        self.translator.set_min_undo_length(10)
        keyboard_control = keyboardcontrol.KeyboardEmulation()
        bag = SimpleNamespace()
        bag.send_backspaces = keyboard_control.send_backspaces
        bag.send_string = keyboard_control.send_string
        bag.send_key_combination = keyboard_control.send_key_combination
        bag.send_engine_command = engine_command_callback
        self.full_output = bag
        bag = SimpleNamespace()
        bag.send_engine_command = engine_command_callback
        self.command_only_output = bag
        self.running_state = self.translator.get_state()

        auto_start = self.config.getboolean(conf.MACHINE_CONFIG_SECTION,
                                            conf.MACHINE_AUTO_START_OPTION)
        self.set_is_running(auto_start)

        # Start the machine monitoring for steno strokes.
        self.machine.start_capture()
Пример #11
0
 def _update(self, config_update=None, full=False, reset_machine=False):
     original_config = self._config.as_dict()
     # Update configuration.
     if config_update is not None:
         self._config.update(**config_update)
         config = self._config.as_dict()
     else:
         config = original_config
     # Create configuration update.
     if full:
         config_update = config
     else:
         config_update = {
             option: value
             for option, value in config.items()
             if value != original_config[option]
         }
         if 'machine_type' in config_update:
             for opt in (
                     'machine_specific_options',
                     'system_keymap',
             ):
                 config_update[opt] = config[opt]
     # Update logging.
     log.set_stroke_filename(config['log_file_name'])
     log.enable_stroke_logging(config['enable_stroke_logging'])
     log.enable_translation_logging(config['enable_translation_logging'])
     # Update output.
     self._formatter.set_space_placement(config['space_placement'])
     self._formatter.start_attached = config['start_attached']
     self._formatter.start_capitalized = config['start_capitalized']
     self._translator.set_min_undo_length(config['undo_levels'])
     # Update system.
     system_name = config['system_name']
     if system.NAME != system_name:
         log.info('loading system: %s', system_name)
         system.setup(system_name)
     # Update machine.
     update_keymap = False
     start_machine = False
     machine_params = MachineParams(config['machine_type'],
                                    config['machine_specific_options'],
                                    config['system_keymap'])
     # Do not reset if only the keymap changed.
     if self._machine_params is None or \
        self._machine_params.type != machine_params.type or \
        self._machine_params.options != machine_params.options:
         reset_machine = True
     if reset_machine:
         if self._machine is not None:
             self._machine.stop_capture()
             self._machine = None
         machine_type = config['machine_type']
         machine_options = config['machine_specific_options']
         try:
             machine_class = registry.get_plugin('machine',
                                                 machine_type).obj
         except Exception as e:
             raise InvalidConfigurationError(str(e))
         log.info('setting machine: %s', machine_type)
         self._machine = machine_class(machine_options)
         self._machine.set_suppression(self._is_running)
         self._machine.add_state_callback(self._machine_state_callback)
         self._machine.add_stroke_callback(self._machine_stroke_callback)
         self._machine_params = machine_params
         update_keymap = True
         start_machine = True
     elif self._machine is not None:
         update_keymap = 'system_keymap' in config_update
     if update_keymap:
         machine_keymap = config['system_keymap']
         if machine_keymap is not None:
             self._machine.set_keymap(machine_keymap)
     if start_machine:
         self._machine.start_capture()
     # Update running extensions.
     enabled_extensions = config['enabled_extensions']
     running_extensions = set(self._running_extensions)
     self._stop_extensions(running_extensions - enabled_extensions)
     self._start_extensions(enabled_extensions - running_extensions)
     # Trigger `config_changed` hook.
     if config_update:
         self._trigger_hook('config_changed', config_update)
     # Update dictionaries.
     config_dictionaries = OrderedDict(
         (d.path, d) for d in config['dictionaries'])
     copy_default_dictionaries(config_dictionaries.keys())
     # Start by unloading outdated dictionaries.
     self._dictionaries_manager.unload_outdated()
     self._set_dictionaries([
         d for d in self._dictionaries.dicts
         if d.path in config_dictionaries and \
            d.path in self._dictionaries_manager
     ])
     # And then (re)load all dictionaries.
     dictionaries = []
     for result in self._dictionaries_manager.load(
             config_dictionaries.keys()):
         if isinstance(result, DictionaryLoaderException):
             d = ErroredDictionary(result.path, result.exception)
             # Only show an error if it's new.
             if d != self._dictionaries.get(result.path):
                 log.error('loading dictionary `%s` failed: %s',
                           shorten_path(result.path), str(result.exception))
         else:
             d = result
         d.enabled = config_dictionaries[d.path].enabled
         dictionaries.append(d)
     self._set_dictionaries(dictionaries)
Пример #12
0
 def load(self, fp):
     self._config = RawConfigParser()
     try:
         self._config.readfp(fp)
     except ConfigParser.Error as e:
         raise InvalidConfigurationError(str(e))