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") user = common.get_logged_user() if cherrypy.request.method == "POST" and save: try: form = EditUserForm() data = form.to_python(data) if data.get(KEY_PASSWORD): user.password = md5(data[KEY_PASSWORD]).hexdigest() if data.get(KEY_EMAIL): user.email = data[KEY_EMAIL] old_password = None if data.get("old_password"): old_password = md5(data["old_password"]).hexdigest() self.user_service.edit_user(user, old_password) if old_password: common.set_info_message("Changes Submitted!") else: common.set_info_message("Submitted! No password changed.") except formencode.Invalid, excep: template_specification[common.KEY_ERRORS] = excep.unpack_errors() except UsernameException, excep: self.logger.exception(excep) user = common.get_logged_user() common.add2session(common.KEY_USER, self.user_service.get_user_by_id(user.id)) common.set_error_message("Could not save changes. Probably wrong old password!!")
def execute_post(self, project_id, submit_url, step_key, algorithm, **data): """ Execute HTTP POST on a generic step.""" errors = None adapter_instance = ABCAdapter.build_adapter(algorithm) try: form = adapter_instance.get_form()(project_id=project_id) if 'fill_defaults' in data: form.fill_from_post_plus_defaults(data) else: form.fill_from_post(data) view_model = None if form.validate(): try: view_model = form.get_view_model()() form.fill_trait(view_model) self.context.add_view_model_to_session(view_model) except NotImplementedError: self.logger.exception("Form and/or ViewModel not fully implemented for " + str(form)) raise InvalidFormValues("Invalid form inputs! Could not find a model for this form!", error_dict=form.get_errors_dict()) else: raise InvalidFormValues("Invalid form inputs! Could not fill algorithm from the given inputs!", error_dict=form.get_errors_dict()) adapter_instance.submit_form(form) if issubclass(type(adapter_instance), ABCDisplayer): adapter_instance.current_project_id = project_id adapter_instance.user_id = common.get_logged_user().id result = adapter_instance.launch(view_model) if isinstance(result, dict): return result else: common.set_error_message("Invalid result returned from Displayer! Dictionary is expected!") return {} result = self.operation_services.fire_operation(adapter_instance, common.get_logged_user(), project_id, view_model=view_model) if isinstance(result, list): result = "Launched %s operations." % len(result) common.set_important_message(str(result)) except formencode.Invalid as excep: errors = excep.unpack_errors() common.set_error_message("Invalid form inputs") self.logger.warning("Invalid form inputs %s" % errors) except (OperationException, LaunchException, TraitValueError) as excep1: self.logger.exception("Error while executing a Launch procedure:" + excep1.message) common.set_error_message(excep1.message) except InvalidFormValues as excep2: message, errors = excep2.display_full_errors() common.set_error_message(message) self.logger.warning("%s \n %s" % (message, errors)) template_specification = self.get_template_for_adapter(project_id, step_key, algorithm, submit_url) if (errors is not None) and (template_specification is not None): template_specification[common.KEY_ERRORS] = errors return template_specification
def execute_post(self, project_id, submit_url, step_key, algorithm, **data): """ Execute HTTP POST on a generic step.""" errors = None adapter_instance = ABCAdapter.build_adapter(algorithm) try: form = adapter_instance.get_form()(project_id=project_id) form.fill_from_post(data) view_model = None if form.validate(): try: view_model = form.get_view_model()() form.fill_trait(view_model) except NotImplementedError: raise formencode.Invalid("Could not find a model for this form!", {}, None, error_dict=form.get_errors_dict()) else: raise formencode.Invalid("Could not fill algorithm from the given inputs!", {}, None, error_dict=form.get_errors_dict()) adapter_instance.submit_form(form) if issubclass(type(adapter_instance), ABCDisplayer): adapter_instance.current_project_id = project_id adapter_instance.user_id = common.get_logged_user().id result = adapter_instance.launch(view_model) if isinstance(result, dict): return result else: common.set_error_message("Invalid result returned from Displayer! Dictionary is expected!") return {} result = self.flow_service.fire_operation(adapter_instance, common.get_logged_user(), project_id, view_model=view_model) # 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(result, list): result = "Launched %s operations." % len(result) common.set_important_message(str(result)) except formencode.Invalid as excep: errors = excep.unpack_errors() common.set_error_message("Invalid form inputs") self.logger.warning("Invalid form inputs %s" % errors) except OperationException as excep1: self.logger.exception("Error while executing a Launch procedure:" + excep1.message) common.set_error_message(excep1.message) previous_step = self.context.get_current_substep() should_reset = previous_step is None or data.get(common.KEY_ADAPTER) != previous_step template_specification = self.get_template_for_adapter(project_id, step_key, algorithm, submit_url, should_reset) if (errors is not None) and (template_specification is not None): template_specification[common.KEY_ERRORS] = errors template_specification[common.KEY_OPERATION_ID] = adapter_instance.operation_id return template_specification
def index(self): current_user_id = common.get_logged_user().id # In case the number of dynamics gets big we should add a filter in the ui. dynamics = dao.get_dynamics_for_user(current_user_id) if not dynamics: return self.no_dynamics_page() burst_config = common.get_from_session(common.KEY_BURST_CONFIG) des = SerializationManager(burst_config) connectivity = des.get_connectivity() if connectivity is None: msg = 'You have to select a connectivity before setting up the region Model. ' common.set_error_message(msg) raise ValueError(msg) params = ConnectivityViewer.get_connectivity_parameters(connectivity) params.update({ 'title': 'Model parameters', 'mainContent': 'burst/model_param_region', 'isSingleMode': True, 'submit_parameters_url': '/burst/modelparameters/regions/submit_model_parameters', 'dynamics': dynamics, 'dynamics_json': self._dynamics_json(dynamics), 'initial_dynamic_ids': json.dumps(burst_config.dynamic_ids) }) return self.fill_default_attributes(params, 'regionmodel')
def index(self): current_user_id = common.get_logged_user().id # In case the number of dynamics gets big we should add a filter in the ui. dynamics = dao.get_dynamics_for_user(current_user_id) if not dynamics: return self.no_dynamics_page() burst_config = common.get_from_session(common.KEY_BURST_CONFIG) des = SerializationManager(burst_config) connectivity = des.get_connectivity() params = ConnectivityViewer.get_connectivity_parameters(connectivity) params.update({ 'title': 'Model parameters', 'mainContent': 'burst/model_param_region', 'isSingleMode': True, 'submit_parameters_url': '/burst/modelparameters/regions/submit_model_parameters', 'dynamics': dynamics, 'dynamics_json': self._dynamics_json(dynamics), 'initial_dynamic_ids': json.dumps(burst_config.dynamic_ids) }) return self.fill_default_attributes(params, 'regionmodel')
def create_stimulus(self): """ Creates a stimulus from the given data. """ try: current_surface_stim = common.get_from_session(KEY_SURFACE_STIMULI) surface_stimulus_creator = ABCAdapter.build_adapter_from_class( SurfaceStimulusCreator) self.operation_service.fire_operation( surface_stimulus_creator, common.get_logged_user(), common.get_current_project().id, view_model=current_surface_stim) common.set_important_message( "The operation for creating the stimulus was successfully launched." ) except (NameError, ValueError, SyntaxError): common.set_error_message( "The operation failed due to invalid parameter input.") return False except Exception as ex: common.set_error_message(ex) return False return True
def execute_post(self, project_id, submit_url, step_key, algorithm, **data): """ Execute HTTP POST on a generic step.""" errors = None adapter_instance = ABCAdapter.build_adapter(algorithm) try: result = self.flow_service.fire_operation(adapter_instance, common.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[common.KEY_OPERATION_ID] = adapter_instance.operation_id return result else: common.set_error_message("Invalid result returned from Displayer! Dictionary is expected!") else: if isinstance(result, list): result = "Launched %s operations." % len(result) common.set_important_message(str(result)) except formencode.Invalid, excep: errors = excep.unpack_errors()
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 = common.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 as excep: self.logger.error(excep) self.logger.warning("Could not select project: " + str(selected_project_id)) common.set_error_message("Could not select project: " + str(selected_project_id)) # Prepare template response prjs, pages_no = self.project_service.retrieve_projects_for_user( current_user_id, page) template_specification = dict(mainContent="project/viewall", title="Available TVB Projects", projectsList=prjs, page_number=page, total_pages=pages_no) return self.fill_default_attributes(template_specification, 'list')
def usermanagement(self, cancel=False, page=1, do_persist=False, **data): """ Display a table used for user management. """ if cancel: raise cherrypy.HTTPRedirect('/user/profile') page = int(page) if cherrypy.request.method == 'POST' and do_persist: not_deleted = 0 for key in data: user_id = int(key.split('_')[1]) if 'delete_' in key: self.user_service.delete_user(user_id) if ("role_" in key) and not (("delete_" + str(user_id)) in data): valid = ("validate_" + str(user_id)) in data user = self.user_service.get_user_by_id(user_id) user.role = data[key] user.validated = valid self.user_service.edit_user(user) not_deleted += 1 # The entire current page was deleted, go to previous page if not_deleted == 0 and page > 1: page -= 1 admin_ = common.get_logged_user().username user_list, pages_no = self.user_service.retrieve_all_users(admin_, page) template_specification = dict(mainContent="user_management", title="Users management", page_number=page, total_pages=pages_no, userList=user_list, allRoles=UserService.USER_ROLES, data={}) return self.fill_default_attributes(template_specification)
def submit(self, dynamic_gid, dynamic_name): if dao.get_dynamic_by_name(dynamic_name): return {'saved': False, 'msg': 'There is another configuration with the same name'} dynamic = self.get_cached_dynamic(dynamic_gid) model = dynamic.model integrator = dynamic.integrator model_parameters = [] for name in model.ui_configurable_parameters: value = getattr(model, name)[0] model_parameters.append((name, value)) entity = tvb.core.entities.model.Dynamic( dynamic_name, common.get_logged_user().id, model.__class__.__name__, json.dumps(model_parameters), integrator.__class__.__name__, None # todo: serialize integrator parameters # json.dumps(integrator.raw_ui_integrator_parameters) ) dao.store_entity(entity) return {'saved': True}
def render_adapter_form(self, adapter_form, is_callout=False): show_online_help = common.get_logged_user().is_online_help_active() return { 'adapter_form': adapter_form, 'showOnlineHelp': show_online_help, 'isCallout': is_callout }
def storeresultfigure(self, img_type, **kwargs): """Create preview for current displayed canvas and store image in current session, for future comparison.""" project = common.get_current_project() user = common.get_logged_user() suggested_name = kwargs.get("suggestedName") self.figure_service.store_result_figure(project, user, img_type, kwargs['export_data'], suggested_name)
def execute_post(self, project_id, submit_url, step_key, algorithm, **data): """ Execute HTTP POST on a generic step.""" errors = None adapter_instance = ABCAdapter.build_adapter(algorithm) try: result = self.flow_service.fire_operation(adapter_instance, common.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[common. KEY_OPERATION_ID] = adapter_instance.operation_id return result else: common.set_error_message( "Invalid result returned from Displayer! Dictionary is expected!" ) else: if isinstance(result, list): result = "Launched %s operations." % len(result) common.set_important_message(str(result)) except formencode.Invalid, excep: errors = excep.unpack_errors()
def launch_burst(self, launch_mode, burst_name, **data): """ Do the actual burst launch, using the configuration saved in current session. :param launch_mode: new/branch/continue :param burst_name: user-given burst name. It can be empty (case in which we will fill with simulation_x) :param data: kwargs for simulation input parameters. """ data = json.loads(data['simulator_parameters']) burst_config = common.get_from_session(common.KEY_BURST_CONFIG) ## Validate new burst-name if launch_mode == LAUNCH_NEW and burst_name != 'none_undefined': validation_result = self._is_burst_name_ok(burst_name) if validation_result is True: burst_config.name = burst_name else: return {'error': validation_result} ## Fill all parameters user_id = common.get_logged_user().id data[common.KEY_ADAPTER] = self.cached_simulator_algorithm_id burst_config.update_simulator_configuration(data) burst_config.fk_project = common.get_current_project().id ## Do the asynchronous launch try: burst_id, burst_name = self.burst_service.launch_burst(burst_config, 0, self.cached_simulator_algorithm_id, user_id, launch_mode) return {'id': burst_id, 'name': burst_name} except BurstServiceException, e: self.logger.exception("Could not launch burst!") return {'error': e.message}
def submit(self, dynamic_gid, dynamic_name): if dao.get_dynamic_by_name(dynamic_name): return { 'saved': False, 'msg': 'There is another configuration with the same name' } dynamic = self.get_cached_dynamic(dynamic_gid) model = dynamic.model integrator = dynamic.integrator model_parameters = [] for name in model.ui_configurable_parameters: value = getattr(model, name)[0] model_parameters.append((name, value)) entity = model_burst.Dynamic( dynamic_name, common.get_logged_user().id, model.__class__.__name__, json.dumps(model_parameters), integrator.__class__.__name__, None # todo: serialize integrator parameters # json.dumps(integrator.raw_ui_integrator_parameters) ) dao.store_entity(entity) return {'saved': True}
def index(self): current_user_id = common.get_logged_user().id # In case the number of dynamics gets big we should add a filter in the ui. dynamics = dao.get_dynamics_for_user(current_user_id) if not dynamics: return self.no_dynamics_page() burst_config = common.get_from_session(common.KEY_BURST_CONFIG) des = SerializationManager(burst_config) connectivity = des.get_connectivity() params = ConnectivityViewer.get_connectivity_parameters(connectivity) params.update( { "title": "Model parameters", "mainContent": "burst/model_param_region", "isSingleMode": True, "submit_parameters_url": "/burst/modelparameters/regions/submit_model_parameters", "dynamics": dynamics, "dynamics_json": self._dynamics_json(dynamics), "initial_dynamic_ids": json.dumps(burst_config.dynamic_ids), } ) return self.fill_default_attributes(params, "regionmodel")
def launch_burst(self, launch_mode, burst_name, **data): """ Do the actual burst launch, using the configuration saved in current session. :param launch_mode: new/branch/continue :param burst_name: user-given burst name. It can be empty (case in which we will fill with simulation_x) :param data: kwargs for simulation input parameters. """ data = json.loads(data['simulator_parameters']) burst_config = common.get_from_session(common.KEY_BURST_CONFIG) ## Validate new burst-name if launch_mode == LAUNCH_NEW and burst_name != 'none_undefined': validation_result = self._is_burst_name_ok(burst_name) if validation_result is True: burst_config.name = burst_name else: return {'error': validation_result} ## Fill all parameters user_id = common.get_logged_user().id data[common.KEY_ADAPTER] = self.cached_simulator_algorithm.id burst_config.update_simulator_configuration(data) burst_config.fk_project = common.get_current_project().id ## Do the asynchronous launch try: burst_id, burst_name = self.burst_service.launch_burst( burst_config, 0, self.cached_simulator_algorithm.id, user_id, launch_mode) return {'id': burst_id, 'name': burst_name} except BurstServiceException as e: self.logger.exception("Could not launch burst!") return {'error': e.message}
def store_exploration_section(self, val_range, step, dt_group_guid): """ Launching method for further simulations. """ range_list = [float(num) for num in val_range.split(",")] step_list = [float(num) for num in step.split(",")] datatype_group_ob = ProjectService().get_datatypegroup_by_gid(dt_group_guid) operation_grp = datatype_group_ob.parent_operation_group operation_obj = self.flow_service.load_operation(datatype_group_ob.fk_from_operation) parameters = json.loads(operation_obj.parameters) range1name, range1_dict = json.loads(operation_grp.range1) range2name, range2_dict = json.loads(operation_grp.range2) parameters[RANGE_PARAMETER_1] = range1name parameters[RANGE_PARAMETER_2] = range2name ##change the existing simulator parameters to be min max step types range1_dict = {constants.ATT_MINVALUE: range_list[0], constants.ATT_MAXVALUE: range_list[1], constants.ATT_STEP: step_list[0]} range2_dict = {constants.ATT_MINVALUE: range_list[2], constants.ATT_MAXVALUE: range_list[3], constants.ATT_STEP: step_list[1]} parameters[range1name] = json.dumps(range1_dict) # this is for the x axis parameter parameters[range2name] = json.dumps(range2_dict) # this is for the y axis parameter OperationService().group_operation_launch(common.get_logged_user().id, common.get_current_project().id, operation_obj.algorithm.id, operation_obj.algorithm.fk_category, datatype_group_ob, **parameters) return [True, 'Stored the exploration material successfully']
def index(self): current_user_id = common.get_logged_user().id # In case the number of dynamics gets big we should add a filter in the ui. dynamics = dao.get_dynamics_for_user(current_user_id) if not dynamics: return self.no_dynamics_page() sim_config = common.get_from_session(common.KEY_SIMULATOR_CONFIG) connectivity = sim_config.connectivity if connectivity is None: msg = 'You have to select a connectivity before setting up the region Model. ' common.set_error_message(msg) raise ValueError(msg) current_project = common.get_current_project() file_handler = FilesHelper() conn_idx = dao.get_datatype_by_gid(connectivity.hex) conn_path = file_handler.get_project_folder(current_project, str(conn_idx.fk_from_operation)) params = ConnectivityViewer.get_connectivity_parameters(conn_idx, conn_path) burst_config = common.get_from_session(common.KEY_BURST_CONFIG) params.update({ 'title': 'Model parameters', 'mainContent': 'burst/model_param_region', 'isSingleMode': True, 'submit_parameters_url': '/burst/modelparameters/regions/submit_model_parameters', 'dynamics': dynamics, 'dynamics_json': self._dynamics_json(dynamics), 'initial_dynamic_ids': burst_config.dynamic_ids }) return self.fill_default_attributes(params, 'regionmodel')
def invokeadaptermethod(self, adapter_id, method_name, **data): """ Public web method, to be used when invoking specific methods from external Adapters/Algorithms. """ algo_group = self.flow_service.get_algo_group_by_identifier(adapter_id) try: adapter_instance = self.flow_service.build_adapter_instance(algo_group) result = self.flow_service.fire_operation(adapter_instance, common.get_logged_user(), common.get_current_project().id, method_name, **data) common.set_info_message("Submit OK!") if isinstance(adapter_instance, ABCDisplayer) and isinstance(result, dict): common.pop_message_from_session() result[ABCDisplayer.KEY_IS_ADAPTER] = True result[common.KEY_DISPLAY_MENU] = True result[common.KEY_OPERATION_ID] = adapter_instance.operation_id result[common.KEY_ADAPTER] = adapter_id if KEY_CONTROLLS not in result: result[KEY_CONTROLLS] = None self._populate_section(algo_group, result) return self.fill_default_attributes(result, algo_group.displayname) except OperationException, excep: common.set_warning_message('Problem when submitting data!') self.logger.error("Invalid method, or wrong parameters when invoking external method on post!") self.logger.exception(excep)
def invokeadaptermethod(self, adapter_id, method_name, **data): """ Public web method, to be used when invoking specific methods from external Adapters/Algorithms. """ algo_group = self.flow_service.get_algo_group_by_identifier(adapter_id) try: adapter_instance = self.flow_service.build_adapter_instance( algo_group) result = self.flow_service.fire_operation( adapter_instance, common.get_logged_user(), common.get_current_project().id, method_name, **data) common.set_info_message("Submit OK!") if isinstance(adapter_instance, ABCDisplayer) and isinstance( result, dict): common.pop_message_from_session() result[ABCDisplayer.KEY_IS_ADAPTER] = True result[common.KEY_DISPLAY_MENU] = True result[common.KEY_OPERATION_ID] = adapter_instance.operation_id result[common.KEY_ADAPTER] = adapter_id if KEY_CONTROLLS not in result: result[KEY_CONTROLLS] = None self._populate_section(algo_group, result) return self.fill_default_attributes(result, algo_group.displayname) except OperationException, excep: common.set_warning_message('Problem when submitting data!') self.logger.error( "Invalid method, or wrong parameters when invoking external method on post!" ) self.logger.exception(excep)
def __call__(self, function, args, keywords): """Call *function*, tracing its arguments and return value. :arg tuple args: the positional arguments for *function* :arg dict keywords: the keyword arguments for *function* :return: the value returned by calling *function* with positional arguments *args* and keyword arguments *keywords* .. warning:: This method does **not** perform a level check, and delegates *directly* to :meth:`logging.Logger.handle`. The caller is expected to perform the level check prior to calling this method. .. note:: If the return value of *function* is a `generator iterator <https://docs.python.org/3/glossary.html#term-generator-iterator>`_, then this method returns *value* wrapped in a :class:`_GeneratorIteratorTracingProxy` object to provide the ``yield`` and ``StopIteration`` tracing support. """ try: logged_user = get_logged_user() except Exception: logged_user = None gid = logged_user.gid if logged_user is not None else "" self.logger.setLevel(TRACE) self.logger.log(TRACE, "USER: {} | METHOD: {} | PARAMS: *{} **{}".format(gid, repr(function), args, keywords)) value = function(*args, **keywords) return (_GeneratorIteratorTracingProxy(function, value, self._logger) if isgenerator(value) else value)
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="user/profile", title="User Profile") user = common.get_logged_user() if cherrypy.request.method == 'POST' and save: try: form = EditUserForm() data = form.to_python(data) if data.get(KEY_PASSWORD): user.password = hash_password(data[KEY_PASSWORD]) if data.get(KEY_EMAIL): user.email = data[KEY_EMAIL] old_password = None if data.get('old_password'): old_password = hash_password(data['old_password']) self.user_service.edit_user(user, old_password) if old_password: common.set_info_message("Changes Submitted!") else: common.set_info_message("Submitted! No password changed.") except formencode.Invalid as excep: template_specification[ common.KEY_ERRORS] = excep.unpack_errors() except UsernameException as excep: self.logger.exception(excep) user = common.get_logged_user() common.add2session(common.KEY_USER, self.user_service.get_user_by_id(user.id)) common.set_error_message( "Could not save changes. Probably wrong old password!!") else: # Update session user since disk size might have changed from last time to profile. user = self.user_service.get_user_by_id(user.id) common.add2session(common.KEY_USER, user) template_specification['user_used_disk_human'] = format_bytes_human( self.user_service.compute_user_generated_disk_size(user.id)) return self.fill_default_attributes(template_specification)
def deco(*a, **b): if hasattr(cherrypy, common.KEY_SESSION): user = common.get_logged_user() if user is not None and user.is_administrator( ) or TvbProfile.is_first_run(): return func(*a, **b) raise common.NotAuthenticated( 'Only Administrators can access this application area!', redirect_url='/tvb')
def create_stimulus(self): """ Creates a stimulus from the given data. """ current_stimulus_region = common.get_from_session(KEY_REGION_STIMULUS) region_stimulus_creator = ABCAdapter.build_adapter_from_class(RegionStimulusCreator) self.flow_service.fire_operation(region_stimulus_creator, common.get_logged_user(), common.get_current_project().id, view_model=current_stimulus_region) common.set_important_message("The operation for creating the stimulus was successfully launched.")
def storeresultfigure(self, img_type, **kwargs): """Create preview for current displayed canvas and store image in current session, for future comparison.""" project = common.get_current_project() user = common.get_logged_user() operation_id = kwargs.get("operationId") suggested_name = kwargs.get("suggestedName") self.figure_service.store_result_figure(project, user, img_type, kwargs['export_data'], image_name=suggested_name, operation_id=operation_id)
def switch_online_help(self): """ Switch flag that displays online helps """ user = common.get_logged_user() # Change OnlineHelp Active flag and save user user.switch_online_help_state() self.user_service.edit_user(user) raise cherrypy.HTTPRedirect("/user/profile")
def getmemberspage(self, page, project_id=None): """Retrieve a new page of Project members.""" current_name = common.get_logged_user().username all_users, members, _ = self.user_service.get_users_for_project(current_name, project_id, int(page)) edit_enabled = True if project_id is not None: current_project = self.project_service.find_project(project_id) edit_enabled = (current_name == current_project.administrator.username) return dict(usersList=all_users, usersMembers=[m.id for m in members], usersCurrentPage=page, editUsersEnabled=edit_enabled)
def create_local_connectivity(self, **kwargs): """ Used for creating and storing a local connectivity. """ current_lconn = common.get_from_session(KEY_LCONN) local_connectivity_creator = ABCAdapter.build_adapter_from_class(LocalConnectivityCreator) self.operation_service.fire_operation(local_connectivity_creator, common.get_logged_user(), common.get_current_project().id, view_model=current_lconn) common.set_important_message("The operation for creating the local connectivity was successfully launched.") return self.step_1()
def editone(self, project_id=None, cancel=False, save=False, delete=False, **data): """ Create or change Project. When project_id is empty we create a new entity, otherwise we are to edit and existent one. """ if cherrypy.request.method == 'POST' and cancel: raise cherrypy.HTTPRedirect('/project') if cherrypy.request.method == 'POST' and delete: self._remove_project(project_id) raise cherrypy.HTTPRedirect('/project/viewall') current_user = common.get_logged_user() is_create = False if project_id is None or not int(project_id): is_create = True data["administrator"] = current_user.display_name admin_username = current_user.username else: current_project = self.project_service.find_project(project_id) if not save: # Only when we do not have submitted data, # populate fields with initial values for edit. data = dict(name=current_project.name, description=current_project.description) data["administrator"] = current_project.administrator.display_name admin_username = current_project.administrator.username self._mark_selected(current_project) data["project_id"] = project_id template_specification = dict(mainContent="project/editone", data=data, isCreate=is_create, title="Create new project" if is_create else "Edit " + data["name"], editUsersEnabled=(current_user.username == admin_username)) try: if cherrypy.request.method == 'POST' and save: data = EditForm().to_python(data) saved_project = self.project_service.store_project(current_user, is_create, project_id, **data) if StorageInterface.encryption_enabled() and is_create: project_folder = StorageInterface().get_project_folder(saved_project.name) StorageInterface.sync_folders(project_folder) shutil.rmtree(project_folder) self._mark_selected(saved_project) raise cherrypy.HTTPRedirect('/project/viewall') except formencode.Invalid as excep: self.logger.debug(str(excep)) template_specification[common.KEY_ERRORS] = excep.unpack_errors() except ProjectServiceException as excep: self.logger.debug(str(excep)) common.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')
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 = common.get_current_project() user = common.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: common.set_info_message("The session was successfully updated!") else: common.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: common.set_info_message("The session was removed successfully!") else: common.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: common.set_info_message("Figure removed successfully!") else: common.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)
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]: import_service = ImportService() import_service.import_project_structure(data[upload_param], common.get_logged_user().id) except ServicesBaseException, excep: self.logger.warning(excep.message) common.set_error_message(excep.message)
def create_stimulus(self): """ Creates a stimulus from the given data. """ context = common.get_from_session(KEY_REGION_CONTEXT) local_connectivity_creator = self.get_creator_and_interface(REGION_STIMULUS_CREATOR_MODULE, REGION_STIMULUS_CREATOR_CLASS, StimuliRegion())[0] context.equation_kwargs.update({'weight': json.dumps(context.get_weights())}) self.flow_service.fire_operation(local_connectivity_creator, common.get_logged_user(), common.get_current_project().id, **context.equation_kwargs) common.set_important_message("The operation for creating the stimulus was successfully launched.")
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 = common.get_current_project() user = common.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.items(): 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: common.set_info_message("The session was successfully updated!") else: common.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.items(): for figure in value: success = self.figure_service.remove_result_figure(figure.id) if not success: successfully_removed = False if successfully_removed: common.set_info_message("The session was removed successfully!") else: common.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: common.set_info_message("Figure removed successfully!") else: common.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)
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") user = common.get_logged_user() if cherrypy.request.method == 'POST' and save: try: form = EditUserForm() data = form.to_python(data) if data.get(KEY_PASSWORD): user.password = md5(data[KEY_PASSWORD]).hexdigest() if data.get(KEY_EMAIL): user.email = data[KEY_EMAIL] old_password = None if data.get('old_password'): old_password = md5(data['old_password']).hexdigest() self.user_service.edit_user(user, old_password) if old_password: common.set_info_message("Changes Submitted!") else: common.set_info_message("Submitted! No password changed.") except formencode.Invalid as excep: template_specification[common.KEY_ERRORS] = excep.unpack_errors() except UsernameException as excep: self.logger.exception(excep) user = common.get_logged_user() common.add2session(common.KEY_USER, self.user_service.get_user_by_id(user.id)) common.set_error_message("Could not save changes. Probably wrong old password!!") else: #Update session user since disk size might have changed from last time to profile. user = self.user_service.get_user_by_id(user.id) common.add2session(common.KEY_USER, user) template_specification['user_used_disk_human'] = format_bytes_human( self.user_service.compute_user_generated_disk_size(user.id)) return self.fill_default_attributes(template_specification)
def create_local_connectivity(self, **kwargs): """ Used for creating and storing a local connectivity. """ context = common.get_from_session(KEY_LCONN_CONTEXT) local_connectivity_creator = self.get_creator_and_interface(LOCAL_CONN_CREATOR_MODULE, LOCAL_CONN_CREATOR_CLASS, LocalConnectivity())[0] self.flow_service.fire_operation(local_connectivity_creator, common.get_logged_user(), common.get_current_project().id, **kwargs) common.set_important_message("The operation for creating the local connectivity was successfully launched.") context.reset() return self.step_1()
def _populate_user_and_project(self, template_dictionary, escape_db_operations=False): """ Populate the template dictionary with current logged user (from session). """ logged_user = common.get_logged_user() template_dictionary[common.KEY_USER] = logged_user show_help = logged_user is not None and logged_user.is_online_help_active() template_dictionary[common.KEY_SHOW_ONLINE_HELP] = show_help project = common.get_current_project() template_dictionary[common.KEY_PROJECT] = project if project is not None and not escape_db_operations: self.update_operations_count() return template_dictionary
def __get_operations_filters(self): """ Filters for VIEW_ALL_OPERATIONS page. Get from session currently selected filters, or build a new set of filters. """ session_filtes = common.get_from_session(self.KEY_OPERATION_FILTERS) if session_filtes: return session_filtes else: sim_group = self.flow_service.get_algorithm_by_module_and_class(SIMULATOR_MODULE, SIMULATOR_CLASS)[1] new_filters = StaticFiltersFactory.build_operations_filters(sim_group, common.get_logged_user().id) common.add2session(self.KEY_OPERATION_FILTERS, new_filters) return new_filters
def __get_operations_filters(self): """ Filters for VIEW_ALL_OPERATIONS page. Get from session currently selected filters, or build a new set of filters. """ session_filtes = common.get_from_session(self.KEY_OPERATION_FILTERS) if session_filtes: return session_filtes else: sim_group = self.flow_service.get_algorithm_by_module_and_class(SIMULATOR_MODULE, SIMULATOR_CLASS) new_filters = StaticFiltersFactory.build_operations_filters(sim_group, common.get_logged_user().id) common.add2session(self.KEY_OPERATION_FILTERS, new_filters) return new_filters
def displayresultfigures(self, selected_session='all_sessions'): """ Collect and display saved previews, grouped by session.""" project = common.get_current_project() user = common.get_logged_user() data, all_sessions_info = self.figure_service.retrieve_result_figures(project, user, selected_session) manage_figure_title = "Figures for " + str(selected_session) + " category" if selected_session == 'all_sessions': manage_figure_title = "Figures for all categories" template_specification = dict(mainContent="project/figures_display", title="Stored Visualizer Previews", controlPage=None, displayControl=False, selected_sessions_data=data, all_sessions_info=all_sessions_info, selected_session=selected_session, manageFigureTitle=manage_figure_title) template_specification = self.fill_default_attributes(template_specification, subsection='figures') return template_specification
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") user = common.get_logged_user() if cherrypy.request.method == 'POST' and save: try: form = EditUserForm() data = form.to_python(data) if data.get(KEY_PASSWORD): user.password = md5(data[KEY_PASSWORD]).hexdigest() if data.get(KEY_EMAIL): user.email = data[KEY_EMAIL] old_password = None if data.get('old_password'): old_password = md5(data['old_password']).hexdigest() self.user_service.edit_user(user, old_password) if old_password: common.set_info_message("Changes Submitted!") else: common.set_info_message("Submitted! No password changed.") except formencode.Invalid, excep: template_specification[ common.KEY_ERRORS] = excep.unpack_errors() except UsernameException, excep: self.logger.exception(excep) user = common.get_logged_user() common.add2session(common.KEY_USER, self.user_service.get_user_by_id(user.id)) common.set_error_message( "Could not save changes. Probably wrong old password!!")
def editone(self, project_id=None, cancel=False, save=False, delete=False, **data): """ Create or change Project. When project_id is empty we create a new entity, otherwise we are to edit and existent one. """ if cherrypy.request.method == 'POST' and cancel: raise cherrypy.HTTPRedirect('/project') if cherrypy.request.method == 'POST' and delete: self._remove_project(project_id) raise cherrypy.HTTPRedirect('/project/viewall') current_user = common.get_logged_user() is_create = False if project_id is None or not int(project_id): is_create = True data["administrator"] = current_user.username else: current_project = self.project_service.find_project(project_id) if not save: # Only when we do not have submitted data, # populate fields with initial values for edit. data = dict(name=current_project.name, description=current_project.description) data["administrator"] = current_project.administrator.username self._mark_selected(current_project) data["project_id"] = project_id template_specification = dict( mainContent="project/editone", data=data, isCreate=is_create, 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: common.remove_from_session(common.KEY_PROJECT) common.remove_from_session(common.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[common.KEY_ERRORS] = excep.unpack_errors()
def prepare_group_launch(self, group_gid, step_key, algorithm_id, **data): """ Receives as input a group gid and an algorithm given by category and id, along with data that gives the name of the required input parameter for the algorithm. Having these generate a range of GID's for all the DataTypes in the group and launch a new operation group. """ prj_service = ProjectService() dt_group = prj_service.get_datatypegroup_by_gid(group_gid) datatypes = prj_service.get_datatypes_from_datatype_group(dt_group.id) range_param_name = data.pop('range_param_name') data[RANGE_PARAMETER_1] = range_param_name data[range_param_name] = ','.join(dt.gid for dt in datatypes) OperationService().group_operation_launch(common.get_logged_user().id, common.get_current_project().id, int(algorithm_id), int(step_key), **data) redirect_url = self._compute_back_link('operations', common.get_current_project()) raise cherrypy.HTTPRedirect(redirect_url)
def create_stimulus(self): """ Creates a stimulus from the given data. """ try: context = common.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, common.get_logged_user(), common.get_current_project().id, **context.equation_kwargs) common.set_important_message("The operation for creating the stimulus was successfully launched.") context.selected_stimulus = None except (NameError, ValueError, SyntaxError), _: common.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 = common.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)) common.set_error_message("Could not select project: " + str(selected_project_id))
def _get_linkable_projects_dict(self, datatype_id): """" UI ready dictionary with projects in which current DataType can be linked.""" self.logger.debug("Searching projects to link for DT " + str(datatype_id)) for_link, linked = self.project_service.get_linkable_projects_for_user(common.get_logged_user().id, datatype_id) projects_for_link, linked_projects = None, None if for_link: projects_for_link = {} for project in for_link: projects_for_link[project.id] = project.name if linked: linked_projects = {} for project in linked: linked_projects[project.id] = project.name template_specification = {self.PRROJECTS_FOR_LINK_KEY: projects_for_link, self.PRROJECTS_LINKED_KEY: linked_projects, "datatype_id": datatype_id} return template_specification
def editone(self, project_id=None, cancel=False, save=False, delete=False, **data): """ Create or change Project. When project_id is empty we create a new entity, otherwise we are to edit and existent one. """ if cherrypy.request.method == 'POST' and cancel: raise cherrypy.HTTPRedirect('/project') if cherrypy.request.method == 'POST' and delete: self._remove_project(project_id) raise cherrypy.HTTPRedirect('/project/viewall') current_user = common.get_logged_user() is_create = False if project_id is None or not int(project_id): is_create = True data["administrator"] = current_user.username else: current_project = self.project_service.find_project(project_id) if not save: # Only when we do not have submitted data, # populate fields with initial values for edit. data = dict(name=current_project.name, description=current_project.description) data["administrator"] = current_project.administrator.username self._mark_selected(current_project) data["project_id"] = project_id template_specification = dict(mainContent="project/editone", data=data, isCreate=is_create, 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: common.remove_from_session(common.KEY_PROJECT) common.remove_from_session(common.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[common.KEY_ERRORS] = excep.unpack_errors()
def submit(self, dynamic_gid, dynamic_name): dynamic = self.get_cached_dynamic(dynamic_gid) model = dynamic.model integrator = dynamic.integrator model_parameters = [] for name in model.ui_configurable_parameters: value = getattr(model, name)[0] model_parameters.append((name, value)) entity = tvb.core.entities.model.Dynamic( dynamic_name, common.get_logged_user().id, model.__class__.__name__, json.dumps(model_parameters), integrator.__class__.__name__, None # todo: serialize integrator parameters # json.dumps(integrator.raw_ui_integrator_parameters) ) dao.store_entity(entity)
def execute_post(self, project_id, submit_url, step_key, algorithm, **data): """ Execute HTTP POST on a generic step.""" errors = None adapter_instance = ABCAdapter.build_adapter(algorithm) try: result = self.flow_service.fire_operation(adapter_instance, common.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[common.KEY_OPERATION_ID] = adapter_instance.operation_id return result else: common.set_error_message("Invalid result returned from Displayer! Dictionary is expected!") else: if isinstance(result, list): result = "Launched %s operations." % len(result) common.set_important_message(str(result)) except formencode.Invalid as excep: errors = excep.unpack_errors() except OperationException as excep1: self.logger.exception("Error while executing a Launch procedure:" + excep1.message) common.set_error_message(excep1.message) previous_step = self.context.get_current_substep() should_reset = previous_step is None or data.get(common.KEY_ADAPTER) != previous_step template_specification = self.get_template_for_adapter(project_id, step_key, algorithm, submit_url, should_reset) if (errors is not None) and (template_specification is not None): template_specification[common.KEY_ERRORS] = errors template_specification[common.KEY_OPERATION_ID] = adapter_instance.operation_id return template_specification
def set_viewer_color_scheme(self, color_scheme_name): user = common.get_logged_user() user.set_viewers_color_scheme(color_scheme_name) self.user_service.edit_user(user)
def set_project_structure_grouping(self, first, second): user = common.get_logged_user() user.set_project_structure_grouping(first, second) self.user_service.edit_user(user)
def get_project_structure_grouping(self): user = common.get_logged_user() return user.get_project_structure_grouping()