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

Apply SIM

This commit is contained in:
Mo 2023-11-02 19:38:09 +01:00
parent 029cc974e3
commit b1d3c26b07
8 changed files with 245 additions and 273 deletions

View file

@ -1084,9 +1084,8 @@ class GroupExperimentView(SecureAdminModelView):
self.session.add(appointment) self.session.add(appointment)
def after_model_change(self, form, model, is_created): def after_model_change(self, form, model, is_created):
if is_created: if is_created and model.appointments:
if model.appointments: flash(f"Appointments {model.appointments} added.", "success")
flash(f"Appointments {model.appointments} added.", "success")
def groupExperimentQueryFactory(): def groupExperimentQueryFactory():

View file

@ -20,11 +20,7 @@ def assistant_group_experiment_form_factory(current_user, group_experiment):
appointments = group_experiment.appointments appointments = group_experiment.appointments
appointment_num = 1 appointment_num = 1
for appointment in appointments: for appointment in appointments:
description = None description = "Yes" if appointment.special else "No"
if appointment.special:
description = "Yes"
else:
description = "No"
setattr( setattr(
AssistantGroupExperimentForm, AssistantGroupExperimentForm,

View file

@ -231,10 +231,7 @@ class Group(db.Model):
.order_by(Group.number.desc()) .order_by(Group.number.desc())
) )
if highestGroupNumber is not None: number = highestGroupNumber + 1 if highestGroupNumber is not None else 1
number = highestGroupNumber + 1
else:
number = 1
return Group( return Group(
program=program, program=program,
@ -529,9 +526,8 @@ class Semester(db.Model):
def __init__(self, label, year, **kwargs): def __init__(self, label, year, **kwargs):
last_semester = Semester.lastSemester() last_semester = Semester.lastSemester()
if last_semester is not None: if last_semester is not None and (year < last_semester.year or (year == last_semester.year and label == "SS")):
if year < last_semester.year or (year == last_semester.year and label == "SS"): raise DatabaseException(f"You can only create semesters later than the last semester {last_semester}!")
raise DatabaseException(f"You can only create semesters later than the last semester {last_semester}!")
super().__init__(label=label, year=year, **kwargs) super().__init__(label=label, year=year, **kwargs)

View file

@ -44,15 +44,9 @@ def post_login():
if current_active_semester.done: if current_active_semester.done:
current_user.set_last_semester_as_active() current_user.set_last_semester_as_active()
if current_user.has_role("admin"): endpoint_base = "admin" if current_user.has_role("admin") else "assistant"
endpoint_base = "admin"
else:
endpoint_base = "assistant"
if current_user.login_count == 1: url = url_for(endpoint_base + "_docs.index") if current_user.login_count == 1 else url_for(endpoint_base + ".index")
url = url_for(endpoint_base + "_docs.index")
else:
url = url_for(endpoint_base + ".index")
return redirect(url) return redirect(url)
@ -60,10 +54,7 @@ def post_login():
@bp.route("/user-settings") @bp.route("/user-settings")
@auth_required() @auth_required()
def user_settings(): def user_settings():
if current_user.has_role("admin"): role = "admin" if current_user.has_role("admin") else "assistant"
role = "admin"
else:
role = "assistant"
url = url_for("main.index") + role + "/user/edit/?id=" + str(current_user.id) url = url_for("main.index") + role + "/user/edit/?id=" + str(current_user.id)

View file

@ -12,39 +12,38 @@ def _reset_admin_password(manage):
app = create_app(create_for_server=False) app = create_app(create_for_server=False)
with app.app_context(): with app.app_context(), db.session.begin():
with db.session.begin(): admins = db.session.scalars(select(Admin).join(User).where(User.active is True)).all()
admins = db.session.scalars(select(Admin).join(User).where(User.active is True)).all() activate_user = False
activate_user = False
if len(admins) == 0: if len(admins) == 0:
click.echo("There is no admin with an active user. The user of the chosen admin will be activated.") click.echo("There is no admin with an active user. The user of the chosen admin will be activated.")
admins = db.session.scalars(select(Admin)).all() admins = db.session.scalars(select(Admin)).all()
activate_user = True activate_user = True
num_admins = len(admins) num_admins = len(admins)
prompt = "Admins:\n" prompt = "Admins:\n"
for ind, admin in enumerate(admins): for ind, admin in enumerate(admins):
user = admin.user user = admin.user
prompt += f"[{ind}] {user.first_name} {user.last_name}: {user.email}\n" prompt += f"[{ind}] {user.first_name} {user.last_name}: {user.email}\n"
prompt += f"Enter number [0-{num_admins - 1}]" prompt += f"Enter number [0-{num_admins - 1}]"
admin_index = click.prompt( admin_index = click.prompt(
prompt, prompt,
type=click.IntRange(0, num_admins - 1), type=click.IntRange(0, num_admins - 1),
) )
chosen_admin_user = admins[admin_index].user chosen_admin_user = admins[admin_index].user
new_password = randomPassword() new_password = randomPassword()
admin_change_password( admin_change_password(
chosen_admin_user, new_password, notify=False chosen_admin_user, new_password, notify=False
) # Password is automatically hashed with this function ) # Password is automatically hashed with this function
if activate_user: if activate_user:
chosen_admin_user.active = True chosen_admin_user.active = True
manage.box(f"New password: {new_password}") manage.box(f"New password: {new_password}")

View file

@ -24,64 +24,61 @@ def _init_db(manage):
app = create_app(create_for_server=False) app = create_app(create_for_server=False)
with app.app_context(): with app.app_context(), db.session.begin():
with db.session.begin(): # Create new database
# Create new database db.create_all()
db.create_all()
semester_label = click.prompt( semester_label = click.prompt(
"Enter the label of the current semester", "Enter the label of the current semester",
type=click.Choice(("SS", "WS")), type=click.Choice(("SS", "WS")),
) )
semester_year = click.prompt( semester_year = click.prompt(
f"Enter the year of the current semester (between {MIN_YEAR} and {MAX_YEAR})", f"Enter the year of the current semester (between {MIN_YEAR} and {MAX_YEAR})",
type=click.IntRange(MIN_YEAR, MAX_YEAR), type=click.IntRange(MIN_YEAR, MAX_YEAR),
) )
semester = Semester(label=semester_label, year=semester_year) semester = Semester(label=semester_label, year=semester_year)
db.session.add(semester) db.session.add(semester)
adminRole = user_datastore.create_role(name="admin") adminRole = user_datastore.create_role(name="admin")
user_datastore.create_role(name="assistant") user_datastore.create_role(name="assistant")
manage.box("The first admin account will be created now.") manage.box("The first admin account will be created now.")
admin_email = click.prompt( admin_email = click.prompt(
"Enter the admin's email address", "Enter the admin's email address",
type=EmailParamType(), type=EmailParamType(),
) )
admin_first_name = click.prompt("Enter the admin's first name") admin_first_name = click.prompt("Enter the admin's first name")
admin_last_name = click.prompt("Enter the admin's last name") admin_last_name = click.prompt("Enter the admin's last name")
admin_phone_number = click.prompt( admin_phone_number = click.prompt("Enter the admin's phone number (optional)", default="", show_default=False)
"Enter the admin's phone number (optional)", default="", show_default=False admin_mobile_phone_number = click.prompt(
) "Enter the admin's mobile phone number (optional)", default="", show_default=False
admin_mobile_phone_number = click.prompt( )
"Enter the admin's mobile phone number (optional)", default="", show_default=False admin_building = click.prompt("Enter the admin's building (optional)", default="", show_default=False)
) admin_room = click.prompt("Enter the admin's room (optional)", default="", show_default=False)
admin_building = click.prompt("Enter the admin's building (optional)", default="", show_default=False)
admin_room = click.prompt("Enter the admin's room (optional)", default="", show_default=False)
admin_password = randomPassword() admin_password = randomPassword()
admin_hashed_password = hash_password(admin_password) admin_hashed_password = hash_password(admin_password)
admin_user = user_datastore.create_user( admin_user = user_datastore.create_user(
email=admin_email, email=admin_email,
password=admin_hashed_password, password=admin_hashed_password,
roles=[adminRole], roles=[adminRole],
first_name=admin_first_name.strip(), first_name=admin_first_name.strip(),
last_name=admin_last_name.strip(), last_name=admin_last_name.strip(),
phone_number=admin_phone_number.strip() or None, phone_number=admin_phone_number.strip() or None,
mobile_phone_number=admin_mobile_phone_number.strip() or None, mobile_phone_number=admin_mobile_phone_number.strip() or None,
building=admin_building.strip() or None, building=admin_building.strip() or None,
room=admin_room.strip() or None, room=admin_room.strip() or None,
active_semester=semester, active_semester=semester,
) )
admin = Admin(user=admin_user) admin = Admin(user=admin_user)
db.session.add(admin) db.session.add(admin)
manage.box(f"Admin password: {admin_password}") manage.box(f"Admin password: {admin_password}")

View file

@ -45,202 +45,196 @@ def _generate_test_db():
app = create_app(create_for_server=False) app = create_app(create_for_server=False)
with app.app_context(): with app.app_context(), db.session.begin():
with db.session.begin(): db.create_all()
db.create_all()
bs_prog = db_add(Program(label="BS")) bs_prog = db_add(Program(label="BS"))
ms_prog = db_add(Program(label="MS")) ms_prog = db_add(Program(label="MS"))
be_prog = db_add(Program(label="BE")) be_prog = db_add(Program(label="BE"))
programs = (bs_prog, ms_prog, be_prog) programs = (bs_prog, ms_prog, be_prog)
ss = db_add(Semester(label="SS", year=23)) ss = db_add(Semester(label="SS", year=23))
ws = db_add(Semester(label="WS", year=23)) ws = db_add(Semester(label="WS", year=23))
semesters = (ss, ws) semesters = (ss, ws)
bs_1_ss_part = db_add(Part(semester=ss, program=bs_prog, number=1)) bs_1_ss_part = db_add(Part(semester=ss, program=bs_prog, number=1))
bs_2_ss_part = db_add(Part(semester=ss, program=bs_prog, number=2)) bs_2_ss_part = db_add(Part(semester=ss, program=bs_prog, number=2))
ms_1_ss_part = db_add(Part(semester=ss, program=ms_prog, number=1)) ms_1_ss_part = db_add(Part(semester=ss, program=ms_prog, number=1))
ms_2_ss_part = db_add(Part(semester=ss, program=ms_prog, number=2)) ms_2_ss_part = db_add(Part(semester=ss, program=ms_prog, number=2))
be_1_ss_part = db_add(Part(semester=ss, program=be_prog, number=1)) be_1_ss_part = db_add(Part(semester=ss, program=be_prog, number=1))
be_2_ss_part = db_add(Part(semester=ss, program=be_prog, number=2)) be_2_ss_part = db_add(Part(semester=ss, program=be_prog, number=2))
ss_parts = (bs_1_ss_part, bs_2_ss_part, ms_1_ss_part, ms_2_ss_part, be_1_ss_part, be_2_ss_part) ss_parts = (bs_1_ss_part, bs_2_ss_part, ms_1_ss_part, ms_2_ss_part, be_1_ss_part, be_2_ss_part)
db_add(Part(semester=ws, program=bs_prog, number=1)) db_add(Part(semester=ws, program=bs_prog, number=1))
bs_2_ws_part = db_add(Part(semester=ws, program=bs_prog, number=2)) bs_2_ws_part = db_add(Part(semester=ws, program=bs_prog, number=2))
ms_1_ws_part = db_add(Part(semester=ws, program=ms_prog, number=1)) ms_1_ws_part = db_add(Part(semester=ws, program=ms_prog, number=1))
ms_2_ws_part = db_add(Part(semester=ws, program=ms_prog, number=2)) ms_2_ws_part = db_add(Part(semester=ws, program=ms_prog, number=2))
db_add(Part(semester=ws, program=be_prog, number=1)) db_add(Part(semester=ws, program=be_prog, number=1))
be_2_ws_part = db_add(Part(semester=ws, program=be_prog, number=2)) be_2_ws_part = db_add(Part(semester=ws, program=be_prog, number=2))
semester_program_part_students = { semester_program_part_students = {
ss: {program: [] for program in programs}, ss: {program: [] for program in programs},
ws: {program: [] for program in programs}, ws: {program: [] for program in programs},
} }
def add_part_student(student, part): def add_part_student(student, part):
part_student = db_add(PartStudent(student=student, part=part)) part_student = db_add(PartStudent(student=student, part=part))
semester_program_part_students[part.semester][part.program].append(part_student) semester_program_part_students[part.semester][part.program].append(part_student)
for ind, name in enumerate(student_names): for ind, name in enumerate(student_names):
if randint(0, 1) == 0: # nosec: B311 contact_email = f"{name[0]}-{name[1]}@private.de".lower() if ind % 2 == 0 else None
contact_email = f"{name[0]}-{name[1]}@private.de".lower()
else:
contact_email = None
student = db_add( student = db_add(
Student( Student(
student_number=ind, student_number=ind,
first_name=name[0], first_name=name[0],
last_name=name[1], last_name=name[1],
uni_email=f"{name[0]}-{name[1]}@uni.de".lower(), uni_email=f"{name[0]}-{name[1]}@uni.de".lower(),
contact_email=contact_email, contact_email=contact_email,
)
) )
)
part = ss_parts[ind % len(ss_parts)] part = ss_parts[ind % len(ss_parts)]
add_part_student(student, part) add_part_student(student, part)
if random() < 0.9: # nosec: B311 if random() < 0.9: # nosec: B311
# Transfer to the next part in the second semester # Transfer to the next part in the second semester
if part == bs_1_ss_part: if part == bs_1_ss_part:
add_part_student(student, bs_2_ws_part) add_part_student(student, bs_2_ws_part)
elif part == bs_2_ss_part: elif part == bs_2_ss_part:
add_part_student(student, ms_1_ws_part) add_part_student(student, ms_1_ws_part)
elif part == ms_1_ss_part: elif part == ms_1_ss_part:
add_part_student(student, ms_2_ws_part) add_part_student(student, ms_2_ws_part)
elif part == be_1_ss_part: elif part == be_1_ss_part:
add_part_student(student, be_2_ws_part) add_part_student(student, be_2_ws_part)
program_groups = {program: [] for program in programs} program_groups = {program: [] for program in programs}
for _semester, program_part_students in semester_program_part_students.items(): for _semester, program_part_students in semester_program_part_students.items():
for program, part_students in program_part_students.items(): for program, part_students in program_part_students.items():
if len(part_students) % 2 == 1: if len(part_students) % 2 == 1:
# Add the first 3 students into a special group for an uneven number of students # Add the first 3 students into a special group for an uneven number of students
group_part_students = [] group_part_students = []
for _ in range(3): for _ in range(3):
if len(part_students) == 0: if len(part_students) == 0:
break
group_part_students.append(part_students.pop(0))
group = db_add(Group.customInit(group_part_students))
program_groups[program].append(group)
while len(part_students) >= 2:
# Add the rest of the students into groups of 2
group = db_add(Group.customInit([part_students.pop(0) for i in range(2)]))
program_groups[program].append(group)
program_semester_experiments = {program: [] for program in programs}
all_semester_experiments = []
for ind, title in enumerate(experiment_titles):
program = programs[ind % len(programs)]
experiment = db_add(
Experiment(
number=ind + 1,
program=program,
title=title,
building="Not assigned",
room="Not assigned",
duration_in_days=2,
)
)
for semester in semesters:
semester_experiment = db_add(SemesterExperiment(experiment=experiment, semester=semester))
program_semester_experiments[program].append(semester_experiment)
all_semester_experiments.append(semester_experiment)
all_group_experiments = []
for program in programs:
semester_experiments = program_semester_experiments[program]
num_semester_experiments = len(semester_experiments)
for ind, group in enumerate(program_groups[program]):
num_tries = 0
while True:
try:
semester_experiment = semester_experiments[ind % num_semester_experiments]
group_experiment = db_add(
GroupExperiment(semester_experiment=semester_experiment, group=group)
)
except DatabaseException as ex:
# Catch an error when a student becomes the same experiment for the second time.
# Try the next experiment!
ind += 1
num_tries += 1
if num_tries == num_semester_experiments:
raise ex
else:
break break
all_group_experiments.append(group_experiment) group_part_students.append(part_students.pop(0))
adminRole = user_datastore.create_role(name="admin") group = db_add(Group.customInit(group_part_students))
assistantRole = user_datastore.create_role(name="assistant") program_groups[program].append(group)
admin_names = ( while len(part_students) >= 2:
("Aileen", "Grant"), # Add the rest of the students into groups of 2
("Ben", "Huber"), group = db_add(Group.customInit([part_students.pop(0) for i in range(2)]))
program_groups[program].append(group)
program_semester_experiments = {program: [] for program in programs}
all_semester_experiments = []
for ind, title in enumerate(experiment_titles):
program = programs[ind % len(programs)]
experiment = db_add(
Experiment(
number=ind + 1,
program=program,
title=title,
building="Not assigned",
room="Not assigned",
duration_in_days=2,
)
) )
for name in admin_names:
user = user_datastore.create_user(
email=f"{name[0]}-{name[1]}@uni.de".lower(),
password=hash_password("admin"),
roles=[adminRole],
first_name=name[0],
last_name=name[1],
active_semester=ws,
)
db_add(Admin(user=user)) for semester in semesters:
semester_experiment = db_add(SemesterExperiment(experiment=experiment, semester=semester))
program_semester_experiments[program].append(semester_experiment)
all_semester_experiments.append(semester_experiment)
num_assistants = len(assistant_names) all_group_experiments = []
num_assistant_experiments = ceil(len(all_semester_experiments) / num_assistants) for program in programs:
semester_experiments = program_semester_experiments[program]
num_semester_experiments = len(semester_experiments)
for name in assistant_names: for ind, group in enumerate(program_groups[program]):
user = user_datastore.create_user( num_tries = 0
email=f"{name[0]}-{name[1]}@uni.de".lower(), while True:
password=hash_password("assistant"), try:
roles=[assistantRole], semester_experiment = semester_experiments[ind % num_semester_experiments]
first_name=name[0], group_experiment = db_add(GroupExperiment(semester_experiment=semester_experiment, group=group))
last_name=name[1], except DatabaseException as ex:
mobile_phone_number="01" + "".join(str(randint(0, 9)) for i in range(10)), # nosec: B311 # Catch an error when a student becomes the same experiment for the second time.
active_semester=ws, # Try the next experiment!
) ind += 1
num_tries += 1
semester_experiments = [] if num_tries == num_semester_experiments:
for _ in range(num_assistant_experiments): raise ex
if len(all_semester_experiments) == 0: else:
break break
semester_experiments.append(all_semester_experiments.pop(0)) all_group_experiments.append(group_experiment)
db_add(Assistant(user=user, semester_experiments=semester_experiments)) adminRole = user_datastore.create_role(name="admin")
assistantRole = user_datastore.create_role(name="assistant")
for group_experiment in all_group_experiments: admin_names = (
semester_experiment = group_experiment.semester_experiment ("Aileen", "Grant"),
special = False ("Ben", "Huber"),
semester = semester_experiment.semester )
if semester.label == "SS": for name in admin_names:
month = randint(3, 8) # nosec: B311 user = user_datastore.create_user(
if month <= 4: email=f"{name[0]}-{name[1]}@uni.de".lower(),
special = True password=hash_password("admin"),
else: roles=[adminRole],
month = randint(9, 12) # nosec: B311 first_name=name[0],
if month <= 10: last_name=name[1],
special = True active_semester=ws,
)
year = 2000 + semester.year db_add(Admin(user=user))
day = randint(1, 28) # nosec: B311
for appointment_date in (date(year, month, day), date(year, month, day + 1)): num_assistants = len(assistant_names)
db_add( num_assistant_experiments = ceil(len(all_semester_experiments) / num_assistants)
Appointment(
date=appointment_date, for name in assistant_names:
special=special, user = user_datastore.create_user(
group_experiment=group_experiment, email=f"{name[0]}-{name[1]}@uni.de".lower(),
assistant=semester_experiment.assistants[0], password=hash_password("assistant"),
) roles=[assistantRole],
first_name=name[0],
last_name=name[1],
mobile_phone_number="01" + "".join(str(randint(0, 9)) for i in range(10)), # nosec: B311
active_semester=ws,
)
semester_experiments = []
for _ in range(num_assistant_experiments):
if len(all_semester_experiments) == 0:
break
semester_experiments.append(all_semester_experiments.pop(0))
db_add(Assistant(user=user, semester_experiments=semester_experiments))
for group_experiment in all_group_experiments:
semester_experiment = group_experiment.semester_experiment
special = False
semester = semester_experiment.semester
if semester.label == "SS":
month = randint(3, 8) # nosec: B311
if month <= 4:
special = True
else:
month = randint(9, 12) # nosec: B311
if month <= 10:
special = True
year = 2000 + semester.year
day = randint(1, 28) # nosec: B311
for appointment_date in (date(year, month, day), date(year, month, day + 1)):
db_add(
Appointment(
date=appointment_date,
special=special,
group_experiment=group_experiment,
assistant=semester_experiment.assistants[0],
) )
)

View file

@ -27,7 +27,7 @@ requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.ruff] [tool.ruff]
select = ["E", "W", "F", "I", "UP", "YTT", "S", "B", "C4", "ICN", "PIE", "Q", "RET"] select = ["E", "W", "F", "I", "UP", "YTT", "S", "B", "C4", "ICN", "PIE", "Q", "RET", "SIM"]
ignore = ["E5", "S3", "S6", "RET504"] ignore = ["E5", "S3", "S6", "RET504"]
line-length = 120 line-length = 120