예제 #1
0
def upload_collection(user: User, filename: str, new_data: Dict[str, Any], remove_file=True) -> Collection:
    """
    From an uploaded HDF5 file, create a new collection. Metadata will be set from new_data
    :param user:
    :param filename:
    :param new_data:
    :return:
    """
    if validate_file(filename):
        parent_id = new_data['parent_id'] if 'parent_id' in new_data else None
        analysis_id = new_data['analysis_id'] if 'analysis_id' in new_data else None
        analyses = [get_analysis(user, analysis_id)] if analysis_id is not None else []
        new_collection = Collection(owner=user, creator=user, last_editor=user, name=new_data['name'], parent_id=parent_id, analyses=analyses)
        db.session.add(new_collection)
        db.session.commit()
        new_collection.filename = f'{DATADIR}/collections/{new_collection.id}.h5'
        shutil.copy(filename, new_collection.filename)
        if remove_file:
            os.remove(filename)
        new_data['creator_id'] = user.id if 'creator_id' not in new_data else new_data['creator_id']
        new_data['owner_id'] = user.id if 'owner_id' not in new_data else new_data['owner_id']
        update_collection(user, new_collection, new_data)  # apply metadata
        db.session.commit()
        return new_collection
    raise Exception('File not valid.')
예제 #2
0
def render_analysis(analysis_id=None):
    try:
        current_user = get_current_user()
        return render_template('pages/analysis_entry.html',
                               page_data=AnalysisPageData(current_user, get_analysis(current_user, analysis_id)))
    except Exception as e:
        return handle_exception_browser(e)
예제 #3
0
def update_workflow(user: User,
                    workflow: Workflow,
                    new_data: Dict[str, Any],
                    filename: str = None) -> Workflow:
    """
    Update workflow metadata.
    :param user:
    :param workflow:
    :param new_data:
    :parma filename:
    :return:
    """
    if is_write_permitted(user, workflow):
        if 'id' in new_data:
            if workflow.id != int(new_data['id']) and Workflow.query.filter_by(
                    id=new_data['id']) is not None:
                raise ValueError(
                    f'Workflow with id {new_data["id"]} already exists!')
        if 'analysis_ids' in new_data:
            new_analyses = [
                get_analysis(user, analysis_id)
                for analysis_id in new_data['analysis_ids']
            ]
            remove_analyses = [
                analysis for analysis in workflow.analyses
                if analysis.id not in new_data['analysis_ids']
            ]
            for analysis in new_analyses:
                if not is_write_permitted(user, analysis):
                    raise AuthException(
                        f'User {user.email} is not permitted to attach workflow {workflow.id} to analysis {analysis.id}'
                    )
            for analysis in remove_analyses:
                if not is_write_permitted(user, analysis):
                    raise AuthException(
                        f'User {user.email} is not permitted to detach workflow {workflow.id} from analysis {analysis.id}'
                    )
            workflow.analyses = new_analyses
        workflow.update(new_data)
        if 'workflow_definition' in new_data:
            if workflow.file_type == 'json':
                json.dump(new_data['workflow_definition'],
                          open(workflow.filename, 'w+'))
            elif workflow.file_type == 'yaml':
                yaml.dump(new_data['workflow_definition'],
                          open(workflow.filename, 'w+'))
            else:
                open(workflow.filename,
                     'w+').write(new_data['workflow_definition'])
        if filename is not None:
            os.remove(workflow.filename)
            shutil.copy(filename, workflow.filename)
            os.remove(filename)
        db.session.commit()
        return workflow
    raise AuthException(
        f'User {user.email} is not permitted to modify workflow {workflow.id}')
예제 #4
0
def update_external_file(user: User,
                         external_file: ExternalFile,
                         new_data: Dict[str, Any],
                         move_file: bool = False,
                         filename: str = None) -> ExternalFile:
    """
    Update the data in the external file record
    :param user:
    :param external_file:
    :param new_data:
    :param move_file:
    :param filename:
    :return:
    """
    if is_write_permitted(user, external_file):
        if 'id' in new_data:
            if external_file.id != int(
                    new_data['id']) and ExternalFile.query.filter_by(
                        id=new_data['id']) is not None:
                raise ValueError(
                    f'External file with id {new_data["id"]} already exists!')
        if 'analysis_ids' in new_data:
            new_analyses = [
                get_analysis(user, analysis_id)
                for analysis_id in new_data['analysis_ids']
            ]
            remove_analyses = [
                analysis for analysis in external_file.analyses
                if analysis.id not in new_data['analysis_ids']
            ]
            for analysis in new_analyses:
                if not is_write_permitted(user, analysis):
                    raise AuthException(
                        f'User {user.email} is not permitted to attach external file {external_file.id} to analysis {analysis.id}'
                    )
            for analysis in remove_analyses:
                if not is_write_permitted(user, analysis):
                    raise AuthException(
                        f'User {user.email} is not permitted to detach external file {external_file.id} from analysis {analysis.id}'
                    )
            external_file.analyses = new_analyses
        if move_file and 'filename' in new_data:
            original_filename = external_file.filename
            shutil.copy(original_filename, new_data['filename'])
            os.remove(original_filename)
        if filename is not None:
            os.remove(external_file.filename)
            shutil.copy(filename, external_file.filename)
            os.remove(filename)
        external_file.update(new_data)
        external_file.last_editor = user
        db.session.commit()
        return external_file
    raise AuthException(
        f'User {user.id} is not permitted to modify external file record {external_file.id}'
    )
예제 #5
0
def update_collection(user: User, collection: Collection, new_data: Dict[str, Any], filename: str = None) -> Collection:
    """
    Update collection attributes
    :param user:
    :param collection:
    :param new_data:
    :return:
    """
    if is_write_permitted(user, collection):
        # file attributes and database attributes should be separated
        if 'id' in new_data:
            if collection.id != int(new_data['id']) and Collection.query.filter_by(id=new_data['id']) is not None:
                raise ValueError(f'Collection with id {new_data["id"]} already exists!')
        # verify write permissions on analyses to attach to or detach from
        if 'analysis_ids' in new_data:
            new_analyses = [get_analysis(user, analysis_id) for analysis_id in new_data['analysis_ids']]
            remove_analyses = [analysis for analysis in collection.analyses
                               if analysis.id not in new_data['analysis_ids']]
            for analysis in new_analyses:
                if not is_write_permitted(user, analysis):
                    raise AuthException(f'User {user.email} is not permitted to attach collection {collection.id} '
                                        f'to analysis {analysis.id}')
            for analysis in remove_analyses:
                if not is_write_permitted(user, analysis):
                    raise AuthException(f'User {user.email} is not permitted to detach collection {collection.id} '
                                        f'from analysis {analysis.id}')
            collection.analyses = new_analyses
        collection.update(new_data)
        if filename is not None:
            os.remove(collection.filename)
            shutil.copy(filename, collection.filename)
            os.remove(filename)
        if 'file_info' in new_data:
            mdt.update_metadata(collection.filename,
                                {key: value for key, value in new_data['file_info'].items()})
        collection.last_editor = user
        db.session.commit()
        return collection
    raise AuthException(f'User {user.email} is not permitted to modify collection {collection.id}')