mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-12-25 02:44:18 +00:00
Rewrite download function to use ressource ids instead of paths
This commit is contained in:
parent
409d94d0ae
commit
0a6bc055a0
@ -5,7 +5,7 @@ from flask_login import current_user, login_required
|
|||||||
from . import main
|
from . import main
|
||||||
from .forms import CreateCorpusForm
|
from .forms import CreateCorpusForm
|
||||||
from .. import db
|
from .. import db
|
||||||
from ..models import Corpus, CorpusFile, Job
|
from ..models import Corpus, CorpusFile, Job, JobInput, JobResult
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
@ -19,47 +19,29 @@ def index():
|
|||||||
@main.route('/corpora/<int:corpus_id>')
|
@main.route('/corpora/<int:corpus_id>')
|
||||||
@login_required
|
@login_required
|
||||||
def corpus(corpus_id):
|
def corpus(corpus_id):
|
||||||
if (current_user.is_administrator()):
|
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
else:
|
if not (corpus.creator == current_user or current_user.is_administrator()):
|
||||||
corpus = current_user.corpora.filter_by(id=corpus_id).first()
|
abort(403)
|
||||||
if not corpus:
|
|
||||||
print('Corpus not found.')
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
|
||||||
str(corpus.user_id),
|
|
||||||
'corpora',
|
|
||||||
str(corpus.id))
|
|
||||||
files = {}
|
|
||||||
for file in sorted(os.listdir(dir)):
|
|
||||||
files[file] = {}
|
|
||||||
files[file]['path'] = os.path.join(file)
|
|
||||||
|
|
||||||
return render_template('main/corpora/corpus.html.j2',
|
return render_template('main/corpora/corpus.html.j2',
|
||||||
corpus=corpus,
|
corpus=corpus,
|
||||||
files=files,
|
title='Corpus')
|
||||||
title='Corpus: ' + corpus.title)
|
|
||||||
|
|
||||||
|
|
||||||
@main.route('/corpora/<int:corpus_id>/download')
|
@main.route('/corpora/<int:corpus_id>/download')
|
||||||
@login_required
|
@login_required
|
||||||
def corpus_download(corpus_id):
|
def corpus_download(corpus_id):
|
||||||
file = request.args.get('file')
|
corpus_file_id = request.args.get('corpus_file_id')
|
||||||
if (current_user.is_administrator()):
|
corpus_file = CorpusFile.query.get_or_404(corpus_file_id)
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
if not corpus_file.corpus_id == corpus_id:
|
||||||
else:
|
|
||||||
corpus = current_user.corpora.filter_by(id=corpus_id).first()
|
|
||||||
if not file or not corpus:
|
|
||||||
print('File not found.')
|
|
||||||
abort(404)
|
abort(404)
|
||||||
|
if not (corpus_file.corpus.creator == current_user
|
||||||
|
or current_user.is_administrator()):
|
||||||
|
abort(403)
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
||||||
str(corpus.user_id),
|
corpus_file.dir)
|
||||||
'corpora',
|
|
||||||
str(corpus.id))
|
|
||||||
return send_from_directory(as_attachment=True,
|
return send_from_directory(as_attachment=True,
|
||||||
directory=dir,
|
directory=dir,
|
||||||
filename=file)
|
filename=corpus_file.filename)
|
||||||
|
|
||||||
|
|
||||||
@main.route('/corpora/<int:corpus_id>/analysis')
|
@main.route('/corpora/<int:corpus_id>/analysis')
|
||||||
@ -68,7 +50,7 @@ def corpus_analysis(corpus_id):
|
|||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
return render_template('main/corpora/corpus_analysis.html.j2',
|
return render_template('main/corpora/corpus_analysis.html.j2',
|
||||||
corpus=corpus,
|
corpus=corpus,
|
||||||
title='Corpus: ' + corpus.title)
|
title='Corpus Analysis')
|
||||||
|
|
||||||
|
|
||||||
@main.route('/dashboard', methods=['GET', 'POST'])
|
@main.route('/dashboard', methods=['GET', 'POST'])
|
||||||
@ -116,58 +98,33 @@ def dashboard():
|
|||||||
@main.route('/jobs/<int:job_id>')
|
@main.route('/jobs/<int:job_id>')
|
||||||
@login_required
|
@login_required
|
||||||
def job(job_id):
|
def job(job_id):
|
||||||
if (current_user.is_administrator()):
|
|
||||||
job = Job.query.get_or_404(job_id)
|
job = Job.query.get_or_404(job_id)
|
||||||
else:
|
if not (job.creator == current_user or current_user.is_administrator()):
|
||||||
job = current_user.jobs.filter_by(id=job_id).first()
|
abort(403)
|
||||||
if not job:
|
return render_template('main/jobs/job.html.j2', job=job, title='Job')
|
||||||
print('Job not found.')
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
|
||||||
str(job.user_id),
|
|
||||||
'jobs',
|
|
||||||
str(job.id))
|
|
||||||
files = {}
|
|
||||||
for file in sorted(os.listdir(dir)):
|
|
||||||
if file == 'output':
|
|
||||||
continue
|
|
||||||
files[file] = {}
|
|
||||||
files[file]['path'] = os.path.join(file)
|
|
||||||
if job.status == 'complete':
|
|
||||||
files[file]['results'] = {}
|
|
||||||
results_dir = os.path.join(dir, 'output', file)
|
|
||||||
for result in sorted(os.listdir(results_dir)):
|
|
||||||
result_type = result.rsplit(".", 1)[1]
|
|
||||||
files[file]['results'][result_type] = {}
|
|
||||||
files[file]['results'][result_type]['path'] = os.path.join(
|
|
||||||
'output', files[file]['path'], result
|
|
||||||
)
|
|
||||||
|
|
||||||
return render_template('main/jobs/job.html.j2',
|
|
||||||
files=files,
|
|
||||||
job=job,
|
|
||||||
title='Job')
|
|
||||||
|
|
||||||
|
|
||||||
@main.route('/jobs/<int:job_id>/download')
|
@main.route('/jobs/<int:job_id>/download')
|
||||||
@login_required
|
@login_required
|
||||||
def job_download(job_id):
|
def job_download(job_id):
|
||||||
file = request.args.get('file')
|
ressource_id = request.args.get('ressource_id')
|
||||||
if (current_user.is_administrator()):
|
ressource_type = request.args.get('ressource_type')
|
||||||
job = Job.query.get_or_404(job_id)
|
if ressource_type == 'input':
|
||||||
|
ressource = JobInput.query.get_or_404(ressource_id)
|
||||||
|
elif ressource_type == 'result':
|
||||||
|
ressource = JobResult.query.get_or_404(ressource_id)
|
||||||
else:
|
else:
|
||||||
job = current_user.jobs.filter_by(id=job_id).first()
|
abort(400)
|
||||||
if not file or not job:
|
if not ressource.job_id == job_id:
|
||||||
print('File not found.')
|
|
||||||
abort(404)
|
abort(404)
|
||||||
|
if not (ressource.job.creator == current_user
|
||||||
|
or current_user.is_administrator()):
|
||||||
|
abort(403)
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
||||||
str(job.user_id),
|
ressource.dir)
|
||||||
'jobs',
|
|
||||||
str(job.id))
|
|
||||||
return send_from_directory(as_attachment=True,
|
return send_from_directory(as_attachment=True,
|
||||||
directory=dir,
|
directory=dir,
|
||||||
filename=file)
|
filename=ressource.filename)
|
||||||
|
|
||||||
|
|
||||||
@main.route('/jobs/<int:job_id>/delete')
|
@main.route('/jobs/<int:job_id>/delete')
|
||||||
|
@ -1,85 +1,9 @@
|
|||||||
{% extends "limited_width.html.j2" %}
|
{% extends "limited_width.html.j2" %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<script>
|
|
||||||
var corpus_user_id = {{ corpus.user_id|tojson|safe }}
|
|
||||||
socket.emit('inspect_user', {{ corpus_user_id }});
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
var CORPUS_ID = {{ corpus.id|tojson|safe }}
|
|
||||||
var foreignCorpusFlag;
|
|
||||||
{% if current_user.id == corpus.user_id %}
|
|
||||||
foreignCorpusFlag = false;
|
|
||||||
{% else %}
|
|
||||||
foreignCorpusFlag = true;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
class InformationUpdater {
|
|
||||||
constructor(corpusId) {
|
|
||||||
this.corpusId = corpusId;
|
|
||||||
if (foreignCorpusFlag) {
|
|
||||||
foreignCorpusSubscribers.push(this);
|
|
||||||
} else {
|
|
||||||
corporaSubscribers.push(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_init() {
|
|
||||||
var creationDateElement, descriptionElement, titleElement;
|
|
||||||
|
|
||||||
if (foreignCorpusFlag) {
|
|
||||||
this.corpus = foreignCorpora[this.corpusId];
|
|
||||||
} else {
|
|
||||||
this.corpus = corpora[this.corpusId];
|
|
||||||
}
|
|
||||||
creationDateElement = document.getElementById("creation-date");
|
|
||||||
creationDateElement.value = (new Date(this.corpus.creation_date * 1000)).toLocaleString();
|
|
||||||
descriptionElement = document.getElementById("description");
|
|
||||||
descriptionElement.innerHTML = this.corpus.description;
|
|
||||||
titleElement = document.getElementById("title");
|
|
||||||
titleElement.innerHTML = this.corpus.title;
|
|
||||||
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
_update(patch) {
|
|
||||||
var newStatusColor, operation, pathArray, status, statusColor,
|
|
||||||
updatedElement;
|
|
||||||
|
|
||||||
for (operation of patch) {
|
|
||||||
/* "/corpusId/valueName" -> ["corpusId", "valueName"] */
|
|
||||||
pathArray = operation.path.split("/").slice(1);
|
|
||||||
if (pathArray[0] != this.jobId) {continue;}
|
|
||||||
switch(operation.op) {
|
|
||||||
case "delete":
|
|
||||||
location.reload();
|
|
||||||
break;
|
|
||||||
case "replace":
|
|
||||||
switch(pathArray[1]) {
|
|
||||||
case "description":
|
|
||||||
updatedElement = document.getElementById("description");
|
|
||||||
updatedElement.innerHTML = operation.value;
|
|
||||||
break;
|
|
||||||
case "title":
|
|
||||||
updatedElement = document.getElementById("title");
|
|
||||||
updatedElement.innerHTML = operation.value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var informationUpdater = new InformationUpdater(CORPUS_ID);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="col s12 m4">
|
<div class="col s12 m4">
|
||||||
<h3 id="title"></h3>
|
<h3 id="title">{{ corpus.title }}</h3>
|
||||||
<p id="description"></p>
|
<p id="description">{{ corpus.description }}</p>
|
||||||
<h2>Actions:</h2>
|
<h2>Actions:</h2>
|
||||||
<!-- Confirm deletion of job with modal dialogue
|
<!-- Confirm deletion of job with modal dialogue
|
||||||
Modal Trigger-->
|
Modal Trigger-->
|
||||||
@ -106,23 +30,27 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s12 m6">
|
<div class="col s12 m6">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="creation-date" type="text" class="validate">
|
<input disabled value="{{ corpus.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}" id="creation-date" type="text" class="validate">
|
||||||
<label for="creation-date">Creation date</label>
|
<label for="creation-date">Creation date</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="card-title">Files</span>
|
<span class="card-title">Files</span>
|
||||||
<table>
|
<table class="highlight responsive-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 50%;">Inputs</th>
|
<th>Filename</th>
|
||||||
|
<th>Download</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for file in files %}
|
{% for file in corpus.files %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td id="file-{{ file.id }}-filename">{{ file.filename }}</td>
|
||||||
<a href="{{ url_for('main.corpus_download', corpus_id=corpus.id, file=files[file]['path']) }}" class="waves-effect waves-light btn-small"><i class="material-icons left">file_download</i>{{ file }}</a>
|
<td id="file-{{ file.id }}-download">
|
||||||
|
<a class="waves-effect waves-light btn-small" download href="{{ url_for('main.corpus_download', corpus_id=corpus.id, corpus_file_id=file.id) }}">
|
||||||
|
<i class="material-icons">file_download</i>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -130,5 +58,5 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<script>
|
<script>
|
||||||
var job_user_id = {{ job.user_id|tojson|safe }}
|
var job_user_id = {{ job.user_id }}
|
||||||
socket.emit('inspect_user', job_user_id);
|
socket.emit('inspect_user', job_user_id);
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
var JOB_ID = {{ job.id|tojson|safe }}
|
var JOB_ID = {{ job.id }}
|
||||||
var foreignJobFlag;
|
var foreignJobFlag;
|
||||||
{% if current_user.id == job.user_id %}
|
{% if current_user.id == job.user_id %}
|
||||||
foreignJobFlag = false;
|
foreignJobFlag = false;
|
||||||
@ -25,111 +25,45 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
_init() {
|
_init() {
|
||||||
var creationDateElement, descriptionElement, endDateElement,
|
|
||||||
memMbElement, nCoresElement, serviceElement, serviceArgsElement,
|
|
||||||
serviceVersionElement, statusColor, statusElement, titleElement;
|
|
||||||
|
|
||||||
if (foreignJobFlag) {
|
if (foreignJobFlag) {
|
||||||
this.job = foreignJobs[this.jobId];
|
this.job = foreignJobs[this.jobId];
|
||||||
} else {
|
} else {
|
||||||
this.job = jobs[this.jobId];
|
this.job = jobs[this.jobId];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Title
|
|
||||||
this.setTitle(this.job.title);
|
|
||||||
// Description
|
|
||||||
this.setDescription(this.job.description);
|
|
||||||
// Status
|
// Status
|
||||||
this.setStatus(this.job.status);
|
this.setStatus(this.job.status);
|
||||||
// Creation date
|
|
||||||
this.setCreationDate(this.job.creation_date);
|
|
||||||
// End date
|
// End date
|
||||||
if (this.job.end_date) {this.setEndDate(this.job.end_date);}
|
if (this.job.end_date) {this.setEndDate(this.job.end_date);}
|
||||||
// Memory
|
// Input results
|
||||||
this.setMemMb(this.job.mem_mb);
|
for (let input of this.job.inputs) {
|
||||||
// CPU cores
|
for (let result of input.results) {
|
||||||
this.setNCores(this.job.n_cores);
|
this.setResult(result);
|
||||||
// Service
|
|
||||||
this.setService(this.job.service);
|
|
||||||
// Service arguments
|
|
||||||
this.setServiceArgs(this.job.service_args);
|
|
||||||
// Service version
|
|
||||||
this.setServiceVersion(this.job.service_version);
|
|
||||||
|
|
||||||
var filesElement, input, inputDownloadElement, inputElement,
|
|
||||||
inputFilenameElement, inputResultsElement;
|
|
||||||
|
|
||||||
filesElement = document.getElementById("files");
|
|
||||||
for (input of this.job.inputs) {
|
|
||||||
// Data row
|
|
||||||
inputElement = document.createElement("tr");
|
|
||||||
filesElement.append(inputElement);
|
|
||||||
// Input filename
|
|
||||||
inputFilenameElement = document.createElement("td");
|
|
||||||
inputFilenameElement.id = `input-${input.id}-filename`;
|
|
||||||
inputElement.append(inputFilenameElement);
|
|
||||||
// Input download
|
|
||||||
inputDownloadElement = document.createElement("td");
|
|
||||||
inputDownloadElement.id = `input-${input.id}-download`;
|
|
||||||
inputElement.append(inputDownloadElement);
|
|
||||||
// Third column for input result file download buttons
|
|
||||||
inputResultsElement = document.createElement("td");
|
|
||||||
inputResultsElement.id = `input-${input.id}-results`;
|
|
||||||
inputElement.append(inputResultsElement);
|
|
||||||
this.setInputFilename(input);
|
|
||||||
this.setInputDownload(input);
|
|
||||||
this.setInputResults(input);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setInputDownload(input) {
|
|
||||||
var inputDownloadButtonElement, inputDownloadButtonIconElement,
|
|
||||||
inputDownloadElement;
|
|
||||||
inputDownloadElement = document.getElementById(`input-${input.id}-download`);
|
|
||||||
inputDownloadButtonElement = document.createElement("a");
|
|
||||||
inputDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
|
|
||||||
inputDownloadButtonElement.href = `${this.jobId}/download?file=${input.filename}`;
|
|
||||||
inputDownloadButtonElement.setAttribute("download", "");
|
|
||||||
inputDownloadButtonIconElement = document.createElement("i");
|
|
||||||
inputDownloadButtonIconElement.classList.add("material-icons");
|
|
||||||
inputDownloadButtonIconElement.innerText = "file_download";
|
|
||||||
inputDownloadButtonElement.append(inputDownloadButtonIconElement);
|
|
||||||
inputDownloadElement.append(inputDownloadButtonElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
setInputFilename(input) {
|
|
||||||
var inputFilenameElement;
|
|
||||||
inputFilenameElement = document.getElementById(`input-${input.id}-filename`);
|
|
||||||
inputFilenameElement.innerText = input.filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_update(patch) {
|
_update(patch) {
|
||||||
var input, operation, pathArray;
|
var pathArray;
|
||||||
|
|
||||||
for (operation of patch) {
|
for (let operation of patch) {
|
||||||
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
/* "/jobId/valueName" -> ["jobId", "valueName"] */
|
||||||
pathArray = operation.path.split("/").slice(1);
|
pathArray = operation.path.split("/").slice(1);
|
||||||
if (pathArray[0] != this.jobId) {continue;}
|
if (pathArray[0] != this.jobId) {continue;}
|
||||||
switch(operation.op) {
|
switch(operation.op) {
|
||||||
case "add":
|
case "add":
|
||||||
if (pathArray[1] === "inputs" && pathArray[3] === "results") {
|
if (pathArray[1] === "inputs" && pathArray[3] === "results") {
|
||||||
console.log(operation.value);
|
this.setResult(operation.value);
|
||||||
this.setInputResult(operation.value);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
location.reload();
|
location.reload();
|
||||||
break;
|
break;
|
||||||
case "replace":
|
case "replace":
|
||||||
switch(pathArray[1]) {
|
if (pathArray[1] === "end_date") {
|
||||||
case "end_date":
|
|
||||||
this.setEndDate(operation.value);
|
this.setEndDate(operation.value);
|
||||||
break;
|
} else if (pathArray[1] === "status") {
|
||||||
case "status":
|
|
||||||
this.setStatus(operation.value);
|
this.setStatus(operation.value);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -138,109 +72,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle(title) {
|
|
||||||
var titleElement;
|
|
||||||
titleElement = document.getElementById("title");
|
|
||||||
titleElement.innerText = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDescription(description) {
|
|
||||||
var descriptionElement;
|
|
||||||
descriptionElement = document.getElementById("description");
|
|
||||||
descriptionElement.innerText = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
setStatus(status) {
|
|
||||||
var statusColor, statusElement;
|
|
||||||
statusElement = document.getElementById("status");
|
|
||||||
for (statusColor of Object.values(JobList.STATUS_COLORS)) {
|
|
||||||
statusElement.classList.remove(statusColor);
|
|
||||||
}
|
|
||||||
statusElement.classList.add(JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default']);
|
|
||||||
statusElement.innerText = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCreationDate(timestamp) {
|
|
||||||
var creationDateElement;
|
|
||||||
creationDateElement = document.getElementById("creation-date");
|
|
||||||
creationDateElement.value = new Date(timestamp * 1000).toLocaleString();
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
setEndDate(timestamp) {
|
setEndDate(timestamp) {
|
||||||
var endDateElement;
|
document.getElementById("end-date").value = new Date(timestamp * 1000).toLocaleString();
|
||||||
endDateElement = document.getElementById("end-date");
|
|
||||||
endDateElement.value = new Date(timestamp * 1000).toLocaleString();
|
|
||||||
M.updateTextFields();
|
M.updateTextFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
setMemMb(memMb) {
|
setResult(result) {
|
||||||
var memMbElement;
|
var resultsElement, resultDownloadButtonElement,
|
||||||
memMbElement = document.getElementById("mem-mb");
|
|
||||||
memMbElement.value = memMb;
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
setNCores(nCores) {
|
|
||||||
var nCoresElement;
|
|
||||||
nCoresElement = document.getElementById("n-cores");
|
|
||||||
nCoresElement.value = nCores;
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
setService(service) {
|
|
||||||
var serviceElement;
|
|
||||||
serviceElement = document.getElementById("service");
|
|
||||||
serviceElement.value = service;
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
setServiceArgs(serviceArgs) {
|
|
||||||
var serviceArgsElement;
|
|
||||||
serviceArgsElement = document.getElementById("service-args");
|
|
||||||
serviceArgsElement.value = serviceArgs;
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
setServiceVersion(serviceVersion) {
|
|
||||||
var serviceVersionElement;
|
|
||||||
serviceVersionElement = document.getElementById("service-version");
|
|
||||||
serviceVersionElement.value = serviceVersion;
|
|
||||||
M.updateTextFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
setInputResults(input) {
|
|
||||||
var result;
|
|
||||||
for (result of input.results) {
|
|
||||||
this.setInputResult(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setInputResult(result) {
|
|
||||||
var inputResultsElement, resultDownloadButtonElement,
|
|
||||||
resultDownloadButtonIconElement;
|
resultDownloadButtonIconElement;
|
||||||
inputResultsElement = document.getElementById(`input-${result.job_input_id}-results`);
|
resultsElement = document.getElementById(`input-${result.job_input_id}-results`);
|
||||||
resultDownloadButtonElement = document.createElement("a");
|
resultDownloadButtonElement = document.createElement("a");
|
||||||
resultDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
|
resultDownloadButtonElement.classList.add("waves-effect", "waves-light", "btn-small");
|
||||||
var resultFile = `${result.dir}/${result.filename}`;
|
resultDownloadButtonElement.href = `/jobs/${this.jobId}/download?ressource_id=${result.id}&ressource_type=result`;
|
||||||
resultFile = resultFile.substring(resultFile.indexOf("output/"));
|
|
||||||
resultDownloadButtonElement.href = `${this.jobId}/download?file=${resultFile}`;
|
|
||||||
resultDownloadButtonElement.innerText = result.filename.split(".").reverse()[0];
|
resultDownloadButtonElement.innerText = result.filename.split(".").reverse()[0];
|
||||||
resultDownloadButtonElement.setAttribute("download", "");
|
resultDownloadButtonElement.setAttribute("download", "");
|
||||||
resultDownloadButtonIconElement = document.createElement("i");
|
resultDownloadButtonIconElement = document.createElement("i");
|
||||||
resultDownloadButtonIconElement.classList.add("material-icons", "left");
|
resultDownloadButtonIconElement.classList.add("material-icons", "left");
|
||||||
resultDownloadButtonIconElement.innerText = "file_download";
|
resultDownloadButtonIconElement.innerText = "file_download";
|
||||||
resultDownloadButtonElement.prepend(resultDownloadButtonIconElement);
|
resultDownloadButtonElement.prepend(resultDownloadButtonIconElement);
|
||||||
inputResultsElement.append(resultDownloadButtonElement);
|
resultsElement.append(resultDownloadButtonElement);
|
||||||
inputResultsElement.append(" ");
|
resultsElement.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatus(status) {
|
||||||
|
var statusElement;
|
||||||
|
statusElement = document.getElementById("status");
|
||||||
|
statusElement.classList.remove(...Object.values(JobList.STATUS_COLORS));
|
||||||
|
statusElement.classList.add(JobList.STATUS_COLORS[status] || JobList.STATUS_COLORS['default']);
|
||||||
|
statusElement.innerText = status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var informationUpdater = new InformationUpdater(JOB_ID);
|
var informationUpdater = new InformationUpdater(JOB_ID);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="col s12 m4">
|
<div class="col s12 m4">
|
||||||
<h3 id="title"></h3>
|
<h3 id="title">{{ job.title }}</h3>
|
||||||
<p id="description"></p>
|
<p id="description">{{ job.description }}</p>
|
||||||
<a class="waves-effect waves-light btn" id="status"></a>
|
<a class="waves-effect waves-light btn" id="status"></a>
|
||||||
<h2>Actions:</h2>
|
<h2>Actions:</h2>
|
||||||
<!-- Confirm deletion of job with modal dialogue
|
<!-- Confirm deletion of job with modal dialogue
|
||||||
@ -269,7 +137,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s12 m6">
|
<div class="col s12 m6">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="creation-date" type="text" class="validate">
|
<input disabled value="{{ job.creation_date.strftime('%m/%d/%Y, %H:%M:%S %p') }}" id="creation-date" type="text" class="validate">
|
||||||
<label for="creation-date">Creation date</label>
|
<label for="creation-date">Creation date</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -285,13 +153,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s12 m6">
|
<div class="col s12 m6">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="mem-mb" type="text" class="validate">
|
<input disabled value="{{ job.mem_mb }}" id="mem-mb" type="text" class="validate">
|
||||||
<label for="mem-mb">Memory</label>
|
<label for="mem-mb">Memory</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s12 m6">
|
<div class="col s12 m6">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="n-cores" type="text" class="validate">
|
<input disabled value="{{ job.n_cores }}" id="n-cores" type="text" class="validate">
|
||||||
<label for="n-cores">CPU cores</label>
|
<label for="n-cores">CPU cores</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -301,19 +169,19 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s12 m4">
|
<div class="col s12 m4">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="service" type="text" class="validate">
|
<input disabled value="{{ job.service }}" id="service" type="text" class="validate">
|
||||||
<label for="service">Service</label>
|
<label for="service">Service</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s12 m4">
|
<div class="col s12 m4">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="service-args" type="text" class="validate">
|
<input disabled value="{{ job.service_args|e }}" id="service-args" type="text" class="validate">
|
||||||
<label for="service-args">Service arguments</label>
|
<label for="service-args">Service arguments</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col s12 m4">
|
<div class="col s12 m4">
|
||||||
<div class="input-field">
|
<div class="input-field">
|
||||||
<input disabled value="" id="service-version" type="text" class="validate">
|
<input disabled value="{{ job.service_version }}" id="service-version" type="text" class="validate">
|
||||||
<label for="service-version">Service version</label>
|
<label for="service-version">Service version</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -329,12 +197,24 @@
|
|||||||
<table class="highlight responsive-table">
|
<table class="highlight responsive-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>File</th>
|
<th>Filename</th>
|
||||||
<th>Input</th>
|
<th>Download</th>
|
||||||
<th>Results</th>
|
<th>Results</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="files"></tbody>
|
<tbody>
|
||||||
|
{% for input in job.inputs %}
|
||||||
|
<tr>
|
||||||
|
<td id="input-{{ input.id }}-filename">{{ input.filename }}</td>
|
||||||
|
<td id="input-{{ input.id }}-download">
|
||||||
|
<a class="waves-effect waves-light btn-small" download href="{{ url_for('main.job_download', job_id=job.id, ressource_id=input.id, ressource_type='input') }}">
|
||||||
|
<i class="material-icons">file_download</i>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td id="input-{{ input.id }}-results"></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user