def send_room_message(message): data = sanitize_html(message['data']) room = sanitize_html(message['room']) log.debug("%s sent '%s' to %s" % (current_user.username, message, room)) emit('event response room', {'data': data, 'user': current_user.username, 'gravatar': hashlib.md5(current_user.email).hexdigest(), 'chatroom': room}, room=room)
def update( self, trans, id, payload, **kwds ): """ * PUT /api/workflows/{id} updates the workflow stored with ``id`` :type id: str :param id: the encoded id of the workflow to update :type payload: dict :param payload: a dictionary containing any or all the * workflow the json description of the workflow as would be produced by GET workflows/<id>/download or given to `POST workflows` The workflow contents will be updated to target this. * name optional string name for the workflow, if not present in payload, name defaults to existing name * annotation optional string annotation for the workflow, if not present in payload, annotation defaults to existing annotation * menu_entry optional boolean marking if the workflow should appear in the user's menu, if not present, workflow menu entries are not modified :rtype: dict :returns: serialized version of the workflow """ stored_workflow = self.__get_stored_workflow( trans, id ) if 'workflow' in payload: stored_workflow.name = sanitize_html(payload['name']) if ('name' in payload) else stored_workflow.name if 'annotation' in payload: newAnnotation = sanitize_html(payload['annotation']) self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, newAnnotation) if 'menu_entry' in payload: if payload['menu_entry']: menuEntry = model.StoredWorkflowMenuEntry() menuEntry.stored_workflow = stored_workflow trans.get_user().stored_workflow_menu_entries.append(menuEntry) else: # remove if in list entries = {x.stored_workflow_id: x for x in trans.get_user().stored_workflow_menu_entries} if (trans.security.decode_id(id) in entries): trans.get_user().stored_workflow_menu_entries.remove(entries[trans.security.decode_id(id)]) try: workflow, errors = self.workflow_contents_manager.update_workflow_from_dict( trans, stored_workflow, payload[ 'workflow' ], ) except workflows.MissingToolsException: raise exceptions.MessageException( "This workflow contains missing tools. It cannot be saved until they have been removed from the workflow or installed." ) else: message = "Updating workflow requires dictionary containing 'workflow' attribute with new JSON description." raise exceptions.RequestParameterInvalidException( message ) return self.workflow_contents_manager.workflow_to_dict( trans, stored_workflow, style="instance" )
def create(self, trans, payload, **kwd): """ create( self, trans, payload, **kwd ) * POST /api/pages Create a page and return dictionary containing Page summary :param payload: dictionary structure containing:: 'slug' = The title slug for the page URL, must be unique 'title' = Title of the page 'content' = HTML contents of the page 'annotation' = Annotation that will be attached to the page :rtype: dict :returns: Dictionary return of the Page.to_dict call """ user = trans.get_user() if not payload.get("title", None): raise exceptions.ObjectAttributeMissingException( "Page name is required") elif not payload.get("slug", None): raise exceptions.ObjectAttributeMissingException( "Page id is required") elif not self._is_valid_slug(payload["slug"]): raise exceptions.ObjectAttributeInvalidException( "Page identifier must consist of only lowercase letters, numbers, and the '-' character" ) elif trans.sa_session.query(trans.app.model.Page).filter_by( user=user, slug=payload["slug"], deleted=False).first(): raise exceptions.DuplicatedSlugException( "Page slug must be unique") content = payload.get("content", "") content = sanitize_html(content, 'utf-8', 'text/html') # Create the new stored page page = trans.app.model.Page() page.title = payload['title'] page.slug = payload['slug'] page_annotation = sanitize_html(payload.get("annotation", ""), 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, trans.get_user(), page, page_annotation) page.user = user # And the first (empty) page revision page_revision = trans.app.model.PageRevision() page_revision.title = payload['title'] page_revision.page = page page.latest_revision = page_revision page_revision.content = content # Persist session = trans.sa_session session.add(page) session.flush() rval = self.encode_all_ids(trans, page.to_dict(), True) return rval
def save(self, trans, id, content, annotations): id = self.decode_id(id) page = trans.sa_session.query(model.Page).get(id) assert page.user == trans.user # Sanitize content content = sanitize_html(content) processor = _PageContentProcessor(trans, _placeholderRenderForSave) processor.feed(content) # Output is string, so convert to unicode for saving. content = unicodify(processor.output(), 'utf-8') # Add a new revision to the page with the provided content. page_revision = model.PageRevision() page_revision.title = page.title page_revision.page = page page.latest_revision = page_revision page_revision.content = content # Save annotations. annotations = loads(annotations) for annotation_dict in annotations: item_id = self.decode_id(annotation_dict['item_id']) item_class = self.get_class(annotation_dict['item_class']) item = trans.sa_session.query(item_class).filter_by( id=item_id).first() if not item: raise RuntimeError("cannot find annotated item") text = sanitize_html(annotation_dict['text']) # Add/update annotation. if item_id and item_class and text: # Get annotation association. annotation_assoc_class = eval("model.%sAnnotationAssociation" % item_class.__name__) annotation_assoc = trans.sa_session.query( annotation_assoc_class).filter_by(user=trans.get_user()) if item_class == model.History.__class__: annotation_assoc = annotation_assoc.filter_by(history=item) elif item_class == model.HistoryDatasetAssociation.__class__: annotation_assoc = annotation_assoc.filter_by(hda=item) elif item_class == model.StoredWorkflow.__class__: annotation_assoc = annotation_assoc.filter_by( stored_workflow=item) elif item_class == model.WorkflowStep.__class__: annotation_assoc = annotation_assoc.filter_by( workflow_step=item) annotation_assoc = annotation_assoc.first() if not annotation_assoc: # Create association. annotation_assoc = annotation_assoc_class() item.annotations.append(annotation_assoc) annotation_assoc.user = trans.get_user() # Set annotation user text. annotation_assoc.annotation = text trans.sa_session.flush()
def save(self, trans, id, content, annotations): id = self.decode_id(id) page = trans.sa_session.query(model.Page).get(id) assert page.user == trans.user # Sanitize content content = sanitize_html(content) processor = _PageContentProcessor(trans, _placeholderRenderForSave) processor.feed(content) # Output is string, so convert to unicode for saving. content = unicodify(processor.output(), 'utf-8') # Add a new revision to the page with the provided content. page_revision = model.PageRevision() page_revision.title = page.title page_revision.page = page page.latest_revision = page_revision page_revision.content = content # Save annotations. annotations = loads(annotations) for annotation_dict in annotations: item_id = self.decode_id(annotation_dict['item_id']) item_class = self.get_class(annotation_dict['item_class']) item = trans.sa_session.query(item_class).filter_by(id=item_id).first() if not item: raise RuntimeError("cannot find annotated item") text = sanitize_html(annotation_dict['text']) # Add/update annotation. if item_id and item_class and text: # Get annotation association. annotation_assoc_class = eval("model.%sAnnotationAssociation" % item_class.__name__) annotation_assoc = trans.sa_session.query(annotation_assoc_class).filter_by(user=trans.get_user()) if item_class == model.History.__class__: annotation_assoc = annotation_assoc.filter_by(history=item) elif item_class == model.HistoryDatasetAssociation.__class__: annotation_assoc = annotation_assoc.filter_by(hda=item) elif item_class == model.StoredWorkflow.__class__: annotation_assoc = annotation_assoc.filter_by(stored_workflow=item) elif item_class == model.WorkflowStep.__class__: annotation_assoc = annotation_assoc.filter_by(workflow_step=item) annotation_assoc = annotation_assoc.first() if not annotation_assoc: # Create association. annotation_assoc = annotation_assoc_class() item.annotations.append(annotation_assoc) annotation_assoc.user = trans.get_user() # Set annotation user text. annotation_assoc.annotation = text trans.sa_session.flush()
def _validate_and_parse_update_payload(self, payload): """ Validate and parse incomming data payload for a history. """ # This layer handles (most of the stricter idiot proofing): # - unknown/unallowed keys # - changing data keys from api key to attribute name # - protection against bad data form/type # - protection against malicious data content # all other conversions and processing (such as permissions, etc.) should happen down the line # keys listed here don't error when attempting to set, but fail silently # this allows PUT'ing an entire model back to the server without attribute errors on uneditable attrs valid_but_uneditable_keys = ('id', 'model_class', 'nice_size', 'contents_url', 'purged', 'tags', 'state', 'state_details', 'state_ids') validated_payload = {} for key, val in payload.items(): # TODO: lots of boilerplate here, but overhead on abstraction is equally onerous if key == 'name': if not (isinstance(val, str) or isinstance(val, unicode)): raise ValueError('name must be a string or unicode: %s' % (str(type(val)))) validated_payload['name'] = sanitize_html(val, 'utf-8') #TODO:?? if sanitized != val: log.warn( 'script kiddie' ) elif key == 'deleted': if not isinstance(val, bool): raise ValueError('deleted must be a boolean: %s' % (str(type(val)))) validated_payload['deleted'] = val elif key == 'published': if not isinstance(val, bool): raise ValueError('published must be a boolean: %s' % (str(type(val)))) validated_payload['published'] = val elif key == 'genome_build': if not (isinstance(val, str) or isinstance(val, unicode)): raise ValueError('genome_build must be a string: %s' % (str(type(val)))) validated_payload['genome_build'] = sanitize_html(val, 'utf-8') elif key == 'annotation': if not (isinstance(val, str) or isinstance(val, unicode)): raise ValueError( 'annotation must be a string or unicode: %s' % (str(type(val)))) validated_payload['annotation'] = sanitize_html(val, 'utf-8') elif key not in valid_but_uneditable_keys: raise AttributeError('unknown key: %s' % (str(key))) return validated_payload
def _validate_and_parse_update_payload( self, payload ): """ Validate and parse incomming data payload for a history. """ # This layer handles (most of the stricter idiot proofing): # - unknown/unallowed keys # - changing data keys from api key to attribute name # - protection against bad data form/type # - protection against malicious data content # all other conversions and processing (such as permissions, etc.) should happen down the line # keys listed here don't error when attempting to set, but fail silently # this allows PUT'ing an entire model back to the server without attribute errors on uneditable attrs valid_but_uneditable_keys = ( 'id', 'model_class', 'nice_size', 'contents_url', 'purged', 'tags', 'state', 'state_details', 'state_ids' ) validated_payload = {} for key, val in payload.items(): # TODO: lots of boilerplate here, but overhead on abstraction is equally onerous if key == 'name': if not ( isinstance( val, str ) or isinstance( val, unicode ) ): raise ValueError( 'name must be a string or unicode: %s' %( str( type( val ) ) ) ) validated_payload[ 'name' ] = sanitize_html( val, 'utf-8' ) #TODO:?? if sanitized != val: log.warn( 'script kiddie' ) elif key == 'deleted': if not isinstance( val, bool ): raise ValueError( 'deleted must be a boolean: %s' %( str( type( val ) ) ) ) validated_payload[ 'deleted' ] = val elif key == 'published': if not isinstance( val, bool ): raise ValueError( 'published must be a boolean: %s' %( str( type( val ) ) ) ) validated_payload[ 'published' ] = val elif key == 'genome_build' and val is not None: if not ( isinstance( val, str ) or isinstance( val, unicode ) ): raise ValueError( 'genome_build must be a string: %s' %( str( type( val ) ) ) ) validated_payload[ 'genome_build' ] = sanitize_html( val, 'utf-8' ) elif key == 'annotation': if not ( isinstance( val, str ) or isinstance( val, unicode ) ): raise ValueError( 'annotation must be a string or unicode: %s' %( str( type( val ) ) ) ) validated_payload[ 'annotation' ] = sanitize_html( val, 'utf-8' ) elif key == 'tags': if isinstance( val, list ): validated_payload[ 'tags' ] = [ sanitize_html( t, 'utf-8' ) for t in val ] elif key not in valid_but_uneditable_keys: pass #log.warn( 'unknown key: %s', str( key ) ) return validated_payload
def create( self, trans, payload, **kwd ): """ create( self, trans, payload, **kwd ) * POST /api/pages Create a page and return dictionary containing Page summary :param payload: dictionary structure containing:: 'slug' = The title slug for the page URL, must be unique 'title' = Title of the page 'content' = HTML contents of the page 'annotation' = Annotation that will be attached to the page :rtype: dict :returns: Dictionary return of the Page.to_dict call """ user = trans.get_user() if not payload.get("title", None): raise exceptions.ObjectAttributeMissingException( "Page name is required" ) elif not payload.get("slug", None): raise exceptions.ObjectAttributeMissingException( "Page id is required" ) elif not self._is_valid_slug( payload["slug"] ): raise exceptions.ObjectAttributeInvalidException( "Page identifier must consist of only lowercase letters, numbers, and the '-' character" ) elif trans.sa_session.query( trans.app.model.Page ).filter_by( user=user, slug=payload["slug"], deleted=False ).first(): raise exceptions.DuplicatedSlugException( "Page slug must be unique" ) content = payload.get("content", "") content = sanitize_html( content, 'utf-8', 'text/html' ) # Create the new stored page page = trans.app.model.Page() page.title = payload['title'] page.slug = payload['slug'] page_annotation = sanitize_html( payload.get( "annotation", "" ), 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), page, page_annotation ) page.user = user # And the first (empty) page revision page_revision = trans.app.model.PageRevision() page_revision.title = payload['title'] page_revision.page = page page.latest_revision = page_revision page_revision.content = content # Persist session = trans.sa_session session.add( page ) session.flush() rval = self.encode_all_ids( trans, page.to_dict(), True ) return rval
def validate_and_sanitize_basestring_list(key, val): try: assert isinstance(val, list) return [sanitize_html(t) for t in val] except (AssertionError, TypeError): raise exceptions.RequestParameterInvalidException( '%s must be a list of strings: %s' % (key, str(type(val))))
def edit(self, trans, payload=None, **kwd): """ Edit a visualization's attributes. """ id = kwd.get('id') if not id: return self.message_exception(trans, 'No visualization id received for editing.') v = self.get_visualization(trans, id, check_ownership=True) if trans.request.method == 'GET': if v.slug is None: self.create_item_slug(trans.sa_session, v) return { 'title' : 'Edit visualization attributes', 'inputs' : [{ 'name' : 'title', 'label' : 'Name', 'value' : v.title }, { 'name' : 'slug', 'label' : 'Identifier', 'value' : v.slug, 'help' : 'A unique identifier that will be used for public links to this visualization. This field can only contain lowercase letters, numbers, and dashes (-).' }, { 'name' : 'dbkey', 'label' : 'Build', 'type' : 'select', 'optional' : True, 'value' : v.dbkey, 'options' : trans.app.genomes.get_dbkeys(trans, chrom_info=True), 'help' : 'Parameter to associate your visualization with a database key.' }, { 'name' : 'annotation', 'label' : 'Annotation', 'value' : self.get_item_annotation_str(trans.sa_session, trans.user, v), 'help' : 'A description of the visualization. The annotation is shown alongside published visualizations.' }] } else: v_title = payload.get('title') v_slug = payload.get('slug') v_dbkey = payload.get('dbkey') v_annotation = payload.get('annotation') if not v_title: return self.message_exception(trans, 'Please provide a visualization name is required.') elif not v_slug: return self.message_exception(trans, 'Please provide a unique identifier.') elif not self._is_valid_slug(v_slug): return self.message_exception(trans, 'Visualization identifier can only contain lowercase letters, numbers, and dashes (-).') elif v_slug != v.slug and trans.sa_session.query(model.Visualization).filter_by(user=v.user, slug=v_slug, deleted=False).first(): return self.message_exception(trans, 'Visualization id must be unique.') else: v.title = v_title v.slug = v_slug v.dbkey = v_dbkey if v_annotation: v_annotation = sanitize_html(v_annotation, 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, trans.get_user(), v, v_annotation) trans.sa_session.add(v) trans.sa_session.flush() return {'message': 'Attributes of \'%s\' successfully saved.' % v.title, 'status': 'success'}
def build_workflow_from_dict( self, trans, data, source=None, add_to_menu=False, publish=False, create_stored_workflow=True, exact_tools=False, ): # Put parameters in workflow mode trans.workflow_building_mode = True # If there's a source, put it in the workflow name. if source: name = "%s (imported from %s)" % (data['name'], source) else: name = data['name'] workflow, missing_tool_tups = self._workflow_from_dict( trans, data, name=name, exact_tools=exact_tools, ) if 'uuid' in data: workflow.uuid = data['uuid'] if create_stored_workflow: # Connect up stored = model.StoredWorkflow() stored.name = workflow.name workflow.stored_workflow = stored stored.latest_workflow = workflow stored.user = trans.user stored.published = publish if data['annotation']: annotation = sanitize_html(data['annotation'], 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, stored.user, stored, annotation) # Persist trans.sa_session.add(stored) if add_to_menu: if trans.user.stored_workflow_menu_entries is None: trans.user.stored_workflow_menu_entries = [] menuEntry = model.StoredWorkflowMenuEntry() menuEntry.stored_workflow = stored trans.user.stored_workflow_menu_entries.append(menuEntry) else: stored = None # Persist trans.sa_session.add(workflow) trans.sa_session.flush() return CreatedWorkflow(stored_workflow=stored, workflow=workflow, missing_tools=missing_tool_tups)
def __module_from_dict(self, trans, step_dict, exact_tools=False): """ Create a WorkflowStep model object and corresponding module representing type-specific functionality from the incoming dictionary. """ step = model.WorkflowStep() # TODO: Consider handling position inside module. step.position = step_dict['position'] if "uuid" in step_dict and step_dict['uuid'] != "None": step.uuid = step_dict["uuid"] if "label" in step_dict: step.label = step_dict["label"] step_type = step_dict.get("type", None) if step_type == "subworkflow": subworkflow = self.__load_subworkflow_from_step_dict( trans, step_dict) step_dict["subworkflow"] = subworkflow module = module_factory.from_dict(trans, step_dict, exact_tools=exact_tools) module.save_to_step(step) annotation = step_dict['annotation'] if annotation: annotation = sanitize_html(annotation, 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, trans.get_user(), step, annotation) # Stick this in the step temporarily step.temp_input_connections = step_dict['input_connections'] return module, step
def __module_from_dict(self, trans, step_dict, secure): """ Create a WorkflowStep model object and corrsponding module representing type-specific functionality from the incoming dicitionary. """ step = model.WorkflowStep() # TODO: Consider handling position inside module. step.position = step_dict['position'] if "uuid" in step_dict: step.uuid = step_dict["uuid"] if "label" in step_dict: step.label = step_dict["label"] module = module_factory.from_dict(trans, step_dict, secure=secure) module.save_to_step(step) annotation = step_dict['annotation'] if annotation: annotation = sanitize_html(annotation, 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, trans.get_user(), step, annotation) # Stick this in the step temporarily step.temp_input_connections = step_dict['input_connections'] return module, step
def build_workflow_from_dict( self, trans, data, source=None, add_to_menu=False, publish=False, create_stored_workflow=True, exact_tools=False, ): # Put parameters in workflow mode trans.workflow_building_mode = True # If there's a source, put it in the workflow name. if source: name = "%s (imported from %s)" % ( data['name'], source ) else: name = data['name'] workflow, missing_tool_tups = self._workflow_from_dict( trans, data, name=name, exact_tools=exact_tools, ) if 'uuid' in data: workflow.uuid = data['uuid'] if create_stored_workflow: # Connect up stored = model.StoredWorkflow() stored.name = workflow.name workflow.stored_workflow = stored stored.latest_workflow = workflow stored.user = trans.user stored.published = publish if data[ 'annotation' ]: annotation = sanitize_html( data[ 'annotation' ], 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, stored.user, stored, annotation ) # Persist trans.sa_session.add( stored ) if add_to_menu: if trans.user.stored_workflow_menu_entries is None: trans.user.stored_workflow_menu_entries = [] menuEntry = model.StoredWorkflowMenuEntry() menuEntry.stored_workflow = stored trans.user.stored_workflow_menu_entries.append( menuEntry ) else: stored = None # Persist trans.sa_session.add( workflow ) trans.sa_session.flush() return CreatedWorkflow( stored_workflow=stored, workflow=workflow, missing_tools=missing_tool_tups )
def event_broadcast(message): message = sanitize_html(message['data']) log.debug("%s broadcast '%s'" % (current_user.username, message)) emit('event response', {'data': message, 'user': current_user.username, 'gravatar': hashlib.md5(current_user.email).hexdigest()}, broadcast=True)
def validate_and_sanitize_basestring_list( key, val ): try: assert isinstance( val, list ) return [ sanitize_html( t, 'utf-8', 'text/html' ) for t in val ] except ( AssertionError, TypeError ): raise exceptions.RequestParameterInvalidException( '%s must be a list of strings: %s' % ( key, str( type( val ) ) ) )
def __module_from_dict( self, trans, step_dict, secure ): """ Create a WorkflowStep model object and corresponding module representing type-specific functionality from the incoming dictionary. """ step = model.WorkflowStep() # TODO: Consider handling position inside module. step.position = step_dict['position'] if "uuid" in step_dict and step_dict['uuid'] != "None": step.uuid = step_dict["uuid"] if "label" in step_dict: step.label = step_dict["label"] step_type = step_dict.get("type", None) if step_type == "subworkflow": subworkflow = self.__load_subworkflow_from_step_dict( trans, step_dict ) step_dict["subworkflow"] = subworkflow module = module_factory.from_dict( trans, step_dict, secure=secure ) module.save_to_step( step ) annotation = step_dict[ 'annotation' ] if annotation: annotation = sanitize_html( annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), step, annotation ) # Stick this in the step temporarily step.temp_input_connections = step_dict['input_connections'] return module, step
def __module_from_dict(self, trans, steps, steps_by_external_id, step_dict, **kwds): """ Create a WorkflowStep model object and corresponding module representing type-specific functionality from the incoming dictionary. """ step = model.WorkflowStep() # TODO: Consider handling position inside module. step.position = step_dict['position'] if step_dict.get("uuid", None) and step_dict['uuid'] != "None": step.uuid = step_dict["uuid"] if "label" in step_dict: step.label = step_dict["label"] step_type = step_dict.get("type", None) if step_type == "subworkflow": subworkflow = self.__load_subworkflow_from_step_dict( trans, step_dict) step_dict["subworkflow"] = subworkflow module = module_factory.from_dict(trans, step_dict, **kwds) self.__set_default_label(step, module, step_dict.get('tool_state')) module.save_to_step(step) annotation = step_dict['annotation'] if annotation: annotation = sanitize_html(annotation, 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, trans.get_user(), step, annotation) # Stick this in the step temporarily step.temp_input_connections = step_dict['input_connections'] # Create the model class for the step steps.append(step) steps_by_external_id[step_dict['id']] = step if 'workflow_outputs' in step_dict: workflow_outputs = step_dict['workflow_outputs'] found_output_names = set([]) for workflow_output in workflow_outputs: # Allow workflow outputs as list of output_names for backward compatiblity. if not isinstance(workflow_output, dict): workflow_output = {"output_name": workflow_output} output_name = workflow_output["output_name"] if output_name in found_output_names: raise exceptions.ObjectAttributeInvalidException( "Duplicate workflow outputs with name [%s] found." % output_name) if not output_name: raise exceptions.ObjectAttributeInvalidException( "Workflow output with empty name encountered.") found_output_names.add(output_name) uuid = workflow_output.get("uuid", None) label = workflow_output.get("label", None) m = step.create_or_update_workflow_output( output_name=output_name, uuid=uuid, label=label, ) trans.sa_session.add(m) return module, step
def annotate_async(self, trans, id, new_annotation=None, **kwargs): stored = self.get_stored_workflow(trans, id) if new_annotation: # Sanitize annotation before adding it. new_annotation = sanitize_html(new_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), stored, new_annotation) trans.sa_session.flush() return new_annotation
def rename_async(self, trans, id, new_name=None, **kwargs): stored = self.get_stored_workflow(trans, id) if new_name: san_new_name = sanitize_html(new_name) stored.name = san_new_name stored.latest_workflow.name = san_new_name trans.sa_session.flush() return stored.name
def leave(message): room = sanitize_html(message['room']) log.debug("%s left %s" % (current_user.username, room)) leave_room(room) emit('event response room', {'data': room, 'userleave': current_user.username}, broadcast=True)
def join(message): room = sanitize_html(message['room']) log.debug("%s joined %s" % (current_user.username, room)) join_room(room) emit('event response room', {'data': room, 'userjoin': current_user.username}, broadcast=True)
def display_data(self, trans, data, preview=False, filename=None, to_ext=None, size=None, offset=None, **kwd): """ Old display method, for transition """ #Relocate all composite datatype display to a common location. composite_extensions = trans.app.datatypes_registry.get_composite_extensions( ) composite_extensions.append('html') # for archiving composite datatypes #Prevent IE8 from sniffing content type since we're explicit about it. This prevents intentionally text/plain #content from being rendered in the browser trans.response.headers['X-Content-Type-Options'] = 'nosniff' if isinstance( data, basestring ): return data if filename and filename != "index": # For files in extra_files_path file_path = trans.app.object_store.get_filename(data.dataset, extra_dir='dataset_%s_files' % data.dataset.id, alt_name=filename) if os.path.exists( file_path ): if os.path.isdir( file_path ): return trans.show_error_message( "Directory listing is not allowed." ) #TODO: Reconsider allowing listing of directories? mime, encoding = mimetypes.guess_type( file_path ) if not mime: try: mime = trans.app.datatypes_registry.get_mimetype_by_extension( ".".split( file_path )[-1] ) except: mime = "text/plain" trans.response.set_content_type( mime ) return open( file_path ) else: return trans.show_error_message( "Could not find '%s' on the extra files path %s." % ( filename, file_path ) ) trans.response.set_content_type(data.get_mime()) trans.log_event( "Display dataset id: %s" % str( data.id ) ) from galaxy import datatypes #DBTODO REMOVE THIS AT REFACTOR if to_ext or isinstance(data.datatype, datatypes.binary.Binary): # Saving the file, or binary file if data.extension in composite_extensions: return self._archive_composite_dataset( trans, data, **kwd ) else: trans.response.headers['Content-Length'] = int( os.stat( data.file_name ).st_size ) if not to_ext: to_ext = data.extension valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' fname = ''.join(c in valid_chars and c or '_' for c in data.name)[0:150] trans.response.set_content_type( "application/octet-stream" ) #force octet-stream so Safari doesn't append mime extensions to filename trans.response.headers["Content-Disposition"] = 'attachment; filename="Galaxy%s-[%s].%s"' % (data.hid, fname, to_ext) return open( data.file_name ) if not os.path.exists( data.file_name ): raise paste.httpexceptions.HTTPNotFound( "File Not Found (%s)." % data.file_name ) max_peek_size = 1000000 # 1 MB if isinstance(data.datatype, datatypes.images.Html): max_peek_size = 10000000 # 10 MB for html preview = util.string_as_bool( preview ) if not preview or isinstance(data.datatype, datatypes.images.Image) or os.stat( data.file_name ).st_size < max_peek_size: if trans.app.config.sanitize_all_html and trans.response.get_content_type() == "text/html": # Sanitize anytime we respond with plain text/html content. return sanitize_html(open( data.file_name ).read()) return open( data.file_name ) else: trans.response.set_content_type( "text/html" ) return trans.stream_template_mako( "/dataset/large_file.mako", truncated_data = open( data.file_name ).read(max_peek_size), data = data)
def __module_from_dict( self, trans, steps, steps_by_external_id, step_dict, **kwds ): """ Create a WorkflowStep model object and corresponding module representing type-specific functionality from the incoming dictionary. """ step = model.WorkflowStep() # TODO: Consider handling position inside module. step.position = step_dict['position'] if step_dict.get("uuid", None) and step_dict['uuid'] != "None": step.uuid = step_dict["uuid"] if "label" in step_dict: step.label = step_dict["label"] step_type = step_dict.get("type", None) if step_type == "subworkflow": subworkflow = self.__load_subworkflow_from_step_dict( trans, step_dict ) step_dict["subworkflow"] = subworkflow module = module_factory.from_dict( trans, step_dict, **kwds ) self.__set_default_label( step, module, step_dict.get( 'tool_state' ) ) module.save_to_step( step ) annotation = step_dict[ 'annotation' ] if annotation: annotation = sanitize_html( annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), step, annotation ) # Stick this in the step temporarily step.temp_input_connections = step_dict['input_connections'] # Create the model class for the step steps.append( step ) steps_by_external_id[ step_dict[ 'id' ] ] = step if 'workflow_outputs' in step_dict: workflow_outputs = step_dict['workflow_outputs'] found_output_names = set([]) for workflow_output in workflow_outputs: # Allow workflow outputs as list of output_names for backward compatiblity. if not isinstance(workflow_output, dict): workflow_output = {"output_name": workflow_output} output_name = workflow_output["output_name"] if output_name in found_output_names: raise exceptions.ObjectAttributeInvalidException("Duplicate workflow outputs with name [%s] found." % output_name) if not output_name: raise exceptions.ObjectAttributeInvalidException("Workflow output with empty name encountered.") found_output_names.add(output_name) uuid = workflow_output.get("uuid", None) label = workflow_output.get("label", None) m = step.create_or_update_workflow_output( output_name=output_name, uuid=uuid, label=label, ) trans.sa_session.add(m) return module, step
def save_workflow_as(self, trans, workflow_name, workflow_data, workflow_annotation="", from_tool_form=False): """ Creates a new workflow based on Save As command. It is a new workflow, but is created with workflow_data already present. """ user = trans.get_user() if workflow_name is not None: workflow_contents_manager = self.app.workflow_contents_manager stored_workflow = model.StoredWorkflow() stored_workflow.name = workflow_name stored_workflow.user = user self.slug_builder.create_item_slug(trans.sa_session, stored_workflow) workflow = model.Workflow() workflow.name = workflow_name workflow.stored_workflow = stored_workflow stored_workflow.latest_workflow = workflow # Add annotation. workflow_annotation = sanitize_html(workflow_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, workflow_annotation) # Persist session = trans.sa_session session.add(stored_workflow) session.flush() workflow_update_options = WorkflowUpdateOptions( update_stored_workflow_attributes=False, # taken care of above from_tool_form=from_tool_form, ) try: workflow, errors = workflow_contents_manager.update_workflow_from_raw_description( trans, stored_workflow, workflow_data, workflow_update_options, ) except MissingToolsException as e: return dict( name=e.workflow.name, message= ("This workflow includes missing or invalid tools. " "It cannot be saved until the following steps are removed or the missing tools are enabled." ), errors=e.errors, ) return (trans.security.encode_id(stored_workflow.id)) else: # This is an error state, 'save as' must have a workflow_name log.exception("Error in Save As workflow: no name.")
def create( self, trans, visualization_title="", visualization_slug="", visualization_annotation="", visualization_dbkey="" ): """ Create a new visualization """ user = trans.get_user() visualization_title_err = visualization_slug_err = visualization_annotation_err = "" if trans.request.method == "POST": if not visualization_title: visualization_title_err = "visualization name is required" elif not visualization_slug: visualization_slug_err = "visualization id is required" elif not VALID_SLUG_RE.match( visualization_slug ): visualization_slug_err = "visualization identifier must consist of only lowercase letters, numbers, and the '-' character" elif trans.sa_session.query( model.Visualization ).filter_by( user=user, slug=visualization_slug, deleted=False ).first(): visualization_slug_err = "visualization id must be unique" else: # Create the new stored visualization visualization = model.Visualization() visualization.title = visualization_title visualization.slug = visualization_slug visualization.dbkey = visualization_dbkey visualization.type = 'trackster' # HACK: set visualization type to trackster since it's the only viz visualization_annotation = sanitize_html( visualization_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), visualization, visualization_annotation ) visualization.user = user # And the first (empty) visualization revision visualization_revision = model.VisualizationRevision() visualization_revision.title = visualization_title visualization_revision.config = {} visualization_revision.dbkey = visualization_dbkey visualization_revision.visualization = visualization visualization.latest_revision = visualization_revision # Persist session = trans.sa_session session.add(visualization) session.add(visualization_revision) session.flush() return trans.response.send_redirect( web.url_for( action='list' ) ) return trans.show_form( web.FormBuilder( web.url_for(), "Create new visualization", submit_text="Submit" ) .add_text( "visualization_title", "Visualization title", value=visualization_title, error=visualization_title_err ) .add_text( "visualization_slug", "Visualization identifier", value=visualization_slug, error=visualization_slug_err, help="""A unique identifier that will be used for public links to this visualization. A default is generated from the visualization title, but can be edited. This field must contain only lowercase letters, numbers, and the '-' character.""" ) .add_select( "visualization_dbkey", "Visualization DbKey/Build", value=visualization_dbkey, options=self._get_dbkeys( trans ), error=None) .add_text( "visualization_annotation", "Visualization annotation", value=visualization_annotation, error=visualization_annotation_err, help="A description of the visualization; annotation is shown alongside published visualizations."), template="visualization/create.mako" )
def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, offset=None, ck_size=None, **kwd): """Downloads the ISA dataset if `preview` is `False`; if `preview` is `True`, it returns a preview of the ISA dataset as a HTML page. The preview is triggered when user clicks on the eye icon of the composite dataset.""" # if it is not required a preview use the default behaviour of `display_data` if not preview: return super(_Isa, self).display_data(trans, dataset, preview, filename, to_ext, **kwd) # prepare the preview of the ISA dataset investigation = self._get_investigation(dataset) if investigation is None: html = """<html><header><title>Error while reading ISA archive.</title></header> <body> <h1>An error occurred while reading content of ISA archive.</h1> <p>If you have tried to load your archive with the uploader by selecting isa-tab as composite data type, then try to load it again with isa-json instead. Conversely, if you have tried to load your archive with the uploader by selecting isa-json as composite data type, then try isa-tab instead.</p> <p>You may also try to look into your zip file in order to find out if this is a proper ISA archive. If you see a file i_Investigation.txt inside, then it is an ISA-Tab archive. If you see a file with extension .json inside, then it is an ISA-JSON archive. If you see nothing like that, then either your ISA archive is corrupted, or it is not an ISA archive.</p> </body></html>""" else: html = '<html><body>' html += '<h1>{0} {1}</h1>'.format(investigation.title, investigation.identifier) # Loop on all studies for study in investigation.studies: html += '<h2>Study %s</h2>' % study.identifier html += '<h3>%s</h3>' % study.title html += '<p>%s</p>' % study.description html += '<p>Submitted the %s</p>' % study.submission_date html += '<p>Released on %s</p>' % study.public_release_date html += '<p>Experimental factors used: %s</p>' % ', '.join([x.name for x in study.factors]) # Loop on all assays of this study for assay in study.assays: html += '<h3>Assay %s</h3>' % assay.filename html += '<p>Measurement type: %s</p>' % assay.measurement_type.term # OntologyAnnotation html += '<p>Technology type: %s</p>' % assay.technology_type.term # OntologyAnnotation html += '<p>Technology platform: %s</p>' % assay.technology_platform if assay.data_files is not None: html += '<p>Data files:</p>' html += '<ul>' for data_file in assay.data_files: if data_file.filename != '': html += '<li>' + escape(util.unicodify(str(data_file.filename), 'utf-8')) + ' - ' + escape(util.unicodify(str(data_file.label), 'utf-8')) + '</li>' html += '</ul>' html += '</body></html>' # Set mime type mime = 'text/html' self._clean_and_set_mime_type(trans, mime) return sanitize_html(html).encode('utf-8')
def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, offset=None, ck_size=None, **kwd): """Downloads the ISA dataset if `preview` is `False`; if `preview` is `True`, it returns a preview of the ISA dataset as a HTML page. The preview is triggered when user clicks on the eye icon of the composite dataset.""" # if it is not required a preview use the default behaviour of `display_data` if not preview: return super(_Isa, self).display_data(trans, dataset, preview, filename, to_ext, **kwd) # prepare the preview of the ISA dataset investigation = self._get_investigation(dataset) if investigation is None: html = """<html><header><title>Error while reading ISA archive.</title></header> <body> <h1>An error occured while reading content of ISA archive.</h1> <p>If you have tried to load your archive with the uploader by selecting isa-tab as composite data type, then try to load it again with isa-json instead. Conversely, if you have tried to load your archive with the uploader by selecting isa-json as composite data type, then try isa-tab instead.</p> <p>You may also try to look into your zip file in order to find out if this is a proper ISA archive. If you see a file i_Investigation.txt inside, then it is an ISA-Tab archive. If you see a file with extension .json inside, then it is an ISA-JSON archive. If you see nothing like that, then either your ISA archive is corrupted, or it is not an ISA archive.</p> </body></html>""" else: html = '<html><body>' html += '<h1>{0} {1}</h1>'.format(investigation.title, investigation.identifier) # Loop on all studies for study in investigation.studies: html += '<h2>Study %s</h2>' % study.identifier html += '<h3>%s</h3>' % study.title html += '<p>%s</p>' % study.description html += '<p>Submitted the %s</p>' % study.submission_date html += '<p>Released on %s</p>' % study.public_release_date html += '<p>Experimental factors used: %s</p>' % ', '.join([x.name for x in study.factors]) # Loop on all assays of this study for assay in study.assays: html += '<h3>Assay %s</h3>' % assay.filename html += '<p>Measurement type: %s</p>' % assay.measurement_type.term # OntologyAnnotation html += '<p>Technology type: %s</p>' % assay.technology_type.term # OntologyAnnotation html += '<p>Technology platform: %s</p>' % assay.technology_platform if assay.data_files is not None: html += '<p>Data files:</p>' html += '<ul>' for data_file in assay.data_files: if data_file.filename != '': html += '<li>' + escape(util.unicodify(str(data_file.filename), 'utf-8')) + ' - ' + escape(util.unicodify(str(data_file.label), 'utf-8')) + '</li>' html += '</ul>' html += '</body></html>' # Set mime type mime = 'text/html' self._clean_and_set_mime_type(trans, mime) return sanitize_html(html).encode('utf-8')
def create(self, trans, payload): user = trans.get_user() if not payload.get("title"): raise exceptions.ObjectAttributeMissingException( "Page name is required") elif not payload.get("slug"): raise exceptions.ObjectAttributeMissingException( "Page id is required") elif not base.is_valid_slug(payload["slug"]): raise exceptions.ObjectAttributeInvalidException( "Page identifier must consist of only lowercase letters, numbers, and the '-' character" ) elif trans.sa_session.query(trans.app.model.Page).filter_by( user=user, slug=payload["slug"], deleted=False).first(): raise exceptions.DuplicatedSlugException( "Page identifier must be unique") if payload.get("invocation_id"): invocation_id = payload.get("invocation_id") invocation_report = self.workflow_manager.get_invocation_report( trans, invocation_id) content = invocation_report.get("markdown") content_format = "markdown" else: content = payload.get("content", "") content_format = payload.get("content_format", "html") content = self.rewrite_content_for_import(trans, content, content_format) # Create the new stored page page = trans.app.model.Page() page.title = payload['title'] page.slug = payload['slug'] page_annotation = payload.get("annotation", None) if page_annotation is not None: page_annotation = sanitize_html(page_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), page, page_annotation) page.user = user # And the first (empty) page revision page_revision = trans.app.model.PageRevision() page_revision.title = payload['title'] page_revision.page = page page.latest_revision = page_revision page_revision.content = content page_revision.content_format = content_format # Persist session = trans.sa_session session.add(page) session.flush() return page
def rewrite_content_for_import(self, trans, content): try: content = sanitize_html(content) processor = PageContentProcessor(trans, placeholderRenderForSave) processor.feed(content) # Output is string, so convert to unicode for saving. content = unicodify(processor.output(), 'utf-8') except exceptions.MessageException: raise except Exception: raise exceptions.RequestParameterInvalidException("problem with embedded HTML content [%s]" % content) return content
def create(self, trans, payload=None, **kwd): """ Create a new page. """ if trans.request.method == 'GET': return { 'title' : 'Create a new page', 'inputs' : [{ 'name' : 'title', 'label' : 'Name' }, { 'name' : 'slug', 'label' : 'Identifier', 'help' : 'A unique identifier that will be used for public links to this page. This field can only contain lowercase letters, numbers, and dashes (-).' }, { 'name' : 'annotation', 'label' : 'Annotation', 'help' : 'A description of the page. The annotation is shown alongside published pages.' }] } else: user = trans.get_user() p_title = payload.get('title') p_slug = payload.get('slug') p_annotation = payload.get('annotation') if not p_title: return self.message_exception(trans, 'Please provide a page name is required.') elif not p_slug: return self.message_exception(trans, 'Please provide a unique identifier.') elif not self._is_valid_slug(p_slug): return self.message_exception(trans, 'Page identifier can only contain lowercase letters, numbers, and dashes (-).') elif trans.sa_session.query(model.Page).filter_by(user=user, slug=p_slug, deleted=False).first(): return self.message_exception(trans, 'Page id must be unique.') else: # Create the new stored page p = model.Page() p.title = p_title p.slug = p_slug p.user = user if p_annotation: p_annotation = sanitize_html(p_annotation, 'utf-8', 'text/html') self.add_item_annotation(trans.sa_session, user, p, p_annotation) # And the first (empty) page revision p_revision = model.PageRevision() p_revision.title = p_title p_revision.page = p p.latest_revision = p_revision p_revision.content = "" # Persist trans.sa_session.add(p) trans.sa_session.flush() return {'message': 'Page \'%s\' successfully created.' % p.title, 'status': 'success'}
def edit(self, trans, payload=None, **kwd): """ Edit a page's attributes. """ id = kwd.get('id') if not id: return self.message_exception(trans, 'No page id received for editing.') decoded_id = self.decode_id(id) user = trans.get_user() p = trans.sa_session.query(model.Page).get(decoded_id) if trans.request.method == 'GET': if p.slug is None: self.create_item_slug(trans.sa_session, p) return { 'title' : 'Edit page attributes', 'inputs' : [{ 'name' : 'title', 'label' : 'Name', 'value' : p.title }, { 'name' : 'slug', 'label' : 'Identifier', 'value' : p.slug, 'help' : 'A unique identifier that will be used for public links to this page. This field can only contain lowercase letters, numbers, and dashes (-).' }, { 'name' : 'annotation', 'label' : 'Annotation', 'value' : self.get_item_annotation_str(trans.sa_session, user, p), 'help' : 'A description of the page. The annotation is shown alongside published pages.' }] } else: p_title = payload.get('title') p_slug = payload.get('slug') p_annotation = payload.get('annotation') if not p_title: return self.message_exception(trans, 'Please provide a page name is required.') elif not p_slug: return self.message_exception(trans, 'Please provide a unique identifier.') elif not self._is_valid_slug(p_slug): return self.message_exception(trans, 'Page identifier can only contain lowercase letters, numbers, and dashes (-).') elif p_slug != p.slug and trans.sa_session.query(model.Page).filter_by(user=p.user, slug=p_slug, deleted=False).first(): return self.message_exception(trans, 'Page id must be unique.') else: p.title = p_title p.slug = p_slug if p_annotation: p_annotation = sanitize_html(p_annotation) self.add_item_annotation(trans.sa_session, user, p, p_annotation) trans.sa_session.add(p) trans.sa_session.flush() return {'message': 'Attributes of \'%s\' successfully saved.' % p.title, 'status': 'success'}
def create(self, trans, payload=None, **kwd): """ Create a new page. """ if trans.request.method == 'GET': return { 'title' : 'Create a new page', 'inputs' : [{ 'name' : 'title', 'label' : 'Name' }, { 'name' : 'slug', 'label' : 'Identifier', 'help' : 'A unique identifier that will be used for public links to this page. This field can only contain lowercase letters, numbers, and dashes (-).' }, { 'name' : 'annotation', 'label' : 'Annotation', 'help' : 'A description of the page. The annotation is shown alongside published pages.' }] } else: user = trans.get_user() p_title = payload.get('title') p_slug = payload.get('slug') p_annotation = payload.get('annotation') if not p_title: return self.message_exception(trans, 'Please provide a page name is required.') elif not p_slug: return self.message_exception(trans, 'Please provide a unique identifier.') elif not self._is_valid_slug(p_slug): return self.message_exception(trans, 'Page identifier can only contain lowercase letters, numbers, and dashes (-).') elif trans.sa_session.query(model.Page).filter_by(user=user, slug=p_slug, deleted=False).first(): return self.message_exception(trans, 'Page id must be unique.') else: # Create the new stored page p = model.Page() p.title = p_title p.slug = p_slug p.user = user if p_annotation: p_annotation = sanitize_html(p_annotation) self.add_item_annotation(trans.sa_session, user, p, p_annotation) # And the first (empty) page revision p_revision = model.PageRevision() p_revision.title = p_title p_revision.page = p p.latest_revision = p_revision p_revision.content = "" # Persist trans.sa_session.add(p) trans.sa_session.flush() return {'message': 'Page \'%s\' successfully created.' % p.title, 'status': 'success'}
def save( self, trans, id, content ): id = trans.security.decode_id( id ) page = trans.sa_session.query( model.Page ).get( id ) assert page.user == trans.user # Sanitize content content = sanitize_html( content, 'utf-8', 'text/html' ) # Add a new revision to the page with the provided content page_revision = model.PageRevision() page_revision.title = page.title page_revision.page = page page.latest_revision = page_revision page_revision.content = content trans.sa_session.flush()
def create(self, trans, payload, **kwd): if "text" not in payload: return "" idnum = kwd[self.tagged_item_id] item = self._get_item_from_id(trans, idnum) if item is not None: new_annotation = payload.get("text") # Sanitize annotation before adding it. new_annotation = sanitize_html(new_annotation, "utf-8", "text/html") self.add_item_annotation(trans.sa_session, trans.get_user(), item, new_annotation) trans.sa_session.flush() return new_annotation return ""
def create( self, trans, payload, **kwd ): if "text" not in payload: return "" idnum = kwd[self.tagged_item_id] item = self._get_item_from_id(trans, idnum) if item is not None: new_annotation = payload.get("text") #TODO: sanitize on display not entry new_annotation = sanitize_html.sanitize_html( new_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), item, new_annotation ) trans.sa_session.flush() return new_annotation return ""
def create( self, trans, payload, **kwd ): if "text" not in payload: return "" idnum = kwd[self.tagged_item_id] item = self._get_item_from_id(trans, idnum) if item is not None: new_annotation = payload.get("text") # Sanitize annotation before adding it. new_annotation = sanitize_html( new_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), item, new_annotation ) trans.sa_session.flush() return new_annotation return ""
def _yield_user_file_content(self, trans, from_dataset, filename): """This method is responsible for sanitizing the HTML if needed.""" if trans.app.config.sanitize_all_html and trans.response.get_content_type() == "text/html": # Sanitize anytime we respond with plain text/html content. # Check to see if this dataset's parent job is whitelisted # We cannot currently trust imported datasets for rendering. if not from_dataset.creating_job.imported and from_dataset.creating_job.tool_id in trans.app.config.sanitize_whitelist: return open(filename, mode='rb') # This is returning to the browser, it needs to be encoded. # TODO Ideally this happens a layer higher, but this is a bad # issue affecting many tools return sanitize_html(open(filename, 'r').read()).encode('utf-8') return open(filename, mode='rb')
def create(self, trans, payload, **kwd): if "text" not in payload: return "" idnum = kwd[self.tagged_item_id] item = self._get_item_from_id(trans, idnum) if item is not None: new_annotation = payload.get("text") # TODO: sanitize on display not entry new_annotation = sanitize_html(new_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), item, new_annotation) trans.sa_session.flush() return new_annotation return ""
def _yield_user_file_content(self, trans, from_dataset, filename): """This method is responsible for sanitizing the HTML if needed.""" if trans.app.config.sanitize_all_html and trans.response.get_content_type() == "text/html": # Sanitize anytime we respond with plain text/html content. # Check to see if this dataset's parent job is whitelisted # We cannot currently trust imported datasets for rendering. if not from_dataset.creating_job.imported and from_dataset.creating_job.tool_id in trans.app.config.sanitize_whitelist: return open(filename) # This is returning to the browser, it needs to be encoded. # TODO Ideally this happens a layer higher, but this is a bad # issue affecting many tools return sanitize_html(open(filename).read()).encode('utf-8') return open(filename)
def edit( self, trans, id, page_title="", page_slug="", page_annotation="" ): """ Edit a page's attributes. """ encoded_id = id id = trans.security.decode_id( id ) session = trans.sa_session page = session.query( model.Page ).get( id ) user = trans.user assert page.user == user page_title_err = page_slug_err = page_annotation_err = "" if trans.request.method == "POST": if not page_title: page_title_err = "Page name is required" elif not page_slug: page_slug_err = "Page id is required" elif not self._is_valid_slug( page_slug ): page_slug_err = "Page identifier must consist of only lowercase letters, numbers, and the '-' character" elif page_slug != page.slug and trans.sa_session.query( model.Page ).filter_by( user=user, slug=page_slug, deleted=False ).first(): page_slug_err = "Page id must be unique" elif not page_annotation: page_annotation_err = "Page annotation is required" else: page.title = page_title page.slug = page_slug page_annotation = sanitize_html( page_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), page, page_annotation ) session.flush() # Redirect to page list. return trans.response.send_redirect( web.url_for(controller='page', action='list' ) ) else: page_title = page.title page_slug = page.slug page_annotation = self.get_item_annotation_str( trans.sa_session, trans.user, page ) if not page_annotation: page_annotation = "" return trans.show_form( web.FormBuilder( web.url_for(controller='page', action='edit', id=encoded_id ), "Edit page attributes", submit_text="Submit" ) .add_text( "page_title", "Page title", value=page_title, error=page_title_err ) .add_text( "page_slug", "Page identifier", value=page_slug, error=page_slug_err, help="""A unique identifier that will be used for public links to this page. A default is generated from the page title, but can be edited. This field must contain only lowercase letters, numbers, and the '-' character.""" ) .add_text( "page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err, help="A description of the page; annotation is shown alongside published pages."), template="page/create.mako" )
def create(self, trans, payload=None, **kwd): if trans.request.method == 'GET': return { 'title': 'Create Workflow', 'inputs': [{ 'name': 'workflow_name', 'label': 'Name', 'value': 'Unnamed workflow' }, { 'name': 'workflow_annotation', 'label': 'Annotation', 'help': 'A description of the workflow; annotation is shown alongside shared or published workflows.' }] } else: user = trans.get_user() workflow_name = payload.get('workflow_name') workflow_annotation = payload.get('workflow_annotation') if not workflow_name: return self.message_exception( trans, 'Please provide a workflow name.') # Create the new stored workflow stored_workflow = model.StoredWorkflow() stored_workflow.name = workflow_name stored_workflow.user = user self.slug_builder.create_item_slug(trans.sa_session, stored_workflow) # And the first (empty) workflow revision workflow = model.Workflow() workflow.name = workflow_name workflow.stored_workflow = stored_workflow stored_workflow.latest_workflow = workflow # Add annotation. workflow_annotation = sanitize_html(workflow_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, workflow_annotation) # Persist session = trans.sa_session session.add(stored_workflow) session.flush() return { 'id': trans.security.encode_id(stored_workflow.id), 'message': f'Workflow {workflow_name} has been created.' }
def create( self, trans, page_title="", page_slug="", page_annotation="" ): """ Create a new page """ user = trans.get_user() page_title_err = page_slug_err = page_annotation_err = "" if trans.request.method == "POST": if not page_title: page_title_err = "Page name is required" elif not page_slug: page_slug_err = "Page id is required" elif not self._is_valid_slug( page_slug ): page_slug_err = "Page identifier must consist of only lowercase letters, numbers, and the '-' character" elif trans.sa_session.query( model.Page ).filter_by( user=user, slug=page_slug, deleted=False ).first(): page_slug_err = "Page id must be unique" else: # Create the new stored page page = model.Page() page.title = page_title page.slug = page_slug page_annotation = sanitize_html( page_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), page, page_annotation ) page.user = user # And the first (empty) page revision page_revision = model.PageRevision() page_revision.title = page_title page_revision.page = page page.latest_revision = page_revision page_revision.content = "" # Persist session = trans.sa_session session.add( page ) session.flush() # Display the management page ## trans.set_message( "Page '%s' created" % page.title ) return trans.response.send_redirect( web.url_for(controller='page', action='list' ) ) return trans.show_form( web.FormBuilder( web.url_for(controller='page', action='create'), "Create new page", submit_text="Submit" ) .add_text( "page_title", "Page title", value=page_title, error=page_title_err ) .add_text( "page_slug", "Page identifier", value=page_slug, error=page_slug_err, help="""A unique identifier that will be used for public links to this page. A default is generated from the page title, but can be edited. This field must contain only lowercase letters, numbers, and the '-' character.""" ) .add_text( "page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err, help="A description of the page; annotation is shown alongside published pages."), template="page/create.mako" )
def edit( self, trans, id, page_title="", page_slug="", page_annotation="" ): """ Edit a page's attributes. """ encoded_id = id id = self.decode_id( id ) session = trans.sa_session page = session.query( model.Page ).get( id ) user = trans.user assert page.user == user page_title_err = page_slug_err = page_annotation_err = "" if trans.request.method == "POST": if not page_title: page_title_err = "Page name is required" elif not page_slug: page_slug_err = "Page id is required" elif not self._is_valid_slug( page_slug ): page_slug_err = "Page identifier must consist of only lowercase letters, numbers, and the '-' character" elif page_slug != page.slug and trans.sa_session.query( model.Page ).filter_by( user=user, slug=page_slug, deleted=False ).first(): page_slug_err = "Page id must be unique" elif not page_annotation: page_annotation_err = "Page annotation is required" else: page.title = page_title page.slug = page_slug page_annotation = sanitize_html( page_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), page, page_annotation ) session.flush() # Redirect to page list. return trans.response.send_redirect( web.url_for(controller='page', action='list' ) ) else: page_title = page.title page_slug = page.slug page_annotation = self.get_item_annotation_str( trans.sa_session, trans.user, page ) if not page_annotation: page_annotation = "" return trans.show_form( web.FormBuilder( web.url_for(controller='page', action='edit', id=encoded_id ), "Edit page attributes", submit_text="Submit" ) .add_text( "page_title", "Page title", value=page_title, error=page_title_err ) .add_text( "page_slug", "Page identifier", value=page_slug, error=page_slug_err, help="""A unique identifier that will be used for public links to this page. A default is generated from the page title, but can be edited. This field must contain only lowercase letters, numbers, and the '-' character.""" ) .add_text( "page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err, help="A description of the page; annotation is shown alongside published pages."), template="page/create.mako" )
def create( self, trans, page_title="", page_slug="", page_annotation="" ): """ Create a new page """ user = trans.get_user() page_title_err = page_slug_err = page_annotation_err = "" if trans.request.method == "POST": if not page_title: page_title_err = "Page name is required" elif not page_slug: page_slug_err = "Page id is required" elif not self._is_valid_slug( page_slug ): page_slug_err = "Page identifier must consist of only lowercase letters, numbers, and the '-' character" elif trans.sa_session.query( model.Page ).filter_by( user=user, slug=page_slug, deleted=False ).first(): page_slug_err = "Page id must be unique" else: # Create the new stored page page = model.Page() page.title = page_title page.slug = page_slug page_annotation = sanitize_html( page_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), page, page_annotation ) page.user = user # And the first (empty) page revision page_revision = model.PageRevision() page_revision.title = page_title page_revision.page = page page.latest_revision = page_revision page_revision.content = "" # Persist session = trans.sa_session session.add( page ) session.flush() # Display the management page # trans.set_message( "Page '%s' created" % page.title ) return trans.response.send_redirect( web.url_for(controller='page', action='list' ) ) return trans.show_form( web.FormBuilder( web.url_for(controller='page', action='create'), "Create new page", submit_text="Submit" ) .add_text( "page_title", "Page title", value=page_title, error=page_title_err ) .add_text( "page_slug", "Page identifier", value=page_slug, error=page_slug_err, help="""A unique identifier that will be used for public links to this page. A default is generated from the page title, but can be edited. This field must contain only lowercase letters, numbers, and the '-' character.""" ) .add_text( "page_annotation", "Page annotation", value=page_annotation, error=page_annotation_err, help="A description of the page; annotation is shown alongside published pages."), template="page/create.mako" )
def edit( self, trans, id, visualization_title="", visualization_slug="", visualization_annotation="" ): """ Edit a visualization's attributes. """ visualization = self.get_visualization( trans, id, check_ownership=True ) session = trans.sa_session visualization_title_err = visualization_slug_err = visualization_annotation_err = "" if trans.request.method == "POST": if not visualization_title: visualization_title_err = "Visualization name is required" elif not visualization_slug: visualization_slug_err = "Visualization id is required" elif not self._is_valid_slug( visualization_slug ): visualization_slug_err = "Visualization identifier must consist of only lowercase letters, numbers, and the '-' character" elif visualization_slug != visualization.slug and trans.sa_session.query( model.Visualization ).filter_by( user=visualization.user, slug=visualization_slug, deleted=False ).first(): visualization_slug_err = "Visualization id must be unique" else: visualization.title = visualization_title visualization.slug = visualization_slug if visualization_annotation != "": visualization_annotation = sanitize_html( visualization_annotation, 'utf-8', 'text/html' ) self.add_item_annotation( trans.sa_session, trans.get_user(), visualization, visualization_annotation ) session.flush() # Redirect to visualization list. return trans.response.send_redirect( web.url_for(controller='visualization', action='list' ) ) else: visualization_title = visualization.title # Create slug if it's not already set. if visualization.slug is None: self.create_item_slug( trans.sa_session, visualization ) visualization_slug = visualization.slug visualization_annotation = self.get_item_annotation_str( trans.sa_session, trans.user, visualization ) if not visualization_annotation: visualization_annotation = "" return trans.show_form( web.FormBuilder( web.url_for(controller='visualization', action='edit', id=id ), "Edit visualization attributes", submit_text="Submit" ) .add_text( "visualization_title", "Visualization title", value=visualization_title, error=visualization_title_err ) .add_text( "visualization_slug", "Visualization identifier", value=visualization_slug, error=visualization_slug_err, help="""A unique identifier that will be used for public links to this visualization. A default is generated from the visualization title, but can be edited. This field must contain only lowercase letters, numbers, and the '-' character.""" ) .add_text( "visualization_annotation", "Visualization annotation", value=visualization_annotation, error=visualization_annotation_err, help="A description of the visualization; annotation is shown alongside published visualizations."), template="visualization/create.mako" )
def save_workflow_as(self, trans, workflow_name, workflow_data, workflow_annotation=""): """ Creates a new workflow based on Save As command. It is a new workflow, but is created with workflow_data already present. """ user = trans.get_user() if workflow_name is not None: workflow_contents_manager = workflows.WorkflowContentsManager(trans.app) stored_workflow = model.StoredWorkflow() stored_workflow.name = workflow_name stored_workflow.user = user self.create_item_slug(trans.sa_session, stored_workflow) workflow = model.Workflow() workflow.name = workflow_name workflow.stored_workflow = stored_workflow stored_workflow.latest_workflow = workflow # Add annotation. workflow_annotation = sanitize_html(workflow_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, workflow_annotation) # Persist session = trans.sa_session session.add(stored_workflow) session.flush() try: workflow, errors = workflow_contents_manager.update_workflow_from_dict( trans, stored_workflow, workflow_data, ) except workflows.MissingToolsException as e: return dict( name=e.workflow.name, message=("This workflow includes missing or invalid tools. " "It cannot be saved until the following steps are removed or the missing tools are enabled."), errors=e.errors, ) return (trans.security.encode_id(stored_workflow.id)) else: # This is an error state, 'save as' must have a workflow_name log.exception("Error in Save As workflow: no name.")
def create( self, trans, page_id, payload, **kwd ): """ create( self, trans, page_id, payload **kwd ) * POST /api/pages/{page_id}/revisions Create a new revision for a page :param page_id: Add revision to Page with ID=page_id :param payload: A dictionary containing:: 'title' = New title of the page 'content' = New content of the page :rtype: dictionary :returns: Dictionary with 'success' or 'error' element to indicate the result of the request """ content = payload.get("content", None) if not content: raise exceptions.ObjectAttributeMissingException("content undefined or empty") page = self._get_page( trans, page_id ) self._verify_page_ownership( trans, page ) if 'title' in payload: title = payload['title'] else: title = page.title content = sanitize_html( content, 'utf-8', 'text/html' ) page_revision = trans.app.model.PageRevision() page_revision.title = title page_revision.page = page page.latest_revision = page_revision page_revision.content = content # Persist session = trans.sa_session session.flush() return page_revision.to_dict( view="element" )
def save_workflow( trans, workflow, workflow_dict=None): """Use the received in-memory Workflow object for saving to the Galaxy database.""" stored = trans.model.StoredWorkflow() stored.name = workflow.name workflow.stored_workflow = stored stored.latest_workflow = workflow stored.user = trans.user if workflow_dict and workflow_dict.get('annotation', ''): annotation = sanitize_html( workflow_dict['annotation'], 'utf-8', 'text/html' ) new_annotation = trans.model.StoredWorkflowAnnotationAssociation() new_annotation.annotation = annotation new_annotation.user = trans.user stored.annotations.append(new_annotation) trans.sa_session.add( stored ) trans.sa_session.flush() # Add a new entry to the Workflows menu. if trans.user.stored_workflow_menu_entries is None: trans.user.stored_workflow_menu_entries = [] menuEntry = trans.model.StoredWorkflowMenuEntry() menuEntry.stored_workflow = stored trans.user.stored_workflow_menu_entries.append( menuEntry ) trans.sa_session.flush() return stored