Commit b1febcff75c394cffe183cf0dafcb2cbda47442f

Authored by Miguel Barão
1 parent cfeff397
Exists in master and in 1 other branch dev

- check for imports and abort with nice error message

Showing 3 changed files with 52 additions and 10 deletions   Show diff stats
1 1
2 # Example: 2 # Example:
3 # 3 #
  4 +# # read everything from question files
4 # pool = QuestionPool() 5 # pool = QuestionPool()
5 # pool.add_from_files(['file1.yaml', 'file1.yaml']) 6 # pool.add_from_files(['file1.yaml', 'file1.yaml'])
6 # 7 #
  8 +# # generate a new test, creating instances for all questions
7 # test = [] 9 # test = []
8 # for q in pool.values(): 10 # for q in pool.values():
9 # test.append(create_question(q)) 11 # test.append(create_question(q))
10 # 12 #
  13 +# # experiment answering one question and correct it
11 # test[0]['answer'] = 42 # insert answer 14 # test[0]['answer'] = 42 # insert answer
12 # grade = test[0].correct() # correct answer 15 # grade = test[0].correct() # correct answer
13 16
14 17
15 -# Functions:  
16 -# create_question(q)  
17 -# q - dictionary with question in yaml format  
18 -# returns - question instance with the correct class  
19 18
  19 +# QuestionsPool - dictionary of questions not yet instantiated
  20 +#
  21 +# question_generator - runs external script to get a question dictionary
  22 +# create_question - returns question instance with the correct class
20 23
21 # An instance of an actual question is a Question object: 24 # An instance of an actual question is a Question object:
22 # 25 #
@@ -28,12 +31,18 @@ @@ -28,12 +31,18 @@
28 # QuestionTextArea - corrected by an external program 31 # QuestionTextArea - corrected by an external program
29 # QuestionInformation - not a question, just a box with content 32 # QuestionInformation - not a question, just a box with content
30 33
31 -import yaml  
32 import random 34 import random
33 import re 35 import re
34 import subprocess 36 import subprocess
35 import os.path 37 import os.path
36 import logging 38 import logging
  39 +import sys
  40 +
  41 +try:
  42 + import yaml
  43 +except ImportError:
  44 + print('The package "yaml" is missing. See README.md for instructions.')
  45 + sys.exit(1)
37 46
38 47
39 qlogger = logging.getLogger('Questions') 48 qlogger = logging.getLogger('Questions')
@@ -4,10 +4,23 @@ @@ -4,10 +4,23 @@
4 # The program runs a web server where students login to answer a sequence of questions. 4 # The program runs a web server where students login to answer a sequence of questions.
5 # Their grades are automatically calculated and stored in a sqlite3 database. 5 # Their grades are automatically calculated and stored in a sqlite3 database.
6 6
7 -import cherrypy  
8 -from mako.lookup import TemplateLookup  
9 -import argparse  
10 from os import path 7 from os import path
  8 +import sys
  9 +import argparse
  10 +# from threading import Lock
  11 +
  12 +try:
  13 + import cherrypy
  14 +except ImportError:
  15 + print('The package "cherrypy" is missing. See README.md for instructions.')
  16 + sys.exit(1)
  17 +
  18 +try:
  19 + from mako.lookup import TemplateLookup
  20 + import djks
  21 +except ImportError:
  22 + print('The package "mako" is missing. See README.md for instructions.')
  23 + sys.exit(1)
11 24
12 # path where this file is located 25 # path where this file is located
13 SERVER_PATH = path.dirname(path.realpath(__file__)) 26 SERVER_PATH = path.dirname(path.realpath(__file__))
@@ -30,7 +43,9 @@ class Root(object): @@ -30,7 +43,9 @@ class Root(object):
30 self.database = database.Database(testconf['database']) 43 self.database = database.Database(testconf['database'])
31 self.auth = AuthController(database=testconf['database']) 44 self.auth = AuthController(database=testconf['database'])
32 self.templates = TemplateLookup(directories=[TEMPLATES_DIR], input_encoding='utf-8') 45 self.templates = TemplateLookup(directories=[TEMPLATES_DIR], input_encoding='utf-8')
33 - self.tags = {'online': set(), 'finished': set()} # FIXME should be in application, not server 46 + # FIXME should be in application, not server
  47 + # FIXME lock and threading
  48 + self.tags = {'allowed': set(['0']), 'online': set(), 'finished': set()}
34 49
35 # --- DEFAULT ------------------------------------------------------------ 50 # --- DEFAULT ------------------------------------------------------------
36 # any path, e.g. /xpto/aargh is redirected to the test 51 # any path, e.g. /xpto/aargh is redirected to the test
@@ -89,6 +104,12 @@ class Root(object): @@ -89,6 +104,12 @@ class Root(object):
89 # If it's the first time, create instance of the test and register the 104 # If it's the first time, create instance of the test and register the
90 # time. 105 # time.
91 uid = cherrypy.session.get('userid') 106 uid = cherrypy.session.get('userid')
  107 + # if uid not in self.tags['allowed']:
  108 + # print('not allowed')
  109 + # raise cherrypy.HTTPRedirect('/logout')
  110 + # return
  111 + # print(self.tags)
  112 +
92 name = cherrypy.session.get('name') 113 name = cherrypy.session.get('name')
93 t = cherrypy.session.get('test', None) 114 t = cherrypy.session.get('test', None)
94 if t is None: 115 if t is None:
1 1
2 import os, sys, fnmatch 2 import os, sys, fnmatch
3 import random 3 import random
4 -import yaml, json  
5 import sqlite3 4 import sqlite3
6 from datetime import datetime 5 from datetime import datetime
7 6
  7 +try:
  8 + import yaml
  9 +except ImportError:
  10 + print('The package "yaml" is missing. See README.md for instructions.')
  11 + sys.exit(1)
  12 +
  13 +try:
  14 + import json
  15 +except ImportError:
  16 + print('The package "json" is missing. See README.md for instructions.')
  17 + sys.exit(1)
  18 +
  19 +
8 # my code 20 # my code
9 import questions 21 import questions
10 import database 22 import database