mirror of
https://codeberg.org/Mo8it/AdvLabDB.git
synced 2024-12-04 22:40:30 +00:00
Add manual backup action
This commit is contained in:
parent
5e6c809b53
commit
a1361d6e22
3 changed files with 29 additions and 20 deletions
|
@ -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(
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue