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"> |