def post(self, preprocessed_data_id): user = self.current_user # make sure user is admin and can therefore actually submit to VAMPS if user.level != 'admin': raise HTTPError(403, "User %s cannot submit to VAMPS!" % user.id) msg = '' msg_level = 'success' plugin = Software.from_name_and_version('Qiita', 'alpha') cmd = plugin.get_command('submit_to_VAMPS') artifact = Artifact(preprocessed_data_id) # Check if the artifact is already being submitted to VAMPS is_being_submitted = any([ j.status in ('queued', 'running') for j in artifact.jobs(cmd=cmd) ]) if is_being_submitted == 'submitting': msg = "Cannot resubmit! Data is already being submitted" msg_level = 'danger' self.display_template(preprocessed_data_id, msg, msg_level) else: params = Parameters.load( cmd, values_dict={'artifact': preprocessed_data_id}) job = ProcessingJob.create(user, params) job.submit() self.redirect('/study/description/%s' % artifact.study.study_id)
def post(self, preprocessed_data_id): user = self.current_user # make sure user is admin and can therefore actually submit to VAMPS if user.level != 'admin': raise HTTPError(403, "User %s cannot submit to VAMPS!" % user.id) msg = '' msg_level = 'success' plugin = Software.from_name_and_version('Qiita', 'alpha') cmd = plugin.get_command('submit_to_VAMPS') artifact = Artifact(preprocessed_data_id) # Check if the artifact is already being submitted to VAMPS is_being_submitted = any( [j.status in ('queued', 'running') for j in artifact.jobs(cmd=cmd)]) if is_being_submitted == 'submitting': msg = "Cannot resubmit! Data is already being submitted" msg_level = 'danger' self.display_template(preprocessed_data_id, msg, msg_level) else: params = Parameters.load( cmd, values_dict={'artifact': preprocessed_data_id}) job = ProcessingJob.create(user, params, True) job.submit() self.redirect('/study/description/%s' % artifact.study.study_id)
def list_options_handler_get_req(command_id, artifact_id=None): """Returns the available default parameters set for the given command Parameters ---------- command_id : int The command id artifact_id : int, optional The artifact id so to limit options based on how it has already been processed Returns ------- dict of objects A dictionary containing the commands information {'status': str, 'message': str, 'options': list of dicts of {'id: str', 'name': str, 'values': dict of {str: str}}} """ def _helper_process_params(params): return dumps({k: str(v).lower() for k, v in params.items()}, sort_keys=True) command = Command(command_id) rparamers = command.required_parameters.keys() eparams = [] if artifact_id is not None: artifact = Artifact(artifact_id) for job in artifact.jobs(cmd=command): jstatus = job.status outputs = job.outputs if job.status == 'success' else None # this ignore any jobs that weren't successful or are in # construction, or the results have been deleted [outputs == {}] if jstatus not in {'success', 'in_construction'} or outputs == {}: continue params = job.parameters.values.copy() for k in rparamers: del params[k] eparams.append(_helper_process_params(params)) options = [{ 'id': p.id, 'name': p.name, 'values': p.values } for p in command.default_parameter_sets if _helper_process_params(p.values) not in eparams] return { 'status': 'success', 'message': '', 'options': options, 'req_options': command.required_parameters, 'opt_options': command.optional_parameters }
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] }
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]}
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]}
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]}
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)}
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 }
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}
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 }
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 }
job_id=job_id, title='VAMPS Submission', completion_redirect='/compute_complete/%s' % job_id) return ======= if user.level != 'admin': raise HTTPError(403, reason="User %s cannot submit to VAMPS!" % user.id) msg = '' msg_level = 'success' plugin = Software.from_name_and_version('Qiita', 'alpha') cmd = plugin.get_command('submit_to_VAMPS') artifact = Artifact(preprocessed_data_id) # Check if the artifact is already being submitted to VAMPS is_being_submitted = any( [j.status in ('queued', 'running') for j in artifact.jobs(cmd=cmd)]) >>>>>>> 405cbef0c9f71c620da95a0c1ba6c7d3d588b3ed if is_being_submitted == 'submitting': msg = "Cannot resubmit! Data is already being submitted" msg_level = 'danger' self.display_template(preprocessed_data_id, msg, msg_level) else: params = Parameters.load( cmd, values_dict={'artifact': preprocessed_data_id}) job = ProcessingJob.create(user, params, True) job.submit() self.redirect('/study/description/%s' % artifact.study.study_id)