Commit 8f401eb72179700f241599609265e0e601c4566e
1 parent
91893722
Exists in
master
and in
1 other branch
- Modified how paths to scripts are handled. Paths are now relative to the direc…
…tory of the question yaml file (instead of questions_dir).
Showing
4 changed files
with
67 additions
and
21 deletions
Show diff stats
BUGS.md
@@ -2,13 +2,12 @@ | @@ -2,13 +2,12 @@ | ||
2 | # BUGS | 2 | # BUGS |
3 | 3 | ||
4 | - Review de um teste que foi apagado rebenta. | 4 | - Review de um teste que foi apagado rebenta. |
5 | -- Gerar pdf's com todos os testes no final (pdfkit). | ||
6 | - permitir eliminar teste a decorrer de modo a que o aluno possa recomeçar (e.g. noutro browser) | 5 | - permitir eliminar teste a decorrer de modo a que o aluno possa recomeçar (e.g. noutro browser) |
7 | - servidor nao esta a lidar com eventos scroll/resize. ignorar? | 6 | - servidor nao esta a lidar com eventos scroll/resize. ignorar? |
8 | 7 | ||
9 | # TODO | 8 | # TODO |
10 | 9 | ||
11 | -- configurar pf em freebsd, port forward 80 -> 8080. documentacao | 10 | +- Gerar pdf's com todos os testes no final (pdfkit). |
12 | - testar SSL | 11 | - testar SSL |
13 | - manter registo dos unfocus durante o teste e de qual a pergunta visivel nesse momento | 12 | - manter registo dos unfocus durante o teste e de qual a pergunta visivel nesse momento |
14 | 13 | ||
@@ -28,6 +27,8 @@ | @@ -28,6 +27,8 @@ | ||
28 | 27 | ||
29 | # FIXED | 28 | # FIXED |
30 | 29 | ||
30 | +- configuração do teste não joga bem com o do aprendizations. Em particular os scripts não ficam com o mesmo path!!! | ||
31 | +- configurar pf em freebsd, port forward 80 -> 8080. documentacao | ||
31 | - barras com notas em grade estão desalinhadas. | 32 | - barras com notas em grade estão desalinhadas. |
32 | - erros nos generators devem ser ERROR e não WARNING. | 33 | - erros nos generators devem ser ERROR e não WARNING. |
33 | - se directorio "logs" não existir no directorio actual aborta com mensagem de erro. | 34 | - se directorio "logs" não existir no directorio actual aborta com mensagem de erro. |
README.md
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | 8 | ||
9 | ### Requirements | 9 | ### Requirements |
10 | 10 | ||
11 | -The webserver is a python application and requires `python3.5` and `pip` to be installed, plus the following additional packages: | 11 | +The webserver is a python application and requires `python3.6` and `pip` to be installed, plus the following additional packages: |
12 | 12 | ||
13 | - CherryPy | 13 | - CherryPy |
14 | - Mako | 14 | - Mako |
@@ -29,7 +29,7 @@ pip install --user cherrypy mako markdown pyyaml pygments sqlalchemy bcrypt | @@ -29,7 +29,7 @@ pip install --user cherrypy mako markdown pyyaml pygments sqlalchemy bcrypt | ||
29 | #### Installing packages in a virtual environment (alternative) | 29 | #### Installing packages in a virtual environment (alternative) |
30 | 30 | ||
31 | ```.bash | 31 | ```.bash |
32 | -pyvenv-3.5 venv/perguntations # or other virtualenv directory | 32 | +pyvenv-3.6 venv/perguntations # or other virtualenv directory |
33 | source venv/perguntations/bin/activate # activate virtualenv | 33 | source venv/perguntations/bin/activate # activate virtualenv |
34 | 34 | ||
35 | pip install cherrypy mako markdown pyyaml pygments sqlalchemy bcrypt | 35 | pip install cherrypy mako markdown pyyaml pygments sqlalchemy bcrypt |
@@ -80,7 +80,7 @@ We are now ready to run the server: | @@ -80,7 +80,7 @@ We are now ready to run the server: | ||
80 | ./serve.py demo/test.yaml # run demo test | 80 | ./serve.py demo/test.yaml # run demo test |
81 | ``` | 81 | ``` |
82 | 82 | ||
83 | -By default the server listens on all IPs of all network interfaces. | 83 | +By default the server listens on port 8080 and on all IPs of all network interfaces. |
84 | Open the browser at `http://127.0.0.1:8080/` and login as user number `0` (administrator) and choose any password. Then | 84 | Open the browser at `http://127.0.0.1:8080/` and login as user number `0` (administrator) and choose any password. Then |
85 | 85 | ||
86 | 1. Authorize students by clicking the checkboxes. | 86 | 1. Authorize students by clicking the checkboxes. |
@@ -90,7 +90,7 @@ The server can be stoped from the terminal with `^C`. | @@ -90,7 +90,7 @@ The server can be stoped from the terminal with `^C`. | ||
90 | 90 | ||
91 | ## Running on port 80 | 91 | ## Running on port 80 |
92 | 92 | ||
93 | -Port 80 is reserved for the root user and and this software _should NOT be run as root_. Instead, the firewall should be configured to forward tcp traffic from port 80 to 8080 where the server is listening. The details depend on the operating system. | 93 | +Ports 80 and 443 are reserved for the root user and and this software _should NOT be run as root_. Instead, the firewall should be configured to forward tcp traffic from port 80 to 8080 where the server is listening. The details depend on the operating system. |
94 | 94 | ||
95 | ### debian: | 95 | ### debian: |
96 | 96 | ||
@@ -109,9 +109,28 @@ Explanation: | @@ -109,9 +109,28 @@ Explanation: | ||
109 | - `-j REDIRECT` what to do when packet matches the rule. | 109 | - `-j REDIRECT` what to do when packet matches the rule. |
110 | - `--to-ports 8080` where to redirect the packets. | 110 | - `--to-ports 8080` where to redirect the packets. |
111 | 111 | ||
112 | -### freebsd | 112 | +### FreeBSD and pf |
113 | 113 | ||
114 | -Todo... | 114 | +Edit `/etc/pf.conf`: |
115 | + | ||
116 | + ext_if="em0" | ||
117 | + rdr on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 port 8080 | ||
118 | + rdr on $ext_if proto tcp from any to any port 443 -> 127.0.0.1 port 8443 | ||
119 | + | ||
120 | +or `ext_if="vtnet0"` for guest additions under virtual box. | ||
121 | + | ||
122 | +Edit `rc.conf` | ||
123 | + | ||
124 | + pf_enable="YES" | ||
125 | + pf_flags="" | ||
126 | + pf_rules="/etc/pf.conf" | ||
127 | + | ||
128 | + # optional logging: | ||
129 | + pflog_enable="YES" | ||
130 | + pflog_flags="" | ||
131 | + pflog_logfile="/var/log/pflog" | ||
132 | + | ||
133 | +Reboot. | ||
115 | 134 | ||
116 | ## Enabling SSL | 135 | ## Enabling SSL |
117 | 136 | ||
@@ -119,12 +138,20 @@ Todo... | @@ -119,12 +138,20 @@ Todo... | ||
119 | 138 | ||
120 | ## Troubleshooting | 139 | ## Troubleshooting |
121 | 140 | ||
122 | -* The server tries to run `python3`. If only a `python3.5` command is available, you need to set the default python using the OS package manager or manually create a symbolic link: | ||
123 | - - macOS/macports: `sudo port select --set python3 python35` | ||
124 | - - FreeBSD 11: `cd /usr/local/bin; ln -s python3.5 python3` | 141 | +* The server tries to run `python3`. If only a `python3.6` command is available, you need to set the default python using the OS package manager or manually create a symbolic link: |
142 | + - macOS/macports: `sudo port select --set python3 python36` | ||
143 | + - FreeBSD 11: `cd /usr/local/bin; ln -s python3.6 python3` | ||
125 | 144 | ||
126 | -* If you are getting any `UnicodeEncodeError` type of errors that's because the terminal is not supporting UTF-8. Try running `locale` on the terminal and see if there is any error messages. Solutions: | 145 | +* If you are getting any `UnicodeEncodeError` type of errors that's because the terminal is not supporting UTF-8. This error may occur when a unicode character is printed to the screen by the server or, when running question generator or correction scripts, a message is piped between the server and the scripts that includes unicode characters. |
146 | +Try running `locale` on the terminal and see if there are any error messages. Solutions: | ||
127 | - debian: fix it with `sudo dpkg-reconfigure locales`, select your UTF-8 locales and try again. | 147 | - debian: fix it with `sudo dpkg-reconfigure locales`, select your UTF-8 locales and try again. |
148 | + - FreeBSD: edit `~/.login_conf` to use UTF-8, for example: | ||
149 | + | ||
150 | + ``` | ||
151 | + me:\ | ||
152 | + :charset=UTF-8:\ | ||
153 | + :lang=en_US.UTF-8: | ||
154 | + ``` | ||
128 | 155 | ||
129 | ## Contribute ### | 156 | ## Contribute ### |
130 | 157 |
questions.py
@@ -83,24 +83,33 @@ class QuestionFactory(dict): | @@ -83,24 +83,33 @@ class QuestionFactory(dict): | ||
83 | # ----------------------------------------------------------------------- | 83 | # ----------------------------------------------------------------------- |
84 | # load single YAML questions file | 84 | # load single YAML questions file |
85 | # ----------------------------------------------------------------------- | 85 | # ----------------------------------------------------------------------- |
86 | - def load_file(self, filename, questions_dir=''): | ||
87 | - f = path.normpath(path.join(questions_dir, filename)) | ||
88 | - questions = load_yaml(f, default=[]) | 86 | + def load_file(self, pathfile, questions_dir=''): |
87 | + # questions_dir is a base directory | ||
88 | + # pathfile is a path of a file under the questions_dir | ||
89 | + # For example, if | ||
90 | + # pathfile = 'math/questions.yaml' | ||
91 | + # questions_dir = '/home/john/questions' | ||
92 | + # then the complete path is | ||
93 | + # fullpath = '/home/john/questions/math/questions.yaml' | ||
94 | + fullpath = path.normpath(path.join(questions_dir, pathfile)) | ||
95 | + (dirname, filename) = path.split(fullpath) | ||
96 | + | ||
97 | + questions = load_yaml(fullpath, default=[]) | ||
89 | 98 | ||
90 | n = 0 | 99 | n = 0 |
91 | for i, q in enumerate(questions): | 100 | for i, q in enumerate(questions): |
92 | if isinstance(q, dict): | 101 | if isinstance(q, dict): |
93 | q.update({ | 102 | q.update({ |
94 | 'filename': filename, | 103 | 'filename': filename, |
95 | - 'path': questions_dir, | 104 | + 'path': dirname, |
96 | 'index': i # position in the file, 0 based | 105 | 'index': i # position in the file, 0 based |
97 | }) | 106 | }) |
98 | self.add(q) # add question | 107 | self.add(q) # add question |
99 | n += 1 # counter | 108 | n += 1 # counter |
100 | else: | 109 | else: |
101 | - logger.error('Question index {0} from file {1} is not a dictionary. Skipped!'.format(i, filename)) | 110 | + logger.error('Question index {0} from file {1} is not a dictionary. Skipped!'.format(i, pathfile)) |
102 | 111 | ||
103 | - logger.info('Loaded {0} questions from "{1}".'.format(n, filename)) | 112 | + logger.info('Loaded {0} questions from "{1}".'.format(n, pathfile)) |
104 | 113 | ||
105 | # ----------------------------------------------------------------------- | 114 | # ----------------------------------------------------------------------- |
106 | # load multiple YAML question files | 115 | # load multiple YAML question files |
serve.py
1 | #!/usr/bin/env python3 | 1 | #!/usr/bin/env python3 |
2 | -# -*- coding: utf-8 -*- | ||
3 | - | ||
4 | 2 | ||
5 | from os import path | 3 | from os import path |
6 | import sys | 4 | import sys |
@@ -9,10 +7,21 @@ import logging.config | @@ -9,10 +7,21 @@ import logging.config | ||
9 | import json | 7 | import json |
10 | 8 | ||
11 | try: | 9 | try: |
10 | + # required here | ||
12 | import cherrypy | 11 | import cherrypy |
13 | from mako.lookup import TemplateLookup | 12 | from mako.lookup import TemplateLookup |
13 | + # required elsewhere | ||
14 | + from json import __version__ as json_version | ||
15 | + from bcrypt import __version__ as bcrypt_version | ||
16 | + from sqlalchemy import __version__ as alchemy_version | ||
17 | + from yaml import __version__ as yaml_version | ||
18 | + from markdown import version as markdown_version | ||
14 | except ImportError: | 19 | except ImportError: |
15 | - print('Some python packages are missing. See README.md for instructions.') | 20 | + print(''' |
21 | + Some python packages are missing. | ||
22 | + Try running "pip3 install --user cherrypy mako markdown pyyaml pygments sqlalchemy bcrypt" | ||
23 | + See README.md for instructions. | ||
24 | + ''') | ||
16 | sys.exit(1) | 25 | sys.exit(1) |
17 | 26 | ||
18 | from tools import load_yaml | 27 | from tools import load_yaml |