Example #1
0
def artifact_summary_post_request(user_id, artifact_id):
    """Launches the HTML summary generation and returns the job information

    Parameters
    ----------
    user_id : str
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'status': str,
         'message': str,
         'job': list of [str, str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)

    access_error = check_access(artifact.study.id, user_id)
    if access_error:
        return access_error

    # Check if the summary is being generated or has been already generated
    command = Command.get_html_generator(artifact.artifact_type)
    jobs = artifact.jobs(cmd=command)
    jobs = [j for j in jobs if j.status in ['queued', 'running', 'success']]
    if jobs:
        # The HTML summary is either being generated or already generated.
        # Return the information of that job so we only generate the HTML
        # once
        job = jobs[0]
    else:
        # Create a new job to generate the HTML summary and return the newly
        # created job information
        job = ProcessingJob.create(
            User(user_id),
            Parameters.load(command, values_dict={'input_data': artifact_id}))
        job.submit()

    return {
        'status': 'success',
        'message': '',
        'job': [job.id, job.status, job.step]
    }
Example #2
0
def artifact_summary_post_request(user_id, artifact_id):
    """Launches the HTML summary generation and returns the job information

    Parameters
    ----------
    user_id : str
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'status': str,
         'message': str,
         'job': list of [str, str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)

    access_error = check_access(artifact.study.id, user_id)
    if access_error:
        return access_error

    # Check if the summary is being generated or has been already generated
    command = Command.get_html_generator(artifact.artifact_type)
    jobs = artifact.jobs(cmd=command)
    jobs = [j for j in jobs if j.status in ['queued', 'running', 'success']]
    if jobs:
        # The HTML summary is either being generated or already generated.
        # Return the information of that job so we only generate the HTML
        # once
        job = jobs[0]
    else:
        # Create a new job to generate the HTML summary and return the newly
        # created job information
        job = ProcessingJob.create(
            User(user_id),
            Parameters.load(command, values_dict={'input_data': artifact_id}))
        job.submit()

    return {'status': 'success',
            'message': '',
            'job': [job.id, job.status, job.step]}
Example #3
0
def artifact_summary_post_request(user, artifact_id):
    """Launches the HTML summary generation and returns the job information

    Parameters
    ----------
    user : qiita_db.user.User
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the job summary information
        {'job': [str, str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)

    check_artifact_access(user, artifact)

    # Check if the summary is being generated or has been already generated
    command = Command.get_html_generator(artifact.artifact_type)
    jobs = artifact.jobs(cmd=command)
    jobs = [j for j in jobs if j.status in ['queued', 'running', 'success']]
    if jobs:
        # The HTML summary is either being generated or already generated.
        # Return the information of that job so we only generate the HTML
        # once - Magic number 0 -> we are ensuring that there is only one
        # job generating the summary, so we can use the index 0 to access to
        # that job
        job = jobs[0]
    else:
        # Create a new job to generate the HTML summary and return the newly
        # created job information
        job = ProcessingJob.create(
            user,
            Parameters.load(command, values_dict={'input_data': artifact_id}),
            True)
        job.submit()

    return {'job': [job.id, job.status, job.step]}
Example #4
0
def artifact_summary_post_request(user, artifact_id):
    """Launches the HTML summary generation and returns the job information

    Parameters
    ----------
    user : qiita_db.user.User
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the job summary information
        {'job': [str, str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)

    check_artifact_access(user, artifact)

    # Check if the summary is being generated or has been already generated
    command = Command.get_html_generator(artifact.artifact_type)
    jobs = artifact.jobs(cmd=command)
    jobs = [j for j in jobs if j.status in ['queued', 'running', 'success']]
    if jobs:
        # The HTML summary is either being generated or already generated.
        # Return the information of that job so we only generate the HTML
        # once - Magic number 0 -> we are ensuring that there is only one
        # job generating the summary, so we can use the index 0 to access to
        # that job
        job = jobs[0]
    else:
        # Create a new job to generate the HTML summary and return the newly
        # created job information
        job = ProcessingJob.create(user, Parameters.load(
            command, values_dict={'input_data': artifact_id}), True)
        job.submit()

    return {'job': [job.id, job.status, job.step]}
Example #5
0
def artifact_summary_get_request(user_id, artifact_id):
    """Returns the information for the artifact summary page

    Parameters
    ----------
    user_id : str
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'status': str,
         'message': str,
         'name': str,
         'summary': str,
         'job': list of [str, str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)

    access_error = check_access(artifact.study.id, user_id)
    if access_error:
        return access_error

    user = User(user_id)
    visibility = artifact.visibility
    summary = artifact.html_summary_fp
    job_info = None
    errored_jobs = []
    processing_jobs = []
    for j in artifact.jobs():
        if j.command.software.type == "artifact transformation":
            status = j.status
            if status == 'success':
                continue
            j_msg = j.log.msg if status == 'error' else None
            processing_jobs.append(
                [j.id, j.command.name, j.status, j.step, j_msg])

    # Check if the HTML summary exists
    if summary:
        with open(summary[1]) as f:
            summary = f.read()
    else:
        # Check if the summary is being generated
        command = Command.get_html_generator(artifact.artifact_type)
        all_jobs = set(artifact.jobs(cmd=command))
        jobs = [j for j in all_jobs if j.status in ['queued', 'running']]
        errored_jobs = [(j.id, j.log.msg)
                        for j in all_jobs if j.status in ['error']]
        if jobs:
            # There is already a job generating the HTML. Also, there should be
            # at most one job, because we are not allowing here to start more
            # than one
            job = jobs[0]
            job_info = [job.id, job.status, job.step]

    buttons = []
    btn_base = (
        '<button onclick="if (confirm(\'Are you sure you want to %s '
        'artifact id: {0}?\')) {{ set_artifact_visibility(\'%s\', {0}) }}" '
        'class="btn btn-primary btn-sm">%s</button>').format(artifact_id)

    if qiita_config.require_approval:
        if visibility == 'sandbox':
            # The request approval button only appears if the artifact is
            # sandboxed and the qiita_config specifies that the approval should
            # be requested
            buttons.append(
                btn_base % ('request approval for', 'awaiting_approval',
                            'Request approval'))

        elif user.level == 'admin' and visibility == 'awaiting_approval':
            # The approve artifact button only appears if the user is an admin
            # the artifact is waiting to be approvaed and the qiita config
            # requires artifact approval
            buttons.append(btn_base % ('approve', 'private',
                                       'Approve artifact'))
    if visibility == 'private':
        # The make public button only appears if the artifact is private
        buttons.append(btn_base % ('make public', 'public', 'Make public'))

    # The revert to sandbox button only appears if the artifact is not
    # sandboxed nor public
    if visibility not in {'sandbox', 'public'}:
        buttons.append(btn_base % ('revert to sandbox', 'sandbox',
                                   'Revert to sandbox'))

    if artifact.can_be_submitted_to_ebi:
        if not artifact.is_submitted_to_ebi:
            buttons.append(
                '<a class="btn btn-primary btn-sm" '
                'href="/ebi_submission/%d">'
                '<span class="glyphicon glyphicon-export"></span>'
                ' Submit to EBI</a>' % artifact_id)
    if artifact.can_be_submitted_to_vamps:
        if not artifact.is_submitted_to_vamps:
            buttons.append(
                '<a class="btn btn-primary btn-sm" href="/vamps/%d">'
                '<span class="glyphicon glyphicon-export"></span>'
                ' Submit to VAMPS</a>' % artifact_id)
    files = [(f_id, "%s (%s)" % (basename(fp), f_type.replace('_', ' ')))
             for f_id, fp, f_type in artifact.filepaths
             if f_type != 'directory']

    # TODO: https://github.com/biocore/qiita/issues/1724 Remove this hardcoded
    # values to actually get the information from the database once it stores
    # the information
    if artifact.artifact_type in ['SFF', 'FASTQ', 'FASTA', 'FASTA_Sanger',
                                  'per_sample_FASTQ']:
        # If the artifact is one of the "raw" types, only the owner of the
        # study and users that has been shared with can see the files
        if not artifact.study.has_access(user, no_public=True):
            files = []

    return {'status': 'success',
            'message': '',
            'name': artifact.name,
            'summary': summary,
            'job': job_info,
            'errored_jobs': errored_jobs,
            'processing_jobs': processing_jobs,
            'visibility': visibility,
            'buttons': ' '.join(buttons),
            'files': files,
            'editable': artifact.study.can_edit(user)}
Example #6
0
def artifact_summary_get_request(user, artifact_id):
    """Returns the information for the artifact summary page

    Parameters
    ----------
    user : qiita_db.user.User
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'name': str,
         'artifact_id': int,
         'visibility': str,
         'editable': bool,
         'buttons': str,
         'processing_parameters': dict of {str: object},
         'files': list of (int, str),
         'is_from_analysis': bool,
         'summary': str or None,
         'job': [str, str, str],
         'errored_jobs': list of [str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)
    artifact_type = artifact.artifact_type

    check_artifact_access(user, artifact)

    visibility = artifact.visibility
    summary = artifact.html_summary_fp
    job_info = None
    errored_summary_jobs = []

    # Check if the HTML summary exists
    if summary:
        # Magic number 1: If the artifact has a summary, the call
        # artifact.html_summary_fp returns a tuple with 2 elements. The first
        # element is the filepath id, while the second one is the actual
        # actual filepath. We are only interested on the actual filepath,
        # hence the 1 value.
        summary = relpath(summary[1], qiita_config.base_data_dir)
    else:
        # Check if the summary is being generated
        command = Command.get_html_generator(artifact_type)
        all_jobs = set(artifact.jobs(cmd=command))
        jobs = []
        errored_summary_jobs = []
        for j in all_jobs:
            if j.status in ['queued', 'running']:
                jobs.append(j)
            elif j.status in ['error']:
                errored_summary_jobs.append(j)
        if jobs:
            # There is already a job generating the HTML. Also, there should be
            # at most one job, because we are not allowing here to start more
            # than one
            job = jobs[0]
            job_info = [job.id, job.status, job.step]

    # Check if the artifact is editable by the given user
    study = artifact.study
    analysis = artifact.analysis
    if artifact_type == 'job-output-folder':
        editable = False
    else:
        editable = study.can_edit(user) if study else analysis.can_edit(user)

    buttons = []
    btn_base = (
        '<button onclick="if (confirm(\'Are you sure you want to %s '
        'artifact id: {0}?\')) {{ set_artifact_visibility(\'%s\', {0}) }}" '
        'class="btn btn-primary btn-sm">%s</button>').format(artifact_id)
    if not analysis and artifact_type != 'job-output-folder':
        # If the artifact is part of a study, the buttons shown depend in
        # multiple factors (see each if statement for an explanation of those)
        if qiita_config.require_approval:
            if visibility == 'sandbox' and artifact.parents:
                # The request approval button only appears if the artifact is
                # sandboxed and the qiita_config specifies that the approval
                # should be requested
                buttons.append(btn_base %
                               ('request approval for', 'awaiting_approval',
                                'Request approval'))
            elif user.level == 'admin' and visibility == 'awaiting_approval':
                # The approve artifact button only appears if the user is an
                # admin the artifact is waiting to be approvaed and the qiita
                # config requires artifact approval
                buttons.append(btn_base %
                               ('approve', 'private', 'Approve artifact'))

        if visibility == 'private':
            # The make public button only appears if the artifact is private
            buttons.append(btn_base % ('make public', 'public', 'Make public'))

        # The revert to sandbox button only appears if the artifact is not
        # sandboxed nor public
        if visibility not in {'sandbox', 'public'}:
            buttons.append(
                btn_base %
                ('revert to sandbox', 'sandbox', 'Revert to sandbox'))

        if user.level == 'admin' and not study.autoloaded:
            if artifact.can_be_submitted_to_ebi:
                buttons.append(
                    '<a class="btn btn-primary btn-sm" '
                    'href="/ebi_submission/%d">'
                    '<span class="glyphicon glyphicon-export"></span>'
                    ' Submit to EBI</a>' % artifact_id)
            if artifact.can_be_submitted_to_vamps:
                if not artifact.is_submitted_to_vamps:
                    buttons.append(
                        '<a class="btn btn-primary btn-sm" href="/vamps/%d">'
                        '<span class="glyphicon glyphicon-export"></span>'
                        ' Submit to VAMPS</a>' % artifact_id)

    if visibility != 'public':
        # Have no fear, this is just python to generate html with an onclick in
        # javascript that makes an ajax call to a separate url, takes the
        # response and writes it to the newly uncollapsed div.  Do note that
        # you have to be REALLY CAREFUL with properly escaping quotation marks.
        private_download = (
            '<button class="btn btn-primary btn-sm" type="button" '
            'aria-expanded="false" aria-controls="privateDownloadLink" '
            'onclick="generate_private_download_link(%d)">Generate '
            'Download Link</button><div class="collapse" '
            'id="privateDownloadLink"><div class="card card-body" '
            'id="privateDownloadText">Generating Download Link...'
            '</div></div>') % artifact_id
        buttons.append(private_download)

    files = [(x['fp_id'],
              "%s (%s)" % (basename(x['fp']), x['fp_type'].replace('_', ' ')),
              x['checksum'], naturalsize(x['fp_size'], gnu=True))
             for x in artifact.filepaths if x['fp_type'] != 'directory']

    # TODO: https://github.com/biocore/qiita/issues/1724 Remove this hardcoded
    # values to actually get the information from the database once it stores
    # the information
    if artifact_type in [
            'SFF', 'FASTQ', 'FASTA', 'FASTA_Sanger', 'per_sample_FASTQ'
    ]:
        # If the artifact is one of the "raw" types, only the owner of the
        # study and users that has been shared with can see the files
        study = artifact.study
        has_access = study.has_access(user, no_public=True)
        if (not study.public_raw_download and not has_access):
            files = []

    proc_params = artifact.processing_parameters
    if proc_params:
        cmd = proc_params.command
        sw = cmd.software
        processing_info = {
            'command': cmd.name,
            'software': sw.name,
            'software_version': sw.version,
            'processing_parameters': proc_params.values,
            'command_active': cmd.active,
            'software_deprecated': sw.deprecated,
        }
    else:
        processing_info = {}

    return {
        'name': artifact.name,
        'artifact_id': artifact_id,
        'artifact_type': artifact_type,
        'visibility': visibility,
        'editable': editable,
        'buttons': ' '.join(buttons),
        'processing_info': processing_info,
        'files': files,
        'is_from_analysis': artifact.analysis is not None,
        'summary': summary,
        'job': job_info,
        'artifact_timestamp': artifact.timestamp.strftime("%Y-%m-%d %H:%m"),
        'being_deleted': artifact.being_deleted_by is not None,
        'errored_summary_jobs': errored_summary_jobs
    }
Example #7
0
def artifact_summary_get_request(user, artifact_id):
    """Returns the information for the artifact summary page

    Parameters
    ----------
    user : qiita_db.user.User
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'name': str,
         'artifact_id': int,
         'visibility': str,
         'editable': bool,
         'buttons': str,
         'processing_parameters': dict of {str: object},
         'files': list of (int, str),
         'is_from_analysis': bool,
         'summary': str or None,
         'job': [str, str, str],
         'errored_jobs': list of [str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)
    artifact_type = artifact.artifact_type

    check_artifact_access(user, artifact)

    visibility = artifact.visibility
    summary = artifact.html_summary_fp
    job_info = None
    errored_summary_jobs = []

    # Check if the HTML summary exists
    if summary:
        # Magic number 1: If the artifact has a summary, the call
        # artifact.html_summary_fp returns a tuple with 2 elements. The first
        # element is the filepath id, while the second one is the actual
        # actual filepath. We are only interested on the actual filepath,
        # hence the 1 value.
        summary = relpath(summary[1], qiita_config.base_data_dir)
    else:
        # Check if the summary is being generated
        command = Command.get_html_generator(artifact_type)
        all_jobs = set(artifact.jobs(cmd=command))
        jobs = []
        errored_summary_jobs = []
        for j in all_jobs:
            if j.status in ['queued', 'running']:
                jobs.append(j)
            elif j.status in ['error']:
                errored_summary_jobs.append(j)
        if jobs:
            # There is already a job generating the HTML. Also, there should be
            # at most one job, because we are not allowing here to start more
            # than one
            job = jobs[0]
            job_info = [job.id, job.status, job.step]

    # Check if the artifact is editable by the given user
    study = artifact.study
    analysis = artifact.analysis
    editable = study.can_edit(user) if study else analysis.can_edit(user)

    buttons = []
    btn_base = (
        '<button onclick="if (confirm(\'Are you sure you want to %s '
        'artifact id: {0}?\')) {{ set_artifact_visibility(\'%s\', {0}) }}" '
        'class="btn btn-primary btn-sm">%s</button>').format(artifact_id)

    if not analysis:
        # If the artifact is part of a study, the buttons shown depend in
        # multiple factors (see each if statement for an explanation of those)
        if qiita_config.require_approval:
            if visibility == 'sandbox' and artifact.parents:
                # The request approval button only appears if the artifact is
                # sandboxed and the qiita_config specifies that the approval
                # should be requested
                buttons.append(
                    btn_base % ('request approval for', 'awaiting_approval',
                                'Request approval'))
            elif user.level == 'admin' and visibility == 'awaiting_approval':
                # The approve artifact button only appears if the user is an
                # admin the artifact is waiting to be approvaed and the qiita
                # config requires artifact approval
                buttons.append(btn_base % ('approve', 'private',
                                           'Approve artifact'))

        if visibility == 'private':
            # The make public button only appears if the artifact is private
            buttons.append(btn_base % ('make public', 'public', 'Make public'))

        # The revert to sandbox button only appears if the artifact is not
        # sandboxed nor public
        if visibility not in {'sandbox', 'public'}:
            buttons.append(btn_base % ('revert to sandbox', 'sandbox',
                                       'Revert to sandbox'))

        if user.level == 'admin':
            if artifact.can_be_submitted_to_ebi:
                buttons.append(
                    '<a class="btn btn-primary btn-sm" '
                    'href="/ebi_submission/%d">'
                    '<span class="glyphicon glyphicon-export"></span>'
                    ' Submit to EBI</a>' % artifact_id)
            if artifact.can_be_submitted_to_vamps:
                if not artifact.is_submitted_to_vamps:
                    buttons.append(
                        '<a class="btn btn-primary btn-sm" href="/vamps/%d">'
                        '<span class="glyphicon glyphicon-export"></span>'
                        ' Submit to VAMPS</a>' % artifact_id)

    files = [(x['fp_id'], "%s (%s)" % (basename(x['fp']),
                                       x['fp_type'].replace('_', ' ')),
              x['checksum'], naturalsize(x['fp_size']))
             for x in artifact.filepaths if x['fp_type'] != 'directory']

    # TODO: https://github.com/biocore/qiita/issues/1724 Remove this hardcoded
    # values to actually get the information from the database once it stores
    # the information
    if artifact_type in ['SFF', 'FASTQ', 'FASTA', 'FASTA_Sanger',
                         'per_sample_FASTQ']:
        # If the artifact is one of the "raw" types, only the owner of the
        # study and users that has been shared with can see the files
        study = artifact.study
        has_access = study.has_access(user, no_public=True)
        if (not study.public_raw_download and not has_access):
            files = []

    proc_params = artifact.processing_parameters
    if proc_params:
        cmd = proc_params.command
        sw = cmd.software
        processing_info = {
            'command': cmd.name,
            'software': sw.name,
            'software_version': sw.version,
            'processing_parameters': proc_params.values,
            'command_active': cmd.active,
            'software_deprecated': sw.deprecated,
            }
    else:
        processing_info = {}

    return {'name': artifact.name,
            'artifact_id': artifact_id,
            'artifact_type': artifact_type,
            'visibility': visibility,
            'editable': editable,
            'buttons': ' '.join(buttons),
            'processing_info': processing_info,
            'files': files,
            'is_from_analysis': artifact.analysis is not None,
            'summary': summary,
            'job': job_info,
            'artifact_timestamp': artifact.timestamp.strftime(
                "%Y-%m-%d %H:%m"),
            'errored_summary_jobs': errored_summary_jobs}
Example #8
0
def artifact_summary_get_request(user, artifact_id):
    """Returns the information for the artifact summary page

    Parameters
    ----------
    user : qiita_db.user.User
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'name': str,
         'artifact_id': int,
         'visibility': str,
         'editable': bool,
         'buttons': str,
         'processing_parameters': dict of {str: object},
         'files': list of (int, str),
         'is_from_analysis': bool,
         'processing_jobs': list of [str, str, str, str, str],
         'summary': str or None,
         'job': [str, str, str],
         'errored_jobs': list of [str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)
    artifact_type = artifact.artifact_type

    check_artifact_access(user, artifact)

    visibility = artifact.visibility
    summary = artifact.html_summary_fp
    job_info = None
    errored_jobs = []
    processing_jobs = []
    for j in artifact.jobs():
        if j.command.software.type == "artifact transformation":
            status = j.status
            if status == 'success':
                continue
            j_msg = j.log.msg if status == 'error' else None
            processing_jobs.append(
                [j.id, j.command.name, j.status, j.step, j_msg])

    # Check if the HTML summary exists
    if summary:
        # Magic number 1: If the artifact has a summary, the call
        # artifact.html_summary_fp returns a tuple with 2 elements. The first
        # element is the filepath id, while the second one is the actual
        # actual filepath. We are only interested on the actual filepath,
        # hence the 1 value.
        summary = relpath(summary[1], qiita_config.base_data_dir)
    else:
        # Check if the summary is being generated
        command = Command.get_html_generator(artifact_type)
        all_jobs = set(artifact.jobs(cmd=command))
        jobs = [j for j in all_jobs if j.status in ['queued', 'running']]
        errored_jobs = [(j.id, j.log.msg) for j in all_jobs
                        if j.status in ['error']]
        if jobs:
            # There is already a job generating the HTML. Also, there should be
            # at most one job, because we are not allowing here to start more
            # than one
            job = jobs[0]
            job_info = [job.id, job.status, job.step]

    # Check if the artifact is editable by the given user
    study = artifact.study
    analysis = artifact.analysis
    editable = study.can_edit(user) if study else analysis.can_edit(user)

    buttons = []
    btn_base = (
        '<button onclick="if (confirm(\'Are you sure you want to %s '
        'artifact id: {0}?\')) {{ set_artifact_visibility(\'%s\', {0}) }}" '
        'class="btn btn-primary btn-sm">%s</button>').format(artifact_id)

    if analysis:
        # If the artifact is part of an analysis, we don't require admin
        # approval, and the artifact can be made public only if all the
        # artifacts used to create the initial artifact set are public
        if analysis.can_be_publicized and visibility != 'public':
            buttons.append(btn_base % ('make public', 'public', 'Make public'))

    else:
        # If the artifact is part of a study, the buttons shown depend in
        # multiple factors (see each if statement for an explanation of those)
        if qiita_config.require_approval:
            if visibility == 'sandbox':
                # The request approval button only appears if the artifact is
                # sandboxed and the qiita_config specifies that the approval
                # should be requested
                buttons.append(btn_base %
                               ('request approval for', 'awaiting_approval',
                                'Request approval'))
            elif user.level == 'admin' and visibility == 'awaiting_approval':
                # The approve artifact button only appears if the user is an
                # admin the artifact is waiting to be approvaed and the qiita
                # config requires artifact approval
                buttons.append(btn_base %
                               ('approve', 'private', 'Approve artifact'))

        if visibility == 'private':
            # The make public button only appears if the artifact is private
            buttons.append(btn_base % ('make public', 'public', 'Make public'))

        # The revert to sandbox button only appears if the artifact is not
        # sandboxed nor public
        if visibility not in {'sandbox', 'public'}:
            buttons.append(
                btn_base %
                ('revert to sandbox', 'sandbox', 'Revert to sandbox'))

        if user.level == 'admin':
            if artifact.can_be_submitted_to_ebi:
                buttons.append(
                    '<a class="btn btn-primary btn-sm" '
                    'href="/ebi_submission/%d">'
                    '<span class="glyphicon glyphicon-export"></span>'
                    ' Submit to EBI</a>' % artifact_id)
            if artifact.can_be_submitted_to_vamps:
                if not artifact.is_submitted_to_vamps:
                    buttons.append(
                        '<a class="btn btn-primary btn-sm" href="/vamps/%d">'
                        '<span class="glyphicon glyphicon-export"></span>'
                        ' Submit to VAMPS</a>' % artifact_id)

    files = [(f_id, "%s (%s)" % (basename(fp), f_type.replace('_', ' ')))
             for f_id, fp, f_type in artifact.filepaths
             if f_type != 'directory']

    # TODO: https://github.com/biocore/qiita/issues/1724 Remove this hardcoded
    # values to actually get the information from the database once it stores
    # the information
    if artifact_type in [
            'SFF', 'FASTQ', 'FASTA', 'FASTA_Sanger', 'per_sample_FASTQ'
    ]:
        # If the artifact is one of the "raw" types, only the owner of the
        # study and users that has been shared with can see the files
        if not artifact.study.has_access(user, no_public=True):
            files = []

    processing_parameters = (artifact.processing_parameters.values
                             if artifact.processing_parameters is not None else
                             {})

    return {
        'name': artifact.name,
        'artifact_id': artifact_id,
        'artifact_type': artifact_type,
        'visibility': visibility,
        'editable': editable,
        'buttons': ' '.join(buttons),
        'processing_parameters': processing_parameters,
        'files': files,
        'is_from_analysis': artifact.analysis is not None,
        'processing_jobs': processing_jobs,
        'summary': summary,
        'job': job_info,
        'artifact_timestamp': artifact.timestamp.strftime("%Y-%m-%d %H:%m"),
        'errored_jobs': errored_jobs
    }
Example #9
0
def artifact_summary_get_request(user_id, artifact_id):
    """Returns the information for the artifact summary page

    Parameters
    ----------
    user_id : str
        The user making the request
    artifact_id : int or str
        The artifact id

    Returns
    -------
    dict of objects
        A dictionary containing the artifact summary information
        {'status': str,
         'message': str,
         'name': str,
         'summary': str,
         'job': list of [str, str, str]}
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)

    access_error = check_access(artifact.study.id, user_id)
    if access_error:
        return access_error

    user = User(user_id)
    visibility = artifact.visibility
    summary = artifact.html_summary_fp
    job_info = None
    errored_jobs = []
    processing_jobs = []
    for j in artifact.jobs():
        if j.command.software.type == "artifact transformation":
            status = j.status
            if status == 'success':
                continue
            j_msg = j.log.msg if status == 'error' else None
            processing_jobs.append(
                [j.id, j.command.name, j.status, j.step, j_msg])

    # Check if the HTML summary exists
    if summary:
        with open(summary[1]) as f:
            summary = f.read()
    else:
        # Check if the summary is being generated
        command = Command.get_html_generator(artifact.artifact_type)
        all_jobs = set(artifact.jobs(cmd=command))
        jobs = [j for j in all_jobs if j.status in ['queued', 'running']]
        errored_jobs = [(j.id, j.log.msg) for j in all_jobs
                        if j.status in ['error']]
        if jobs:
            # There is already a job generating the HTML. Also, there should be
            # at most one job, because we are not allowing here to start more
            # than one
            job = jobs[0]
            job_info = [job.id, job.status, job.step]

    buttons = []
    btn_base = (
        '<button onclick="if (confirm(\'Are you sure you want to %s '
        'artifact id: {0}?\')) {{ set_artifact_visibility(\'%s\', {0}) }}" '
        'class="btn btn-primary btn-sm">%s</button>').format(artifact_id)

    if qiita_config.require_approval:
        if visibility == 'sandbox':
            # The request approval button only appears if the artifact is
            # sandboxed and the qiita_config specifies that the approval should
            # be requested
            buttons.append(btn_base %
                           ('request approval for', 'awaiting_approval',
                            'Request approval'))

        elif user.level == 'admin' and visibility == 'awaiting_approval':
            # The approve artifact button only appears if the user is an admin
            # the artifact is waiting to be approvaed and the qiita config
            # requires artifact approval
            buttons.append(btn_base %
                           ('approve', 'private', 'Approve artifact'))

    if visibility == 'private':
        # The make public button only appears if the artifact is private
        buttons.append(btn_base % ('make public', 'public', 'Make public'))

    # The revert to sandbox button only appears if the artifact is not
    # sandboxed nor public
    if visibility not in {'sandbox', 'public'}:
        buttons.append(btn_base %
                       ('revert to sandbox', 'sandbox', 'Revert to sandbox'))

    if user.level == 'admin':
        if artifact.can_be_submitted_to_ebi:
            if not artifact.is_submitted_to_ebi:
                buttons.append(
                    '<a class="btn btn-primary btn-sm" '
                    'href="/ebi_submission/%d">'
                    '<span class="glyphicon glyphicon-export"></span>'
                    ' Submit to EBI</a>' % artifact_id)
        if artifact.can_be_submitted_to_vamps:
            if not artifact.is_submitted_to_vamps:
                buttons.append(
                    '<a class="btn btn-primary btn-sm" href="/vamps/%d">'
                    '<span class="glyphicon glyphicon-export"></span>'
                    ' Submit to VAMPS</a>' % artifact_id)

    files = [(f_id, "%s (%s)" % (basename(fp), f_type.replace('_', ' ')))
             for f_id, fp, f_type in artifact.filepaths
             if f_type != 'directory']

    # TODO: https://github.com/biocore/qiita/issues/1724 Remove this hardcoded
    # values to actually get the information from the database once it stores
    # the information
    if artifact.artifact_type in [
            'SFF', 'FASTQ', 'FASTA', 'FASTA_Sanger', 'per_sample_FASTQ'
    ]:
        # If the artifact is one of the "raw" types, only the owner of the
        # study and users that has been shared with can see the files
        if not artifact.study.has_access(user, no_public=True):
            files = []

    return {
        'status': 'success',
        'message': '',
        'name': artifact.name,
        'summary': summary,
        'job': job_info,
        'errored_jobs': errored_jobs,
        'processing_jobs': processing_jobs,
        'visibility': visibility,
        'buttons': ' '.join(buttons),
        'files': files,
        'editable': artifact.study.can_edit(user),
        'study_id': artifact.study.id,
        'prep_id': artifact.prep_templates[0].id
    }