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