diff --git a/aprendizations/initdb.py b/aprendizations/initdb.py index edf7733..9288ebb 100644 --- a/aprendizations/initdb.py +++ b/aprendizations/initdb.py @@ -100,19 +100,6 @@ def hashpw(student, pw=None): # =========================================================================== -def insert_students_into_db(session, students): - try: - # --- start db session --- - session.add_all([Student(id=s['uid'], name=s['name'], password=s['pw']) - for s in students]) - session.commit() - - except sa.exc.IntegrityError: - print('!!! Integrity error. Users already in database. Aborted !!!\n') - session.rollback() - - -# =========================================================================== def show_students_in_database(session, verbose=False): try: users = session.query(Student).all() @@ -120,7 +107,7 @@ def show_students_in_database(session, verbose=False): raise else: n = len(users) - print(f'Registered users:') + print(f'\nRegistered users:') if n == 0: print(' -- none --') else: @@ -143,46 +130,67 @@ def show_students_in_database(session, verbose=False): def main(): args = parse_commandline_arguments() + # --- database stuff + print(f'Using database: ', args.db) + engine = sa.create_engine(f'sqlite:///{args.db}', echo=False) + Base.metadata.create_all(engine) # Creates schema if needed + Session = sa.orm.sessionmaker(bind=engine) + session = Session() + # --- make list of students to insert/update students = [] for csvfile in args.csvfile: - print('Adding users from:', csvfile) + # print('Adding users from:', csvfile) students.extend(get_students_from_csv(csvfile)) if args.admin: - print('Adding user: 0, Admin.') + # print('Adding user: 0, Admin.') students.append({'uid': '0', 'name': 'Admin'}) if args.add: for uid, name in args.add: - print(f'Adding user: {uid}, {name}.') + # print(f'Adding user: {uid}, {name}.') students.append({'uid': uid, 'name': name}) - # --- password hashing - if students: + # --- only insert students that are not yet in the database + db_students = {user.id for user in session.query(Student).all()} + new_students = list(filter(lambda s: s['uid'] not in db_students, students)) + + if new_students: + # --- password hashing print(f'Generating password hashes', end='') with ThreadPoolExecutor() as executor: - executor.map(lambda s: hashpw(s, args.pw), students) - print() - - # --- database stuff - print(f'Using database: ', args.db) - engine = sa.create_engine(f'sqlite:///{args.db}', echo=False) - Base.metadata.create_all(engine) # Criate schema if needed - Session = sa.orm.sessionmaker(bind=engine) - session = Session() - - if students: - print(f'Inserting {len(students)}') - insert_students_into_db(session, students) + executor.map(lambda s: hashpw(s, args.pw), new_students) + + print('\nAdding students:') + for s in new_students: + print(f' + {s["uid"]}, {s["name"]}') + + try: + session.add_all([Student(id=s['uid'], + name=s['name'], + password=s['pw']) + for s in new_students]) + session.commit() + except sa.exc.IntegrityError: + print('!!! Integrity error. Aborted !!!\n') + session.rollback() + + print(f'Inserted {len(new_students)} new student(s).') + else: + print('There are no new students to add.') + # --- update data for student in the database for s in args.update: print(f'Updating password of: {s}') u = session.query(Student).get(s) - pw = (args.pw or s).encode('utf-8') - u.password = bcrypt.hashpw(pw, bcrypt.gensalt()) - session.commit() + if u is not None: + pw = (args.pw or s).encode('utf-8') + u.password = bcrypt.hashpw(pw, bcrypt.gensalt()) + session.commit() + else: + print(f'!!! Student {s} does not exist. Skipping update !!!') show_students_in_database(session, args.verbose) diff --git a/aprendizations/student.py b/aprendizations/student.py index 8480273..10fad38 100644 --- a/aprendizations/student.py +++ b/aprendizations/student.py @@ -174,8 +174,11 @@ class StudentState(object): now = datetime.now() for tref, s in self.state.items(): dt = now - s['date'] - forgetting_factor = self.deps.nodes[tref]['forgetting_factor'] - s['level'] *= forgetting_factor ** dt.days # forgetting factor + try: + forgetting_factor = self.deps.nodes[tref]['forgetting_factor'] + s['level'] *= forgetting_factor ** dt.days # forgetting factor + except KeyError: + logger.warning(f'Topic {tref} is not on the graph!') # ------------------------------------------------------------------------ # Unlock topics whose dependencies are satisfied (> min_level) -- libgit2 0.21.2