Commit 3f6a1c207658c97779e3abea4196a23d81ed3c02
Exists in
master
and in
1 other branch
Merge branch 'master' into dev
Showing
2 changed files
with
48 additions
and
37 deletions
Show diff stats
aprendizations/initdb.py
| ... | ... | @@ -100,19 +100,6 @@ def hashpw(student, pw=None): |
| 100 | 100 | |
| 101 | 101 | |
| 102 | 102 | # =========================================================================== |
| 103 | -def insert_students_into_db(session, students): | |
| 104 | - try: | |
| 105 | - # --- start db session --- | |
| 106 | - session.add_all([Student(id=s['uid'], name=s['name'], password=s['pw']) | |
| 107 | - for s in students]) | |
| 108 | - session.commit() | |
| 109 | - | |
| 110 | - except sa.exc.IntegrityError: | |
| 111 | - print('!!! Integrity error. Users already in database. Aborted !!!\n') | |
| 112 | - session.rollback() | |
| 113 | - | |
| 114 | - | |
| 115 | -# =========================================================================== | |
| 116 | 103 | def show_students_in_database(session, verbose=False): |
| 117 | 104 | try: |
| 118 | 105 | users = session.query(Student).all() |
| ... | ... | @@ -120,7 +107,7 @@ def show_students_in_database(session, verbose=False): |
| 120 | 107 | raise |
| 121 | 108 | else: |
| 122 | 109 | n = len(users) |
| 123 | - print(f'Registered users:') | |
| 110 | + print(f'\nRegistered users:') | |
| 124 | 111 | if n == 0: |
| 125 | 112 | print(' -- none --') |
| 126 | 113 | else: |
| ... | ... | @@ -143,46 +130,67 @@ def show_students_in_database(session, verbose=False): |
| 143 | 130 | def main(): |
| 144 | 131 | args = parse_commandline_arguments() |
| 145 | 132 | |
| 133 | + # --- database stuff | |
| 134 | + print(f'Using database: ', args.db) | |
| 135 | + engine = sa.create_engine(f'sqlite:///{args.db}', echo=False) | |
| 136 | + Base.metadata.create_all(engine) # Creates schema if needed | |
| 137 | + Session = sa.orm.sessionmaker(bind=engine) | |
| 138 | + session = Session() | |
| 139 | + | |
| 146 | 140 | # --- make list of students to insert/update |
| 147 | 141 | students = [] |
| 148 | 142 | |
| 149 | 143 | for csvfile in args.csvfile: |
| 150 | - print('Adding users from:', csvfile) | |
| 144 | + # print('Adding users from:', csvfile) | |
| 151 | 145 | students.extend(get_students_from_csv(csvfile)) |
| 152 | 146 | |
| 153 | 147 | if args.admin: |
| 154 | - print('Adding user: 0, Admin.') | |
| 148 | + # print('Adding user: 0, Admin.') | |
| 155 | 149 | students.append({'uid': '0', 'name': 'Admin'}) |
| 156 | 150 | |
| 157 | 151 | if args.add: |
| 158 | 152 | for uid, name in args.add: |
| 159 | - print(f'Adding user: {uid}, {name}.') | |
| 153 | + # print(f'Adding user: {uid}, {name}.') | |
| 160 | 154 | students.append({'uid': uid, 'name': name}) |
| 161 | 155 | |
| 162 | - # --- password hashing | |
| 163 | - if students: | |
| 156 | + # --- only insert students that are not yet in the database | |
| 157 | + db_students = {user.id for user in session.query(Student).all()} | |
| 158 | + new_students = list(filter(lambda s: s['uid'] not in db_students, students)) | |
| 159 | + | |
| 160 | + if new_students: | |
| 161 | + # --- password hashing | |
| 164 | 162 | print(f'Generating password hashes', end='') |
| 165 | 163 | with ThreadPoolExecutor() as executor: |
| 166 | - executor.map(lambda s: hashpw(s, args.pw), students) | |
| 167 | - print() | |
| 168 | - | |
| 169 | - # --- database stuff | |
| 170 | - print(f'Using database: ', args.db) | |
| 171 | - engine = sa.create_engine(f'sqlite:///{args.db}', echo=False) | |
| 172 | - Base.metadata.create_all(engine) # Criate schema if needed | |
| 173 | - Session = sa.orm.sessionmaker(bind=engine) | |
| 174 | - session = Session() | |
| 175 | - | |
| 176 | - if students: | |
| 177 | - print(f'Inserting {len(students)}') | |
| 178 | - insert_students_into_db(session, students) | |
| 164 | + executor.map(lambda s: hashpw(s, args.pw), new_students) | |
| 165 | + | |
| 166 | + print('\nAdding students:') | |
| 167 | + for s in new_students: | |
| 168 | + print(f' + {s["uid"]}, {s["name"]}') | |
| 169 | + | |
| 170 | + try: | |
| 171 | + session.add_all([Student(id=s['uid'], | |
| 172 | + name=s['name'], | |
| 173 | + password=s['pw']) | |
| 174 | + for s in new_students]) | |
| 175 | + session.commit() | |
| 176 | + except sa.exc.IntegrityError: | |
| 177 | + print('!!! Integrity error. Aborted !!!\n') | |
| 178 | + session.rollback() | |
| 179 | + | |
| 180 | + print(f'Inserted {len(new_students)} new student(s).') | |
| 181 | + else: | |
| 182 | + print('There are no new students to add.') | |
| 179 | 183 | |
| 184 | + # --- update data for student in the database | |
| 180 | 185 | for s in args.update: |
| 181 | 186 | print(f'Updating password of: {s}') |
| 182 | 187 | u = session.query(Student).get(s) |
| 183 | - pw = (args.pw or s).encode('utf-8') | |
| 184 | - u.password = bcrypt.hashpw(pw, bcrypt.gensalt()) | |
| 185 | - session.commit() | |
| 188 | + if u is not None: | |
| 189 | + pw = (args.pw or s).encode('utf-8') | |
| 190 | + u.password = bcrypt.hashpw(pw, bcrypt.gensalt()) | |
| 191 | + session.commit() | |
| 192 | + else: | |
| 193 | + print(f'!!! Student {s} does not exist. Skipping update !!!') | |
| 186 | 194 | |
| 187 | 195 | show_students_in_database(session, args.verbose) |
| 188 | 196 | ... | ... |
aprendizations/student.py
| ... | ... | @@ -174,8 +174,11 @@ class StudentState(object): |
| 174 | 174 | now = datetime.now() |
| 175 | 175 | for tref, s in self.state.items(): |
| 176 | 176 | dt = now - s['date'] |
| 177 | - forgetting_factor = self.deps.nodes[tref]['forgetting_factor'] | |
| 178 | - s['level'] *= forgetting_factor ** dt.days # forgetting factor | |
| 177 | + try: | |
| 178 | + forgetting_factor = self.deps.nodes[tref]['forgetting_factor'] | |
| 179 | + s['level'] *= forgetting_factor ** dt.days # forgetting factor | |
| 180 | + except KeyError: | |
| 181 | + logger.warning(f'Topic {tref} is not on the graph!') | |
| 179 | 182 | |
| 180 | 183 | # ------------------------------------------------------------------------ |
| 181 | 184 | # Unlock topics whose dependencies are satisfied (> min_level) | ... | ... |