From 0d060f0cbfdd4534111b5c53810de4cf4b9399b3 Mon Sep 17 00:00:00 2001 From: Stephan Porada Date: Tue, 17 Sep 2019 16:31:41 +0200 Subject: [PATCH] Move job and user delete functions to utils.py --- app/admin/views.py | 13 +++---- app/auth/views.py | 28 +++------------ app/main/views.py | 26 +++----------- app/models.py | 14 ++++++-- app/templates/auth/settings.html.j2 | 1 + app/utils.py | 53 +++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 55 deletions(-) create mode 100644 app/utils.py diff --git a/app/admin/views.py b/app/admin/views.py index 6358167f..6879fc95 100644 --- a/app/admin/views.py +++ b/app/admin/views.py @@ -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')) diff --git a/app/auth/views.py b/app/auth/views.py index dd327cfb..ade94357 100644 --- a/app/auth/views.py +++ b/app/auth/views.py @@ -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')) diff --git a/app/main/views.py b/app/main/views.py index 51ba514e..13a64be3 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -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//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')) diff --git a/app/models.py b/app/models.py index 3d4d4f0b..8bf8481f 100644 --- a/app/models.py +++ b/app/models.py @@ -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() diff --git a/app/templates/auth/settings.html.j2 b/app/templates/auth/settings.html.j2 index bb2b533d..ab4dff9a 100644 --- a/app/templates/auth/settings.html.j2 +++ b/app/templates/auth/settings.html.j2 @@ -85,6 +85,7 @@

Confirm deletion

Do you really want to delete your account and all associated data? + All associated jobs and job files will be permanently deleted!