import sys from pathlib import Path from email_validator import validate_email from flask_security import hash_password from advlabdb import app, db, user_datastore from advlabdb.independent_funs import randomPassword from advlabdb.models import MAX_YEAR, MIN_YEAR, Admin, Semester scripts_dir = Path(__file__).parent.absolute() / "scripts" sys.path.insert(0, str(scripts_dir)) from shared import box def validating_input( prompt, options=None, format_function=lambda ans: ans, check_constraints_function=lambda ans: True, ): if options is not None: prompt += " [" for opt in options[:-1]: prompt += opt + "/" prompt += options[-1] + "]: " lowered_options = [opt.lower() for opt in options] def adj_check_constraints_function(ans): return ans.lower() in lowered_options and check_constraints_function(ans) else: prompt += ": " adj_check_constraints_function = check_constraints_function ans = None first_run = True while ans is None or not adj_check_constraints_function(ans): if not first_run: print("Invalid input!") else: first_run = False ans = input(prompt) try: ans = format_function(ans) except Exception as ex: ans = None return ans def confirm(prompt): ans = validating_input( prompt, options=("y", "n"), format_function=lambda ans: ans.lower(), ) if ans == "y": return True else: return False def main(): print("This script should only be used to initialize the database after setting up a server") print("The old database will be DELETED and a new database will be created.") if not confirm("Are you sure that you want to continue?"): print("Aborted!") return with app.app_context(): with db.session.begin(): # Delete old database db.drop_all() # Create new database db.create_all() semester_label = validating_input( "Enter the label of the current semester", options=("SS", "WS"), format_function=lambda ans: ans.upper(), ) semester_year = validating_input( f"Enter the year of the current semester (between {MIN_YEAR} and {MAX_YEAR})", format_function=lambda n_str: int(n_str), check_constraints_function=lambda n: MIN_YEAR <= n <= MAX_YEAR, ) semester = Semester.customInit(label=semester_label, year=semester_year) db.session.add(semester) adminRole = user_datastore.create_role(name="admin") assistantRole = user_datastore.create_role(name="assistant") box("The first admin account will now be created") admin_email = validating_input( "Enter the admin's email address", format_function=lambda ans: validate_email(ans).email, ) admin_first_name = input("Enter the admin's first name: ") admin_last_name = input("Enter the admin's last name: ") admin_phone_number = input("Enter the admin's phone number (optional): ") admin_mobile_phone_number = input("Enter the admin's mobile phone number (optional): ") admin_building = input("Enter the admin's building (optional): ") admin_room = input("Enter the admin's room (optional): ") admin_password = randomPassword() admin_hashed_password = hash_password(admin_password) admin_user = user_datastore.create_user( email=admin_email.strip(), 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, ) admin = Admin(user=admin_user) db.session.add(admin) box(admin_password, "Admin password") print("Done! Successfull database initialization.") if __name__ == "__main__": main()