Commit 2c260807a1ac4c4649cadf93514a975bc200709f
1 parent
289991dc
Exists in
master
and in
1 other branch
- fix initdb-aprendizations to skip on adding repeated students
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) | ... | ... |