def recoverpassword(self, cancel=False, **data): """ This form should reset a password for a given userName/email and send a notification message to that email. """ template_specification = dict(mainContent="recover_password", title="Recover password", data=data) redirect = False if cherrypy.request.method == 'POST': if cancel: raise cherrypy.HTTPRedirect('/user') form = RecoveryForm() try: data = form.to_python(data) okmessage = self.user_service.reset_password(**data) basecontroller.set_info_message(okmessage) redirect = True except formencode.Invalid, excep: template_specification[ basecontroller.KEY_ERRORS] = excep.unpack_errors() redirect = False except UsernameException, excep1: self.logger.error("Could not reset password!") self.logger.exception(excep1) basecontroller.set_error_message(excep1.message) redirect = False
def getfiltereddatatypes(self, name, parent_div, tree_session_key, filters): """ Given the name from the input tree, the dataType required and a number of filters, return the available dataType that satisfy the conditions imposed. """ previous_tree = self.context.get_session_tree_for_key(tree_session_key) if previous_tree is None: base.set_error_message( "Adapter Interface not in session for filtering!") raise cherrypy.HTTPRedirect("/tvb?error=True") current_node = self._get_node(previous_tree, name) if current_node is None: raise Exception("Could not find node :" + name) datatype = current_node[ABCAdapter.KEY_DATATYPE] filters = json.loads(filters) availablefilter = json.loads( FilterChain.get_filters_for_type(datatype)) for i, filter_ in enumerate(filters[FILTER_FIELDS]): #Check for filter input of type 'date' as these need to be converted if filter_ in availablefilter and availablefilter[filter_][ FILTER_TYPE] == 'date': try: filter_ = string2date(filter_, False) filters[FILTER_VALUES][i] = filter_ except ValueError, excep: raise excep
def register(self, cancel=False, **data): """ This register form send an e-mail to the user and to the site admin. """ template_specification = dict(mainContent="register", title="Register", data=data) redirect = False if cherrypy.request.method == 'POST': if cancel: raise cherrypy.HTTPRedirect('/user') try: okmessage = self._create_user(**data) basecontroller.set_info_message(okmessage) redirect = True except formencode.Invalid, excep: template_specification[ basecontroller.KEY_ERRORS] = excep.unpack_errors() redirect = False except Exception, excep1: self.logger.error("Could not create user:"******"username"]) self.logger.exception(excep1) basecontroller.set_error_message( "We are very sorry, but we could not create your " + "user. Most probably is because it was impossible" + " to sent emails. Please try again later...") redirect = False
def create_new(self, cancel=False, **data): """ Create new user with data submitted from UI. """ if cancel: raise cherrypy.HTTPRedirect('/user/usermanagement') template_specification = dict(mainContent="create_new", title="Create New", data=data) redirect = False if cherrypy.request.method == 'POST': try: data[KEY_COMMENT] = "Created by administrator." # User is created by administrator, should be validated automatically, and credentials # should be sent to user by email. email_msg = """A TVB account was just created for you by an administrator. Your credentials are username=%s, password=%s.""" % ( data[KEY_USERNAME], data[KEY_PASSWORD]) self._create_user(email_msg=email_msg, validated=True, **data) basecontroller.set_info_message( "New user created successfully.") redirect = True except formencode.Invalid, excep: template_specification[ basecontroller.KEY_ERRORS] = excep.unpack_errors() except Exception, excep: self.logger.exceptrion(excep) basecontroller.set_error_message( "We are very sorry, but we could not create your " + "user. Most probably is because it was impossible" + " to sent emails. Please try again later...")
def deco(*a, **b): """Declare Function Decorator.""" if hasattr(cherrypy, base.KEY_SESSION): if base.KEY_PROJECT in cherrypy.session: return funct(*a, **b) base.set_error_message('You should first select a Project!') raise cherrypy.HTTPRedirect('/project/viewall')
def index(self, **data): """ Login page (with or without messages). """ template_specification = dict(mainContent="login", title="Login", data=data) if cherrypy.request.method == 'POST': form = LoginForm() try: data = form.to_python(data) username = data[KEY_USERNAME] password = data[KEY_PASSWORD] user = self.user_service.check_login(username, password) if user is not None: basecontroller.add2session(basecontroller.KEY_USER, user) basecontroller.set_info_message('Welcome ' + username) self.logger.debug("User " + username + " has just logged in!") if user.selected_project is not None: prj = user.selected_project prj = ProjectService().find_project(prj) self._mark_selected(prj) raise cherrypy.HTTPRedirect('/user/profile') else: basecontroller.set_error_message( 'Wrong username/password, or user not yet validated...' ) self.logger.debug("Wrong username " + username + " !!!") except formencode.Invalid, excep: template_specification[ basecontroller.KEY_ERRORS] = excep.unpack_errors()
def get_data_from_burst_configuration(self): """ Returns the model, integrator, connectivity and surface instances from the burst configuration. """ ### Read from session current burst-configuration burst_configuration = base.get_from_session(base.KEY_BURST_CONFIG) if burst_configuration is None: return None, None, None first_range = burst_configuration.get_simulation_parameter_value( 'first_range') second_range = burst_configuration.get_simulation_parameter_value( 'second_range') if ((first_range is not None and str(first_range).startswith(MODEL_PARAMETERS)) or (second_range is not None and str(second_range).startswith(MODEL_PARAMETERS))): base.set_error_message( "When configuring model parameters you are not allowed to specify range values." ) raise cherrypy.HTTPRedirect("/burst/") group = self.flow_service.get_algorithm_by_module_and_class( SIMULATOR_MODULE, SIMULATOR_CLASS)[1] simulator_adapter = self.flow_service.build_adapter_instance(group) try: params_dict = simulator_adapter.convert_ui_inputs( burst_configuration.get_all_simulator_values()[0], False) except Exception, excep: self.logger.exception(excep) base.set_error_message( "Some of the provided parameters have an invalid value.") raise cherrypy.HTTPRedirect("/burst/")
def settings(self, save_settings=False, **data): """Main settings page submit and get""" template_specification = dict( mainContent="../settings/system_settings", title="System Settings") if save_settings: try: form = SettingsForm() data = form.to_python(data) isrestart, isreset = self.settingsservice.save_settings(**data) if isrestart: thread = threading.Thread(target=self._restart_services, kwargs={'should_reset': isreset}) thread.start() bc.add2session(bc.KEY_IS_RESTART, True) bc.set_info_message( 'Please wait until TVB is restarted properly!') raise cherrypy.HTTPRedirect('/tvb') # Here we will leave the same settings page to be displayed. # It will continue reloading when CherryPy restarts. except formencode.Invalid, excep: template_specification[bc.KEY_ERRORS] = excep.unpack_errors() except InvalidSettingsException, excep: self.logger.error( 'Invalid settings! Exception %s was raised' % (str(excep))) bc.set_error_message(excep.message)
def deco(*a, **b): """ Allow to get the docstring back""" if hasattr(cherrypy, basecontroller.KEY_SESSION): if basecontroller.get_logged_user(): return func(*a, **b) basecontroller.set_error_message('Login Required!') raise cherrypy.HTTPRedirect('/user')
def _remove_project(self, project_id): """Private method for removing project.""" try: self.project_service.remove_project(project_id) except ServicesBaseException, exc: self.logger.error("Could not delete project!") self.logger.exception(exc) bc.set_error_message(exc.message)
def deco(*a, **b): """ Decorator for public method""" if hasattr(cherrypy, basecontroller.KEY_SESSION): user = basecontroller.get_logged_user() if (user is not None and user.is_administrator() ) or SettingsService.is_first_run(): return func(*a, **b) basecontroller.set_error_message( 'Only Administrators can access this application area!') raise cherrypy.HTTPRedirect('/tvb')
def get_data_for_param_sliders(self, connectivity_node_index, context_model_parameters): """ Method used only for handling the exception. """ try: return context_model_parameters.get_data_for_param_sliders(connectivity_node_index) except ValueError, excep: self.logger.info("All the model parameters that are configurable should be valid arrays or numbers.") self.logger.exception(excep) base.set_error_message("All the model parameters that are configurable should be valid arrays or numbers.") raise cherrypy.HTTPRedirect("/burst/")
def updatemetadata(self, **data): """ Submit MetaData edited for DataType(Group) or Operation(Group). """ try: self.project_service.update_metadata(data) except ServicesBaseException, excep: self.logger.error("Could not execute MetaData update!") self.logger.exception(excep) bc.set_error_message(excep.message) return excep.message
def projectupload(self, **data): """Upload Project from TVB ZIP.""" self.logger.debug("Uploading ..." + str(data)) try: upload_param = "uploadedfile" if upload_param in data and data[upload_param]: self.import_service.import_project_structure( data[upload_param], bc.get_logged_user().id) except ServicesBaseException, excep: self.logger.warning(excep.message) bc.set_error_message(excep.message)
def _update_figure(self, figure_id, **data): """ Updates the figure details to the given data. """ try: data = EditPreview().to_python(data) self.figure_service.edit_result_figure(figure_id, **data) base.set_info_message('Figure details updated successfully.') return True except formencode.Invalid, excep: self.logger.debug(excep) base.set_error_message(excep.message) return False
def validate(self, name): """ A link to this page will be sent to the administrator to validate the registration of each user. """ success = self.user_service.validate_user(name) if not success: basecontroller.set_error_message("Problem validating user:"******"!! Please check logs.") self.logger.error("Problem validating user " + name) else: basecontroller.set_info_message( "User Validated successfully and notification email sent!") raise cherrypy.HTTPRedirect('/tvb')
def create_stimulus(self): """ Creates a stimulus from the given data. """ try: context = base.get_from_session(KEY_SURFACE_CONTEXT) surface_stimulus_creator = self.get_creator_and_interface(SURFACE_STIMULUS_CREATOR_MODULE, SURFACE_STIMULUS_CREATOR_CLASS, StimuliSurface())[0] self.flow_service.fire_operation(surface_stimulus_creator, base.get_logged_user(), base.get_current_project().id, **context.equation_kwargs) base.set_info_message("The operation for creating the stimulus was successfully launched.") context.selected_stimulus = None except (NameError, ValueError, SyntaxError), _: base.set_error_message("The operation failed due to invalid parameter input.") return False
def viewall(self, create=False, page=1, selected_project_id=None, **_): """ Display all existent projects. Choose one project to work with. """ page = int(page) if cherrypy.request.method == 'POST' and create: raise cherrypy.HTTPRedirect('/project/editone') current_user_id = bc.get_logged_user().id ## Select project if user choose one. if selected_project_id is not None: try: selected_project = self.project_service.find_project( selected_project_id) self._mark_selected(selected_project) except ProjectServiceException, excep: self.logger.error(excep) self.logger.warning("Could not select project: " + str(selected_project_id)) bc.set_error_message("Could not select project: " + str(selected_project_id))
def execute_post(self, project_id, submit_url, success_url, step_key, algo_group, method_name=None, **data): """ Execute HTTP POST on a generic step.""" errors = None adapter_instance = self.flow_service.build_adapter_instance(algo_group) try: if method_name is not None: data['method_name'] = method_name result = self.flow_service.fire_operation(adapter_instance, base.get_logged_user(), project_id, **data) # Store input data in session, for informing user of it. step = self.flow_service.get_category_by_id(step_key) if not step.rawinput: self.context.add_adapter_to_session(None, None, copy.deepcopy(data)) if isinstance(adapter_instance, ABCDisplayer): if isinstance(result, dict): result[ base.KEY_OPERATION_ID] = adapter_instance.operation_id return result else: base.set_error_message( "Invalid result returned from Displayer! Dictionary is expected!" ) else: base.set_info_message(str(result)) raise cherrypy.HTTPRedirect(success_url) except formencode.Invalid, excep: errors = excep.unpack_errors()
def profile(self, logout=False, save=False, **data): """ Display current user's profile page. On POST: logout, or save password/email. """ if cherrypy.request.method == 'POST' and logout: raise cherrypy.HTTPRedirect('/user/logout') template_specification = dict(mainContent="profile", title="User Profile") if cherrypy.request.method == 'POST' and save: try: form = EditUserForm() data = form.to_python(data) user = basecontroller.get_logged_user() if KEY_PASSWORD in data and data[KEY_PASSWORD]: user.password = md5(data[KEY_PASSWORD]).hexdigest() if KEY_EMAIL in data and data[KEY_EMAIL]: user.email = data[KEY_EMAIL] old_password = None if 'old_password' in data and data['old_password']: old_password = md5(data['old_password']).hexdigest() self.user_service.edit_user(user, old_password) if old_password: basecontroller.set_info_message("Changes Submitted!") else: basecontroller.set_info_message( "Submitted! No password changed.") except formencode.Invalid, excep: template_specification[ basecontroller.KEY_ERRORS] = excep.unpack_errors() except UsernameException, excep: self.logger.exception(excep) user = basecontroller.get_logged_user() basecontroller.add2session( basecontroller.KEY_USER, self.user_service.get_user_by_id(user.id)) basecontroller.set_error_message( "Could not save changes. Probably wrong old password!!")
def start_dti_pipeline(self, cancel=False, start=False, **data): """ Prepare DTI Pipeline run. """ project_id = basecontroller.get_current_project().id if cherrypy.request.method == 'POST' and cancel: raise cherrypy.HTTPRedirect("/project/editstructure/" + str(project_id)) template_specification = dict( title="Import Connectivity", data=data, section_name='project', subsection_name='pipeline', mainContent="pipeline/get_connectivity", includedResources='project/included_resources') if cherrypy.request.method == 'POST' and start: form = ImportForm() try: data = form.to_python(data) service = DTIPipelineService(data['server_ip'], data['username']) current_project = basecontroller.get_current_project() current_user = basecontroller.get_logged_user() service.fire_pipeline(data['dti_scans'], current_project, current_user, data['threads_number']) okmessage = "Import Started! You will see results after few hours on Data Structure Page!" basecontroller.set_info_message(okmessage) raise cherrypy.HTTPRedirect("/project/editstructure/" + str(project_id)) except formencode.Invalid, excep: basecontroller.set_error_message( "Some parameters are invalid!") template_specification[ basecontroller.KEY_ERRORS] = excep.unpack_errors()
title="Create new project" if is_create else "Edit " + data["name"], editUsersEnabled=(current_user.username == data['administrator'])) try: if cherrypy.request.method == 'POST' and save: bc.remove_from_session(bc.KEY_PROJECT) bc.remove_from_session(bc.KEY_CACHED_SIMULATOR_TREE) self._persist_project(data, project_id, is_create, current_user) raise cherrypy.HTTPRedirect('/project/viewall') except formencode.Invalid, excep: self.logger.debug(str(excep)) template_specification[bc.KEY_ERRORS] = excep.unpack_errors() except ProjectServiceException, excep: self.logger.debug(str(excep)) bc.set_error_message(excep.message) raise cherrypy.HTTPRedirect('/project/viewall') all_users, members, pages = self.user_service.get_users_for_project( current_user.username, project_id) template_specification['usersList'] = all_users template_specification['usersMembers'] = [m.id for m in members] template_specification['usersPages'] = pages template_specification['usersCurrentPage'] = 1 return self.fill_default_attributes(template_specification, 'properties') @cherrypy.expose @using_template('project/project_members') @logged() def getmemberspage(self, page, project_id=None):
base.KEY_OPERATION_ID] = adapter_instance.operation_id return result else: base.set_error_message( "Invalid result returned from Displayer! Dictionary is expected!" ) else: base.set_info_message(str(result)) raise cherrypy.HTTPRedirect(success_url) except formencode.Invalid, excep: errors = excep.unpack_errors() except OperationException, excep1: self.logger.error("Error while executing a Launch procedure:" + excep1.message) self.logger.exception(excep1) base.set_error_message(excep1.message) previous_step = self.context.get_current_substep() should_reset = (previous_step is None or (base.KEY_ADAPTER not in data) or data[base.KEY_ADAPTER] != previous_step) template_specification = self.get_template_for_adapter( project_id, step_key, algo_group, submit_url, should_reset) if (errors is not None) and (template_specification is not None): template_specification[base.KEY_ERRORS] = errors template_specification[ base.KEY_OPERATION_ID] = adapter_instance.operation_id return template_specification def get_template_for_adapter(self, project_id, step_key,
class SurfaceStimulusController(SpatioTemporalController): """ Control layer for defining Stimulus entities on a cortical surface. """ def __init__(self): SpatioTemporalController.__init__(self) #if any field that starts with one of the following prefixes is changed # than the temporal equation chart will be redrawn self.temporal_fields_prefixes = ['temporal', 'min_tmp_x', 'max_tmp_x'] self.spatial_fields_prefixes = ['spatial', 'min_space_x', 'max_space_x'] def step_1(self): """ Used for generating the interface which allows the user to define a stimulus. """ context = base.get_from_session(KEY_SURFACE_CONTEXT) right_side_interface = self._get_stimulus_interface() selected_stimulus_gid = context.get_selected_stimulus() left_side_interface = self.get_select_existent_entities('Load Surface Stimulus:', StimuliSurface, selected_stimulus_gid) #add interface to session, needed for filters self.add_interface_to_session(left_side_interface, right_side_interface['inputList']) template_specification = dict(title="Spatio temporal - Surface stimulus") template_specification['existentEntitiesInputList'] = left_side_interface template_specification['mainContent'] = 'spatial/stimulus_surface_step1_main' template_specification.update(right_side_interface) template_specification['temporalEquationViewerUrl'] = '/spatial/stimulus/surface/get_temporal_equation_chart' template_specification['temporalFieldsPrefixes'] = json.dumps(self.temporal_fields_prefixes) template_specification['spatialEquationViewerUrl'] = '/spatial/stimulus/surface/get_spatial_equation_chart' template_specification['spatialFieldsPrefixes'] = json.dumps(self.spatial_fields_prefixes) template_specification['next_step_url'] = '/spatial/stimulus/surface/step_1_submit' return self.fill_default_attributes(template_specification) def step_2(self): """ Used for generating the interface which allows the user to define a stimulus. """ context = base.get_from_session(KEY_SURFACE_CONTEXT) selected_stimulus_gid = context.get_selected_stimulus() left_side_interface = self.get_select_existent_entities('Load Surface Stimulus:', StimuliSurface, selected_stimulus_gid) template_specification = dict(title="Spatio temporal - Surface stimulus") template_specification['existentEntitiesInputList'] = left_side_interface template_specification['mainContent'] = 'spatial/stimulus_surface_step2_main' template_specification['next_step_url'] = '/spatial/stimulus/surface/step_2_submit' template_specification['loadExistentEntityUrl'] = LOAD_EXISTING_URL template_specification['resetToDefaultUrl'] = RELOAD_DEFAULT_PAGE_URL template_specification['surfaceGID'] = context.get_session_surface() template_specification[base.KEY_PARAMETERS_CONFIG] = False template_specification['definedFocalPoints'] = json.dumps(context.focal_points_list) template_specification.update(self.display_surface(context.get_session_surface())) return self.fill_default_attributes(template_specification) def do_step(self, step_idx, from_step=None): """ Go to the step given by :param step_idx. In case the next step is the create one (3), we want to remain on the same step as before so that is handled differently depending on the :param from_step. """ if int(step_idx) == 1: return self.step_1() if int(step_idx) == 2: return self.step_2() if int(step_idx) == 3: if self.create_stimulus(): base.set_info_message("Successfully created a new stimulus.") if from_step == 2: return self.step_2() return self.step_1() @cherrypy.expose @using_template('base_template') @logged() def step_1_submit(self, next_step, do_reset=0, **kwargs): """ Any submit from the first step should be handled here. Update the context then go to the next step as required. In case a reset is needed create a clear context. """ if int(do_reset) == 1: new_context = SurfaceStimulusContext() base.add2session(KEY_SURFACE_CONTEXT, new_context) context = base.get_from_session(KEY_SURFACE_CONTEXT) if kwargs.get(SURFACE_PARAMETER) != context.get_session_surface(): context.set_focal_points('[]') context.update_eq_kwargs(kwargs) return self.do_step(next_step) @cherrypy.expose @using_template('base_template') @logged() def step_2_submit(self, next_step, **kwargs): """ Any submit from the second step should be handled here. Update the context and then do the next step as required. """ context = base.get_from_session(KEY_SURFACE_CONTEXT) submited_focal_points = kwargs['defined_focal_points'] context.set_focal_points(submited_focal_points) context.equation_kwargs[DataTypeMetaData.KEY_TAG_1] = kwargs[DataTypeMetaData.KEY_TAG_1] return self.do_step(next_step, 2) def create_stimulus(self): """ Creates a stimulus from the given data. """ try: context = base.get_from_session(KEY_SURFACE_CONTEXT) surface_stimulus_creator = self.get_creator_and_interface(SURFACE_STIMULUS_CREATOR_MODULE, SURFACE_STIMULUS_CREATOR_CLASS, StimuliSurface())[0] self.flow_service.fire_operation(surface_stimulus_creator, base.get_logged_user(), base.get_current_project().id, **context.equation_kwargs) base.set_info_message("The operation for creating the stimulus was successfully launched.") context.selected_stimulus = None except (NameError, ValueError, SyntaxError), _: base.set_error_message("The operation failed due to invalid parameter input.") return False except Exception, ex: base.set_error_message(ex.message) return False
def editresultfigures(self, remove_figure=False, rename_session=False, remove_session=False, **data): """ This method knows how to handle the following actions: remove figure, update figure, remove session and update session. """ project = base.get_current_project() user = base.get_logged_user() redirect_url = '/project/figure/displayresultfigures' if "selected_session" in data and data[ "selected_session"] is not None and len( data["selected_session"]): redirect_url += '/' + data["selected_session"] del data["selected_session"] figure_id = None if "figure_id" in data: figure_id = data["figure_id"] del data["figure_id"] if cherrypy.request.method == 'POST' and rename_session: successfully_updated = True if "old_session_name" in data and "new_session_name" in data: figures_dict, _ = self.figure_service.retrieve_result_figures( project, user, data["old_session_name"]) for _key, value in figures_dict.iteritems(): for figure in value: new_data = { "name": figure.name, "session_name": data["new_session_name"] } success = self._update_figure(figure.id, **new_data) if not success: successfully_updated = False if successfully_updated: base.set_info_message( "The session was successfully updated!") else: base.set_error_message( "The session was not successfully updated! " "There could be some figures that still refer to the old session." ) elif cherrypy.request.method == 'POST' and remove_session: successfully_removed = True if "old_session_name" in data: figures_dict, _ = self.figure_service.retrieve_result_figures( project, user, data["old_session_name"]) for _key, value in figures_dict.iteritems(): for figure in value: success = self.figure_service.remove_result_figure( figure.id) if not success: successfully_removed = False if successfully_removed: base.set_info_message( "The session was removed successfully!") else: base.set_error_message( "The session was not entirely removed!") elif cherrypy.request.method == 'POST' and remove_figure and figure_id is not None: success = self.figure_service.remove_result_figure(figure_id) if success: base.set_info_message("Figure removed successfully!") else: base.set_error_message("Figure could not be removed!") elif figure_id is not None: self._update_figure(figure_id, **data) raise cherrypy.HTTPRedirect(redirect_url)