from pathlib import Path import click from email_validator import validate_email from flask_security.utils import hash_password from advlabdb import create_app, data_dir, user_datastore from advlabdb.model_independent_funs import randomPassword from advlabdb.models import MAX_YEAR, MIN_YEAR, Admin, Semester, db # Class to validate email in click.prompt class EmailParamType(click.ParamType): def convert(self, value, param, ctx): try: return validate_email(value).email except Exception: self.fail(f"{value} is not a valid email!", param, ctx) def _init_db(manage): db_file = data_dir / "db/advlab.db" if db_file.is_file(): click.echo(f"Skipping database initialization because the database does already exist at {db_file}.") return app = create_app(create_for_server=False) with app.app_context(): with db.session.begin(): # Create new database db.create_all() semester_label = click.prompt( "Enter the label of the current semester", type=click.Choice(("SS", "WS")), ) semester_year = click.prompt( f"Enter the year of the current semester (between {MIN_YEAR} and {MAX_YEAR})", type=click.IntRange(MIN_YEAR, MAX_YEAR), ) semester = Semester(label=semester_label, year=semester_year) db.session.add(semester) adminRole = user_datastore.create_role(name="admin") user_datastore.create_role(name="assistant") manage.box("The first admin account will be created now.") admin_email = click.prompt( "Enter the admin's email address", type=EmailParamType(), ) admin_first_name = click.prompt("Enter the admin's first name") admin_last_name = click.prompt("Enter the admin's last name") admin_phone_number = click.prompt( "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_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_hashed_password = hash_password(admin_password) admin_user = user_datastore.create_user( email=admin_email, password=admin_hashed_password, roles=[adminRole], first_name=admin_first_name.strip(), last_name=admin_last_name.strip(), phone_number=admin_phone_number.strip() or None, mobile_phone_number=admin_mobile_phone_number.strip() or None, building=admin_building.strip() or None, room=admin_room.strip() or None, active_semester=semester, ) admin = Admin(user=admin_user) db.session.add(admin) manage.box(f"Admin password: {admin_password}") click.echo(click.style("Done database initialization!", fg="green"))