Add delete corpora function and function to view an delete foreign jobs and corpora.

This commit is contained in:
Stephan Porada 2019-09-24 14:04:49 +02:00
parent 4858f36d76
commit ed288598cd
5 changed files with 121 additions and 19 deletions

View File

@ -1,11 +1,11 @@
from app.utils import background_delete_job
from app.utils import background_delete_job, background_delete_corpus
from flask import (abort, current_app, flash, redirect, request,
render_template, url_for, send_from_directory)
from flask_login import current_user, login_required
from . import main
from .forms import CreateCorpusForm
from .. import db
from ..models import Corpus
from ..models import Corpus, Job
import os
import threading
@ -18,13 +18,16 @@ def index():
@main.route('/corpora/<int:corpus_id>')
@login_required
def corpus(corpus_id):
if (current_user.is_administrator()):
corpus = Corpus.query.get_or_404(corpus_id)
else:
corpus = current_user.corpora.filter_by(id=corpus_id).first()
if not corpus:
print('Corpus not found.')
abort(404)
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
str(current_user.id),
str(corpus.user_id),
'corpora',
str(corpus.id))
files = {}
@ -42,12 +45,15 @@ def corpus(corpus_id):
@login_required
def corpus_download(corpus_id):
file = request.args.get('file')
if (current_user.is_administrator()):
corpus = Corpus.query.get_or_404(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)
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
str(current_user.id),
str(corpus.user_id),
'corpora',
str(corpus.id))
return send_from_directory(as_attachment=True,
@ -91,13 +97,16 @@ def dashboard():
@main.route('/jobs/<int:job_id>')
@login_required
def job(job_id):
if (current_user.is_administrator()):
job = Job.query.get_or_404(job_id)
else:
job = current_user.jobs.filter_by(id=job_id).first()
if not job:
print('Job not found.')
abort(404)
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
str(current_user.id),
str(job.user_id),
'jobs',
str(job.id))
files = {}
@ -126,12 +135,15 @@ def job(job_id):
@login_required
def job_download(job_id):
file = request.args.get('file')
if (current_user.is_administrator()):
job = Job.query.get_or_404(job_id)
else:
job = current_user.jobs.filter_by(id=job_id).first()
if not file or not job:
print('File not found.')
abort(404)
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
str(current_user.id),
str(job.user_id),
'jobs',
str(job.id))
return send_from_directory(as_attachment=True,
@ -149,3 +161,15 @@ def delete_job(job_id):
delete_thread.start()
flash('Job has been deleted!')
return redirect(url_for('main.dashboard'))
@main.route('/corpora/<int:corpus_id>/delete')
@login_required
def delete_corpus(corpus_id):
delete_thread = threading.Thread(
target=background_delete_corpus,
args=(current_app._get_current_object(), corpus_id)
)
delete_thread.start()
flash('Corpus has been deleted!')
return redirect(url_for('main.dashboard'))

View File

@ -8,7 +8,6 @@ from datetime import datetime
import os
import shutil
import logging
import time
class Permission:
@ -357,6 +356,20 @@ class Corpus(db.Model):
'title': self.title,
'user_id': self.user_id}
def delete_corpus(self):
logger = logging.getLogger(__name__)
delete_path = os.path.join('/mnt/opaque/', str(self.user_id), 'corpora',
str(self.id))
logger.warning('Delete path is: {}'.format(delete_path))
while os.path.exists(delete_path):
try:
shutil.rmtree(delete_path, ignore_errors=True)
logger.warning('Path does still exist.')
except OSError:
pass
db.session.delete(self)
db.session.commit()
'''
' Flask-Login is told to use the applications custom anonymous user by setting

View File

@ -2,18 +2,36 @@
{% block page_content %}
<script>
var CORPUS_ID = {{ corpus.id }}
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");
@ -62,6 +80,21 @@
<div class="col s12 m4">
<h3 id="title"></h3>
<p id="description"></p>
<h2>Actions:</h2>
<!-- Confirm deletion of job with modal dialogue
Modal Trigger-->
<a href="#modal-confirm-delete" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete Corpus</a>
<!-- Modal Strucutre -->
<div id="modal-confirm-delete" class="modal">
<div class="modal-content">
<h4>Confirm deletion</h4>
<p>Do you really want to delete the Corpus {{corpus.title}}?
All files will be permanently deleted.</p>
</div>
<div class="modal-footer">
<a href="{{ url_for('main.delete_corpus', corpus_id=corpus.id) }}" class="modal-close waves-effect waves-green btn red"><i class="material-icons left">delete</i>Delete Corpus</a></a>
</div>
</div>
</div>
<div class="col s12 m8">

View File

@ -2,20 +2,38 @@
{% block page_content %}
<script>
var JOB_ID = {{ job.id }}
var job_user_id = {{ job.user_id|tojson|safe }}
socket.emit('inspect_user', job_user_id);
</script>
<script>
var JOB_ID = {{ job.id|tojson|safe }}
var foreignJobFlag;
{% if current_user.id == job.user_id %}
foreignJobFlag = false;
{% else %}
foreignJobFlag = true;
{% endif %}
class InformationUpdater {
constructor(jobId) {
this.jobId = jobId;
if (foreignJobFlag) {
foreignJobsSubscribers.push(this);
} else {
jobsSubscribers.push(this);
}
}
_init() {
var creationDateElement, descriptionElement, endDateElement,
memMbElement, nCoresElement, serviceElement, serviceArgsElement,
serviceVersionElement, statusColor, statusElement, titleElement;
if (foreignJobFlag) {
this.job = foreignJobs[this.jobId];
} else {
this.job = jobs[this.jobId];
}
creationDateElement = document.getElementById("creation-date");
creationDateElement.value = (new Date(this.job.creation_date * 1000)).toLocaleString();
descriptionElement = document.getElementById("description");

View File

@ -1,4 +1,4 @@
from .models import Job, User
from .models import Job, User, Corpus
from . import db
import logging
@ -15,6 +15,7 @@ def background_delete_user(app, current_user_id):
logger.warning('Called by delete_thread.')
logger.warning('User id is: {}.'.format(current_user_id))
jobs = Job.query.filter_by(user_id=current_user_id).all()
corpora = Corpus.query.filter_by(user_id=current_user_id).all()
logger.warning('Jobs to delete are: {}'.format(jobs))
user = User.query.get_or_404(current_user_id)
for job in jobs:
@ -29,7 +30,10 @@ def background_delete_user(app, current_user_id):
logger.warning('Job status is deleted.')
job.delete_job()
deleted = True
logger.warning('Loop has ended.')
logger.warning('Job deletion loop has ended.')
for corpus in corpora:
corpus.delete_corpus()
logger.warning('Corpus deletion loop has ended.')
user.delete_user()
@ -51,3 +55,13 @@ def background_delete_job(app, job_id):
job.delete_job()
deleted = True
logger.warning('Loop has ended.')
def background_delete_corpus(app, corpus_id):
logger = logging.getLogger(__name__)
with app.app_context():
logger.warning('Called by delete_thread.')
logger.warning('Corpus id is: {}.'.format(corpus_id))
corpus = Corpus.query.filter_by(id=corpus_id).first()
logger.warning('Corpus object is: {}'.format(corpus))
corpus.delete_corpus()