diff --git a/aprendizations/main.py b/aprendizations/main.py index 99a95db..2f1bae1 100644 --- a/aprendizations/main.py +++ b/aprendizations/main.py @@ -7,6 +7,7 @@ Setup configurations and then runs the application. # python standard library import argparse +import asyncio import logging import logging.config from os import environ, path @@ -16,7 +17,7 @@ from typing import Any, Dict # this project from .learnapp import LearnApp, LearnException -from .serve import run_webserver +from .serve import webserver from .tools import load_yaml from . import APP_NAME, APP_VERSION @@ -179,17 +180,19 @@ def main(): # --- start application -------------------------------------------------- try: - learnapp = LearnApp(courses=arg.courses, - prefix=arg.prefix, - dbase=arg.db, - check=arg.check) + app = LearnApp(courses=arg.courses, + prefix=arg.prefix, + dbase=arg.db, + check=arg.check) except LearnException: logging.critical('Failed to start application') sys.exit(1) logging.info('LearnApp started') # --- run webserver forever ---------------------------------------------- - run_webserver(app=learnapp, ssl=ssl_ctx, port=arg.port, debug=arg.debug) + asyncio.run(webserver(app=app, ssl=ssl_ctx, port=arg.port, debug=arg.debug)) + + logging.critical('Webserver stopped.') # ---------------------------------------------------------------------------- diff --git a/aprendizations/serve.py b/aprendizations/serve.py index e34b772..a9f1520 100644 --- a/aprendizations/serve.py +++ b/aprendizations/serve.py @@ -4,6 +4,7 @@ Webserver # python standard library +import asyncio import base64 import functools from logging import getLogger @@ -58,8 +59,9 @@ class WebApplication(tornado.web.Application): (r'/rankings', RankingsHandler), # rankings table (r'/topic/(.+)', TopicHandler), # start topic (r'/file/(.+)', FileHandler), # serve file - (r'/courses', CoursesHandler), # show list of courses - (r'/course/(.*)', CourseHandler), # show course topics + (r'/courses', CoursesHandler), # show available courses + (r'/course/(.*)', CourseHandler), # show topics from course + (r'/course2/(.*)', CourseHandler2), # show topics from course FIXME (r'/', RootHandler), # redirects ] settings = { @@ -241,9 +243,38 @@ class CoursesHandler(BaseHandler): # ============================================================================ +class CourseHandler2(BaseHandler): + @tornado.web.authenticated + def get(self, course_id) -> None: + ''' + Handles get /course/... + Starts a given course and show list of topics + ''' + uid = self.current_user + logger.debug('[CourseHandler2] uid="%s", course_id="%s"', uid, course_id) + + if course_id == '': + course_id = self.learn.get_current_course_id(uid) + + try: + self.learn.start_course(uid, course_id) + except LearnException: + self.redirect('/courses') + + # print(self.learn.get_course(course_id)) + self.render('maintopics-table2.html', + appname=APP_NAME, + uid=uid, + name=self.learn.get_student_name(uid), + state=self.learn.get_student_state(uid), + course_id=course_id, + course=self.learn.get_course(course_id) + ) + +# ============================================================================ class CourseHandler(BaseHandler): ''' - Handles a particular course to show the topics table + Show topics for a particular course ''' @tornado.web.authenticated @@ -253,6 +284,8 @@ class CourseHandler(BaseHandler): Starts a given course and show list of topics ''' uid = self.current_user + logger.debug('[CourseHandler] uid="%s", course_id="%s"', uid, course_id) + if course_id == '': course_id = self.learn.get_current_course_id(uid) @@ -286,7 +319,7 @@ class TopicHandler(BaseHandler): Starts a given topic ''' uid = self.current_user - logger.debug('[TopicHandler.get] %s', topic) + logger.debug('[TopicHandler] %s', topic) try: await self.learn.start_topic(uid, topic) # FIXME GET should not modify state... except KeyError: @@ -315,8 +348,8 @@ class FileHandler(BaseHandler): public_dir = self.learn.get_current_public_dir(uid) filepath = expanduser(join(public_dir, filename)) - logger.debug('uid=%s, public_dir=%s, filepath=%s', uid, public_dir, - filepath) + logger.debug('[FileHandler] uid=%s, public_dir=%s, filepath=%s', + uid, public_dir, filepath) try: with open(filepath, 'rb') as file: data = file.read() @@ -356,7 +389,7 @@ class QuestionHandler(BaseHandler): ''' Get question to render or an animated trophy if no more questions. ''' - logger.debug('[QuestionHandler.get]') + logger.debug('[QuestionHandler]') user = self.current_user question = await self.learn.get_question(user) @@ -396,7 +429,7 @@ class QuestionHandler(BaseHandler): user = self.current_user answer = self.get_body_arguments('answer') # list qid = self.get_body_arguments('qid')[0] - # logger.debug('[QuestionHandler] answer=%s', answer) + logger.debug('[QuestionHandler] answer=%s', answer) # --- check if browser opened different questions simultaneously if qid != self.learn.get_current_question_id(user): @@ -486,9 +519,9 @@ def signal_handler(*_) -> None: # ---------------------------------------------------------------------------- -def run_webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: +async def webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: ''' - Starts and runs webserver until a SIGINT signal (Ctrl-C) is received. + Runs webserver until a SIGINT signal (Ctrl-C) is received. ''' # --- create web application @@ -517,10 +550,6 @@ def run_webserver(app, ssl, port: int = 8443, debug: bool = False) -> None: # --- set signal handler for Control-C signal.signal(signal.SIGINT, signal_handler) - # --- run tornado webserver - try: - tornado.ioloop.IOLoop.current().start() # running... - except Exception: - logger.critical('Webserver stopped.') - tornado.ioloop.IOLoop.current().stop() - raise + # --- run event loop (and tornado webserver) + await asyncio.Event().wait() + -- libgit2 0.21.2