def process( self ): """ Main method called by WebForm auto dispatcher to begin processing. Handles locating and loading a project based on the URL call. """ if self.driver_conf == None: self.__panic( "Missing DriverConf.py" , """Could not find module DriverConf.py in the slither directory. Please make sure that this file exists and has the appropriate permissions. """ ) # attempt to get the project binding dict if not hasattr( self.driver_conf, "projects" ): self.__panic( "Missing 'projects' dictionary.", """Could not find the 'projects' directory in DriverConf.py. Please make sure that the dictionary exists and properly defined. """ ) self.__project_dict = getattr( self.driver_conf, "projects" ) self.logger.writeDebug( "Loaded base projects dictionary.\nproject_dict = %s"%( self.__project_dict ) ) # parse the URL url_profile = self.__parse_url( os.environ.get( 'REQUEST_URI', '' ) ) # attempt to load the project ( project_profile, load_msg, tb ) = self.__load_project( url_profile ) if project_profile: try: self.logger.writeDebug( "Running project..." ) # dispatch the project output = project_profile['project'].run() change_cwd( self.__driver_path ) self.logger.writeDebug( "Printing result" ) #self.logger.writeEntry( "OUTPUT: %s"%(output[:500]) ) # output the results to the browser #sys.stdout.write( output ) sys.stdout.write( output ) except: # an error occured during dispatching sys.stdout = project_profile['project'].stdout_save error_msg = "Project '%s' experienced errors during execution.\n" % ( project_profile['project_name'] ) self.logger.writeError( error_msg ) change_cwd( self.__driver_path ) self.__panic( "Fatal project execution error.", error_msg, traceBack() ) else: sys.exit( 0 ) else: #error_msg = "One more problems encountered when loading the requested project.\n%s"%( load_msg ) self.logger.writeError( load_msg ) self.__panic( "Could not load project.", load_msg, tb )
def __load_state( self, state_profile ): """ Loads a state and returns a reference to the state object. """ # initialize the state to None state_profile[ 'state' ] = None error_msg = '' try: # check state properties if state_profile[ 'path' ] == '' or \ state_profile[ 'state_name' ] == '': raise LoadException( "Invalid state path %s or state module/class name '%s'."%( state_profile['path'], state_profile['state_name'] ) ) # change to state directory ( chdir_result, chdir_msg) = change_cwd( state_profile[ 'full_path' ] ) if not chdir_result: raise LoadException( "Full state path %s does not appear to be a valid or accessible directory. %s"%( state_profile['full_path'], chdir_msg ) ) # add the state path to the execution path Path.path.addDir( state_profile['full_path'] ) # import the state state_module = __import__( state_profile[ 'state_name' ] ) # load the state instance_code = "state = state_module.%s()"%( state_profile['state_name'] ) self.logger.writeEntry( "__load_state: Executing state instance code: %s"%( instance_code ), SYSTEM_LOG_DEBUG ) exec instance_code self.logger.writeEntry( "__load_state: State %s.%s successfully instantiated."%( state_profile['state_name'], state_profile['state_name'] ), SYSTEM_LOG_DEBUG ) # make sure that the class is a State instance if not isinstance( state, State ): raise LoadException( "Class %s.%s is not an instance of the State class."%( state_profile['state_name'] , state_profile['state_name'] ) ) # change back to project directory change_cwd( self.project_profile[ 'webroot' ] ) # init the project if necessary # (Note: this is a place holder for future expansion.) apply( state.init_state, (), state_profile ) state_profile[ 'state' ] = state return ( state_profile, "Successfully loaded state %s.%s."%( state_profile['state_name'], state_profile['state_name'] ) ) except LoadException, details: error_msg = "Invalid state properties.\nDetails: %s"%( details )
def __cookie_strategy( self, operation, user_profile=None ): """ Internal method that implements session management with cookies. It will use an ID stored in as a cookie to locate a UserProfile object. Oherwise, it will create a new UserProfile object and store the assigned unique ID as a cookie. """ # check directory (chdir_result, chdir_msg) = change_cwd( self.__user_profile_dir, check_only=1 ) if not chdir_result: self.logger.writeEntry( "User profile directory '%s' is not \ valid or accessible.\n%s"%( self.__user_profile_dir, chdir_msg ), SYSTEM_LOG_ERROR ) return UserProfile() self.logger.writeEntry("__cookie_strategy: cwd = %s"%( os.getcwd() ), SYSTEM_LOG_DEBUG ) cookie = self.Request.get_cookie( self.__user_profile_cookie_name ) if operation == 'load' and cookie != None: self.logger.writeEntry( "__cookie_strategy: cookie : %s"%( cookie ), SYSTEM_LOG_DEBUG ) self.logger.writeEntry( "__cookie_strategy: cookie value : %s"%( cookie.value ), SYSTEM_LOG_DEBUG ) up_file_name = os.path.join( self.__user_profile_dir, cookie.value ) try: user_profile_file = open( up_file_name, 'r' ) user_profile = cPickle.load( user_profile_file ) user_profile_file.close() self.logger.writeEntry( "__cookie_strategy: Successfully loaded user profile for session %s."%(cookie.value), SYSTEM_LOG_DEBUG ) return user_profile except: self.logger.writeEntry( "__cookie_strategy: Exceptions raised while loading user profile file '%s'. Details: %s"%(up_file_name, traceBack() ), SYSTEM_LOG_WARNING ) self.logger.writeEntry( "__cookie_strategy: Creating and returning a fresh UserProfile." ) return UserProfile() elif operation == 'load' and cookie == None: self.logger.writeEntry( "__cookie_strategy: First time that user has accessd project. Creating new UserProfile.", SYSTEM_LOG_DEBUG ) return UserProfile() elif operation == 'save' and isinstance( user_profile, UserProfile ) == 1: up_file_name = os.path.join( self.__user_profile_dir, 'UserProfile.'+ user_profile.getId() ) try: #save the file user_profile_file = open( up_file_name, 'w' ) cPickle.dump( user_profile , user_profile_file ) user_profile_file.close() #cookie = self.get_new_cookie() #cookie[ self.__user_profile_cookie_name ] = 'UserProfile.'+ user_profile.getId() #cookie[ self.__user_profile_cookie_name ]['path'] = self.__session_access_path #cookie[ self.__user_profile_cookie_name ]['domain'] = self.__session_access_domain #cookie[ self.__user_profile_cookie_name ]['expires'] = self.__session_expiration self.Response.set_cookie( self.__user_profile_cookie_name, 'UserProfile.'+ user_profile.getId(), self.__session_access_domain, self.__session_access_path, self.__session_expiration ) self.logger.writeEntry( "__cookie_strategy: User profile cookie set with name: UserProfile.%s"%( user_profile.getId() ), SYSTEM_LOG_DEBUG ) except: self.logger.writeEntry( "__vookie_strategy: Error occured while saving user profile file '%s'.\nDetails: %s"%( up_file_name, traceBack() ), SYSTEM_LOG_DEBUG ) else: self.logger.writeEntry( "__cookie_strategy: Did not know how to handle operation '%s'. Nothing done."%( operation ), SYSTEM_LOG_WARNING ) self.logger.writeEntry( "__cookie_strategy: user_profile = %s"%( user_profile ), SYSTEM_LOG_DEBUG ) pass
def run( self ): """ Main method called to dispatch stages and handle stage exceptions. """ # capture all data written to the standard output stream # so that it can be safely emitted #stdout_capture = StringIO.StringIO() stdout_capture = stdout_to_log( self.logger ) self.stdout_save = sys.stdout sys.stdout = stdout_capture # load the session self.logger.writeEntry( "Loading session...", SYSTEM_LOG_DEBUG ) self.user_profile = self.session( 'load' ) # bind the user profile to Request self.Request.session = self.user_profile self.state_exception = ( None, None ) self.trace_back = "" # load exception and plugin tables try: self.logger.writeEntry( "Loading exception and plugin tables...", SYSTEM_LOG_DEBUG ) self.load_exceptions() self.load_plugins() except: self.logger.writeEntry( "Error while loading plugins and/or exceptions.", SYSTEM_LOG_ERROR ) self.logger.writeEntry( "Attempting to continue executing the request.\nDetails: %s"%( traceBack() ), SYSTEM_LOG_ERROR ) self.trace_back = traceBack() ######################### # begin execution of call #error_flag = 0 if self.trace_back == "": try: self.logger.writeEntry( "Calling preprocess...", SYSTEM_LOG_DEBUG ) self.preprocess() except: self.logger.writeEntry( "Error occured executing project's preprocess method.", SYSTEM_LOG_ERROR ) self.logger.writeEntry( "No states will be loaded.\nDetails: %s"%( traceBack() ), SYSTEM_LOG_ERROR ) self.trace_back = traceBack() # run loop paramters loop_control = 'run' out = '' first_state_profile = self.parse_state_path( self.project_profile[ 'project_state_path' ] ) call_path = first_state_profile[ 'call_path' ] load_path = self.project_profile[ 'project_state_path' ] last_call_path = '' state_profile = None load_msg = '' loop_count = -1 # must start at -1 because it is called at teh top of the loop while( loop_control=='run' and self.trace_back == "" ): loop_count = loop_count + 1 # check loop count to make sure we are not in a cycle if loop_count > self.__max_transitions: self.logger.writeEntry( "Loop count exceeded maximum count.", SYSTEM_LOG_ERROR ) self.logger.writeEntry( "You might thave a cycle in your code. Calling project's render().", SYSTEM_LOG_ERROR ) out = self.render() break; # set params. for loading the state if last_call_path != call_path: self.logger.writeEntry( "Loading state: call_path '%s', last_call_path '%s'"%( call_path, last_call_path ), SYSTEM_LOG_DEBUG ) state_profile = self.load_state_module( load_path ) if state_profile == None: self.logger.writeEntry( "Could not load state; calling default project render().", SYSTEM_LOG_DEBUG ) out = self.render() break; elif state_profile[ 'method' ][0] == "_": # attempted to load a protectedor private method # reject and call default render self.logger.writeEntry( "Attempted to call protected/private method %s; \ default project render() called."%(state_profile[ 'method' ]), SYSTEM_LOG_WARNING ) out = self.render() break; try: # change cwd to the state object directory change_cwd( state_profile['full_path'] ) # capture the state profile prior to run # used later to detect state changes last_call_path = state_profile[ 'call_path' ] self.logger.writeEntry( "Setting last_call_path to %s."%( last_call_path ), SYSTEM_LOG_DEBUG ) self.logger.writeEntry( "Calling method %s()..."%(state_profile[ 'method' ]), SYSTEM_LOG_DEBUG ) # get a handle to the funtion (exceptions are raised if the function does not exist) func = getattr( state_profile[ 'state' ], state_profile[ 'method' ] ) # call the function out = apply( func, [], {} ) # cahnge cwd to back to project change_cwd( self.project_profile['webroot'] ) # no exeptions raised; clear last exception self.state_exception = ( None, None ) except StageProcessException, details: self.logger.writeEntry( "State %s raised StageProcessException."%( state_profile['state_name'] ), SYSTEM_LOG_DEBUG ) out = details break; except:
self.logger.writeEntry( "State %s scheduled; restarting call loop."%(state_profile['state'].getNextCallPath() ), SYSTEM_LOG_DEBUG ) # restart the loop to process new state continue; else: self.logger.writeEntry( "Nothing else to do; retruning default render page.", SYSTEM_LOG_DEBUG ) out = self.render() break; # change cwd back to project change_cwd( self.project_profile['webroot'] ) #if error_flag == 0: if self.trace_back == "": # call postprocess try: # reset the context self.logger.resetContext() self.logger.writeEntry( "Calling postprocess...", SYSTEM_LOG_DEBUG ) self.postprocess() except: self.logger.writeEntry( "Error occured while executing project's postprocess method. Renderig default page.\ \nDetails: %s"%( traceBack() ), SYSTEM_LOG_ERROR ) self.trace_back = traceBack()
def __load_project( self, url_profile ): """ Internal method used to load the properties of a project so that the project can be dispatched. """ try: tb = "" project_name = url_profile[ 'project_name' ] if project_name == "": raise LoadException( "No project name specified." ) # read proeprty from conf file project_profile = self.__project_dict.get( project_name, None ) if project_profile == None: raise LoadException( "No registration found for project name '%s'."%( project_name ) ) else: # at this point we have a prety good chance of loading the project project_profile[ 'project_name' ] = project_name project_profile[ 'project_state_path' ] = url_profile[ 'state_path' ] project_profile[ 'base_url' ] = url_profile[ 'base_url' ] # check project properties if project_profile.get( 'webroot', '' ) == '' or \ project_profile.get( 'project_module' , '' ) == '': raise LoadException( "Project '%s' missing valid entries for 'webroot' \ or 'project_module' properties."%( project_name ) ) # we assume that the project_class has the same name as the # project_module if the project_class property is not supplied. project_profile[ 'project_class' ] = project_profile.get( 'project_class', project_profile[ 'project_module' ] ) ( chdir_result, chdir_msg ) = change_cwd( project_profile.get( 'webroot', '' ) ) if not chdir_result: raise LoadException( "The registered path '%s' for project '%s' does \ not appear to be a valid or accessible. %s"%( project_profile[ 'webroot' ], project_name, chdir_msg ) ) self.logger.writeDebug( "cwd = %s"%(os.getcwd() ) ) #for p in sys.path: # self.logger.writeDebug( "%s"%(p) ) sys.path = [ "." ] + sys.path # add to the project profile some useful information project_profile[ "slither_driver_path" ] = self.__driver_path # import the Project file project_module = __import__( project_profile[ 'project_module' ] ) self.logger.writeDebug( "Imported project module!" ) # create new instance of the project project = None instance_code = "project = project_module.%s()"%( project_profile['project_class'] ) self.logger.writeDebug( "Executing instance_code : %s"%( instance_code ) ) exec instance_code self.logger.writeDebug( "Project '%s' successfully instantiated."%( project_name ) ) # make sure that this class is an instance of Project if not isinstance( project, Project ): raise LoadException( "Class %s.%s is not an instance of the Project class."%( project_profile['project_module'], project_profile['project_class'] ) ) project.init_project( project_profile = project_profile, argv = self.__argv[1:] ) # call the project's init method project.init() project_profile[ 'project' ] = project return ( project_profile , "Successfully loaded project '%s'."%( project_name ), "" ) except LoadException, details: error_msg = "Invalid project properties. %s" % ( details ) tb = ""
except AttributeError, details : error_msg = "Could not instantiate class '%s' for project \n \ name '%s'. Make sure the class name is correct in module '%s'."%( project_profile['project_class'], project_profile['project_name'], project_profile['project_module'], ) tb = traceBack() except: error_msg = "Unexpected error while loading project '%s'."%( project_name ) tb = traceBack() # post exception processing self.logger.writeError( error_msg + "Traceback: " + tb ) change_cwd( self.__driver_path ) return ( None, error_msg, tb ) def __parse_url( self, url ): """ Internal method used to parse the calling URL into sub pieces used to load the project and later the requested state. """ self.logger.writeDebug( "Parsing URL: %s"%( url ) ) url_property = {} url_property[ 'project_name' ] = ''
def process(self): """ Main method called by WebForm auto dispatcher to begin processing. Handles locating and loading a project based on the URL call. """ if self.driver_conf == None: self.__panic( "Missing DriverConf.py", """Could not find module DriverConf.py in the slither directory. Please make sure that this file exists and has the appropriate permissions. """ ) # attempt to get the project binding dict if not hasattr(self.driver_conf, "projects"): self.__panic( "Missing 'projects' dictionary.", """Could not find the 'projects' directory in DriverConf.py. Please make sure that the dictionary exists and properly defined. """ ) self.__project_dict = getattr(self.driver_conf, "projects") self.logger.writeDebug( "Loaded base projects dictionary.\nproject_dict = %s" % (self.__project_dict)) # parse the URL url_profile = self.__parse_url(os.environ.get('REQUEST_URI', '')) # attempt to load the project (project_profile, load_msg, tb) = self.__load_project(url_profile) if project_profile: try: self.logger.writeDebug("Running project...") # dispatch the project output = project_profile['project'].run() change_cwd(self.__driver_path) self.logger.writeDebug("Printing result") #self.logger.writeEntry( "OUTPUT: %s"%(output[:500]) ) # output the results to the browser #sys.stdout.write( output ) sys.stdout.write(output) except: # an error occured during dispatching sys.stdout = project_profile['project'].stdout_save error_msg = "Project '%s' experienced errors during execution.\n" % ( project_profile['project_name']) self.logger.writeError(error_msg) change_cwd(self.__driver_path) self.__panic("Fatal project execution error.", error_msg, traceBack()) else: sys.exit(0) else: #error_msg = "One more problems encountered when loading the requested project.\n%s"%( load_msg ) self.logger.writeError(load_msg) self.__panic("Could not load project.", load_msg, tb)
def __load_project(self, url_profile): """ Internal method used to load the properties of a project so that the project can be dispatched. """ try: tb = "" project_name = url_profile['project_name'] if project_name == "": raise LoadException("No project name specified.") # read proeprty from conf file project_profile = self.__project_dict.get(project_name, None) if project_profile == None: raise LoadException( "No registration found for project name '%s'." % (project_name)) else: # at this point we have a prety good chance of loading the project project_profile['project_name'] = project_name project_profile['project_state_path'] = url_profile[ 'state_path'] project_profile['base_url'] = url_profile['base_url'] # check project properties if project_profile.get( 'webroot', '' ) == '' or \ project_profile.get( 'project_module' , '' ) == '': raise LoadException( "Project '%s' missing valid entries for 'webroot' \ or 'project_module' properties." % (project_name)) # we assume that the project_class has the same name as the # project_module if the project_class property is not supplied. project_profile['project_class'] = project_profile.get( 'project_class', project_profile['project_module']) (chdir_result, chdir_msg) = change_cwd(project_profile.get('webroot', '')) if not chdir_result: raise LoadException( "The registered path '%s' for project '%s' does \ not appear to be a valid or accessible. %s" % (project_profile['webroot'], project_name, chdir_msg)) self.logger.writeDebug("cwd = %s" % (os.getcwd())) #for p in sys.path: # self.logger.writeDebug( "%s"%(p) ) sys.path = ["."] + sys.path # add to the project profile some useful information project_profile["slither_driver_path"] = self.__driver_path # import the Project file project_module = __import__(project_profile['project_module']) self.logger.writeDebug("Imported project module!") # create new instance of the project project = None instance_code = "project = project_module.%s()" % ( project_profile['project_class']) self.logger.writeDebug("Executing instance_code : %s" % (instance_code)) exec instance_code self.logger.writeDebug("Project '%s' successfully instantiated." % (project_name)) # make sure that this class is an instance of Project if not isinstance(project, Project): raise LoadException( "Class %s.%s is not an instance of the Project class." % (project_profile['project_module'], project_profile['project_class'])) project.init_project(project_profile=project_profile, argv=self.__argv[1:]) # call the project's init method project.init() project_profile['project'] = project return (project_profile, "Successfully loaded project '%s'." % (project_name), "") except LoadException, details: error_msg = "Invalid project properties. %s" % (details) tb = ""
name '%s'. Make sure the class name is correct in module '%s'." % ( project_profile['project_class'], project_profile['project_name'], project_profile['project_module'], ) tb = traceBack() except: error_msg = "Unexpected error while loading project '%s'." % ( project_name) tb = traceBack() # post exception processing self.logger.writeError(error_msg + "Traceback: " + tb) change_cwd(self.__driver_path) return (None, error_msg, tb) def __parse_url(self, url): """ Internal method used to parse the calling URL into sub pieces used to load the project and later the requested state. """ self.logger.writeDebug("Parsing URL: %s" % (url)) url_property = {} url_property['project_name'] = '' url_property['state_path'] = '' # split url based '/'