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,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 def show_students_in_database(session, verbose=False): 103 def show_students_in_database(session, verbose=False):
117 try: 104 try:
118 users = session.query(Student).all() 105 users = session.query(Student).all()
@@ -120,7 +107,7 @@ def show_students_in_database(session, verbose=False): @@ -120,7 +107,7 @@ def show_students_in_database(session, verbose=False):
120 raise 107 raise
121 else: 108 else:
122 n = len(users) 109 n = len(users)
123 - print(f'Registered users:') 110 + print(f'\nRegistered users:')
124 if n == 0: 111 if n == 0:
125 print(' -- none --') 112 print(' -- none --')
126 else: 113 else:
@@ -143,46 +130,67 @@ def show_students_in_database(session, verbose=False): @@ -143,46 +130,67 @@ def show_students_in_database(session, verbose=False):
143 def main(): 130 def main():
144 args = parse_commandline_arguments() 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 # --- make list of students to insert/update 140 # --- make list of students to insert/update
147 students = [] 141 students = []
148 142
149 for csvfile in args.csvfile: 143 for csvfile in args.csvfile:
150 - print('Adding users from:', csvfile) 144 + # print('Adding users from:', csvfile)
151 students.extend(get_students_from_csv(csvfile)) 145 students.extend(get_students_from_csv(csvfile))
152 146
153 if args.admin: 147 if args.admin:
154 - print('Adding user: 0, Admin.') 148 + # print('Adding user: 0, Admin.')
155 students.append({'uid': '0', 'name': 'Admin'}) 149 students.append({'uid': '0', 'name': 'Admin'})
156 150
157 if args.add: 151 if args.add:
158 for uid, name in args.add: 152 for uid, name in args.add:
159 - print(f'Adding user: {uid}, {name}.') 153 + # print(f'Adding user: {uid}, {name}.')
160 students.append({'uid': uid, 'name': name}) 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 print(f'Generating password hashes', end='') 162 print(f'Generating password hashes', end='')
165 with ThreadPoolExecutor() as executor: 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 for s in args.update: 185 for s in args.update:
181 print(f'Updating password of: {s}') 186 print(f'Updating password of: {s}')
182 u = session.query(Student).get(s) 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 show_students_in_database(session, args.verbose) 195 show_students_in_database(session, args.verbose)
188 196
aprendizations/student.py
@@ -174,8 +174,11 @@ class StudentState(object): @@ -174,8 +174,11 @@ class StudentState(object):
174 now = datetime.now() 174 now = datetime.now()
175 for tref, s in self.state.items(): 175 for tref, s in self.state.items():
176 dt = now - s['date'] 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 # Unlock topics whose dependencies are satisfied (> min_level) 184 # Unlock topics whose dependencies are satisfied (> min_level)