예제 #1
0
    def _load_script(self):
        """Loads the script from the filesystem

        :raises exceptions.IOError: if the script file could not be opened
        """
        script_text = filesystem.read_file(self.path, self.filename)

        if not script_text:
            raise IOError("Script file could not be opened or was empty: {0}"
                          "".format(os.path.join(self.path, self.filename)))
        self.script = script_text
예제 #2
0
import imp
import yaml
from gtkmvc3.observable import Observable

from rafcon.core.config import global_config
from rafcon.core.id_generator import generate_script_id
from rafcon.core.storage.storage import SCRIPT_FILE
import rafcon.core.singleton

from rafcon.utils import filesystem
from rafcon.utils import log
logger = log.get_logger(__name__)

DEFAULT_SCRIPT_FILE = "default_script.py"

DEFAULT_SCRIPT = filesystem.read_file(os.path.dirname(__file__),
                                      DEFAULT_SCRIPT_FILE)


class Script(Observable, yaml.YAMLObject):
    """A class for representing the script file for all execution states in a state machine.

    It inherits from Observable to make a change of its fields observable.

    :ivar path: the path where the script resides
    :ivar filename: the full name of the script file
    :ivar _compiled_module: the compiled module
    :ivar _script_id: the id of the script
    :ivar check_path: a flag to indicate if the path should be checked for existence

    """
예제 #3
0
파일: storage.py 프로젝트: ylshimp/RAFCON
def load_state_recursively(parent, state_path=None, dirty_states=[]):
    """Recursively loads the state

    It calls this method on each sub-state of a container state.

    :param parent:  the root state of the last load call to which the loaded state will be added
    :param state_path: the path on the filesystem where to find the meta file for the state
    :param dirty_states: a dict of states which changed during loading
    :return:
    """
    from rafcon.core.states.execution_state import ExecutionState
    from rafcon.core.states.container_state import ContainerState
    from rafcon.core.states.hierarchy_state import HierarchyState

    path_core_data = os.path.join(state_path, FILE_NAME_CORE_DATA)

    logger.debug("Load state recursively: {0}".format(str(state_path)))

    # TODO: Should be removed with next minor release
    if not os.path.exists(path_core_data):
        path_core_data = os.path.join(state_path, FILE_NAME_CORE_DATA_OLD)

    try:
        state_info = load_data_file(path_core_data)
    except ValueError as e:
        logger.exception("Error while loading state data: {0}".format(e))
        return
    except LibraryNotFoundException as e:
        logger.error(
            "Library could not be loaded: {0}\n"
            "Skipping library and continuing loading the state machine".format(
                e))
        state_info = storage_utils.load_objects_from_json(path_core_data,
                                                          as_dict=True)
        state_id = state_info["state_id"]
        dummy_state = HierarchyState(LIBRARY_NOT_FOUND_DUMMY_STATE_NAME,
                                     state_id=state_id)
        # set parent of dummy state
        if isinstance(parent, ContainerState):
            parent.add_state(dummy_state, storage_load=True)
        else:
            dummy_state.parent = parent
        return dummy_state

    # Transitions and data flows are not added when loading a state, as also states are not added.
    # We have to wait until the child states are loaded, before adding transitions and data flows, as otherwise the
    # validity checks for transitions and data flows would fail
    if not isinstance(state_info, tuple):
        state = state_info
    else:
        state = state_info[0]
        transitions = state_info[1]
        data_flows = state_info[2]

    # set parent of state
    if parent is not None and isinstance(parent, ContainerState):
        parent.add_state(state, storage_load=True)
    else:
        state.parent = parent

    # read script file if state is an ExecutionState
    if isinstance(state, ExecutionState):
        script_text = read_file(state_path, state.script.filename)
        state.script.set_script_without_compilation(script_text)

    # load semantic data
    try:
        semantic_data = load_data_file(
            os.path.join(state_path, SEMANTIC_DATA_FILE))
        state.semantic_data = semantic_data
    except Exception as e:
        # semantic data file does not have to be there
        pass

    one_of_my_child_states_not_found = False

    # load child states
    for p in os.listdir(state_path):
        child_state_path = os.path.join(state_path, p)
        if os.path.isdir(child_state_path):
            if not os.path.exists(
                    os.path.join(child_state_path, FILE_NAME_CORE_DATA)):
                # this means that child_state_path is a folder, not containing a valid state
                # this also happens when pip creates __pycache__ folders for the script.py files upon installing rafcon
                continue
            child_state = load_state_recursively(state, child_state_path,
                                                 dirty_states)
            if not child_state:
                return None
            if child_state.name is LIBRARY_NOT_FOUND_DUMMY_STATE_NAME:
                one_of_my_child_states_not_found = True

    if one_of_my_child_states_not_found:
        # omit adding transitions and data flows in this case
        pass
    else:
        # Now we can add transitions and data flows, as all child states were added
        if isinstance(state_info, tuple):
            # safe version
            # state.transitions = transitions
            # state.data_flows = data_flows
            state._transitions = transitions
            for _, transition in state.transitions.items():
                transition._parent = ref(state)
            state._data_flows = data_flows
            for _, data_flow in state.data_flows.items():
                data_flow._parent = ref(state)

    state.file_system_path = state_path

    if state.marked_dirty:
        dirty_states.append(state)

    return state
예제 #4
0
def trigger_source_editor_signals():
    # gui elements
    import rafcon.gui.singleton
    import rafcon.gui.config as gui_config

    # ---setup---
    menubar_ctrl = rafcon.gui.singleton.main_window_controller.get_controller('menu_bar_controller')

    # ---setup new statemachine and add a new state---
    call_gui_callback(menubar_ctrl.on_new_activate, None)
    call_gui_callback(menubar_ctrl.on_add_state_activate, None)

    # ---focus the newly added state and get the source controller---
    sm_m = menubar_ctrl.model.get_selected_state_machine_model()
    call_gui_callback(rafcon.gui.singleton.state_machine_manager.__setattr__, "active_state_machine_id",
                      sm_m.state_machine.state_machine_id)
    root_state_m = sm_m.root_state
    state_m = root_state_m.states.values()[0]
    states_editor_controller = rafcon.gui.singleton.main_window_controller.get_controller('states_editor_ctrl')
    state_identifier = states_editor_controller.get_state_identifier(state_m)
    call_gui_callback(states_editor_controller.activate_state_tab, state_m)
    tab_list = states_editor_controller.tabs
    source_editor_controller = tab_list[state_identifier]['controller'].get_controller('source_ctrl')

    # ---check if the default text equals the default_script.py
    default_content = filesystem.read_file(os.path.join(rafcon.__path__[0], 'core', 'default_script.py'))
    content = source_editor_controller.source_text
    assert content == default_content

    # ---check if the source text can be changed---
    content = 'Test'
    call_gui_callback(source_editor_controller.set_script_text, content)
    assert content == source_editor_controller.source_text

    # ---check if a wrong shell command returns false by the append_...() method
    assert not call_gui_callback(source_editor_controller.execute_shell_command_with_path, 'gibberish', 'foo.txt')

    source_view = source_editor_controller.view
    test_text = 'apply_test'

    # get the textview buffer and replace the buffer text with another
    test_buffer = source_view.get_buffer()
    test_buffer.set_text(test_text, 10)

    # ---check if a new buffer doesnt change the source text
    source_view.textview.set_buffer(test_buffer)
    assert not source_editor_controller.source_text == test_text

    # ---check if the cancel button resets the buffer to the source text
    cancel_button = source_view['cancel_button']
    call_gui_callback(source_editor_controller.cancel_clicked, cancel_button)
    assert source_view.get_buffer().get_text(test_buffer.get_start_iter(), test_buffer.get_end_iter()) == content

    # test buffer now contains the source_text which equals content so test_buffer is again set to contain test_text
    test_buffer.set_text(test_text, 10)

    # ---check if changing the buffer and applying the changes has an impact on the source text
    source_view.textview.set_buffer(test_buffer)
    print("test_buffer " + test_buffer.get_text(test_buffer.get_start_iter(), test_buffer.get_end_iter()))
    apply_button = source_view['apply_button']
    call_gui_callback(source_editor_controller.apply_clicked, apply_button)
    assert source_editor_controller.source_text == test_text

    # ----------- Test requiring gedit to work ------------
    if not check_for_editor('gedit'):
        call_gui_callback(menubar_ctrl.on_quit_activate, None, None, True)
        return False

    # ---check if the open external button opens a gedit instance

    kill_running_processes('gedit')
    call_gui_callback(gui_config.global_gui_config.set_config_value, 'DEFAULT_EXTERNAL_EDITOR', 'gedit')
    button = source_view['open_external_button']

    call_gui_callback(button.set_active, True)
    assert find_running_process('gedit')
    assert button.get_label() == 'Unlock'

    kill_running_processes('gedit')

    call_gui_callback(button.set_active, False)
    assert button.get_label() == 'Open externally'

    return True
예제 #5
0
 def load_and_set_file_content(self, file_system_path):
     """ Implements the abstract method of the ExternalEditor class.
     """
     content = filesystem.read_file(file_system_path, storage.SCRIPT_FILE)
     if content is not None:
         self.set_script_text(content)
예제 #6
0
def test_gui(gui):
    # queue = Queue.Queue() # TODO think about to use this to get call_back methods return value by a generic scheme
    # thread = threading.Thread(target=lambda q, arg1: q.put(trigger_source_editor_signals(arg1)), args=(queue, main_window_controller))
    errors = 3

    import rafcon
    import rafcon.gui.config as gui_config
    import psutil

    # ---setup---
    menubar_ctrl = gui.singletons.main_window_controller.menu_bar_controller

    # ---setup new statemachine and add a new state---
    gui(menubar_ctrl.on_new_activate, None)
    gui(menubar_ctrl.on_add_state_activate, None)

    # ---focus the newly added state and get the source controller---
    sm_m = menubar_ctrl.model.get_selected_state_machine_model()
    root_state_m = sm_m.root_state
    state_m = list(root_state_m.states.values())[0]
    states_editor_controller = gui.singletons.main_window_controller.states_editor_ctrl
    state_identifier = states_editor_controller.get_state_identifier(state_m)
    gui(states_editor_controller.activate_state_tab, state_m)
    tab_list = states_editor_controller.tabs
    source_editor_controller = tab_list[state_identifier][
        'controller'].get_controller('source_ctrl')

    # ---check if the default text equals the default_script.py
    default_content = filesystem.read_file(
        os.path.join(rafcon.__path__[0], 'core', 'default_script.py'))
    content = source_editor_controller.source_text
    assert content == default_content

    # ---check if the source text can be changed---
    content = 'Test'
    # This adds an additional error, as this script cannot be compiled
    gui(source_editor_controller.set_script_text, content)
    assert content == source_editor_controller.source_text
    gui.expected_errors += 1  # NameError: name 'Test' is not defined

    # ---check if a wrong shell command returns false by the append_...() method
    assert not gui(source_editor_controller.execute_shell_command_with_path,
                   'gibberish', 'foo.txt')
    gui.expected_errors += 1  # No such file or directory (gibberish)

    source_view = source_editor_controller.view
    test_text = 'apply_test'

    # get the textview buffer and replace the buffer text with another
    test_buffer = source_view.get_buffer()
    # This adds an additional error, as this script cannot be compiled
    gui(test_buffer.set_text, test_text, -1)

    # ---check if a new buffer doesn't change the source text
    gui(source_view.textview.set_buffer, test_buffer)
    assert not source_editor_controller.source_text == test_text

    # ---check if the cancel button resets the buffer to the source text
    cancel_button = source_view['cancel_button']
    gui(source_editor_controller.cancel_clicked, cancel_button)
    assert source_view.get_buffer().get_text(
        test_buffer.get_start_iter(),
        test_buffer.get_end_iter(),
        include_hidden_chars=True) == content

    # test buffer now contains the source_text which equals content so test_buffer is again set to contain test_text
    gui(test_buffer.set_text, test_text, -1)

    # ---check if changing the buffer and applying the changes has an impact on the source text
    gui(source_view.textview.set_buffer, test_buffer)
    print("test_buffer " + test_buffer.get_text(test_buffer.get_start_iter(),
                                                test_buffer.get_end_iter(),
                                                include_hidden_chars=True))
    apply_button = source_view['apply_button']
    gui(source_editor_controller.apply_clicked, apply_button)
    assert source_editor_controller.source_text == test_text
    gui.expected_errors += 1  # NameError: name 'apply_test' is not defined

    # ----------- Test requiring psutil to work ------------
    try:
        psutil.process_iter()
    except psutil.AccessDenied:
        logger.warning("Cannot finish test: Cannot access process list")
        gui.expected_warnings += 1
        return

    # ----------- Test requiring gedit to work ------------
    try:
        if not check_for_editor('gedit'):
            logger.warning("Cannot finish test: Cannot find gedit")
            gui.expected_warnings += 1
            return
    except psutil.AccessDenied:
        logger.warning("Cannot finish test: Cannot access gedit")
        gui.expected_warnings += 1
        return

    # ---check if the open external button opens a gedit instance

    try:
        kill_running_processes('gedit')
    except psutil.AccessDenied:
        logger.warning("Cannot finish test: Cannot kill gedit")
        gui.expected_warnings += 1
        return

    gui(gui_config.global_gui_config.set_config_value,
        'DEFAULT_EXTERNAL_EDITOR', 'gedit')
    button = source_view['open_external_button']

    gui(button.set_active, True)
    assert find_running_process('gedit')
    assert button.get_label() == 'Unlock'

    kill_running_processes('gedit')

    gui(button.set_active, False)
    assert button.get_label() == 'Open externally'
예제 #7
0
파일: storage.py 프로젝트: uservinu/RAFCON
    if not isinstance(state_info, tuple):
        state = state_info
    else:
        state = state_info[0]
        transitions = state_info[1]
        data_flows = state_info[2]

    # set parent of state
    if parent is not None and isinstance(parent, ContainerState):
        parent.add_state(state, storage_load=True)
    else:
        state.parent = parent

    # read script file if an execution state
    if isinstance(state, ExecutionState):
        script_text = read_file(state_path, state.script.filename)
        state.script_text = script_text

    # load semantic data
    try:
        semantic_data = load_data_file(
            os.path.join(state_path, SEMANTIC_DATA_FILE))
        state.semantic_data = semantic_data
    except Exception, e:
        # semantic data file does not have to be there
        pass

    one_of_my_child_states_not_found = False

    # load child states
    for p in os.listdir(state_path):
예제 #8
0
파일: storage.py 프로젝트: DLR-RM/RAFCON
def load_state_recursively(parent, state_path=None, dirty_states=[]):
    """Recursively loads the state

    It calls this method on each sub-state of a container state.

    :param parent:  the root state of the last load call to which the loaded state will be added
    :param state_path: the path on the filesystem where to find the meta file for the state
    :param dirty_states: a dict of states which changed during loading
    :return:
    """
    from rafcon.core.states.execution_state import ExecutionState
    from rafcon.core.states.container_state import ContainerState
    from rafcon.core.states.hierarchy_state import HierarchyState
    from rafcon.core.singleton import library_manager

    path_core_data = get_core_data_path(state_path)
    path_meta_data = get_meta_data_path(state_path)

    logger.debug("Load state recursively: {0}".format(str(state_path)))

    try:
        state_info = load_data_file(path_core_data)
    except ValueError as e:
        logger.exception("Error while loading state data: {0}".format(e))
        return
    except LibraryNotFoundException as e:
        if global_config.get_config_value(
                "RAISE_ERROR_ON_MISSING_LIBRARY_STATES",
                False) or not library_manager.show_dialog:
            raise
        logger.error(
            "Library could not be loaded: {0}\n"
            "Skipping library and continuing loading the state machine".format(
                e))
        state_info = storage_utils.load_objects_from_json(path_core_data,
                                                          as_dict=True)
        missing_library_meta_data = None
        if os.path.exists(path_meta_data):
            missing_library_meta_data = Vividict(
                storage_utils.load_objects_from_json(path_meta_data))
        state_id = state_info["state_id"]
        outcomes = {
            outcome['outcome_id']: Outcome(outcome['outcome_id'],
                                           outcome['name'])
            for outcome in state_info["outcomes"].values()
        }
        dummy_state = HierarchyState(
            LIBRARY_NOT_FOUND_DUMMY_STATE_NAME,
            state_id=state_id,
            outcomes=outcomes,
            is_dummy=True,
            missing_library_meta_data=missing_library_meta_data)
        library_name = state_info['library_name']
        path_parts = os.path.join(state_info['library_path'],
                                  library_name).split(os.sep)
        dummy_state.description = 'The Missing Library Path: %s\nThe Missing Library Name: %s\n\n' % (
            state_info['library_path'], library_name)
        from rafcon.core.singleton import library_manager
        if path_parts[0] in library_manager.library_root_paths:
            dummy_state.description += 'The Missing Library OS Path: %s' % os.path.join(
                library_manager.library_root_paths[path_parts[0]], *
                path_parts[1:])
        else:
            dummy_state.description += 'The missing library was located in the missing library root "%s"' % path_parts[
                0]
        # set parent of dummy state
        if isinstance(parent, ContainerState):
            parent.add_state(dummy_state, storage_load=True)
        else:
            dummy_state.parent = parent
        return dummy_state
    except LibraryNotFoundSkipException:
        return None

    # Transitions and data flows are not added when loading a state, as also states are not added.
    # We have to wait until the child states are loaded, before adding transitions and data flows, as otherwise the
    # validity checks for transitions and data flows would fail
    if not isinstance(state_info, tuple):
        state = state_info
    else:
        state = state_info[0]
        transitions = state_info[1]
        data_flows = state_info[2]

    # set parent of state
    if parent is not None and isinstance(parent, ContainerState):
        parent.add_state(state, storage_load=True)
    else:
        state.parent = parent

    # read script file if state is an ExecutionState
    if isinstance(state, ExecutionState):
        script_text = read_file(state_path, state.script.filename)
        state.script.set_script_without_compilation(script_text)

    # load semantic data
    try:
        semantic_data = load_data_file(
            os.path.join(state_path, SEMANTIC_DATA_FILE))
        state.semantic_data = semantic_data
    except Exception as e:
        # semantic data file does not have to be there
        pass

    # load child states
    for p in os.listdir(state_path):
        child_state_path = os.path.join(state_path, p)
        if os.path.isdir(child_state_path):
            if not os.path.exists(
                    os.path.join(child_state_path, FILE_NAME_CORE_DATA)):
                # this means that child_state_path is a folder, not containing a valid state
                # this also happens when pip creates __pycache__ folders for the script.py files upon installing rafcon
                continue
            child_state = load_state_recursively(state, child_state_path,
                                                 dirty_states)
            if not child_state:
                return None

    # Now we can add transitions and data flows, as all child states were added
    if isinstance(state_info, tuple):
        safe_init = global_config.get_config_value("LOAD_SM_WITH_CHECKS", True)
        if safe_init:
            # this will trigger all validity checks the state machine
            state.transitions = transitions
        else:
            state._transitions = transitions
            state._data_flows = data_flows
        for _, transition in state.transitions.items():
            transition._parent = ref(state)
        state._data_flows = data_flows
        for _, data_flow in state.data_flows.items():
            data_flow._parent = ref(state)

    state.file_system_path = state_path

    if state.marked_dirty:
        dirty_states.append(state)

    return state
예제 #9
0
.. moduleauthor:: Sebastian Brunner


"""
from os import path

from yaml_configuration.config import DefaultConfig, ConfigError
from rafcon.utils import filesystem
from rafcon.utils import log

logger = log.get_logger(__name__)

CONFIG_FILE = "network_config.yaml"
# DEFAULT is a string and equals the content of the ./network_config.yaml
DEFAULT_CONFIG = filesystem.read_file(path.dirname(__file__), CONFIG_FILE)


class Config(DefaultConfig):
    """
    Class to hold and load the global network configurations.
    """
    def __init__(self, logger_object=None):
        super(Config, self).__init__(DEFAULT_CONFIG,
                                     logger_object,
                                     rel_config_path='rafcon')
        self.load(CONFIG_FILE)
        if self.get_config_value("TYPE") != "NETWORK_CONFIG":
            raise ConfigError(
                "Type should be NETWORK_CONFIG for network configuration. "
                "Please add \"TYPE: NETWORK_CONFIG\" to your network_config.yaml file."