diff --git a/app/jobs/__init__.py b/app/jobs/__init__.py index 3e73643dc6b04eb1d4cf7f40d9db3a881f5a1bb9..3878875c86bf3940d15ecb9f201685dcd9a9d53d 100644 --- a/app/jobs/__init__.py +++ b/app/jobs/__init__.py @@ -3,4 +3,4 @@ from flask import Blueprint jobs = Blueprint('jobs', __name__) -from . import views +from . import forms, views diff --git a/app/services/forms.py b/app/jobs/forms.py similarity index 98% rename from app/services/forms.py rename to app/jobs/forms.py index d3ee9166a41bb5c9cfc27ef878bca2fd1844e10d..04b9381c2c9b3dc9f699c2e883cc4d7e9539a7a8 100644 --- a/app/services/forms.py +++ b/app/jobs/forms.py @@ -4,7 +4,7 @@ from wtforms import (BooleanField, MultipleFileField, SelectField, StringField, from wtforms.validators import DataRequired, Length -class NewNLPJobForm(FlaskForm): +class AddNLPJobForm(FlaskForm): description = StringField('Description', validators=[DataRequired(), Length(1, 255)]) files = MultipleFileField('Files', validators=[DataRequired()]) @@ -34,7 +34,7 @@ class NewNLPJobForm(FlaskForm): ) -class NewOCRJobForm(FlaskForm): +class AddOCRJobForm(FlaskForm): binarization = BooleanField('Binarazation') description = StringField('Description', validators=[DataRequired(), Length(1, 255)]) diff --git a/app/jobs/views.py b/app/jobs/views.py index 4c5252e57b331df277860a9a05909474159956ad..8e3352f059ed27cfbf80d40202787ecaaba4c276 100644 --- a/app/jobs/views.py +++ b/app/jobs/views.py @@ -1,9 +1,9 @@ +from app.models import Job, JobInput, JobResult from app.utils import background_delete_job from flask import (abort, current_app, flash, redirect, render_template, send_from_directory, url_for) from flask_login import current_user, login_required from . import jobs -from ..models import Job, JobInput, JobResult import os import threading diff --git a/app/services/views.py b/app/services/views.py index 413d5573868c5aa44e54b6ae87be2f66597d2d82..ef02b0795a8f876da8ff68ba05d23484fbcc8e38 100644 --- a/app/services/views.py +++ b/app/services/views.py @@ -1,72 +1,65 @@ +from app import db +from app.jobs.forms import AddNLPJobForm, AddOCRJobForm +from app.models import Job, JobInput from flask import abort, current_app, flash, redirect, render_template, url_for from flask_login import current_user, login_required from werkzeug.utils import secure_filename from . import services -from .forms import NewNLPJobForm, NewOCRJobForm -from .. import db -from ..models import Job, JobInput import json import os SERVICES = {'nlp': {'name': 'Natural Language Processing', 'resources': {'mem_mb': 4096, 'n_cores': 2}, - 'new_job_form': NewNLPJobForm}, + 'add_job_form': AddNLPJobForm}, 'ocr': {'name': 'Optical Character Recognition', 'resources': {'mem_mb': 8192, 'n_cores': 4}, - 'new_job_form': NewOCRJobForm}} + 'add_job_form': AddOCRJobForm}} -@services.route('/<service_handle>', methods=['GET', 'POST']) +@services.route('/<service>', methods=['GET', 'POST']) @login_required -def service(service_handle): - if service_handle not in SERVICES: +def service(service): + if service not in SERVICES: abort(404) - new_job_form = SERVICES[service_handle]['new_job_form']() - if new_job_form.validate_on_submit(): - _service_args = ['-l {}'.format(new_job_form.language.data)] - if service_handle == 'ocr': - if not new_job_form.binarization.data: - _service_args.append('--skip-binarisation') - job = Job( - creator=current_user, - description=new_job_form.description.data, - mem_mb=SERVICES[service_handle]['resources']['mem_mb'], - n_cores=SERVICES[service_handle]['resources']['n_cores'], - service=service_handle, - service_args=json.dumps(_service_args), - service_version=new_job_form.version.data, - status='preparing', - title=new_job_form.title.data - ) + add_job_form = SERVICES[service]['add_job_form']() + if add_job_form.validate_on_submit(): + service_args = [] + if service == 'nlp': + service_args.append('-l {}'.format(add_job_form.language.data)) + if service == 'ocr': + service_args.append('-l {}'.format(add_job_form.language.data)) + if not add_job_form.binarization.data: + service_args.append('--skip-binarisation') + job = Job(creator=current_user, + description=add_job_form.description.data, + mem_mb=SERVICES[service]['resources']['mem_mb'], + n_cores=SERVICES[service]['resources']['n_cores'], + service=service, service_args=json.dumps(service_args), + service_version=add_job_form.version.data, + status='preparing', title=add_job_form.title.data) db.session.add(job) db.session.commit() - dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], - str(job.user_id), - 'jobs', - str(job.id)) + relative_dir = os.path.join(str(job.user_id), 'jobs', str(job.id)) + absolut_dir = os.path.join( + current_app.config['OPAQUE_STORAGE_DIRECTORY'], relative_dir) try: - os.makedirs(dir) + os.makedirs(absolut_dir) except OSError: - flash('OSError!') - db.session.remove(job) + flash('[OSError] Could not add job!') + db.session.delete(job) db.session.commit() else: - for file in new_job_form.files.data: + for file in add_job_form.files.data: filename = secure_filename(file.filename) - file.save(os.path.join(dir, filename)) - job_input = JobInput( - dir=os.path.join(str(job.user_id), 'jobs', str(job.id)), - filename=filename, - job=job - ) + file.save(os.path.join(absolut_dir, filename)) + job_input = JobInput(dir=relative_dir, filename=filename, + job=job) db.session.add(job_input) job.status = 'submitted' db.session.commit() - flash('Job created!') - return redirect( - url_for('services.service', service_handle=service_handle) - ) - return render_template('services/{}.html.j2'.format(service_handle), - title=SERVICES[service_handle]['name'], - new_job_form=new_job_form) + flash('Job added!') + return redirect(url_for('jobs.job', job_id=job.id)) + return render_template('services/{}.html.j2'.format(service), + title=SERVICES[service]['name'], + add_job_form=add_job_form) diff --git a/app/static/js/opaque.js b/app/static/js/add_job.js similarity index 80% rename from app/static/js/opaque.js rename to app/static/js/add_job.js index 03964c02fe067a089cd0f5322d301143b2b9e059..f77ae78f07b7e953a2fce0eb1b49adfab88259d9 100644 --- a/app/static/js/opaque.js +++ b/app/static/js/add_job.js @@ -1,8 +1,7 @@ -function sendNewJobFormData(newJobFormElement, progressModalElement, request) { +function SubmitAddJobForm(newJobFormElement, progressModalElement, request) { var formData; var progress; var progressModal; - var request; formData = new FormData(newJobFormElement); progressModal = M.Modal.getInstance(progressModalElement); @@ -15,6 +14,7 @@ function sendNewJobFormData(newJobFormElement, progressModalElement, request) { progressModalElement.querySelector(".determinate").style.width = progressInPercent; }); request.addEventListener("load", function(event) { + console.log(request.response); newJobFormElement.reset(); location.reload(); }); @@ -22,22 +22,20 @@ function sendNewJobFormData(newJobFormElement, progressModalElement, request) { progressModalElement.querySelector(".progress-in-percent").innerHTML = "0%"; progressModalElement.querySelector(".determinate").style.width = "0%"; }); - progressModal.open(); request.open("POST", window.location.href); request.send(formData); } -function initNewJobForm(newJobFormElement, progressModalElement) { +function initAddJobForm(addJobFormElement, progressModalElement) { var request; request = new XMLHttpRequest(); - newJobFormElement.addEventListener("submit", function(event) { + addJobFormElement.addEventListener("submit", function(event) { event.preventDefault(); - sendNewJobFormData(newJobFormElement, progressModalElement, request); + SubmitAddJobForm(addJobFormElement, progressModalElement, request); }); - progressModalElement.querySelector(".cancel").addEventListener("click", function(event) { request.abort(); }); diff --git a/app/templates/base.html.j2 b/app/templates/base.html.j2 index 6e93183a8ef1388eb4a615f56ac85224bdbb9389..2febaeaba32f4b2d8c39f1a54b65e9db8f3ccd36 100644 --- a/app/templates/base.html.j2 +++ b/app/templates/base.html.j2 @@ -11,8 +11,7 @@ <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='fonts/material-icons/material-icons.css') }}"> <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/materialize.min.css') }}" media="screen,projection"/> <link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/opaque.css') }}" media="screen,projection"/> - <script src="{{ url_for('static', filename='js/Animations.js') }}"></script> - <script src="{{ url_for('static', filename='js/opaque.js') }}"></script> + <script src="{{ url_for('static', filename='js/add_job.js') }}"></script> <script src="{{ url_for('static', filename='js/jsonpatch.min.js') }}"></script> <script src="{{ url_for('static', filename='js/socket.io.js') }}"></script> <script src="{{ url_for('static', filename='js/list.js') }}"></script> @@ -137,8 +136,8 @@ <li><a href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a></li> <li><div class="divider"></div></li> <li><a class="subheader">Services</a></li> - <li><a href="{{ url_for('services.service', service_handle='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li> - <li><a href="{{ url_for('services.service', service_handle='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li> + <li><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li> + <li><a href="{{ url_for('services.service', service='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li> {% if current_user.is_administrator() %} <li><div class="divider"></div></li> <li><a class="subheader">Administration</a></li> diff --git a/app/templates/main/dashboard.html.j2 b/app/templates/main/dashboard.html.j2 index 41d5fd282da6791c3fee0fa61907cca869831c56..3d5ee2349da9fe4ad7259318b21fdf4a50c034c0 100644 --- a/app/templates/main/dashboard.html.j2 +++ b/app/templates/main/dashboard.html.j2 @@ -86,7 +86,7 @@ </script> <ul id='new-job-dropdown' class='dropdown-content'> - <li><a href="{{ url_for('services.service', service_handle='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li> - <li><a href="{{ url_for('services.service', service_handle='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li> + <li><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li> + <li><a href="{{ url_for('services.service', service='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li> </ul> {% endblock %} diff --git a/app/templates/services/nlp.html.j2 b/app/templates/services/nlp.html.j2 index 077ea64ba75a40a00143f223e45896ca5c932839..ba0be5e9df5c34854ef32d424761f617f9cd75d5 100644 --- a/app/templates/services/nlp.html.j2 +++ b/app/templates/services/nlp.html.j2 @@ -53,16 +53,16 @@ <div class="col s12"> <div class="card"> - <form method="POST" enctype="multipart/form-data" id="new-nlp-job-form"> + <form method="POST" enctype="multipart/form-data" id="add-job-form"> <div class="card-content"> - {{ new_job_form.hidden_tag() }} + {{ add_job_form.hidden_tag() }} <div class="row"> <div class="col s12 m4"> <div class="input-field"> <i class="material-icons prefix">title</i> - {{ new_job_form.title(data_length='32') }} - {{ new_job_form.title.label }} - {% for error in new_job_form.title.errors %} + {{ add_job_form.title(data_length='32') }} + {{ add_job_form.title.label }} + {% for error in add_job_form.title.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -70,9 +70,9 @@ <div class="col s12 m4"> <div class="input-field"> <i class="material-icons prefix">language</i> - {{ new_job_form.language() }} - {{ new_job_form.language.label }} - {% for error in new_job_form.language.errors %} + {{ add_job_form.language() }} + {{ add_job_form.language.label }} + {% for error in add_job_form.language.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -80,9 +80,9 @@ <div class="col s12 m4"> <div class="input-field"> <i class="material-icons prefix">language</i> - {{ new_job_form.version() }} - {{ new_job_form.version.label }} - {% for error in new_job_form.version.errors %} + {{ add_job_form.version() }} + {{ add_job_form.version.label }} + {% for error in add_job_form.version.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -92,13 +92,13 @@ <div class="col s12 m6"> <div class="file-field input-field"> <div class="btn"> - <span>{{ new_job_form.files.label.text }}</span> - {{ new_job_form.files(accept='text/plain') }} + <span>{{ add_job_form.files.label.text }}</span> + {{ add_job_form.files(accept='text/plain') }} </div> <div class="file-path-wrapper"> <input class="file-path validate" type="text"> </div> - {% for error in new_job_form.files.errors %} + {% for error in add_job_form.files.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -106,9 +106,9 @@ <div class="col s12 m6"> <div class="input-field"> <i class="material-icons prefix">description</i> - {{ new_job_form.description(data_length='255') }} - {{ new_job_form.description.label }} - {% for error in new_job_form.description.errors %} + {{ add_job_form.description(data_length='255') }} + {{ add_job_form.description.label }} + {% for error in add_job_form.description.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -136,7 +136,7 @@ </div> <script> - initNewJobForm(document.getElementById("new-nlp-job-form"), + initAddJobForm(document.getElementById("add-job-form"), document.getElementById("progress-modal")); </script> {% endblock %} diff --git a/app/templates/services/ocr.html.j2 b/app/templates/services/ocr.html.j2 index fe89cc6db41f01957916391dd7a0325081fd7327..7bb0b3c5aaa7d37194f88b8c8efd72e452fe39e6 100644 --- a/app/templates/services/ocr.html.j2 +++ b/app/templates/services/ocr.html.j2 @@ -54,16 +54,16 @@ <div class="col s12"> <div class="card"> - <form method="POST" enctype="multipart/form-data" id="new-ocr-job-form"> + <form method="POST" enctype="multipart/form-data" id="add-job-form"> <div class="card-content"> - {{ new_job_form.hidden_tag() }} + {{ add_job_form.hidden_tag() }} <div class="row"> <div class="col s12 m4"> <div class="input-field"> <i class="material-icons prefix">title</i> - {{ new_job_form.title(data_length='32') }} - {{ new_job_form.title.label }} - {% for error in new_job_form.title.errors %} + {{ add_job_form.title(data_length='32') }} + {{ add_job_form.title.label }} + {% for error in add_job_form.title.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -71,9 +71,9 @@ <div class="col s12 m8"> <div class="input-field"> <i class="material-icons prefix">description</i> - {{ new_job_form.description(data_length='255') }} - {{ new_job_form.description.label }} - {% for error in new_job_form.description.errors %} + {{ add_job_form.description(data_length='255') }} + {{ add_job_form.description.label }} + {% for error in add_job_form.description.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -81,13 +81,13 @@ <div class="col s12 m5"> <div class="file-field input-field"> <div class="btn"> - <span>{{ new_job_form.files.label.text }}</span> - {{ new_job_form.files(accept='application/pdf, image/tiff') }} + <span>{{ add_job_form.files.label.text }}</span> + {{ add_job_form.files(accept='application/pdf, image/tiff') }} </div> <div class="file-path-wrapper"> <input class="file-path validate" type="text"> </div> - {% for error in new_job_form.files.errors %} + {% for error in add_job_form.files.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -95,9 +95,9 @@ <div class="col s12 m4"> <div class="input-field"> <i class="material-icons prefix">language</i> - {{ new_job_form.language() }} - {{ new_job_form.language.label }} - {% for error in new_job_form.language.errors %} + {{ add_job_form.language() }} + {{ add_job_form.language.label }} + {% for error in add_job_form.language.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -105,9 +105,9 @@ <div class="col s12 m3"> <div class="input-field"> <i class="material-icons prefix">apps</i> - {{ new_job_form.version() }} - {{ new_job_form.version.label }} - {% for error in new_job_form.version.errors %} + {{ add_job_form.version() }} + {{ add_job_form.version.label }} + {% for error in add_job_form.version.errors %} <span class="helper-text red-text">{{ error }}</span> {% endfor %} </div> @@ -194,7 +194,7 @@ <div class="col s3"> <div class="switch"> <label> - {{ new_job_form.binarization() }} + {{ add_job_form.binarization() }} <span class="lever"></span> </label> </div> @@ -224,7 +224,7 @@ </div> <script> - initNewJobForm(document.getElementById("new-ocr-job-form"), + initAddJobForm(document.getElementById("add-job-form"), document.getElementById("progress-modal")); </script> {% endblock %}