from flask import ( abort, current_app, render_template, send_from_directory ) from flask_login import current_user, login_required from threading import Thread import os from app import db from app.decorators import admin_required from app.models import Job, JobInput, JobResult, JobStatus from . import bp @bp.route('/') @login_required def job(job_id): job = Job.query.get_or_404(job_id) if not (job.user == current_user or current_user.is_administrator()): abort(403) return render_template( 'jobs/job.html.j2', job=job, title='Job' ) @bp.route('/', methods=['DELETE']) @login_required def delete_job(job_id): def _delete_job(app, job_id): with app.app_context(): job = Job.query.get(job_id) job.delete() db.session.commit() job = Job.query.get_or_404(job_id) if not (job.user == current_user or current_user.is_administrator()): abort(403) thread = Thread( target=_delete_job, args=(current_app._get_current_object(), job_id) ) thread.start() return {}, 202 @bp.route('//log') @login_required @admin_required def job_log(job_id): job = Job.query.get_or_404(job_id) if job.status not in [JobStatus.COMPLETED, JobStatus.FAILED]: response = {'errors': {'message': 'Job status is not completed or failed'}} return response, 409 with open(os.path.join(job.path, 'pipeline_data', 'logs', 'pyflow_log.txt')) as log_file: log = log_file.read() return log, 200, {'Content-Type': 'text/plain; charset=utf-8'} @bp.route('//restart', methods=['POST']) @login_required def restart_job(job_id): def _restart_job(app, job_id): with app.app_context(): job = Job.query.get(job_id) job.restart() db.session.commit() job = Job.query.get_or_404(job_id) if not (job.user == current_user or current_user.is_administrator()): abort(403) if job.status == JobStatus.FAILED: response = {'errors': {'message': 'Job status is not "failed"'}} return response, 409 thread = Thread( target=_restart_job, args=(current_app._get_current_object(), job_id) ) thread.start() return {}, 202 @bp.route('//inputs//download') @login_required def download_job_input(job_id, job_input_id): job_input = JobInput.query.get_or_404(job_input_id) if job_input.job.id != job_id: abort(404) if not (job_input.job.user == current_user or current_user.is_administrator()): abort(403) return send_from_directory( os.path.dirname(job_input.path), os.path.basename(job_input.path), as_attachment=True, attachment_filename=job_input.filename, mimetype=job_input.mimetype ) @bp.route('//results//download') @login_required def download_job_result(job_id, job_result_id): job_result = JobResult.query.get_or_404(job_result_id) if job_result.job.id != job_id: abort(404) if not (job_result.job.user == current_user or current_user.is_administrator()): abort(403) return send_from_directory( os.path.dirname(job_result.path), os.path.basename(job_result.path), as_attachment=True, attachment_filename=job_result.filename, mimetype=job_result.mimetype )