def handle_component_not_found(client_state, username, component_id): """Handles the error when the server fails to find a component""" current_app.logger.debug("Failed to find component " + str(component_id) + \ ". Trying to resolve issue...") # Was it the component that the user is currently on? if client_state["componentid"] == component_id: # Yes sequence_id = 0 try: # Get the sequence sequence_id = client_state["sequenceid"] sequence = db.get_sequence(sequence_id) # Move the client to the first unit operation client_state["componentid"] = sequence["components"][0]["id"] db.update_user_client_state(username, client_state) current_app.logger.warn("Redirecting user to the " + \ "first component of sequence " + str(sequence_id)) except Exceptions.SequenceNotFoundException as ex: # Sequence not found current_app.logger.error("Sequence Not Found Exception" + str(ex)) return handle_sequence_not_found(client_state, username, sequence_id) # Return the state elixys_get_state = Elixys_Get_State() return elixys_get_state.state_index()
def handle_component_not_found(client_state, username, component_id): """ Handles the error when the server fails to find a component Function expects a client state, username and component id that generate the exception. Function return the state from GET /Elixys/state. """ current_app.logger.debug("Failed to find component " + str(component_id)) # Was it the component that the user is currently on? if client_state["componentid"] == component_id: # Yes sequence_id = 0 try: # Get the sequence sequence_id = client_state["sequenceid"] sequence = db.get_sequence(sequence_id) # Move the client to the first unit operation client_state["componentid"] = sequence["components"][0]["id"] db.update_user_client_state(username, client_state) current_app.logger.warn("Redirecting user to the " + \ "first component of sequence " + str(sequence_id)) except Exceptions.SequenceNotFoundException as ex: # Sequence not found current_app.logger.error("Sequence Not Found Exception" + str(ex)) return handle_sequence_not_found(client_state, username, sequence_id) # Return the state elixys_get_state = Elixys_Get_State() return elixys_get_state.state_index()
def handle_get_state_edit(client_state, username): ''' Handles GET /state for Edit Sequence Function shall expect a client state and a string username. Function shall return the "Edit Sequence" screen. ''' server_state = get_server_state(username) current_app.logger.debug("GET /STATE - edit" + "\nclient state: " + str(client_state) + \ "\nclient state[comp id]: " + str(client_state["componentid"]) + \ "\nRun State: " + str(server_state["runstate"])) # Do we have a component ID? if client_state["componentid"] == 0: # No, the component ID is missing. # Get the sequence and the ID of the first component sequence = sequence_manager.GetSequence(username, client_state["sequenceid"], False) client_state["componentid"] = sequence["components"][0]["id"] # Save client state db.update_user_client_state(username, client_state) # Allow running if the system is not in use run_allowed = (server_state["runstate"]["status"] == "Idle") # Allow running from here if this is not a cassette run_here_allowed = False if run_allowed: component = sequence_manager.GetComponent(username, client_state["componentid"], client_state["sequenceid"]) run_here_allowed = (component["componenttype"] != "CASSETTE") # Return the state return { "buttons": [{ "type": "button", "id": "SEQUENCER", "enabled": True }, { "type": "button", "id": "VIEWSEQUENCE", "enabled": True }, { "type": "button", "id": "RUNSEQUENCE", "enabled": run_allowed }, { "type": "button", "id": "RUNSEQUENCEHERE", "enabled": run_here_allowed }], "sequenceid": client_state["sequenceid"], "componentid": client_state["componentid"] }
def handle_get_state_view(client_state, username): ''' Handles GET /state for View Sequence Function expects a client state and a string username. Function returns the "View Sequence" screen. ''' server_state = get_server_state(username) # Do we have a component ID? if client_state["componentid"] == 0: # No, the component ID is missing. # Get the sequence and the ID of the first component sequence = sequence_manager.GetSequence(username, client_state["sequenceid"], False) client_state["componentid"] = sequence["components"][0]["id"] # Save client state db.update_user_client_state(username, client_state) # Allow editing if this is a saved sequence sequence_metadata = db.get_sequence_metadata(client_state["sequenceid"]) edit_allowed = (sequence_metadata["sequencetype"] == "Saved") # Allow running if the system is not in use run_allowed = (server_state["runstate"]["status"] == "Idle") # Allow running from here if this is not a cassette run_here_allowed = False if run_allowed: component = sequence_manager.GetComponent(username, client_state["componentid"], client_state["sequenceid"]) run_here_allowed = (component["componenttype"] != "CASSETTE") # Return the state return { "buttons": [{ "type": "button", "id": "SEQUENCER", "enabled": True }, { "type": "button", "id": "EDITSEQUENCE", "enabled": edit_allowed }, { "type": "button", "id": "RUNSEQUENCE", "enabled": run_allowed }, { "type": "button", "id": "RUNSEQUENCEHERE", "enabled": run_here_allowed }], "sequenceid": client_state["sequenceid"], "componentid": client_state["componentid"] }
def handle_get_state_run(client_state, username): ''' Handles GET /state for Run Sequtate: " + str(server_state)) ''' server_state = get_server_state(username) current_app.logger.debug("In GET /STATE - RUN" + "\nClientstate: " + str(client_state) + \ "\nServerstate: " + str(server_state)) server_state = get_server_state(username) # Sync the client state with the run state if ((client_state["sequenceid"] != server_state["runstate"]["sequenceid"]) or (client_state["componentid"] != server_state["runstate"]["componentid"]) or (client_state["prompt"]["show"] != server_state["runstate"]["prompt"]["show"]) or ((client_state["prompt"].has_key("screen")) and (server_state["runstate"]["prompt"].has_key("screen")) and (client_state["prompt"]["screen"] != server_state["runstate"]["prompt"]["screen"]))): # Log issue current_app.logger.debug("Syncing the client with run state" + "\nClient State:\n" + str(client_state) + "\nRun State:\n" + str(server_state["runstate"])) # Update the sequence and component IDs client_state["sequenceid"] = server_state["runstate"]["sequenceid"] client_state["componentid"] = server_state["runstate"]["componentid"] # Update the prompt client_state["prompt"] = copy.copy(server_state["runstate"]["prompt"]) # Update the client state db.update_user_client_state(username, client_state) # Determine if we are the user running the system if str(username) == server_state["runstate"]["username"]: # Enable or disable buttons sequencer_enabled = False pause_enabled = False #not server_state["runstate"]["runcomplete"] abort_enabled = not server_state["runstate"]["runcomplete"] else: # Enable or disable buttons sequencer_enabled = True pause_enabled = False abort_enabled = False # Return the state return {"buttons":[{"type":"button", "id":"SEQUENCER", "enabled":sequencer_enabled}, {"type":"button", "id":"PAUSERUN", "enabled":pause_enabled}, {"type":"button", "id":"ABORTRUN", "enabled":abort_enabled}, {"type":"button", "id":"LOGOUT", "enabled":True}], "sequenceid":client_state["sequenceid"], "componentid":client_state["componentid"]}
def save_client_state_and_return(client_state, username): ''' Function expects a client state and a string username. Function shall update the client state before calling GET /State from Elixys_Get_State(). Function shall return the output of state_index() called from Elixys_Get_State. ''' db.update_user_client_state(username, client_state) # Call GET /STATE and return get_state = Elixys_Get_State() return get_state.state_index()
def handle_get_state_edit(client_state, username): ''' Handles GET /state for Edit Sequence Function shall expect a client state and a string username. Function shall return the "Edit Sequence" screen. ''' server_state = get_server_state(username) current_app.logger.debug("GET /STATE - edit" + "\nclient state: " + str(client_state) + \ "\nclient state[comp id]: " + str(client_state["componentid"]) + \ "\nRun State: " + str(server_state["runstate"])) # Do we have a component ID? if client_state["componentid"] == 0: # No, the component ID is missing. # Get the sequence and the ID of the first component sequence = sequence_manager.GetSequence( username, client_state["sequenceid"], False) client_state["componentid"] = sequence["components"][0]["id"] # Save client state db.update_user_client_state(username, client_state) # Allow running if the system is not in use run_allowed = (server_state["runstate"]["status"] == "Idle") # Allow running from here if this is not a cassette run_here_allowed = False if run_allowed: component = sequence_manager.GetComponent( username, client_state["componentid"], client_state["sequenceid"]) run_here_allowed = (component["componenttype"] != "CASSETTE") # Return the state return {"buttons":[{"type":"button", "id":"SEQUENCER", "enabled":True}, {"type":"button", "id":"VIEWSEQUENCE", "enabled":True}, {"type":"button", "id":"RUNSEQUENCE", "enabled":run_allowed}, {"type":"button", "id":"RUNSEQUENCEHERE", "enabled":run_here_allowed}], "sequenceid":client_state["sequenceid"], "componentid":client_state["componentid"]}
def handle_get_state_run(client_state, username): ''' Function shall return the state for a Run Sequence state. Function expects a client state and a string username to be passed in. Function shall return the state for the Run Sequence state as a JSON object. ''' # Sync the client state with the run state if ((client_state["sequenceid"] != server_state["runstate"]["sequenceid"]) or (client_state["componentid"] != server_state["runstate"]["componentid"]) or (client_state["prompt"]["show"] != server_state["runstate"]["prompt"]["show"]) or ((client_state["prompt"].has_key("screen")) and (server_state["runstate"]["prompt"].has_key("screen")) and (client_state["prompt"]["screen"] != server_state["runstate"]["prompt"]["screen"]))): # Update the sequence and component IDs client_state["sequenceid"] = server_state["runstate"]["sequenceid"] client_state["componentid"] = server_state["runstate"]["componentid"] # Update the prompt client_state["prompt"] = copy.copy( server_state["runstate"]["prompt"]) # Update the client state db.update_user_client_state(username, client_state) # Determine if we are the user running the system if username == server_state["runstate"]["username"]: # Enable or disable buttons sequencer_enabled = False pause_enabled = False #not server_state["runstate"]["runcomplete"] abort_enabled = not server_state["runstate"]["runcomplete"] else: # Enable or disable buttons sequencer_enabled = True pause_enabled = False abort_enabled = False # Return the state return {"buttons":[{"type":"button", "id":"SEQUENCER", "enabled":sequencer_enabled}, {"type":"button", "id":"PAUSERUN", "enabled":pause_enabled}, {"type":"button", "id":"ABORTRUN", "enabled":abort_enabled}, {"type":"button", "id":"LOGOUT", "enabled":True}], "sequenceid":client_state["sequenceid"], "componentid":client_state["componentid"]}
def handle_sequence_not_found(client_state, username, sequence_id): """Handles the error when the server fails to find a sequence""" current_app.logger.debug("Failed to find sequence %s " % str(sequence_id)) # Was it the sequence that the user is currently on? if client_state["sequenceid"] == sequence_id: # Yes, so return the user to the last Select Sequence screen client_state = direct_to_last_select_screen(client_state) db.update_user_client_state(username, client_state) current_app.logger.error("Redirecting user to select sequences page") # Return the state return Elixys_Get_State.state_index()
def handle_get_state_view(client_state, username): ''' Handles GET /state for View Sequence Function expects a client state and a string username. Function returns the "View Sequence" screen. ''' server_state = get_server_state(username) # Do we have a component ID? if client_state["componentid"] == 0: # No, the component ID is missing. # Get the sequence and the ID of the first component sequence = sequence_manager.GetSequence( username, client_state["sequenceid"], False) client_state["componentid"] = sequence["components"][0]["id"] # Save client state db.update_user_client_state(username, client_state) # Allow editing if this is a saved sequence sequence_metadata = db.get_sequence_metadata( client_state["sequenceid"]) edit_allowed = (sequence_metadata["sequencetype"] == "Saved") # Allow running if the system is not in use run_allowed = (server_state["runstate"]["status"] == "Idle") # Allow running from here if this is not a cassette run_here_allowed = False if run_allowed: component = sequence_manager.GetComponent(username, client_state["componentid"], client_state["sequenceid"]) run_here_allowed = (component["componenttype"] != "CASSETTE") # Return the state return {"buttons":[{"type":"button", "id":"SEQUENCER", "enabled":True}, {"type":"button", "id":"EDITSEQUENCE", "enabled":edit_allowed}, {"type":"button", "id":"RUNSEQUENCE", "enabled":run_allowed}, {"type":"button", "id":"RUNSEQUENCEHERE", "enabled":run_here_allowed}], "sequenceid":client_state["sequenceid"], "componentid":client_state["componentid"]}
def handle_reagent_not_found(client_state, username, reagent_id): """Handles the error when the server fails to find a reagent""" current_app.logger.debug("Failed to find reagent " + str(reagent_id)) # This error should only occur if the user has # the sequence they are currently viewing delete out from # under them. Redirect them to the last Select Sequence screen client_state = direct_to_last_select_screen(client_state) db.update_user_client_state(username, client_state) current_app.logger.warn("Redirecting user to select sequences page") # Return the state get_state = Elixys_Get_State() return get_state.state_index()
def delete_index(s_id, c_id): ''' Function handles a DELETE request from a web request in the form of: DELETE /Elixys/sequence/<sequenceid>/component/<componentid> Function expects two parameters, both integers, that are passed in from the web request. Function will delete the given sequence's component by it's id on the database. Function shall also update the client state by moving to the previous component on the "Edit Sequence" screen on the client. Function shall return the output of GET /Elixys/state. (See elixys_web_get.py) ''' auth = request.authorization username = str(auth.username) client_state = getCurrentClientState(username) current_app.logger.debug("Handling request: " + str(request)) # Make sure we can edit this sequence sequence_metadata = db.GetSequenceMetadata(username, int(s_id)) if sequence_metadata["sequencetype"] != "Saved": raise Exception("Cannot edit sequence") # Is the user currently viewing this component? if ((client_state["sequenceid"] == int(s_id)) and (client_state["componentid"] == int(c_id))): # Yes, so move the user to the previous component in the sequence previous_component = db.get_previous_component(int(c_id)) if previous_component == None: raise Exception("Failed to find previous component") # Update the client state client_state["componentid"] = previous_component["id"] db.update_user_client_state(username, client_state) # Delete the sequence component sequence_manager.DeleteComponent(username, int(s_id), int(c_id)) # Return the state current_app.logger.debug("Calling GET /state") get_state = Elixys_Get_State() return get_state.state_index()
def handle_reagent_not_found(client_state, username, reagent_id): """ Handles the error when the server fails to find a reagent. Function expects a client state, username and reagent id. Function shall redirect user to previous screen on client. Function returns the state from GET /Elixys/state. """ current_app.logger.debug("Failed to find reagent " + str(reagent_id)) # This error should only occur if the user has # the sequence they are currently viewing delete out from # under them. Redirect them to the last Select Sequence screen client_state = direct_to_last_select_screen(client_state) db.update_user_client_state(username, client_state) current_app.logger.warn("Redirecting user to last screen.") # Return the state get_state = Elixys_Get_State() return get_state.state_index()
def handle_sequence_not_found(client_state, username, sequence_id): """ Handles the error when the server fails to find a sequence. Function expects a client state object, a username, and the sequence id that raises the exception. Function shall return the state from GET /Elixys/state. """ client_state = getCurrentClientState(username) current_app.logger.debug("Failed to find sequence: " + str(sequence_id) + "Client state: " + str(client_state)) # Was it the sequence that the user is currently on? if client_state["sequenceid"] == int(sequence_id): # Yes, so return the user to the last Select Sequence screen client_state = direct_to_last_select_screen(client_state) db.update_user_client_state(username, client_state) current_app.logger.error("Redirecting user to select sequences page") # Return the state elixys_get_state = Elixys_Get_State() return elixys_get_state.state_index()
def handle_sequence_not_found(client_state, username, sequence_id): """ Handles the error when the server fails to find a sequence. Function expects a client state object, a username, and the sequence id that raises the exception. Function shall return the state from GET /Elixys/state. """ client_state = getCurrentClientState(username) current_app.logger.debug("Failed to find sequence: " + str(sequence_id) + \ "Client state: " + str(client_state)) # Was it the sequence that the user is currently on? if client_state["sequenceid"] == int(sequence_id): # Yes, so return the user to the last Select Sequence screen client_state = direct_to_last_select_screen(client_state) db.update_user_client_state(username, client_state) current_app.logger.error("Redirecting user to select sequences page") # Return the state elixys_get_state = Elixys_Get_State() return elixys_get_state.state_index()
def state_index(self=None): ''' This function requires authentication prior to executing. Function takes in no parameters. Function shall direct the client based on the client's current screen. Function returns the state to the client as a JSON object. ''' auth = request.authorization user = db.get_user(str(auth.username)) server_state = get_server_state(str(auth.username)) client_state = getCurrentClientState(str(auth.username)) current_app.logger.debug(str(request) + "\nClientstate: " + \ str(client_state) + "\nServerstate: " + str(server_state)) # Is the remote user the one that is currently running the system? if str(auth.username) == server_state["runstate"]["username"]: # Yes, so make sure the user is on the run screen if client_state["screen"] != "RUN": # Update the client state client_state["screen"] = "RUN" db.update_user_client_state(str(auth.username), client_state) return_state = { "type": "state", "user": user, "serverstate": server_state, "clientstate": client_state, "timestamp": time.time() } # Check which screen is active choice = str(client_state["screen"]) current_app.logger.debug("Request for state" + "\nREQUEST: " + str(request) + \ "\nClient state: " + str(client_state) + \ "\nServer state: " + str(server_state)) #current_app.logger.debug("Client State: "+ str(client_state) + \ # "\nChoice from client_state[screen]: " +str(choice)) if choice == "HOME": return_state.update(handle_get_state_home(auth.username)) elif choice == "SELECT_SAVEDSEQUENCES": return_state.update( handle_get_state_select_savedsequences(client_state, auth.username)) elif choice == "SELECT_RUNHISTORY": return_state.update( handle_get_state_select_runhistory(client_state, auth.username)) elif choice == "VIEW": return_state.update( handle_get_state_view(client_state, auth.username)) elif choice == "EDIT": return_state.update( handle_get_state_edit(client_state, auth.username)) elif choice == "RUN": return_state.update( handle_get_state_run(client_state, auth.username)) else: current_app.logger.debug("Unknown screen: %s" % str(choice)) raise Exception("Unknown screen: %s" % str(choice)) #current_app.logger.debug("Return state: " + str(return_state)) return jsonify(return_state)
def handle_get_state_run(client_state, username): ''' Handles GET /state for Run Sequtate: " + str(server_state)) ''' server_state = get_server_state(username) current_app.logger.debug("In GET /STATE - RUN" + "\nClientstate: " + str(client_state) + \ "\nServerstate: " + str(server_state)) server_state = get_server_state(username) # Sync the client state with the run state if ((client_state["sequenceid"] != server_state["runstate"]["sequenceid"]) or (client_state["componentid"] != server_state["runstate"]["componentid"]) or (client_state["prompt"]["show"] != server_state["runstate"]["prompt"]["show"]) or ((client_state["prompt"].has_key("screen")) and (server_state["runstate"]["prompt"].has_key("screen")) and (client_state["prompt"]["screen"] != server_state["runstate"]["prompt"]["screen"]))): # Log issue current_app.logger.debug("Syncing the client with run state" + "\nClient State:\n" + str(client_state) + "\nRun State:\n" + str(server_state["runstate"])) # Update the sequence and component IDs client_state["sequenceid"] = server_state["runstate"]["sequenceid"] client_state["componentid"] = server_state["runstate"]["componentid"] # Update the prompt client_state["prompt"] = copy.copy(server_state["runstate"]["prompt"]) # Update the client state db.update_user_client_state(username, client_state) # Determine if we are the user running the system if str(username) == server_state["runstate"]["username"]: # Enable or disable buttons sequencer_enabled = False pause_enabled = False #not server_state["runstate"]["runcomplete"] abort_enabled = not server_state["runstate"]["runcomplete"] else: # Enable or disable buttons sequencer_enabled = True pause_enabled = False abort_enabled = False # Return the state return { "buttons": [{ "type": "button", "id": "SEQUENCER", "enabled": sequencer_enabled }, { "type": "button", "id": "PAUSERUN", "enabled": pause_enabled }, { "type": "button", "id": "ABORTRUN", "enabled": abort_enabled }, { "type": "button", "id": "LOGOUT", "enabled": True }], "sequenceid": client_state["sequenceid"], "componentid": client_state["componentid"] }
def state_index(self=None): """ This function requires authentication prior to executing. Function takes in no parameters. Function shall direct the client based on the client's current screen. Function returns the state to the client as a JSON object. """ auth = request.authorization user = db.get_user(str(auth.username)) server_state = get_server_state(str(auth.username)) client_state = getCurrentClientState(str(auth.username)) current_app.logger.debug( str(request) + "\nClientstate: " + str(client_state) + "\nServerstate: " + str(server_state) ) # Is the remote user the one that is currently running the system? if str(auth.username) == server_state["runstate"]["username"]: # Yes, so make sure the user is on the run screen if client_state["screen"] != "RUN": # Update the client state client_state["screen"] = "RUN" db.update_user_client_state(str(auth.username), client_state) return_state = { "type": "state", "user": user, "serverstate": server_state, "clientstate": client_state, "timestamp": time.time(), } # Check which screen is active choice = str(client_state["screen"]) current_app.logger.debug( "Request for state" + "\nREQUEST: " + str(request) + "\nClient state: " + str(client_state) + "\nServer state: " + str(server_state) ) # current_app.logger.debug("Client State: "+ str(client_state) + \ # "\nChoice from client_state[screen]: " +str(choice)) if choice == "HOME": return_state.update(handle_get_state_home(auth.username)) elif choice == "SELECT_SAVEDSEQUENCES": return_state.update(handle_get_state_select_savedsequences(client_state, auth.username)) elif choice == "SELECT_RUNHISTORY": return_state.update(handle_get_state_select_runhistory(client_state, auth.username)) elif choice == "VIEW": return_state.update(handle_get_state_view(client_state, auth.username)) elif choice == "EDIT": return_state.update(handle_get_state_edit(client_state, auth.username)) elif choice == "RUN": return_state.update(handle_get_state_run(client_state, auth.username)) else: current_app.logger.debug("Unknown screen: %s" % str(choice)) raise Exception("Unknown screen: %s" % str(choice)) # current_app.logger.debug("Return state: " + str(return_state)) return jsonify(return_state)
def handle_get_state_run(client_state, username): ''' Function shall return the state for a Run Sequence state. Function expects a client state and a string username to be passed in. Function shall return the state for the Run Sequence state as a JSON object. ''' # Sync the client state with the run state if ((client_state["sequenceid"] != server_state["runstate"]["sequenceid"]) or (client_state["componentid"] != server_state["runstate"]["componentid"]) or (client_state["prompt"]["show"] != server_state["runstate"]["prompt"]["show"]) or ((client_state["prompt"].has_key("screen")) and (server_state["runstate"]["prompt"].has_key("screen")) and (client_state["prompt"]["screen"] != server_state["runstate"]["prompt"]["screen"]))): # Update the sequence and component IDs client_state["sequenceid"] = server_state["runstate"]["sequenceid"] client_state["componentid"] = server_state["runstate"][ "componentid"] # Update the prompt client_state["prompt"] = copy.copy( server_state["runstate"]["prompt"]) # Update the client state db.update_user_client_state(username, client_state) # Determine if we are the user running the system if username == server_state["runstate"]["username"]: # Enable or disable buttons sequencer_enabled = False pause_enabled = False #not server_state["runstate"]["runcomplete"] abort_enabled = not server_state["runstate"]["runcomplete"] else: # Enable or disable buttons sequencer_enabled = True pause_enabled = False abort_enabled = False # Return the state return { "buttons": [{ "type": "button", "id": "SEQUENCER", "enabled": sequencer_enabled }, { "type": "button", "id": "PAUSERUN", "enabled": pause_enabled }, { "type": "button", "id": "ABORTRUN", "enabled": abort_enabled }, { "type": "button", "id": "LOGOUT", "enabled": True }], "sequenceid": client_state["sequenceid"], "componentid": client_state["componentid"] }