Commit c36cfb56558fd781bfeb0a4a834f9fd9b860cffb
1 parent
43785de6
Exists in
master
and in
1 other branch
- added try/catch to check if certificates are present.
- fixed 3 bugs in serve.py. - show total topics and questions loaded in logs.
Showing
3 changed files
with
24 additions
and
12 deletions
Show diff stats
learnapp.py
| @@ -287,6 +287,7 @@ def build_dependency_graph(config={}): | @@ -287,6 +287,7 @@ def build_dependency_graph(config={}): | ||
| 287 | 287 | ||
| 288 | # iterate over topics and build graph | 288 | # iterate over topics and build graph |
| 289 | topics = config.get('topics', {}) | 289 | topics = config.get('topics', {}) |
| 290 | + tcount = qcount = 0 # topic and question counters | ||
| 290 | for ref,attr in topics.items(): | 291 | for ref,attr in topics.items(): |
| 291 | g.add_node(ref) | 292 | g.add_node(ref) |
| 292 | tnode = g.node[ref] # current node (topic) | 293 | tnode = g.node[ref] # current node (topic) |
| @@ -313,5 +314,8 @@ def build_dependency_graph(config={}): | @@ -313,5 +314,8 @@ def build_dependency_graph(config={}): | ||
| 313 | tnode['factory'][q['ref']] = QFactory(q) | 314 | tnode['factory'][q['ref']] = QFactory(q) |
| 314 | 315 | ||
| 315 | logger.info(f'{len(tnode["questions"]):6} {ref}') | 316 | logger.info(f'{len(tnode["questions"]):6} {ref}') |
| 317 | + qcount += len(tnode["questions"]) # count total questions | ||
| 318 | + tcount += 1 | ||
| 316 | 319 | ||
| 320 | + logger.info(f'Total loaded: {tcount} topics, {qcount} questions') | ||
| 317 | return g | 321 | return g |
serve.py
| @@ -13,7 +13,7 @@ from concurrent.futures import ThreadPoolExecutor | @@ -13,7 +13,7 @@ from concurrent.futures import ThreadPoolExecutor | ||
| 13 | import tornado.ioloop | 13 | import tornado.ioloop |
| 14 | import tornado.web | 14 | import tornado.web |
| 15 | import tornado.httpserver | 15 | import tornado.httpserver |
| 16 | -from tornado import template #, gen | 16 | +from tornado import template, iostream, gen |
| 17 | 17 | ||
| 18 | from tornado.concurrent import run_on_executor | 18 | from tornado.concurrent import run_on_executor |
| 19 | from tornado.platform.asyncio import to_tornado_future | 19 | from tornado.platform.asyncio import to_tornado_future |
| @@ -101,7 +101,7 @@ class ChangePasswordHandler(BaseHandler): | @@ -101,7 +101,7 @@ class ChangePasswordHandler(BaseHandler): | ||
| 101 | @tornado.web.authenticated | 101 | @tornado.web.authenticated |
| 102 | def post(self): | 102 | def post(self): |
| 103 | uid = self.current_user | 103 | uid = self.current_user |
| 104 | - pw = self.get_body_arguments('new_password')[0]; | 104 | + pw = self.get_body_arguments('new_password')[0] |
| 105 | 105 | ||
| 106 | if self.learn.change_password(uid, pw): | 106 | if self.learn.change_password(uid, pw): |
| 107 | notification = tornado.escape.to_unicode(self.render_string('notification.html', type='success', msg='A password foi alterada!')) | 107 | notification = tornado.escape.to_unicode(self.render_string('notification.html', type='success', msg='A password foi alterada!')) |
| @@ -152,12 +152,13 @@ class TopicHandler(BaseHandler): | @@ -152,12 +152,13 @@ class TopicHandler(BaseHandler): | ||
| 152 | # Based on https://bhch.github.io/posts/2017/12/serving-large-files-with-tornado-safely-without-blocking/ | 152 | # Based on https://bhch.github.io/posts/2017/12/serving-large-files-with-tornado-safely-without-blocking/ |
| 153 | # ---------------------------------------------------------------------------- | 153 | # ---------------------------------------------------------------------------- |
| 154 | class FileHandler(BaseHandler): | 154 | class FileHandler(BaseHandler): |
| 155 | + chunk_size = 4 * 1024 * 1024 # serve up to 4 MiB multiple times | ||
| 156 | + | ||
| 155 | @tornado.web.authenticated | 157 | @tornado.web.authenticated |
| 156 | async def get(self, filename): | 158 | async def get(self, filename): |
| 157 | uid = self.current_user | 159 | uid = self.current_user |
| 158 | public_dir = self.learn.get_current_public_dir(uid) | 160 | public_dir = self.learn.get_current_public_dir(uid) |
| 159 | filepath = path.expanduser(path.join(public_dir, filename)) | 161 | filepath = path.expanduser(path.join(public_dir, filename)) |
| 160 | - chunk_size = 1024 * 1024 # serve up to 1MiB multiple times | ||
| 161 | try: | 162 | try: |
| 162 | f = open(filepath, 'rb') | 163 | f = open(filepath, 'rb') |
| 163 | except FileNotFoundError: | 164 | except FileNotFoundError: |
| @@ -166,7 +167,7 @@ class FileHandler(BaseHandler): | @@ -166,7 +167,7 @@ class FileHandler(BaseHandler): | ||
| 166 | logging.error(f'No permission: {filepath}') | 167 | logging.error(f'No permission: {filepath}') |
| 167 | else: | 168 | else: |
| 168 | with f: | 169 | with f: |
| 169 | - chunk = f.read(chunk_size) | 170 | + chunk = f.read(self.chunk_size) |
| 170 | while chunk: | 171 | while chunk: |
| 171 | try: | 172 | try: |
| 172 | self.write(chunk) # write the cunk to response | 173 | self.write(chunk) # write the cunk to response |
| @@ -178,7 +179,7 @@ class FileHandler(BaseHandler): | @@ -178,7 +179,7 @@ class FileHandler(BaseHandler): | ||
| 178 | del chunk | 179 | del chunk |
| 179 | await gen.sleep(0.000000001) # 1 nanosecond (hack) | 180 | await gen.sleep(0.000000001) # 1 nanosecond (hack) |
| 180 | # in tornnado 5.0 use `await asyncio.sleep(0)` instead | 181 | # in tornnado 5.0 use `await asyncio.sleep(0)` instead |
| 181 | - chunk = f.read(chunk_size) | 182 | + chunk = f.read(self.chunk_size) |
| 182 | 183 | ||
| 183 | 184 | ||
| 184 | # ---------------------------------------------------------------------------- | 185 | # ---------------------------------------------------------------------------- |
| @@ -320,12 +321,17 @@ def main(): | @@ -320,12 +321,17 @@ def main(): | ||
| 320 | raise e | 321 | raise e |
| 321 | 322 | ||
| 322 | # --- create webserver | 323 | # --- create webserver |
| 323 | - http_server = tornado.httpserver.HTTPServer(webapp, | ||
| 324 | - ssl_options={ | ||
| 325 | - "certfile": "certs/cert.pem", | ||
| 326 | - "keyfile": "certs/privkey.pem" | ||
| 327 | - }) | ||
| 328 | - http_server.listen(8443) | 324 | + try: |
| 325 | + http_server = tornado.httpserver.HTTPServer(webapp, | ||
| 326 | + ssl_options={ | ||
| 327 | + "certfile": "certs/cert.pem", | ||
| 328 | + "keyfile": "certs/privkey.pem" | ||
| 329 | + }) | ||
| 330 | + except ValueError: | ||
| 331 | + logging.critical('Certificates cert.pem, privkey.pem not found') | ||
| 332 | + sys.exit(1) | ||
| 333 | + else: | ||
| 334 | + http_server.listen(8443) | ||
| 329 | 335 | ||
| 330 | # --- run webserver | 336 | # --- run webserver |
| 331 | logging.info('Webserver running...') | 337 | logging.info('Webserver running...') |
templates/maintopics.html
| @@ -98,9 +98,11 @@ | @@ -98,9 +98,11 @@ | ||
| 98 | </a> | 98 | </a> |
| 99 | {% end %} | 99 | {% end %} |
| 100 | {% end %} | 100 | {% end %} |
| 101 | - </div> <!-- list-group --> | 101 | + </div> |
| 102 | + <!-- list-group --> | ||
| 102 | </div> | 103 | </div> |
| 103 | 104 | ||
| 105 | + | ||
| 104 | <!-- === Change Password Modal =========================================== --> | 106 | <!-- === Change Password Modal =========================================== --> |
| 105 | <div id="password_modal" class="modal fade" tabindex="-1" role="dialog"> | 107 | <div id="password_modal" class="modal fade" tabindex="-1" role="dialog"> |
| 106 | <div class="modal-dialog modal-sm" role="document"> | 108 | <div class="modal-dialog modal-sm" role="document"> |