Move job and user delete functions to utils.py

This commit is contained in:
Stephan Porada 2019-09-17 16:31:41 +02:00
parent 09f7d7ac68
commit 0d060f0cbf
6 changed files with 80 additions and 55 deletions

View File

@ -2,13 +2,13 @@ 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 .forms import EditProfileAdminForm
from ..models import Corpus, User, Role
from ..models import Corpus, User, Role, Job
from ..tables import AdminUserTable, AdminUserItem
from . import admin
from ..decorators import admin_required
from .. import db
import os
import datetime
import threading
from app.utils import background_delete_user
@admin.route('/overview', methods=['GET', 'POST'])
@ -40,9 +40,10 @@ def admin_user_page(user_id):
@login_required
@admin_required
def admin_delete_user(user_id):
selected_user = User.query.filter_by(id=user_id).first()
db.session.delete(selected_user)
db.session.commit()
delete_thread = threading.Thread(target=background_delete_user,
args=(current_app._get_current_object(),
user_id))
delete_thread.start()
flash('User {} has been deleted!'.format(user_id))
return redirect(url_for('admin.for_admins_only'))

View File

@ -6,9 +6,9 @@ from .. import db
from .forms import (ChangePasswordForm, LoginForm, PasswordResetForm,
PasswordResetRequestForm, RegistrationForm, EditProfileForm)
from ..email import send_email
from ..models import User, Job
import logging
from ..models import User
import threading
from app.utils import background_delete_user
@auth.route('/login', methods=['GET', 'POST'])
@ -169,30 +169,10 @@ def settings():
@auth.route('/settings/delete_self', methods=['GET', 'POST'])
@login_required
def delete_self():
logger = logging.getLogger(__name__)
def background_delete(app, current_user_id):
with app.app_context():
logger.warning('Called by delete_thread.')
logger.warning('User id is: {}.'.format(current_user_id))
jobs = Job.query.join(User).filter_by(id=current_user_id).all()
logger.warning('Jobs to delete are: {}'.format(jobs))
for job in jobs:
job.flag_for_stop()
logger.warning('Job status: {}'.format(job.status))
deleted = False
while deleted is False:
db.session.refresh(job)
if job.status == 'deleted':
logger.warning('Job status is deleted.')
job.delete_job()
deleted = True
delete_thread = threading.Thread(target=background_delete,
delete_thread = threading.Thread(target=background_delete_user,
args=(current_app._get_current_object(),
current_user.id))
delete_thread.start()
db.session.delete(current_user)
db.session.commit()
logout_user()
flash('Your account has been deleted!')
return redirect(url_for('main.index'))

View File

@ -8,6 +8,7 @@ from ..models import Corpus, Job
import os
import logging
import threading
from app.utils import background_delete_job
@main.route('/')
@ -144,28 +145,9 @@ def job_download(job_id):
@main.route('/jobs/<int:job_id>/delete')
@login_required
def delete_job(job_id):
logger = logging.getLogger(__name__)
def background_delete(job_id, app):
with app.app_context():
logger.warning('Called by delete_thread.')
logger.warning('Job id is: {}.'.format(job_id))
job = Job.query.filter_by(id=job_id).first()
logger.warning('Job object is: {}'.format(job))
logger.warning('Job status: {}'.format(job.status))
job.flag_for_stop()
logger.warning('Job status: {}'.format(job.status))
deleted = False
while deleted is False:
db.session.refresh(job)
if job.status == 'deleted':
logger.warning('Job status is deleted.')
job.delete_job()
deleted = True
delete_thread = threading.Thread(target=background_delete,
args=(job_id,
current_app._get_current_object()))
delete_thread = threading.Thread(target=background_delete_job,
args=(current_app._get_current_object(),
job_id))
delete_thread.start()
flash('Job has been deleted!')
return redirect(url_for('main.dashboard'))

View File

@ -220,13 +220,21 @@ class User(UserMixin, db.Model):
jobs[str(job.id)] = job.to_dict()
return jobs
def delete_user(self, user_id):
def delete_user(self):
"""
Delete user from database. Also delete all associated jobs and corpora
files.
"""
user = User.query.filter_by(user_id=user_id)
db.session.delete(user)
logger = logging.getLogger(__name__)
delete_path = os.path.join('/mnt/opaque/', str(self.id))
logger.warning('Delete path for user 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()

View File

@ -85,6 +85,7 @@
<h4>Confirm deletion</h4>
<p>
Do you really want to delete your account and all associated data?
All associated jobs and job files will be permanently deleted!
</p>
</div>
<div class="modal-footer">

53
app/utils.py Normal file
View File

@ -0,0 +1,53 @@
from .models import Job, User
from . import db
import logging
'''
' A list of background process functions. Functions should be called using the
Thread class from the module threading.
'''
def background_delete_user(app, current_user_id):
with app.app_context():
logger = logging.getLogger(__name__)
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()
logger.warning('Jobs to delete are: {}'.format(jobs))
user = User.query.get_or_404(current_user_id)
for job in jobs:
job.flag_for_stop()
logger.warning('Job status: {}'.format(job.status))
deleted = False
while deleted is False:
logger.warning('Refreshing')
db.session.refresh(job)
logger.warning('Refreshed')
if job.status == 'deleted':
logger.warning('Job status is deleted.')
job.delete_job()
deleted = True
logger.warning('Loop has ended.')
user.delete_user()
def background_delete_job(app, job_id):
logger = logging.getLogger(__name__)
with app.app_context():
logger.warning('Called by delete_thread.')
logger.warning('Job id is: {}.'.format(job_id))
job = Job.query.filter_by(id=job_id).first()
logger.warning('Job object is: {}'.format(job))
logger.warning('Job status: {}'.format(job.status))
job.flag_for_stop()
logger.warning('Job status: {}'.format(job.status))
deleted = False
while deleted is False:
db.session.refresh(job)
if job.status == 'deleted':
logger.warning('Job status is deleted.')
job.delete_job()
deleted = True
logger.warning('Loop has ended.')