Commit 2b709b19d9a93a1f83d4605e81509bdb38367489
1 parent
720ccbfa
Exists in
master
and in
1 other branch
fixed several errors in logging and updated messages
all tornado code moved to serve.py disallowed topic restart (avoid regenerating questions)
Showing
7 changed files
with
129 additions
and
107 deletions
Show diff stats
aprendizations/learnapp.py
@@ -79,7 +79,7 @@ class LearnApp(object): | @@ -79,7 +79,7 @@ class LearnApp(object): | ||
79 | 79 | ||
80 | errors = 0 | 80 | errors = 0 |
81 | for qref in self.factory: | 81 | for qref in self.factory: |
82 | - logger.debug(f'[sanity_check_questions] Checking "{qref}"...') | 82 | + logger.debug(f'checking {qref}...') |
83 | try: | 83 | try: |
84 | q = self.factory[qref].generate() | 84 | q = self.factory[qref].generate() |
85 | except Exception: | 85 | except Exception: |
@@ -208,7 +208,7 @@ class LearnApp(object): | @@ -208,7 +208,7 @@ class LearnApp(object): | ||
208 | finishtime=str(q['finish_time']), | 208 | finishtime=str(q['finish_time']), |
209 | student_id=uid, | 209 | student_id=uid, |
210 | topic_id=topic)) | 210 | topic_id=topic)) |
211 | - logger.debug(f'[check_answer] Saved "{q["ref"]}" into database') | 211 | + logger.debug(f'db insert answer of {q["ref"]}') |
212 | 212 | ||
213 | if knowledge.topic_has_finished(): | 213 | if knowledge.topic_has_finished(): |
214 | # finished topic, save into database | 214 | # finished topic, save into database |
@@ -222,7 +222,7 @@ class LearnApp(object): | @@ -222,7 +222,7 @@ class LearnApp(object): | ||
222 | .one_or_none() | 222 | .one_or_none() |
223 | if a is None: | 223 | if a is None: |
224 | # insert new studenttopic into database | 224 | # insert new studenttopic into database |
225 | - logger.debug('[check_answer] Database insert studenttopic') | 225 | + logger.debug('db insert studenttopic') |
226 | t = s.query(Topic).get(topic) | 226 | t = s.query(Topic).get(topic) |
227 | u = s.query(Student).get(uid) | 227 | u = s.query(Student).get(uid) |
228 | # association object | 228 | # association object |
@@ -231,14 +231,12 @@ class LearnApp(object): | @@ -231,14 +231,12 @@ class LearnApp(object): | ||
231 | u.topics.append(a) | 231 | u.topics.append(a) |
232 | else: | 232 | else: |
233 | # update studenttopic in database | 233 | # update studenttopic in database |
234 | - logger.debug('[check_answer] Database update studenttopic') | 234 | + logger.debug(f'db update studenttopic to level {level}') |
235 | a.level = level | 235 | a.level = level |
236 | a.date = date | 236 | a.date = date |
237 | 237 | ||
238 | s.add(a) | 238 | s.add(a) |
239 | 239 | ||
240 | - logger.debug(f'[check_answer] Saved topic "{topic}" into database') | ||
241 | - | ||
242 | return q, action | 240 | return q, action |
243 | 241 | ||
244 | # ------------------------------------------------------------------------ | 242 | # ------------------------------------------------------------------------ |
@@ -347,7 +345,7 @@ class LearnApp(object): | @@ -347,7 +345,7 @@ class LearnApp(object): | ||
347 | # Buils dictionary of question factories | 345 | # Buils dictionary of question factories |
348 | # ------------------------------------------------------------------------ | 346 | # ------------------------------------------------------------------------ |
349 | def make_factory(self) -> Dict[str, QFactory]: | 347 | def make_factory(self) -> Dict[str, QFactory]: |
350 | - logger.info('Building questions factory...') | 348 | + logger.info('Building questions factory:') |
351 | factory = {} # {'qref': QFactory()} | 349 | factory = {} # {'qref': QFactory()} |
352 | g = self.deps | 350 | g = self.deps |
353 | for tref in g.nodes(): | 351 | for tref in g.nodes(): |
aprendizations/main.py
@@ -4,34 +4,17 @@ | @@ -4,34 +4,17 @@ | ||
4 | import argparse | 4 | import argparse |
5 | import logging | 5 | import logging |
6 | from os import environ, path | 6 | from os import environ, path |
7 | -import signal | ||
8 | import ssl | 7 | import ssl |
9 | import sys | 8 | import sys |
10 | 9 | ||
11 | -# third party libraries | ||
12 | -import tornado | ||
13 | - | ||
14 | # this project | 10 | # this project |
15 | from .learnapp import LearnApp, DatabaseUnusableError | 11 | from .learnapp import LearnApp, DatabaseUnusableError |
16 | -from .serve import WebApplication | 12 | +from .serve import run_webserver |
17 | from .tools import load_yaml | 13 | from .tools import load_yaml |
18 | from . import APP_NAME, APP_VERSION | 14 | from . import APP_NAME, APP_VERSION |
19 | 15 | ||
20 | 16 | ||
21 | # ---------------------------------------------------------------------------- | 17 | # ---------------------------------------------------------------------------- |
22 | -# Signal handler to catch Ctrl-C and abort server | ||
23 | -# ---------------------------------------------------------------------------- | ||
24 | -def signal_handler(signal, frame): | ||
25 | - r = input(' --> Stop webserver? (yes/no) ').lower() | ||
26 | - if r == 'yes': | ||
27 | - tornado.ioloop.IOLoop.current().stop() | ||
28 | - logging.critical('Webserver stopped.') | ||
29 | - sys.exit(0) | ||
30 | - else: | ||
31 | - logging.info('Abort canceled...') | ||
32 | - | ||
33 | - | ||
34 | -# ---------------------------------------------------------------------------- | ||
35 | def parse_cmdline_arguments(): | 18 | def parse_cmdline_arguments(): |
36 | argparser = argparse.ArgumentParser( | 19 | argparser = argparse.ArgumentParser( |
37 | description='Server for online learning. Students and topics ' | 20 | description='Server for online learning. Students and topics ' |
@@ -91,7 +74,7 @@ def get_logger_config(debug=False): | @@ -91,7 +74,7 @@ def get_logger_config(debug=False): | ||
91 | 'version': 1, | 74 | 'version': 1, |
92 | 'formatters': { | 75 | 'formatters': { |
93 | 'standard': { | 76 | 'standard': { |
94 | - 'format': '%(asctime)s | %(levelname)-10s | %(message)s', | 77 | + 'format': '%(asctime)s | %(levelname)-8s | %(message)s', |
95 | 'datefmt': '%Y-%m-%d %H:%M:%S', | 78 | 'datefmt': '%Y-%m-%d %H:%M:%S', |
96 | }, | 79 | }, |
97 | }, | 80 | }, |
@@ -115,14 +98,14 @@ def get_logger_config(debug=False): | @@ -115,14 +98,14 @@ def get_logger_config(debug=False): | ||
115 | 'handlers': ['default'], | 98 | 'handlers': ['default'], |
116 | 'level': level, | 99 | 'level': level, |
117 | 'propagate': False, | 100 | 'propagate': False, |
118 | - } for module in ['learnapp', 'models', 'factory', 'questions', | ||
119 | - 'knowledge', 'tools']}) | 101 | + } for module in ['learnapp', 'models', 'factory', 'tools', 'serve', |
102 | + 'questions', 'student']}) | ||
120 | 103 | ||
121 | return load_yaml(config_file, default=default_config) | 104 | return load_yaml(config_file, default=default_config) |
122 | 105 | ||
123 | 106 | ||
124 | # ---------------------------------------------------------------------------- | 107 | # ---------------------------------------------------------------------------- |
125 | -# Tornado web server | 108 | +# Start application and webserver |
126 | # ---------------------------------------------------------------------------- | 109 | # ---------------------------------------------------------------------------- |
127 | def main(): | 110 | def main(): |
128 | # --- Commandline argument parsing | 111 | # --- Commandline argument parsing |
@@ -144,34 +127,6 @@ def main(): | @@ -144,34 +127,6 @@ def main(): | ||
144 | 127 | ||
145 | logging.info('====================== Start Logging ======================') | 128 | logging.info('====================== Start Logging ======================') |
146 | 129 | ||
147 | - # --- start application | ||
148 | - logging.info('Starting App...') | ||
149 | - try: | ||
150 | - learnapp = LearnApp(arg.conffile, prefix=arg.prefix, db=arg.db, | ||
151 | - check=arg.check) | ||
152 | - except DatabaseUnusableError: | ||
153 | - logging.critical('Failed to start application.') | ||
154 | - print('--------------------------------------------------------------') | ||
155 | - print('Could not find a usable database. Use one of the follwing ') | ||
156 | - print('commands to initialize: ') | ||
157 | - print(' ') | ||
158 | - print(' initdb-aprendizations --admin # add admin ') | ||
159 | - print(' initdb-aprendizations -a 86 "Max Smart" # add student ') | ||
160 | - print(' initdb-aprendizations students.csv # add many students') | ||
161 | - print('--------------------------------------------------------------') | ||
162 | - sys.exit(1) | ||
163 | - except Exception: | ||
164 | - logging.critical('Failed to start application.') | ||
165 | - sys.exit(1) | ||
166 | - | ||
167 | - # --- create web application | ||
168 | - logging.info('Starting Web App (tornado)...') | ||
169 | - try: | ||
170 | - webapp = WebApplication(learnapp, debug=arg.debug) | ||
171 | - except Exception: | ||
172 | - logging.critical('Failed to start web application.') | ||
173 | - sys.exit(1) | ||
174 | - | ||
175 | # --- get SSL certificates | 130 | # --- get SSL certificates |
176 | if 'XDG_DATA_HOME' in environ: | 131 | if 'XDG_DATA_HOME' in environ: |
177 | certs_dir = path.join(environ['XDG_DATA_HOME'], 'certs') | 132 | certs_dir = path.join(environ['XDG_DATA_HOME'], 'certs') |
@@ -197,34 +152,35 @@ def main(): | @@ -197,34 +152,35 @@ def main(): | ||
197 | print(' ') | 152 | print(' ') |
198 | print(f' {certs_dir:<62}') | 153 | print(f' {certs_dir:<62}') |
199 | print(' ') | 154 | print(' ') |
155 | + print('(See README.md for more information) ') | ||
200 | print('--------------------------------------------------------------') | 156 | print('--------------------------------------------------------------') |
201 | sys.exit(1) | 157 | sys.exit(1) |
158 | + else: | ||
159 | + logging.info('SSL certificates loaded') | ||
202 | 160 | ||
203 | - # --- create webserver | 161 | + # --- start application |
204 | try: | 162 | try: |
205 | - httpserver = tornado.httpserver.HTTPServer(webapp, ssl_options=ssl_ctx) | ||
206 | - except ValueError: | ||
207 | - logging.critical('Certificates cert.pem and privkey.pem not found') | 163 | + learnapp = LearnApp(arg.conffile, prefix=arg.prefix, db=arg.db, |
164 | + check=arg.check) | ||
165 | + except DatabaseUnusableError: | ||
166 | + logging.critical('Failed to start application.') | ||
167 | + print('--------------------------------------------------------------') | ||
168 | + print('Could not find a usable database. Use one of the follwing ') | ||
169 | + print('commands to initialize: ') | ||
170 | + print(' ') | ||
171 | + print(' initdb-aprendizations --admin # add admin ') | ||
172 | + print(' initdb-aprendizations -a 86 "Max Smart" # add student ') | ||
173 | + print(' initdb-aprendizations students.csv # add many students') | ||
174 | + print('--------------------------------------------------------------') | ||
208 | sys.exit(1) | 175 | sys.exit(1) |
209 | - | ||
210 | - try: | ||
211 | - httpserver.listen(arg.port) | ||
212 | - except OSError: | ||
213 | - logging.critical(f'Cannot bind port {arg.port}. Already in use?') | 176 | + except Exception: |
177 | + logging.critical('Failed to start application.') | ||
214 | sys.exit(1) | 178 | sys.exit(1) |
179 | + else: | ||
180 | + logging.info('Backend application started') | ||
215 | 181 | ||
216 | - logging.info(f'Listening on port {arg.port}.') | ||
217 | - | ||
218 | - # --- run webserver | ||
219 | - signal.signal(signal.SIGINT, signal_handler) | ||
220 | - logging.info('Webserver running. (Ctrl-C to stop)') | ||
221 | - | ||
222 | - try: | ||
223 | - tornado.ioloop.IOLoop.current().start() # running... | ||
224 | - except Exception: | ||
225 | - logging.critical('Webserver stopped.') | ||
226 | - tornado.ioloop.IOLoop.current().stop() | ||
227 | - raise | 182 | + # --- run webserver forever |
183 | + run_webserver(app=learnapp, ssl=ssl_ctx, port=arg.port, debug=arg.debug) | ||
228 | 184 | ||
229 | 185 | ||
230 | # ---------------------------------------------------------------------------- | 186 | # ---------------------------------------------------------------------------- |
aprendizations/questions.py
@@ -461,7 +461,7 @@ class QFactory(object): | @@ -461,7 +461,7 @@ class QFactory(object): | ||
461 | # i.e. a question object (radio, checkbox, ...). | 461 | # i.e. a question object (radio, checkbox, ...). |
462 | # ----------------------------------------------------------------------- | 462 | # ----------------------------------------------------------------------- |
463 | def generate(self) -> Question: | 463 | def generate(self) -> Question: |
464 | - logger.debug(f'[QFactory.generate] "{self.question["ref"]}"...') | 464 | + logger.debug(f'generating {self.question["ref"]}...') |
465 | # Shallow copy so that script generated questions will not replace | 465 | # Shallow copy so that script generated questions will not replace |
466 | # the original generators | 466 | # the original generators |
467 | q = self.question.copy() | 467 | q = self.question.copy() |
@@ -492,7 +492,7 @@ class QFactory(object): | @@ -492,7 +492,7 @@ class QFactory(object): | ||
492 | 492 | ||
493 | # ----------------------------------------------------------------------- | 493 | # ----------------------------------------------------------------------- |
494 | async def generate_async(self) -> Question: | 494 | async def generate_async(self) -> Question: |
495 | - logger.debug(f'[QFactory.generate_async] "{self.question["ref"]}"...') | 495 | + logger.debug(f'generating {self.question["ref"]}...') |
496 | # Shallow copy so that script generated questions will not replace | 496 | # Shallow copy so that script generated questions will not replace |
497 | # the original generators | 497 | # the original generators |
498 | q = self.question.copy() | 498 | q = self.question.copy() |
@@ -520,5 +520,5 @@ class QFactory(object): | @@ -520,5 +520,5 @@ class QFactory(object): | ||
520 | logger.error(f'Invalid type "{q["type"]}" in "{q["ref"]}"') | 520 | logger.error(f'Invalid type "{q["type"]}" in "{q["ref"]}"') |
521 | raise | 521 | raise |
522 | else: | 522 | else: |
523 | - logger.debug(f'[generate_async] Done instance of {q["ref"]}') | 523 | + logger.debug('ok') |
524 | return qinstance | 524 | return qinstance |
aprendizations/serve.py
@@ -6,6 +6,8 @@ import functools | @@ -6,6 +6,8 @@ import functools | ||
6 | import logging.config | 6 | import logging.config |
7 | import mimetypes | 7 | import mimetypes |
8 | from os import path | 8 | from os import path |
9 | +import signal | ||
10 | +import sys | ||
9 | import uuid | 11 | import uuid |
10 | 12 | ||
11 | # third party libraries | 13 | # third party libraries |
@@ -16,6 +18,9 @@ from tornado.escape import to_unicode | @@ -16,6 +18,9 @@ from tornado.escape import to_unicode | ||
16 | from .tools import md_to_html | 18 | from .tools import md_to_html |
17 | from . import APP_NAME | 19 | from . import APP_NAME |
18 | 20 | ||
21 | +# setup logger for this module | ||
22 | +logger = logging.getLogger(__name__) | ||
23 | + | ||
19 | 24 | ||
20 | # ---------------------------------------------------------------------------- | 25 | # ---------------------------------------------------------------------------- |
21 | # Decorator used to restrict access to the administrator only | 26 | # Decorator used to restrict access to the administrator only |
@@ -211,11 +216,11 @@ class FileHandler(BaseHandler): | @@ -211,11 +216,11 @@ class FileHandler(BaseHandler): | ||
211 | with open(filepath, 'rb') as f: | 216 | with open(filepath, 'rb') as f: |
212 | data = f.read() | 217 | data = f.read() |
213 | except FileNotFoundError: | 218 | except FileNotFoundError: |
214 | - logging.error(f'File not found: {filepath}') | 219 | + logger.error(f'File not found: {filepath}') |
215 | except PermissionError: | 220 | except PermissionError: |
216 | - logging.error(f'No permission: {filepath}') | 221 | + logger.error(f'No permission: {filepath}') |
217 | except Exception: | 222 | except Exception: |
218 | - logging.error(f'Error reading: {filepath}') | 223 | + logger.error(f'Error reading: {filepath}') |
219 | raise | 224 | raise |
220 | else: | 225 | else: |
221 | self.set_header("Content-Type", content_type) | 226 | self.set_header("Content-Type", content_type) |
@@ -244,7 +249,7 @@ class QuestionHandler(BaseHandler): | @@ -244,7 +249,7 @@ class QuestionHandler(BaseHandler): | ||
244 | # --- get question to render | 249 | # --- get question to render |
245 | @tornado.web.authenticated | 250 | @tornado.web.authenticated |
246 | def get(self): | 251 | def get(self): |
247 | - logging.debug('[QuestionHandler.get]') | 252 | + logger.debug('[QuestionHandler.get]') |
248 | user = self.current_user | 253 | user = self.current_user |
249 | q = self.learn.get_current_question(user) | 254 | q = self.learn.get_current_question(user) |
250 | 255 | ||
@@ -275,7 +280,7 @@ class QuestionHandler(BaseHandler): | @@ -275,7 +280,7 @@ class QuestionHandler(BaseHandler): | ||
275 | # --- post answer, returns what to do next: shake, new_question, finished | 280 | # --- post answer, returns what to do next: shake, new_question, finished |
276 | @tornado.web.authenticated | 281 | @tornado.web.authenticated |
277 | async def post(self) -> None: | 282 | async def post(self) -> None: |
278 | - logging.debug('[QuestionHandler.post]') | 283 | + logger.debug('[QuestionHandler.post]') |
279 | user = self.current_user | 284 | user = self.current_user |
280 | answer = self.get_body_arguments('answer') # list | 285 | answer = self.get_body_arguments('answer') # list |
281 | 286 | ||
@@ -283,7 +288,7 @@ class QuestionHandler(BaseHandler): | @@ -283,7 +288,7 @@ class QuestionHandler(BaseHandler): | ||
283 | answer_qid = self.get_body_arguments('qid')[0] | 288 | answer_qid = self.get_body_arguments('qid')[0] |
284 | current_qid = self.learn.get_current_question_id(user) | 289 | current_qid = self.learn.get_current_question_id(user) |
285 | if answer_qid != current_qid: | 290 | if answer_qid != current_qid: |
286 | - logging.info(f'User {user} desynchronized questions') | 291 | + logger.info(f'User {user} desynchronized questions') |
287 | self.write({ | 292 | self.write({ |
288 | 'method': 'invalid', | 293 | 'method': 'invalid', |
289 | 'params': { | 294 | 'params': { |
@@ -349,6 +354,59 @@ class QuestionHandler(BaseHandler): | @@ -349,6 +354,59 @@ class QuestionHandler(BaseHandler): | ||
349 | 'tries': q['tries'], | 354 | 'tries': q['tries'], |
350 | } | 355 | } |
351 | else: | 356 | else: |
352 | - logging.error(f'Unknown action: {action}') | 357 | + logger.error(f'Unknown action: {action}') |
353 | 358 | ||
354 | self.write(response) | 359 | self.write(response) |
360 | + | ||
361 | + | ||
362 | +# ---------------------------------------------------------------------------- | ||
363 | +# Signal handler to catch Ctrl-C and abort server | ||
364 | +# ---------------------------------------------------------------------------- | ||
365 | +def signal_handler(signal, frame): | ||
366 | + r = input(' --> Stop webserver? (yes/no) ').lower() | ||
367 | + if r == 'yes': | ||
368 | + tornado.ioloop.IOLoop.current().stop() | ||
369 | + logger.critical('Webserver stopped.') | ||
370 | + sys.exit(0) | ||
371 | + else: | ||
372 | + logger.info('Abort canceled...') | ||
373 | + | ||
374 | + | ||
375 | +# ---------------------------------------------------------------------------- | ||
376 | +def run_webserver(app, ssl, port=8443, debug=False): | ||
377 | + # --- create web application | ||
378 | + try: | ||
379 | + webapp = WebApplication(app, debug=debug) | ||
380 | + except Exception: | ||
381 | + logger.critical('Failed to start web application.') | ||
382 | + sys.exit(1) | ||
383 | + else: | ||
384 | + logger.info('Web application started (tornado.web.Application)') | ||
385 | + | ||
386 | + # --- create tornado webserver | ||
387 | + try: | ||
388 | + httpserver = tornado.httpserver.HTTPServer(webapp, ssl_options=ssl) | ||
389 | + except ValueError: | ||
390 | + logger.critical('Certificates cert.pem and privkey.pem not found') | ||
391 | + sys.exit(1) | ||
392 | + else: | ||
393 | + logger.debug('HTTP server started') | ||
394 | + | ||
395 | + try: | ||
396 | + httpserver.listen(port) | ||
397 | + except OSError: | ||
398 | + logger.critical(f'Cannot bind port {port}. Already in use?') | ||
399 | + sys.exit(1) | ||
400 | + else: | ||
401 | + logger.info(f'HTTP server listening on port {port}') | ||
402 | + | ||
403 | + # --- run webserver | ||
404 | + signal.signal(signal.SIGINT, signal_handler) | ||
405 | + logger.info('Webserver running. (Ctrl-C to stop)') | ||
406 | + | ||
407 | + try: | ||
408 | + tornado.ioloop.IOLoop.current().start() # running... | ||
409 | + except Exception: | ||
410 | + logger.critical('Webserver stopped.') | ||
411 | + tornado.ioloop.IOLoop.current().stop() | ||
412 | + raise |
aprendizations/student.py
@@ -63,7 +63,7 @@ class StudentState(object): | @@ -63,7 +63,7 @@ class StudentState(object): | ||
63 | 'level': 0.0, # unlocked | 63 | 'level': 0.0, # unlocked |
64 | 'date': datetime.now() | 64 | 'date': datetime.now() |
65 | } | 65 | } |
66 | - logger.debug(f'[unlock_topics] Unlocked "{topic}".') | 66 | + logger.debug(f'unlocked "{topic}"') |
67 | # else: # lock this topic if deps do not satisfy min_level | 67 | # else: # lock this topic if deps do not satisfy min_level |
68 | # del self.state[topic] | 68 | # del self.state[topic] |
69 | 69 | ||
@@ -73,15 +73,16 @@ class StudentState(object): | @@ -73,15 +73,16 @@ class StudentState(object): | ||
73 | # current_question: the current question to be presented | 73 | # current_question: the current question to be presented |
74 | # ------------------------------------------------------------------------ | 74 | # ------------------------------------------------------------------------ |
75 | async def start_topic(self, topic: str): | 75 | async def start_topic(self, topic: str): |
76 | - logger.debug(f'[start_topic] topic "{topic}"') | 76 | + logger.debug(f'starting "{topic}"') |
77 | 77 | ||
78 | - # if self.current_topic == topic: | ||
79 | - # logger.info('Restarting current topic is not allowed.') | ||
80 | - # return | 78 | + # avoid regenerating questions in the middle of the current topic |
79 | + if self.current_topic == topic: | ||
80 | + logger.info('Restarting current topic is not allowed.') | ||
81 | + return | ||
81 | 82 | ||
82 | # do not allow locked topics | 83 | # do not allow locked topics |
83 | if self.is_locked(topic): | 84 | if self.is_locked(topic): |
84 | - logger.debug(f'[start_topic] topic "{topic}" is locked') | 85 | + logger.debug(f'is locked "{topic}"') |
85 | return | 86 | return |
86 | 87 | ||
87 | # starting new topic | 88 | # starting new topic |
@@ -95,13 +96,13 @@ class StudentState(object): | @@ -95,13 +96,13 @@ class StudentState(object): | ||
95 | questions = random.sample(t['questions'], k=k) | 96 | questions = random.sample(t['questions'], k=k) |
96 | else: | 97 | else: |
97 | questions = t['questions'][:k] | 98 | questions = t['questions'][:k] |
98 | - logger.debug(f'[start_topic] questions: {", ".join(questions)}') | 99 | + logger.debug(f'selected questions: {", ".join(questions)}') |
99 | 100 | ||
100 | self.questions = [await self.factory[ref].generate_async() | 101 | self.questions = [await self.factory[ref].generate_async() |
101 | for ref in questions] | 102 | for ref in questions] |
102 | 103 | ||
103 | n = len(self.questions) | 104 | n = len(self.questions) |
104 | - logger.debug(f'[start_topic] generated {n} questions') | 105 | + logger.debug(f'generated {n} questions') |
105 | 106 | ||
106 | # get first question | 107 | # get first question |
107 | self.next_question() | 108 | self.next_question() |
@@ -112,7 +113,7 @@ class StudentState(object): | @@ -112,7 +113,7 @@ class StudentState(object): | ||
112 | # The current topic is unchanged. | 113 | # The current topic is unchanged. |
113 | # ------------------------------------------------------------------------ | 114 | # ------------------------------------------------------------------------ |
114 | def finish_topic(self): | 115 | def finish_topic(self): |
115 | - logger.debug(f'[finish_topic] current_topic {self.current_topic}') | 116 | + logger.debug(f'finished {self.current_topic}') |
116 | 117 | ||
117 | self.state[self.current_topic] = { | 118 | self.state[self.current_topic] = { |
118 | 'date': datetime.now(), | 119 | 'date': datetime.now(), |
@@ -129,13 +130,12 @@ class StudentState(object): | @@ -129,13 +130,12 @@ class StudentState(object): | ||
129 | # - if wrong, counts number of tries. If exceeded, moves on. | 130 | # - if wrong, counts number of tries. If exceeded, moves on. |
130 | # ------------------------------------------------------------------------ | 131 | # ------------------------------------------------------------------------ |
131 | async def check_answer(self, answer): | 132 | async def check_answer(self, answer): |
132 | - logger.debug('[check_answer]') | ||
133 | - | ||
134 | q = self.current_question | 133 | q = self.current_question |
135 | q['answer'] = answer | 134 | q['answer'] = answer |
136 | q['finish_time'] = datetime.now() | 135 | q['finish_time'] = datetime.now() |
136 | + logger.debug(f'checking answer of {q["ref"]}...') | ||
137 | await q.correct_async() | 137 | await q.correct_async() |
138 | - logger.debug(f'[check_answer] Grade {q["grade"]:.2} in {q["ref"]}') | 138 | + logger.debug(f'grade = {q["grade"]:.2}') |
139 | 139 | ||
140 | if q['grade'] > 0.999: | 140 | if q['grade'] > 0.999: |
141 | self.correct_answers += 1 | 141 | self.correct_answers += 1 |
@@ -151,7 +151,7 @@ class StudentState(object): | @@ -151,7 +151,7 @@ class StudentState(object): | ||
151 | else: | 151 | else: |
152 | action = 'wrong' | 152 | action = 'wrong' |
153 | if self.current_question['append_wrong']: | 153 | if self.current_question['append_wrong']: |
154 | - logger.debug('[check_answer] Wrong, append new instance') | 154 | + logger.debug('wrong answer, append new question') |
155 | self.questions.append(self.factory[q['ref']].generate()) | 155 | self.questions.append(self.factory[q['ref']].generate()) |
156 | self.next_question() | 156 | self.next_question() |
157 | 157 | ||
@@ -172,7 +172,7 @@ class StudentState(object): | @@ -172,7 +172,7 @@ class StudentState(object): | ||
172 | default_maxtries = self.deps.nodes[self.current_topic]['max_tries'] | 172 | default_maxtries = self.deps.nodes[self.current_topic]['max_tries'] |
173 | maxtries = self.current_question.get('max_tries', default_maxtries) | 173 | maxtries = self.current_question.get('max_tries', default_maxtries) |
174 | self.current_question['tries'] = maxtries | 174 | self.current_question['tries'] = maxtries |
175 | - logger.debug(f'[next_question] "{self.current_question["ref"]}"') | 175 | + logger.debug(f'current_question = {self.current_question["ref"]}') |
176 | 176 | ||
177 | return self.current_question # question or None | 177 | return self.current_question # question or None |
178 | 178 |
config/logger-debug.yaml
@@ -5,8 +5,8 @@ formatters: | @@ -5,8 +5,8 @@ formatters: | ||
5 | void: | 5 | void: |
6 | format: '' | 6 | format: '' |
7 | standard: | 7 | standard: |
8 | - format: '%(asctime)s | %(levelname)-9s | %(name)-24s | %(thread)-15d | %(message)s' | ||
9 | - datefmt: '%H:%M:%S' | 8 | + format: '%(asctime)s | %(thread)-15d | %(levelname)-8s | %(module)-10s | %(funcName)-20s | %(message)s' |
9 | + # datefmt: '%H:%M:%S' | ||
10 | 10 | ||
11 | handlers: | 11 | handlers: |
12 | default: | 12 | default: |
@@ -25,7 +25,7 @@ loggers: | @@ -25,7 +25,7 @@ loggers: | ||
25 | level: 'DEBUG' | 25 | level: 'DEBUG' |
26 | propagate: false | 26 | propagate: false |
27 | 27 | ||
28 | - 'aprendizations.knowledge': | 28 | + 'aprendizations.student': |
29 | handlers: ['default'] | 29 | handlers: ['default'] |
30 | level: 'DEBUG' | 30 | level: 'DEBUG' |
31 | propagate: false | 31 | propagate: false |
@@ -44,3 +44,8 @@ loggers: | @@ -44,3 +44,8 @@ loggers: | ||
44 | handlers: ['default'] | 44 | handlers: ['default'] |
45 | level: 'DEBUG' | 45 | level: 'DEBUG' |
46 | propagate: false | 46 | propagate: false |
47 | + | ||
48 | + 'aprendizations.serve': | ||
49 | + handlers: ['default'] | ||
50 | + level: 'DEBUG' | ||
51 | + propagate: false |
config/logger.yaml
@@ -5,7 +5,7 @@ formatters: | @@ -5,7 +5,7 @@ formatters: | ||
5 | void: | 5 | void: |
6 | format: '' | 6 | format: '' |
7 | standard: | 7 | standard: |
8 | - format: '%(asctime)s | %(thread)-15d | %(levelname)-9s | %(message)s' | 8 | + format: '%(asctime)s | %(levelname)-8s | %(module)-10s | %(message)s' |
9 | datefmt: '%Y-%m-%d %H:%M:%S' | 9 | datefmt: '%Y-%m-%d %H:%M:%S' |
10 | 10 | ||
11 | handlers: | 11 | handlers: |
@@ -25,7 +25,7 @@ loggers: | @@ -25,7 +25,7 @@ loggers: | ||
25 | level: 'INFO' | 25 | level: 'INFO' |
26 | propagate: false | 26 | propagate: false |
27 | 27 | ||
28 | - 'aprendizations.knowledge': | 28 | + 'aprendizations.student': |
29 | handlers: ['default'] | 29 | handlers: ['default'] |
30 | level: 'INFO' | 30 | level: 'INFO' |
31 | propagate: false | 31 | propagate: false |
@@ -44,3 +44,8 @@ loggers: | @@ -44,3 +44,8 @@ loggers: | ||
44 | handlers: ['default'] | 44 | handlers: ['default'] |
45 | level: 'INFO' | 45 | level: 'INFO' |
46 | propagate: false | 46 | propagate: false |
47 | + | ||
48 | + 'aprendizations.serve': | ||
49 | + handlers: ['default'] | ||
50 | + level: 'INFO' | ||
51 | + propagate: false |