Commit 9b98821dc8a9a9d22ad6739c54a20a54a85a0992

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

update README.md

use cdn provided font-awesome and codemirror
remove npm and node dependencies
version bump to 2021.11.dev1
1 # Getting Started 1 # Getting Started
2 2
3 -Latest review: 2021-07-08 3 +Latest review: 2021-11-08
4 4
5 ## Installation 5 ## Installation
6 6
7 To complete the installation we will need to perform the following steps: 7 To complete the installation we will need to perform the following steps:
8 8
9 -1. install python3, pip and npm  
10 -2. download aprendizations from the repository  
11 -3. install javascript libraries (with npm)  
12 -4. install aprendizations (with pip)  
13 -5. generate SSL certificates  
14 -6. configure the firewall (optional) 9 +1. install python3 and pip
  10 +2. install aprendizations
  11 +3. generate SSL certificates
  12 +4. configure the firewall (optional)
15 13
16 To use the software we need to: 14 To use the software we need to:
17 15
18 -1. initialize database 16 +1. initialize a database
19 2. go to the demo directory (or an existing course) 17 2. go to the demo directory (or an existing course)
20 -3. run `aprendizations demo.yaml` 18 +3. run `aprendizations courses.yaml`
21 19
22 Each of these steps is explained below. 20 Each of these steps is explained below.
23 21
24 -### Install python3 with sqlite3 support and npm 22 +### Install python3 with sqlite3 support
25 23
26 -Python can be installed either from the system package management or compiled  
27 -from sources.  
28 -  
29 -#### Installing from the system package manager  
30 -  
31 -```sh  
32 -sudo pkg install python3 npm # FreeBSD  
33 -sudo apt install python3 npm # Linux (Ubuntu)  
34 -sudo port install python38 npm7 # MacOS  
35 -```  
36 -  
37 -In FreeBSD also install `py3X-sqlite3` where `X` is the python version.  
38 -  
39 -#### Installing from source (outdated)  
40 -  
41 -Make sure that the build tools and libraries are installed: 24 +Minimum supported version is python3.8. The installed versions depend on the
  25 +operating system default.
42 26
43 ```sh 27 ```sh
44 -# Ubuntu:  
45 -sudo apt install build-essential libssl-dev zlib1g-dev libncurses5-dev \  
46 - libncursesw5-dev libreadline-dev libsqlite3-dev libgdbm-dev libdb5.3-dev \  
47 - libbz2-dev libexpat1-dev liblzma-dev tk-dev libffi-dev 28 +sudo pkg install python3 py38-sqlite3 # FreeBSD
  29 +sudo apt install python3 # Linux (Ubuntu)
  30 +sudo port install python39 # MacOS
48 ``` 31 ```
49 32
50 -Download [python](http://www.python.org) and  
51 -  
52 -```sh  
53 -tar xvfJ Python-3.7.tar.xz  
54 -cd Python-3.7  
55 -./configure --prefix=$HOME/.local --enable-optimizations  
56 -make && make install  
57 -```  
58 -  
59 -This will install python locally under `~/.local/bin`. Make sure to add it to  
60 -your `PATH` in `~/.profile`. If `~/bin` is already in the path, just make a  
61 -symbolic link `ln -s ~/.local/bin ~/bin`.  
62 -  
63 ### Install pip 33 ### Install pip
64 34
65 Install `pip` from the system package manager: 35 Install `pip` from the system package manager:
66 36
67 ```sh 37 ```sh
68 -sudo apt install python3-pip # Ubuntu  
69 -sudo pkg py38-pip # FreeBSD 38 +sudo pkg install py38-pip # FreeBSD
  39 +sudo apt install python3-pip # Linux (Ubuntu)
70 sudo port install py39-pip # MacOS 40 sudo port install py39-pip # MacOS
71 ``` 41 ```
72 42
73 -Then run `python3 -m pip install -U pip` to install latest version into your  
74 -user account under `~/.local/bin`.  
75 In the end you should be able to run `pip --version` and `python3 -c "import 43 In the end you should be able to run `pip --version` and `python3 -c "import
76 sqlite3"` without errors. 44 sqlite3"` without errors.
77 -In some systems, `pip` can be named `pip3`, `pip3.8` or `pip-3.8`. 45 +In some systems, `pip` can be named `pip3`, `pip3.8` or `pip-3.8`, etc.
78 46
79 -Edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or 47 +Packages should **not** be installed system-wide. To install locally in the user
  48 +area, edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or
80 `Library/Application Support/pip/pip.conf` (MacOS) and add the lines 49 `Library/Application Support/pip/pip.conf` (MacOS) and add the lines
81 50
82 ```ini 51 ```ini
@@ -84,30 +53,22 @@ Edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or @@ -84,30 +53,22 @@ Edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or
84 user = yes 53 user = yes
85 ``` 54 ```
86 55
87 -This will set pip to install modules in the user area (recommended).  
88 -  
89 -### Download and install aprendizations 56 +### Install aprendizations
90 57
91 ```sh 58 ```sh
92 -git clone https://git.xdi.uevora.pt/mjsb/aprendizations.git  
93 -cd aprendizations  
94 -npm install # install javascript libraries  
95 -pip install . # install aprendizations and dependencies 59 +pip install git+https://git.xdi.uevora.pt/mjsb/aprendizations.git
96 ``` 60 ```
97 61
98 -Javascript libraries are installed in `aprendizations/node_modules` and are  
99 -linked from `aprendizations/aprendizations/static`.  
100 -  
101 Python packages are usually installed in: 62 Python packages are usually installed in:
102 63
103 * `~/.local/lib/python3.8/site-packages/` in Linux/FreeBSD. 64 * `~/.local/lib/python3.8/site-packages/` in Linux/FreeBSD.
104 * `~/Library/python/3.9/lib/python/site-packages/` in MacOS. 65 * `~/Library/python/3.9/lib/python/site-packages/` in MacOS.
105 66
106 When aprendizations is installed with pip, all the dependencies are also 67 When aprendizations is installed with pip, all the dependencies are also
107 -installed. The javascript libraries previously installed with npm are copied to  
108 -the above directory and the cloned repository is no longer needed. 68 +installed.
109 69
110 -At this point `aprendizations` is installed in 70 +At this point, the commands `aprendizations` and `initdb-aprendizations` are
  71 +installed in
111 72
112 ```sh 73 ```sh
113 ~/.local/bin # Linux/FreeBSD 74 ~/.local/bin # Linux/FreeBSD
@@ -119,6 +80,7 @@ and can be run from the terminal: @@ -119,6 +80,7 @@ and can be run from the terminal:
119 ```sh 80 ```sh
120 aprendizations --version 81 aprendizations --version
121 aprendizations --help 82 aprendizations --help
  83 +initdb-aprendizations --help
122 ``` 84 ```
123 85
124 ### SSL Certificates 86 ### SSL Certificates
@@ -172,7 +134,7 @@ chmod 400 cert.pem privkey.pem @@ -172,7 +134,7 @@ chmod 400 cert.pem privkey.pem
172 134
173 User data is maintained in a sqlite3 database which has to be created manually 135 User data is maintained in a sqlite3 database which has to be created manually
174 using the `initdb-aprendizations` command. The database file should be located 136 using the `initdb-aprendizations` command. The database file should be located
175 -in the same directory as the main YAML configuration file. 137 +in the same directory as the main YAML configuration file (`courses.yaml`).
176 138
177 For example, to run the included demo do: 139 For example, to run the included demo do:
178 140
@@ -190,12 +152,12 @@ The default password is equal to the user name, if left undefined. @@ -190,12 +152,12 @@ The default password is equal to the user name, if left undefined.
190 152
191 ### Running the demo 153 ### Running the demo
192 154
193 -The application includes a small example in `demo/demo.yaml` that can be used 155 +The application includes a small example in `demo/courses.yaml` that can be used
194 for initial testing. Run it with 156 for initial testing. Run it with
195 157
196 ```sh 158 ```sh
197 cd demo 159 cd demo
198 -aprendizations demo.yaml 160 +aprendizations courses.yaml
199 ``` 161 ```
200 162
201 Open the browser at [https://127.0.0.1:8443](https://127.0.0.1:8443). 163 Open the browser at [https://127.0.0.1:8443](https://127.0.0.1:8443).
@@ -237,28 +199,25 @@ pflog_logfile="/var/log/pflog" @@ -237,28 +199,25 @@ pflog_logfile="/var/log/pflog"
237 199
238 Reboot or `sudo service pf start`. 200 Reboot or `sudo service pf start`.
239 201
  202 +Example configuration files are in the `freebsd` directory.
  203 +
240 ### Testing the system 204 ### Testing the system
241 205
242 Make sure the following steps have been done: 206 Make sure the following steps have been done:
243 207
244 -* installed python3, pip and npm  
245 -* git-cloned the aprendizations from the main repository  
246 -* installed javascript libraries with npm  
247 -* installed aprendizations with pip 208 +* installed python3 and pip
  209 +* installed aprendizations using pip
248 * initialized database with at least 1 user 210 * initialized database with at least 1 user
249 * generate and copy certificates to the appropriate place 211 * generate and copy certificates to the appropriate place
250 * (optional) configure the firewall to do port forwarding 212 * (optional) configure the firewall to do port forwarding
251 -* run `aprendizations demo.yaml --check` 213 +* run `aprendizations courses.yaml --check`
252 214
253 ## Keeping aprendizations updated 215 ## Keeping aprendizations updated
254 216
255 To update aprendizations to the latest version do: 217 To update aprendizations to the latest version do:
256 218
257 ```sh 219 ```sh
258 -cd aprendizations  
259 -git pull # get latest version  
260 -npm update # update javascript libraries  
261 -pip install -U . # updates installed version 220 +pip install -U git+https://git.xdi.uevora.pt/mjsb/aprendizations.git
262 ``` 221 ```
263 222
264 ## Troubleshooting 223 ## Troubleshooting
@@ -304,20 +263,6 @@ To fix this issue you need to allow animations in the Operating System: @@ -304,20 +263,6 @@ To fix this issue you need to allow animations in the Operating System:
304 * On MacOS or iOS search for reduced motion and switch it **OFF** 263 * On MacOS or iOS search for reduced motion and switch it **OFF**
305 (Preferences -> Acessibility -> Display -> Reduce motion). 264 (Preferences -> Acessibility -> Display -> Reduce motion).
306 265
307 -### The application runs but questions do not show up  
308 -  
309 -Some operating systems have an option to disable animations to try to avoid  
310 -motion sickness in some people. Browsers will check this option with the OS and  
311 -prevent animate.css library to work. Since questions have several animations,  
312 -these will will not work and nothing is shown on the page.  
313 -  
314 -To fix this issue you need to allow animations in the Operating System:  
315 -  
316 -* On windows 10, go to System Preferences, search for "Show animations in  
317 - windows" and turn it **ON**.  
318 -* On MacOS or iOS search for reduced motion and switch it **OFF**  
319 - (Preferences -> Acessibility -> Display -> Reduce motion).  
320 -  
321 ## FAQ 266 ## FAQ
322 267
323 Common database manipulations: 268 Common database manipulations:
aprendizations/__init__.py
@@ -30,7 +30,7 @@ are progressively uncovered as the students progress. @@ -30,7 +30,7 @@ are progressively uncovered as the students progress.
30 ''' 30 '''
31 31
32 APP_NAME = 'aprendizations' 32 APP_NAME = 'aprendizations'
33 -APP_VERSION = '2021.08.dev1' 33 +APP_VERSION = '2021.11.dev1'
34 APP_DESCRIPTION = __doc__ 34 APP_DESCRIPTION = __doc__
35 35
36 __author__ = 'Miguel Barão' 36 __author__ = 'Miguel Barão'
aprendizations/learnapp.py
@@ -86,7 +86,7 @@ class LearnApp(): @@ -86,7 +86,7 @@ class LearnApp():
86 for course_file in config.get('topics_from', []): 86 for course_file in config.get('topics_from', []):
87 course_conf = load_yaml(course_file) # course configuration 87 course_conf = load_yaml(course_file) # course configuration
88 # FIXME set defaults?? 88 # FIXME set defaults??
89 - logger.info('%6d topics imported from %s', 89 + logger.info('%6d topics from %s',
90 len(course_conf["topics"]), course_file) 90 len(course_conf["topics"]), course_file)
91 self._populate_graph(course_conf) 91 self._populate_graph(course_conf)
92 logger.info('Graph has %d topics', len(self.deps)) 92 logger.info('Graph has %d topics', len(self.deps))
@@ -327,7 +327,7 @@ class LearnApp(): @@ -327,7 +327,7 @@ class LearnApp():
327 logger.warning('"%s" could not start course "%s"', uid, course_id) 327 logger.warning('"%s" could not start course "%s"', uid, course_id)
328 raise LearnException() from exc 328 raise LearnException() from exc
329 else: 329 else:
330 - logger.info('User "%s" started course "%s"', uid, course_id) 330 + logger.info('User "%s" course "%s"', uid, course_id)
331 331
332 # ------------------------------------------------------------------------ 332 # ------------------------------------------------------------------------
333 # 333 #
@@ -609,15 +609,17 @@ class LearnApp(): @@ -609,15 +609,17 @@ class LearnApp():
609 This should be modified to have a "visible" flag 609 This should be modified to have a "visible" flag
610 ''' 610 '''
611 611
612 - logger.info('User "%s" get rankings for %s', uid, course_id)  
613 - query_students = select(Student.id, Student.name)  
614 - query_student_topics = select(StudentTopic.student_id,  
615 - StudentTopic.topic_id,  
616 - StudentTopic.level,  
617 - StudentTopic.date)  
618 - query_total = select(Answer.student_id, func.count(Answer.ref))  
619 - query_right = select(Answer.student_id, func.count(Answer.ref)).where(Answer.grade == 1.0) 612 + logger.info('User "%s" rankings for "%s"', uid, course_id)
620 with Session(self._engine, future=True) as session: 613 with Session(self._engine, future=True) as session:
  614 + query_students = select(Student.id, Student.name)
  615 + query_student_topics = select(StudentTopic.student_id,
  616 + StudentTopic.topic_id,
  617 + StudentTopic.level,
  618 + StudentTopic.date)
  619 + query_total = select(Answer.student_id, func.count(Answer.ref))
  620 + query_right = select(Answer.student_id, func.count(Answer.ref)) \
  621 + .where(Answer.grade == 1.0)
  622 +
621 # all students in the database FIXME only with answers of this course 623 # all students in the database FIXME only with answers of this course
622 students = session.execute(query_students).all() 624 students = session.execute(query_students).all()
623 625
@@ -625,6 +627,9 @@ class LearnApp(): @@ -625,6 +627,9 @@ class LearnApp():
625 student_topics = session.execute(query_student_topics).all() 627 student_topics = session.execute(query_student_topics).all()
626 628
627 # answer performance 629 # answer performance
  630 +
  631 + # FIXME this does not work when nobody has done anything...
  632 + # FIXME row to dict seems to be deprecated in 1.4+
628 total = dict(session.execute(query_total).all()) 633 total = dict(session.execute(query_total).all())
629 right = dict(session.execute(query_right).all()) 634 right = dict(session.execute(query_right).all())
630 635
aprendizations/static/codemirror
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -../../node_modules/codemirror/  
2 \ No newline at end of file 0 \ No newline at end of file
aprendizations/static/fontawesome-free
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -../../node_modules/@fortawesome/fontawesome-free/  
2 \ No newline at end of file 0 \ No newline at end of file
aprendizations/templates/courses.html
@@ -9,14 +9,16 @@ @@ -9,14 +9,16 @@
9 <link rel="icon" href="favicon.ico"> 9 <link rel="icon" href="favicon.ico">
10 <!-- Styles --> 10 <!-- Styles -->
11 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> 11 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  12 + <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
12 13
13 <link rel="stylesheet" href="{{static_url('css/maintopics.css')}}"> 14 <link rel="stylesheet" href="{{static_url('css/maintopics.css')}}">
14 <link rel="stylesheet" href="{{static_url('css/sticky-footer-navbar.css')}}"> 15 <link rel="stylesheet" href="{{static_url('css/sticky-footer-navbar.css')}}">
15 <!-- Scripts --> 16 <!-- Scripts -->
16 - <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> 17 + <script src="https://code.jquery.com/jquery-3.6.0.min.js"
  18 + integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  19 + <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
  20 + integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
17 21
18 - <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>  
19 - <script defer src="{{static_url('fontawesome-free/js/all.min.js')}}"></script>  
20 <script defer src="{{static_url('js/maintopics.js')}}"></script> 22 <script defer src="{{static_url('js/maintopics.js')}}"></script>
21 23
22 <title>{{appname}}</title> 24 <title>{{appname}}</title>
aprendizations/templates/maintopics-table.html
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 10
11 <!-- Styles --> 11 <!-- Styles -->
12 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> 12 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  13 + <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
13 14
14 <link rel="stylesheet" href="{{static_url('css/maintopics.css')}}"> 15 <link rel="stylesheet" href="{{static_url('css/maintopics.css')}}">
15 16
@@ -17,7 +18,6 @@ @@ -17,7 +18,6 @@
17 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> 18 <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
18 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> 19 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
19 20
20 - <script defer src="{{static_url('fontawesome-free/js/all.min.js')}}"></script>  
21 <script defer src="{{static_url('js/maintopics.js')}}"></script> 21 <script defer src="{{static_url('js/maintopics.js')}}"></script>
22 22
23 <title>{{appname}}</title> 23 <title>{{appname}}</title>
aprendizations/templates/rankings.html
@@ -9,10 +9,12 @@ @@ -9,10 +9,12 @@
9 <link rel="icon" href="/static/favicon.ico"> 9 <link rel="icon" href="/static/favicon.ico">
10 <!-- Styles --> 10 <!-- Styles -->
11 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> 11 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  12 + <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
  13 +
12 <link rel="stylesheet" href="{{static_url('css/maintopics.css')}}"> 14 <link rel="stylesheet" href="{{static_url('css/maintopics.css')}}">
13 <!-- Scripts --> 15 <!-- Scripts -->
14 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> 16 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
15 - <script defer src="{{static_url('fontawesome-free/js/all.min.js')}}"></script> 17 +
16 <script defer src="{{static_url('js/maintopics.js')}}"></script> 18 <script defer src="{{static_url('js/maintopics.js')}}"></script>
17 19
18 <title>{{appname}}</title> 20 <title>{{appname}}</title>
aprendizations/templates/topic.html
@@ -6,16 +6,17 @@ @@ -6,16 +6,17 @@
6 <meta name="author" content="Miguel Barão" /> 6 <meta name="author" content="Miguel Barão" />
7 <link rel="icon" href="/static/favicon.ico"> 7 <link rel="icon" href="/static/favicon.ico">
8 8
9 - <!-- Styles -->  
10 - <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">  
11 - 9 + <!-- Styles ---------------------------------------------------------- -->
  10 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
  11 + integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />
  12 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
12 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" /> 13 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
  14 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.3/codemirror.min.css" />
  15 + <!-- local styles -->
  16 + <link rel="stylesheet" href="{{static_url('css/github.css')}}" />
  17 + <link rel="stylesheet" href="{{static_url('css/topic.css')}}" />
13 18
14 - <link rel="stylesheet" href="{{static_url('codemirror/lib/codemirror.css')}}">  
15 - <link rel="stylesheet" href="{{static_url('css/github.css')}}">  
16 - <link rel="stylesheet" href="{{static_url('css/topic.css')}}">  
17 -  
18 - <!-- MathJax3 --> 19 + <!-- Scripts --------------------------------------------------------- -->
19 <script> 20 <script>
20 MathJax = { 21 MathJax = {
21 tex: { 22 tex: {
@@ -26,15 +27,14 @@ @@ -26,15 +27,14 @@
26 } 27 }
27 }; 28 };
28 </script> 29 </script>
29 - <!-- Scripts -->  
30 <script async type="text/javascript" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> 30 <script async type="text/javascript" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
  31 + <script defer src="https://code.jquery.com/jquery-3.6.0.min.js"
  32 + integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  33 + <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
  34 + integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  35 + <script defer src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.63.3/codemirror.min.js"></script>
31 36
32 - <script defer src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>  
33 -  
34 - <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>  
35 -  
36 - <script defer src="{{static_url('fontawesome-free/js/all.min.js')}}"></script>  
37 - <script defer src="{{static_url('codemirror/lib/codemirror.js')}}"></script> 37 + <!-- local scripts -->
38 <script defer src="{{static_url('js/topic.js')}}"></script> 38 <script defer src="{{static_url('js/topic.js')}}"></script>
39 39
40 <title>{{appname}}</title> 40 <title>{{appname}}</title>
freebsd/pf.conf 0 → 100644
@@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
  1 +
  2 +# Public interface
  3 +ext_if="em0"
  4 +
  5 +table <bruteforce> persist
  6 +
  7 +# Set and drop these IP ranges on public interface
  8 +martians = "{ 0.0.0.0/8, 127.0.0.0/8 }"
  9 +
  10 +# 192.168.0.0/16, 172.16.0.0/12, \
  11 +# 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
  12 +# 240.0.0.0/4 }"
  13 +
  14 +webports = "{ 8080, 8443 }"
  15 +
  16 +tcp_services = "{ domain, ntp, smtp, www, https, ssh }"
  17 +udp_services = "{ domain, ntp }"
  18 +
  19 +# Skip all PF processing on loopback interface
  20 +set skip on lo
  21 +
  22 +# Log statistics on interface
  23 +set loginterface $ext_if
  24 +
  25 +# Packet normalization
  26 +scrub in all
  27 +
  28 +# Redirect http and https ports to 8080 and 8443, resp.
  29 +no rdr on $ext_if proto tcp from <bruteforce> to any
  30 +rdr on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 port 8080
  31 +rdr on $ext_if proto tcp from any to any port 443 -> 127.0.0.1 port 8443
  32 +
  33 +# Default policy
  34 +#block return in log all
  35 +#block out all
  36 +
  37 +# Protect against spoofed or forget IP addresses
  38 +antispoof quick for $ext_if
  39 +
  40 +# Drop all Non-Routable Addresses
  41 +block drop in quick on $ext_if from $martians to any
  42 +block drop out quick on $ext_if from any to $martians
  43 +
  44 +# Protect against SSH attacks
  45 +block quick from <bruteforce>
  46 +pass quick proto { tcp, udp } from any to any port ssh \
  47 + flags S/SA keep state \
  48 + (max-src-conn 10, max-src-conn-rate 5/3, \
  49 + overload <bruteforce> flush global)
  50 +
  51 +# Allow Ping
  52 +pass inet proto icmp icmp-type echoreq
  53 +
  54 +# Webserver
  55 +#pass proto tcp from any to $ext_if port $webports
  56 +
  57 +# Allow essential outgoing traffic
  58 +pass out quick on $ext_if proto tcp to any port $tcp_services
  59 +pass out quick on $ext_if proto udp to any port $udp_services
  60 +
freebsd/rc.conf 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +zfs_enable="YES"
  2 +clear_tmp_enable="YES"
  3 +hostname="bit.xdi.uevora.pt"
  4 +ifconfig_em0="inet 193.137.120.198 netmask 255.255.255.192"
  5 +defaultrouter="193.137.120.254"
  6 +ifconfig_em0_ipv6="inet6 accept_rtadv"
  7 +sshd_enable="YES"
  8 +ntpd_enable="YES"
  9 +ntpd_sync_on_start="YES"
  10 +powerd_enable="NO"
  11 +
  12 +# pf firewall
  13 +pf_enable="YES"
  14 +#pf_flags="-T expire 86400"
  15 +pf_rules="/etc/pf.conf"
  16 +#pflog_enable="YES"
  17 +#pflog_flags=""
  18 +#pflog_logfile="/var/log/pflog"
  19 +
  20 +# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
  21 +dumpdev="NO"
package-lock.json
@@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
1 -{  
2 - "name": "aprendizations",  
3 - "lockfileVersion": 2,  
4 - "requires": true,  
5 - "packages": {  
6 - "": {  
7 - "dependencies": {  
8 - "@fortawesome/fontawesome-free": "^5.15.3",  
9 - "codemirror": "^5.59.4"  
10 - }  
11 - },  
12 - "node_modules/@fortawesome/fontawesome-free": {  
13 - "version": "5.15.4",  
14 - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",  
15 - "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==",  
16 - "hasInstallScript": true,  
17 - "engines": {  
18 - "node": ">=6"  
19 - }  
20 - },  
21 - "node_modules/codemirror": {  
22 - "version": "5.63.3",  
23 - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.63.3.tgz",  
24 - "integrity": "sha512-1C+LELr+5grgJYqwZKqxrcbPsHFHapVaVAloBsFBASbpLnQqLw1U8yXJ3gT5D+rhxIiSpo+kTqN+hQ+9ialIXw=="  
25 - }  
26 - },  
27 - "dependencies": {  
28 - "@fortawesome/fontawesome-free": {  
29 - "version": "5.15.4",  
30 - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz",  
31 - "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="  
32 - },  
33 - "codemirror": {  
34 - "version": "5.63.3",  
35 - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.63.3.tgz",  
36 - "integrity": "sha512-1C+LELr+5grgJYqwZKqxrcbPsHFHapVaVAloBsFBASbpLnQqLw1U8yXJ3gT5D+rhxIiSpo+kTqN+hQ+9ialIXw=="  
37 - }  
38 - }  
39 -}  
package.json
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -{  
2 - "description": "Javascript libraries required to run the server",  
3 - "email": "mjsb@uevora.pt",  
4 - "dependencies": {  
5 - "@fortawesome/fontawesome-free": "^5.15.3",  
6 - "codemirror": "^5.59.4"  
7 - },  
8 - "private": true  
9 -}