1
0
Fork 0
mirror of https://codeberg.org/Mo8it/AdvLabDB.git synced 2024-11-08 21:21:06 +00:00
AdvLabDB/advlabdb/modelViews.py
2021-06-02 01:56:49 +02:00

181 lines
7.6 KiB
Python

from flask import url_for, flash, request
from flask_admin.menu import MenuLink
from flask_admin.contrib.sqla.filters import BaseSQLAFilter
from flask_security import hash_password
from wtforms import BooleanField, SelectField, TextField
from wtforms.validators import DataRequired, Email
from advlabdb import admin, app, user_datastore, db
from advlabdb.utils import randomPassword, userActiveSemester, partFromLabelInUserActiveSemester, setActiveSemester
from advlabdb.customClasses import SecureModelView
from advlabdb.models import User, Role, Semester, Part, Student, PartStudent, Group, GroupExperiment, Experiment, Assistant, Appointment, PartExperiment, ExperimentMark
from advlabdb.configUtils import getConfig
class UserModelView(SecureModelView):
column_list = ["email", "active", "roles", "assistant"]
column_searchable_list = ["email"]
column_filters = ["active"]
form_columns = ["email", "active", "roles"]
form_args = {
"email": {"validators": [Email()]},
"active": {"default": True},
"roles": {"validators": [DataRequired(message="A role is required!")]}
}
def create_model(self, form):
password = randomPassword()
passwordHash = hash_password(password)
email = form.email.data.lower()
roles = [role.name for role in form.roles.data]
if "admin" in roles:
flash("You have registered a new admin!", "danger")
model = user_datastore.create_user(email=email, password=passwordHash, roles=roles)
db.session.commit()
flash(f"{email} registered with roles: {', '.join([role.name for role in form.roles.data])}.", category="success")
flash(f"Random password: {password}", category="warning")
return model
class RoleModelView(SecureModelView):
column_exclude_list = ["update_datetime"]
class SemesterModelView(SecureModelView):
column_list = ["label", "parts"]
form_columns = ["label", "create_parts"]
form_extra_fields = {
"create_parts": BooleanField("Create parts:" + ", ".join(getConfig("partsLabels")) + ".", default=True)
}
def after_model_change(self, form, model, is_created):
if form.create_parts.data:
if is_created == False and model.parts != []:
flash("This semester already has parts!", "danger")
return
for partLabel in getConfig("partsLabels"):
db.session.add(Part(label=partLabel, semester=model))
db.session.commit()
if is_created:
admin.add_link(MenuLink(name=model.label,
url=url_for("set_semester") + "?semester_id=" + str(model.id),
category="Active semester"))
setActiveSemester(model.id)
class PartModelView(SecureModelView):
can_view_details = True
column_details_list = ["label", "semester", "part_experiments", "part_students", "groups"]
form_columns = ["label", "semester"]
partsLabels = getConfig("partsLabels")
form_choices = {"label": list(zip(partsLabels, partsLabels))}
class StudentModelView(SecureModelView):
can_view_details = True
column_list = ["student_number", "first_name", "last_name", "uni_email", "contact_email", "part_students"]
column_details_list = column_list + ["bachelor_thesis", "bachelor_thesis_work_group", "note"]
column_searchable_list = ["student_number", "uni_email", "contact_email", "first_name", "last_name"]
form_columns = column_details_list + ["new_part_student_part", "new_part_student_group_number"]
form_args = {
"uni_email": {"validators": [Email()]},
"contact_email": {"validators": [Email()]},
}
partChoices = ["-"] + getConfig("partsLabels")
form_extra_fields = {
"new_part_student_part": SelectField("Part", choices=list(zip(partChoices, partChoices)), default=partChoices[0]),
"new_part_student_group_number": TextField("Group number")
}
def validate_form(self, form):
if request.method == "POST":
partLabel = form.new_part_student_part.data
groupNumber = form.new_part_student_group_number.data
if (partLabel != self.partChoices[0] and groupNumber == "") or (partLabel == self.partChoices[0] and groupNumber != ""):
flash("You have to assign both part and group if you want to add a part student!", "danger")
return False
if partLabel != self.partChoices[0] and not partFromLabelInUserActiveSemester(partLabel):
flash(f"Part {partLabel} is not created in {str(userActiveSemester())} yet!", "danger")
return False
if groupNumber != "":
message = "The group number has to be an integer > 0 !"
try:
groupNumber = int(groupNumber)
except:
flash(message, "danger")
return False
if groupNumber < 1:
flash(message, "danger")
return False
return super().validate_form(form)
def after_model_change(self, form, model, is_created):
partLabel = form.new_part_student_part.data
print("\nLL\n")
if partLabel != self.partChoices[0]:
groupNumber = int(form.new_part_student_group_number.data)
part = partFromLabelInUserActiveSemester(partLabel)
group = Group.query.filter(Group.number == groupNumber, Group.part == part).first()
if group is None:
group = Group(number=groupNumber, part=part)
db.session.add(group)
flash(f"Added the new group with number {str(groupNumber)} in part {str(part)}.", "success")
partStudent = PartStudent(student=model, part=part, group=group)
db.session.add(partStudent)
db.session.commit()
flash("Added part student.", "success")
class PartFilter(BaseSQLAFilter):
def apply(self, query, value, alias=None):
return query.filter(self.column == partFromLabelInUserActiveSemester(value).id)
def operation(self):
return "equals"
def validate(self, value):
if partFromLabelInUserActiveSemester(value):
return True
else:
flash(f"Part {value} not found in your active semester {userActiveSemester()}!", "danger")
return False
class PartStudentModelView(SecureModelView):
partsLabels = getConfig("partsLabels")
column_filters = [PartFilter(PartStudent.part_id, "Part", options=list(zip(partsLabels, partsLabels)))]
form_excluded_columns = ["experiment_marks"]
admin.add_view(StudentModelView(Student, db.session))
admin.add_view(PartStudentModelView(PartStudent, db.session))
admin.add_view(SecureModelView(Group, db.session))
admin.add_view(SecureModelView(GroupExperiment, db.session))
admin.add_view(SecureModelView(Experiment, db.session))
admin.add_view(SecureModelView(PartExperiment, db.session))
admin.add_view(SecureModelView(Assistant, db.session))
admin.add_view(SecureModelView(Appointment, db.session))
admin.add_view(PartModelView(Part, db.session))
admin.add_view(SemesterModelView(Semester, db.session))
admin.add_view(SecureModelView(ExperimentMark, db.session))
admin.add_view(UserModelView(User, db.session))
admin.add_view(RoleModelView(Role, db.session))
with app.app_context():
semesters = Semester.query.all()[::-1]
for semester in semesters:
admin.add_link(MenuLink(name=semester.label,
url=url_for("set_semester") + "?semester_id=" + str(semester.id),
category="Active semester"))