from flask import ( abort, current_app, Flask, jsonify, redirect, render_template, send_from_directory, url_for ) from flask_login import current_user from threading import Thread from app import db from app.models import Job, JobInput, JobResult, JobStatus from . import bp def _delete_job(app: Flask, job_id: int): with app.app_context(): job = Job.query.get(job_id) job.delete() db.session.commit() def _restart_job(app: Flask, job_id: int): with app.app_context(): job = Job.query.get(job_id) job.restart() db.session.commit() @bp.route('') def jobs(): return redirect(url_for('main.dashboard', _anchor='jobs')) @bp.route('/') def job(job_id: int): 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', title='Job', job=job ) @bp.route('/', methods=['DELETE']) def delete_job(job_id: int): 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 jsonify(f'Job "{job.title}" marked for deletion.'), 202 @bp.route('//log') def get_job_log(job_id: int): job = Job.query.get_or_404(job_id) if not current_user.is_administrator: abort(403) if job.status not in [JobStatus.COMPLETED, JobStatus.FAILED]: abort(409) log_file_path = job.path / 'pipeline_data' / 'logs' / 'pyflow_log.txt' with log_file_path.open() as log_file: log = log_file.read() return jsonify(log) @bp.route('//restart') def restart_job(job_id: int): 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: abort(409) thread = Thread( target=_restart_job, args=(current_app._get_current_object(), job.id) ) thread.start() return jsonify(f'Job "{job.title}" marked for restarting.'), 202 @bp.route('//inputs//download') def download_job_input(job_id: int, job_input_id: int): job_input = JobInput.query.filter_by( job_id=job_id, id=job_input_id ).first_or_404() if not ( job_input.job.user == current_user or current_user.is_administrator ): abort(403) return send_from_directory( job_input.path.parent, job_input.path.name, as_attachment=True, download_name=job_input.filename, mimetype=job_input.mimetype ) @bp.route('//results//download') def download_job_result(job_id: int, job_result_id: int): job_result = JobResult.query.filter_by( job_id=job_id, id=job_result_id ).first_or_404() if not ( job_result.job.user == current_user or current_user.is_administrator ): abort(403) return send_from_directory( job_result.path.parent, job_result.path.name, as_attachment=True, download_name=job_result.filename, mimetype=job_result.mimetype )