Commit 3f6a1c207658c97779e3abea4196a23d81ed3c02

Authored by Miguel Barão
2 parents e8e453f8 2c260807
Exists in master and in 1 other branch dev

Merge branch 'master' into dev

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)
... ...