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 |