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

235 lines
7.6 KiB
Python
Raw Normal View History

from flask import flash
2022-02-23 18:37:09 +00:00
from flask_admin import expose
2022-02-23 19:36:29 +00:00
from flask_security import admin_change_password, current_user
from wtforms import Form
from wtforms.fields import BooleanField, IntegerField, StringField
2022-05-09 00:10:30 +00:00
from wtforms.validators import NumberRange, Optional
2021-07-30 00:50:49 +00:00
2022-05-08 19:26:25 +00:00
from . import assistantSpace, db
2022-06-01 21:57:28 +00:00
from .advlabdb_independent_funs import (
deep_getattr,
flashRandomPassword,
missing_formatter,
str_formatter,
str_without_semester_formatter,
)
2022-05-08 19:26:25 +00:00
from .customClasses import SecureAssistantBaseView, SecureAssistantModelView
from .exceptions import DataBaseException, ModelViewException
from .model_dependent_funs import initActiveSemesterMenuLinks
2022-05-29 17:03:54 +00:00
from .model_independent_funs import randomPassword
2022-05-08 19:26:25 +00:00
from .models import (
2022-04-11 23:44:53 +00:00
MAX_MARK,
MIN_MARK,
2021-07-30 00:50:49 +00:00
Appointment,
Assistant,
ExperimentMark,
GroupExperiment,
2021-07-30 12:20:54 +00:00
SemesterExperiment,
2021-07-30 00:50:49 +00:00
User,
)
class AssistantAppointmentView(SecureAssistantModelView):
2022-02-24 00:28:09 +00:00
can_edit = True
2021-07-31 22:41:21 +00:00
column_list = [
"date",
"special",
"group_experiment.semester_experiment.experiment",
2022-06-01 21:15:22 +00:00
"group_experiment.group.number",
2021-07-31 22:41:21 +00:00
"group_experiment.group.part_students",
]
column_labels = {
"group_experiment.semester_experiment.experiment": "Experiment",
2022-06-01 21:15:22 +00:00
"group_experiment.group.number": "Group number",
2021-07-31 22:41:21 +00:00
"group_experiment.group.part_students": "Students",
}
2021-11-30 00:47:37 +00:00
column_editable_list = [
"date",
]
2022-02-24 00:28:09 +00:00
form_columns = column_editable_list
2022-05-30 02:18:19 +00:00
column_descriptions = {
"special": "A special appointment should take place in the semester break",
}
2022-06-01 21:57:28 +00:00
def part_students_formatter(view, context, model, name):
part_students = deep_getattr(model, name)
if part_students is not None:
return ", ".join([str(part_student.student) for part_student in part_students])
return attr
column_formatters = {
"group_experiment.semester_experiment.experiment": str_formatter,
"group_experiment.group.part_students": part_students_formatter,
}
def query_modifier(self, query):
return (
query.join(GroupExperiment)
.join(SemesterExperiment)
.where(
SemesterExperiment.semester == current_user.active_semester,
Appointment.assistant == current_user.assistant,
)
)
class AssistantExperimentMarkView(SecureAssistantModelView):
class EditForm(Form):
oral_mark = IntegerField(
"Oral Mark",
validators=[Optional(), NumberRange(MIN_MARK, MAX_MARK)],
description=f"Between {MIN_MARK} and {MAX_MARK}",
)
protocol_mark = IntegerField(
"Protocol Mark",
validators=[Optional(), NumberRange(MIN_MARK, MAX_MARK)],
description=f"Between {MIN_MARK} and {MAX_MARK}",
)
2022-02-24 00:28:09 +00:00
can_edit = True
column_display_actions = True
2022-02-24 00:28:09 +00:00
2021-07-31 22:41:21 +00:00
column_list = [
"oral_mark",
"protocol_mark",
2021-08-29 16:15:14 +00:00
"final_experiment_mark",
2022-06-01 21:57:28 +00:00
"group_experiment.semester_experiment.experiment.number",
2022-06-01 21:15:22 +00:00
"part_student.student",
"part_student.group.number",
2021-07-31 22:41:21 +00:00
"part_student.student.uni_email",
"part_student.student.contact_email",
"part_student.part",
"assistant",
2022-02-27 18:30:28 +00:00
"admin",
2021-07-31 22:41:21 +00:00
]
column_labels = {
2022-06-01 21:57:28 +00:00
"group_experiment.semester_experiment.experiment.number": "Experiment number",
2022-06-01 21:15:22 +00:00
"part_student.student": "Student",
"part_student.group.number": "Group number",
2021-07-31 22:41:21 +00:00
"part_student.student.uni_email": "Uni Email",
"part_student.student.contact_email": "Contact Email",
"part_student.part": "Part",
}
column_descriptions = {
2022-04-11 23:44:53 +00:00
"oral_mark": f"Between {MIN_MARK} and {MAX_MARK}",
"protocol_mark": f"Between {MIN_MARK} and {MAX_MARK}",
2021-08-29 16:15:14 +00:00
"final_experiment_mark": "Calculated automatically with oral and protocol marks and weightings",
2021-07-31 22:41:21 +00:00
"part_student.student.contact_email": "The preferred contact email address if entered by the student",
2022-02-27 18:30:28 +00:00
"assistant": "The last assistant who edited the mark",
"admin": "The last admin who edited the mark",
2021-07-31 22:41:21 +00:00
}
column_searchable_list = [
"part_student.student.first_name",
"part_student.student.last_name",
"part_student.student.uni_email",
"part_student.student.contact_email",
]
2022-06-01 21:57:28 +00:00
column_formatters = {
"oral_mark": missing_formatter,
"protocol_mark": missing_formatter,
"part_student.part": str_without_semester_formatter,
}
2021-07-30 00:50:49 +00:00
column_default_sort = [("oral_mark", False), ("protocol_mark", False)]
2021-07-30 00:50:49 +00:00
2022-05-21 16:30:23 +00:00
def query_modifier(self, query):
return (
query.join(GroupExperiment)
.join(SemesterExperiment)
.where(SemesterExperiment.semester == current_user.active_semester)
.join(SemesterExperiment.assistants)
.where(Assistant.user == current_user)
2021-07-30 00:50:49 +00:00
)
def update_model(self, form, model):
2022-05-15 20:25:19 +00:00
if (form.oral_mark is not None and form.oral_mark.data != model.oral_mark) or (
form.protocol_mark is not None and form.protocol_mark.data != model.protocol_mark
):
model.assistant = current_user.assistant
2021-07-30 00:50:49 +00:00
2022-05-15 20:25:19 +00:00
updateSuccessful = super().update_model(form, model)
2021-07-30 00:50:49 +00:00
model.part_student.checkThenSetFinalPartMark()
2022-05-15 20:25:19 +00:00
return updateSuccessful
else:
# Nothing changed
return True
2021-07-30 00:50:49 +00:00
2021-11-30 00:47:37 +00:00
class AssistantUserView(SecureAssistantModelView):
2022-02-23 19:36:29 +00:00
class EditForm(Form):
2022-05-08 20:04:08 +00:00
phone_number = StringField(
"Phone Number",
validators=[Optional()],
)
mobile_phone_number = StringField(
"Mobile Phone Number",
validators=[Optional()],
)
2022-02-23 19:36:29 +00:00
2022-05-08 20:04:08 +00:00
building = StringField(
"Building",
validators=[Optional()],
)
room = StringField(
"Room",
validators=[Optional()],
)
2022-02-23 19:36:29 +00:00
2022-05-08 20:04:08 +00:00
generate_new_password = BooleanField(
"Generate new random password. For security reasons, it is not possible to manually enter a password. Please use a password manager like Bitwarden or KeepassXC to save the randomly generated password.",
default=False,
)
2022-02-23 19:36:29 +00:00
can_edit = True
2022-05-30 13:38:20 +00:00
can_view_details = True
2022-02-23 19:36:29 +00:00
column_display_actions = True
2021-11-30 00:47:37 +00:00
column_sortable_list = []
column_list = [
"email",
"phone_number",
"mobile_phone_number",
"building",
2022-02-23 19:36:29 +00:00
"room",
2021-11-30 00:47:37 +00:00
"assistant.semester_experiments",
]
column_labels = {
"assistant.semester_experiments": "Semester Experiments",
}
2022-05-21 16:30:23 +00:00
def query_modifier(self, query):
return query.where(User.id == current_user.id)
2021-11-30 00:47:37 +00:00
2022-02-23 19:36:29 +00:00
def on_model_change(self, form, model, is_created):
if form.generate_new_password.data:
password = randomPassword()
flashRandomPassword(password)
admin_change_password(model, password, notify=False) # Password is automatically hashed with this function
2021-11-30 00:47:37 +00:00
2022-02-23 18:37:09 +00:00
class AssistantDocsView(SecureAssistantBaseView):
2022-03-04 02:49:02 +00:00
@expose("/")
2022-02-23 18:37:09 +00:00
def index(self):
2022-05-30 15:02:00 +00:00
return self.render("docs/docs.html", role="assistant")
2022-02-23 18:37:09 +00:00
assistantSpace.add_view(
AssistantAppointmentView(Appointment, db.session, endpoint="assistant_appointment", url="appointment")
)
2021-07-30 00:50:49 +00:00
assistantSpace.add_view(
2022-05-30 15:02:00 +00:00
AssistantExperimentMarkView(ExperimentMark, db.session, endpoint="assistant_experimentmark", url="experiment_mark")
2021-07-30 00:50:49 +00:00
)
2021-11-30 00:47:37 +00:00
assistantSpace.add_view(AssistantUserView(User, db.session, endpoint="assistant_user", url="user"))
2022-02-23 18:37:09 +00:00
assistantSpace.add_view(AssistantDocsView(name="Docs", endpoint="assistant_docs", url="docs"))
initActiveSemesterMenuLinks(assistantSpace)