1
0
Fork 0
mirror of https://codeberg.org/Mo8it/AdvLabDB.git synced 2024-09-19 18:31:16 +00:00

Add manual backup action

This commit is contained in:
Mo 2023-11-01 23:18:47 +01:00
parent 5e6c809b53
commit a1361d6e22
3 changed files with 29 additions and 20 deletions

View file

@ -1,7 +1,10 @@
from datetime import datetime
from flask import flash from flask import flash
from flask_login import current_user from flask_login import current_user
from sqlalchemy import select from sqlalchemy import select
import subprocess
from . import data_dir
from .models import Assistant, Semester, User, db from .models import Assistant, Semester, User, db
@ -11,6 +14,23 @@ def update_final_experiment_and_part_marks():
flash("Manually updated all final experiment and part marks.", "success") flash("Manually updated all final experiment and part marks.", "success")
def backup(backup_prefix):
db_path = data_dir / "db/advlabdb.sqlite"
db_bk_dir = db_path.parent / "backups"
db_bk_dir.mkdir(exist_ok=True)
now = datetime.now().strftime("%d_%m_%Y_%H_%M_%S")
dest = db_bk_dir / f"{backup_prefix}_{now}.sqlite"
status = subprocess.run(["sqlite3", db_path, f".backup {dest}"]).returncode
if status == 0:
flash(f"Created a database backup at the path {dest}", "success")
else:
flash("Failed to create a database backup! Make sure that `sqlite3` is installed on your system!", "danger")
def manual_backup():
backup("manual")
def deactivate_assistants(): def deactivate_assistants():
user_ids_to_deactivate = db.session.scalars( user_ids_to_deactivate = db.session.scalars(

View file

@ -28,7 +28,7 @@ from wtforms.validators import URL, DataRequired, Email, NumberRange, Optional
from wtforms.widgets import NumberInput from wtforms.widgets import NumberInput
from . import data_dir, user_datastore from . import data_dir, user_datastore
from .actions import deactivate_assistants, update_final_experiment_and_part_marks from .actions import deactivate_assistants, update_final_experiment_and_part_marks, manual_backup
from .admin_link_formatters import ( from .admin_link_formatters import (
admin_formatter, admin_formatter,
appointment_date_formatter, appointment_date_formatter,
@ -1341,6 +1341,9 @@ class ImportView(SecureAdminBaseView):
class ActionsView(SecureAdminBaseView): class ActionsView(SecureAdminBaseView):
class ActionsForm(FlaskForm): class ActionsForm(FlaskForm):
manual_backup = BooleanField(
label="Create a manual database backup",
)
update_final_experiment_and_part_marks = BooleanField( update_final_experiment_and_part_marks = BooleanField(
label="Manually update all final experiment and part marks in the active semester", label="Manually update all final experiment and part marks in the active semester",
) )
@ -1357,6 +1360,8 @@ class ActionsView(SecureAdminBaseView):
form = ActionsView.ActionsForm() form = ActionsView.ActionsForm()
if form.validate_on_submit(): if form.validate_on_submit():
if form.manual_backup.data:
manual_backup()
if form.update_final_experiment_and_part_marks.data: if form.update_final_experiment_and_part_marks.data:
update_final_experiment_and_part_marks() update_final_experiment_and_part_marks()
if form.deactivate_assistants.data: if form.deactivate_assistants.data:

View file

@ -1,12 +1,12 @@
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from shutil import copy2
from flask import flash from flask import flash
from sqlalchemy import select from sqlalchemy import select
from . import data_dir from . import data_dir
from .exceptions import DatabaseImportException from .exceptions import DatabaseImportException
from .actions import backup
from .models import ( from .models import (
Appointment, Appointment,
Assistant, Assistant,
@ -25,10 +25,6 @@ from .models import (
) )
def now():
return datetime.now().strftime("%d_%m_%Y_%H_%M_%S")
def is_null(entry): def is_null(entry):
return entry == "NULL" or entry == "" return entry == "NULL" or entry == ""
@ -48,11 +44,6 @@ def not_nullable(entry):
def importFromFile(filePath: Path): def importFromFile(filePath: Path):
db_path = data_dir / "db/advlabdb.sqlite"
db_bk_dir = db_path.parent / "backups"
db_bk_dir.mkdir(exist_ok=True)
if filePath.name[-4:] != ".txt": if filePath.name[-4:] != ".txt":
raise DatabaseImportException( raise DatabaseImportException(
"The import file has to be a text file with txt extension (.txt at the end of the filename)!" "The import file has to be a text file with txt extension (.txt at the end of the filename)!"
@ -330,11 +321,7 @@ def importFromFile(filePath: Path):
) )
db.session.add(dbAppointment) db.session.add(dbAppointment)
# Backup backup(f"before_{dbSemester}_import")
dest = db_bk_dir / f"before_{dbSemester}_import_{now()}.sqlite"
copy2(db_path, dest)
flash(f"Made a backup of the database before committing the import at {dest}")
db.session.commit() db.session.commit()
except Exception as ex: except Exception as ex:
@ -342,10 +329,7 @@ def importFromFile(filePath: Path):
raise ex raise ex
dest = db_bk_dir / f"after_{dbSemester}_import_{now()}.sqlite" backup(f"after_{dbSemester}_import")
copy2(db_path, dest)
flash(f"Made a backup of the database after the import at {dest}")
flash("\nImport done!", "success") flash("\nImport done!", "success")
flash("Please check that everything worked as expected. Restore the database backup otherwise!", "warning") flash("Please check that everything worked as expected. Restore the database backup otherwise!", "warning")