mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-12-25 02:44:18 +00:00
Add delete corpora function and function to view an delete foreign jobs and corpora.
This commit is contained in:
parent
4858f36d76
commit
ed288598cd
@ -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,
|
from flask import (abort, current_app, flash, redirect, request,
|
||||||
render_template, url_for, send_from_directory)
|
render_template, url_for, send_from_directory)
|
||||||
from flask_login import current_user, login_required
|
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
|
from ..models import Corpus, Job
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
@ -18,13 +18,16 @@ 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):
|
||||||
corpus = current_user.corpora.filter_by(id=corpus_id).first()
|
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:
|
if not corpus:
|
||||||
print('Corpus not found.')
|
print('Corpus not found.')
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
||||||
str(current_user.id),
|
str(corpus.user_id),
|
||||||
'corpora',
|
'corpora',
|
||||||
str(corpus.id))
|
str(corpus.id))
|
||||||
files = {}
|
files = {}
|
||||||
@ -42,12 +45,15 @@ def corpus(corpus_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def corpus_download(corpus_id):
|
def corpus_download(corpus_id):
|
||||||
file = request.args.get('file')
|
file = request.args.get('file')
|
||||||
corpus = current_user.corpora.filter_by(id=corpus_id).first()
|
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:
|
if not file or not corpus:
|
||||||
print('File not found.')
|
print('File not found.')
|
||||||
abort(404)
|
abort(404)
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
||||||
str(current_user.id),
|
str(corpus.user_id),
|
||||||
'corpora',
|
'corpora',
|
||||||
str(corpus.id))
|
str(corpus.id))
|
||||||
return send_from_directory(as_attachment=True,
|
return send_from_directory(as_attachment=True,
|
||||||
@ -91,13 +97,16 @@ 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):
|
||||||
job = current_user.jobs.filter_by(id=job_id).first()
|
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:
|
if not job:
|
||||||
print('Job not found.')
|
print('Job not found.')
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
||||||
str(current_user.id),
|
str(job.user_id),
|
||||||
'jobs',
|
'jobs',
|
||||||
str(job.id))
|
str(job.id))
|
||||||
files = {}
|
files = {}
|
||||||
@ -126,12 +135,15 @@ def job(job_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def job_download(job_id):
|
def job_download(job_id):
|
||||||
file = request.args.get('file')
|
file = request.args.get('file')
|
||||||
job = current_user.jobs.filter_by(id=job_id).first()
|
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:
|
if not file or not job:
|
||||||
print('File not found.')
|
print('File not found.')
|
||||||
abort(404)
|
abort(404)
|
||||||
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'],
|
||||||
str(current_user.id),
|
str(job.user_id),
|
||||||
'jobs',
|
'jobs',
|
||||||
str(job.id))
|
str(job.id))
|
||||||
return send_from_directory(as_attachment=True,
|
return send_from_directory(as_attachment=True,
|
||||||
@ -149,3 +161,15 @@ def delete_job(job_id):
|
|||||||
delete_thread.start()
|
delete_thread.start()
|
||||||
flash('Job has been deleted!')
|
flash('Job has been deleted!')
|
||||||
return redirect(url_for('main.dashboard'))
|
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'))
|
||||||
|
@ -8,7 +8,6 @@ from datetime import datetime
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
class Permission:
|
class Permission:
|
||||||
@ -357,6 +356,20 @@ class Corpus(db.Model):
|
|||||||
'title': self.title,
|
'title': self.title,
|
||||||
'user_id': self.user_id}
|
'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 application’s custom anonymous user by setting
|
' Flask-Login is told to use the application’s custom anonymous user by setting
|
||||||
|
@ -2,18 +2,36 @@
|
|||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<script>
|
<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 {
|
class InformationUpdater {
|
||||||
constructor(corpusId) {
|
constructor(corpusId) {
|
||||||
this.corpusId = corpusId;
|
this.corpusId = corpusId;
|
||||||
corporaSubscribers.push(this);
|
if (foreignCorpusFlag) {
|
||||||
|
foreignCorpusSubscribers.push(this);
|
||||||
|
} else {
|
||||||
|
corporaSubscribers.push(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_init() {
|
_init() {
|
||||||
var creationDateElement, descriptionElement, titleElement;
|
var creationDateElement, descriptionElement, titleElement;
|
||||||
|
|
||||||
this.corpus = corpora[this.corpusId];
|
if (foreignCorpusFlag) {
|
||||||
|
this.corpus = foreignCorpora[this.corpusId];
|
||||||
|
} else {
|
||||||
|
this.corpus = corpora[this.corpusId];
|
||||||
|
}
|
||||||
creationDateElement = document.getElementById("creation-date");
|
creationDateElement = document.getElementById("creation-date");
|
||||||
creationDateElement.value = (new Date(this.corpus.creation_date * 1000)).toLocaleString();
|
creationDateElement.value = (new Date(this.corpus.creation_date * 1000)).toLocaleString();
|
||||||
descriptionElement = document.getElementById("description");
|
descriptionElement = document.getElementById("description");
|
||||||
@ -62,6 +80,21 @@
|
|||||||
<div class="col s12 m4">
|
<div class="col s12 m4">
|
||||||
<h3 id="title"></h3>
|
<h3 id="title"></h3>
|
||||||
<p id="description"></p>
|
<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>
|
||||||
|
|
||||||
<div class="col s12 m8">
|
<div class="col s12 m8">
|
||||||
|
@ -2,12 +2,26 @@
|
|||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<script>
|
<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 {
|
class InformationUpdater {
|
||||||
constructor(jobId) {
|
constructor(jobId) {
|
||||||
this.jobId = jobId;
|
this.jobId = jobId;
|
||||||
jobsSubscribers.push(this);
|
if (foreignJobFlag) {
|
||||||
|
foreignJobsSubscribers.push(this);
|
||||||
|
} else {
|
||||||
|
jobsSubscribers.push(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_init() {
|
_init() {
|
||||||
@ -15,7 +29,11 @@
|
|||||||
memMbElement, nCoresElement, serviceElement, serviceArgsElement,
|
memMbElement, nCoresElement, serviceElement, serviceArgsElement,
|
||||||
serviceVersionElement, statusColor, statusElement, titleElement;
|
serviceVersionElement, statusColor, statusElement, titleElement;
|
||||||
|
|
||||||
this.job = jobs[this.jobId];
|
if (foreignJobFlag) {
|
||||||
|
this.job = foreignJobs[this.jobId];
|
||||||
|
} else {
|
||||||
|
this.job = jobs[this.jobId];
|
||||||
|
}
|
||||||
creationDateElement = document.getElementById("creation-date");
|
creationDateElement = document.getElementById("creation-date");
|
||||||
creationDateElement.value = (new Date(this.job.creation_date * 1000)).toLocaleString();
|
creationDateElement.value = (new Date(this.job.creation_date * 1000)).toLocaleString();
|
||||||
descriptionElement = document.getElementById("description");
|
descriptionElement = document.getElementById("description");
|
||||||
|
18
app/utils.py
18
app/utils.py
@ -1,4 +1,4 @@
|
|||||||
from .models import Job, User
|
from .models import Job, User, Corpus
|
||||||
from . import db
|
from . import db
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ def background_delete_user(app, current_user_id):
|
|||||||
logger.warning('Called by delete_thread.')
|
logger.warning('Called by delete_thread.')
|
||||||
logger.warning('User id is: {}.'.format(current_user_id))
|
logger.warning('User id is: {}.'.format(current_user_id))
|
||||||
jobs = Job.query.filter_by(user_id=current_user_id).all()
|
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))
|
logger.warning('Jobs to delete are: {}'.format(jobs))
|
||||||
user = User.query.get_or_404(current_user_id)
|
user = User.query.get_or_404(current_user_id)
|
||||||
for job in jobs:
|
for job in jobs:
|
||||||
@ -29,7 +30,10 @@ def background_delete_user(app, current_user_id):
|
|||||||
logger.warning('Job status is deleted.')
|
logger.warning('Job status is deleted.')
|
||||||
job.delete_job()
|
job.delete_job()
|
||||||
deleted = True
|
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()
|
user.delete_user()
|
||||||
|
|
||||||
|
|
||||||
@ -51,3 +55,13 @@ def background_delete_job(app, job_id):
|
|||||||
job.delete_job()
|
job.delete_job()
|
||||||
deleted = True
|
deleted = True
|
||||||
logger.warning('Loop has ended.')
|
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()
|
||||||
|
Loading…
Reference in New Issue
Block a user