README.md 5.62 KB
Newer Older
Robert Czechowski's avatar
Robert Czechowski committed
1
# The Medal Contest Platform   ![Logo](static/images/medal_logo_small.png)
Robert Czechowski's avatar
Robert Czechowski committed
2

Robert Czechowski's avatar
Robert Czechowski committed
3 4 5 6 7
[![crates.io](https://img.shields.io/crates/v/medal?color=orange)](https://crates.io/crates/medal)
[![documentation](https://img.shields.io/crates/v/medal?label=docs)](https://jim.test.bwinf.de/doc/medal/)
[![pipeline](https://git.bwinf.de/bwinf/medal/badges/master/pipeline.svg)](https://git.bwinf.de/bwinf/medal/-/pipelines)
[![License: AGPL3](https://img.shields.io/crates/l/medal?color=green)](LICENSE)

Robert Czechowski's avatar
Robert Czechowski committed
8 9
Medal is a small platform for in-browser running contest written in rust.

10
It is designed for the German "Jugendwettbewerb Informatik", a computer science contest with tasks using Google Blockly as a programming language-replacement.
Robert Czechowski's avatar
Robert Czechowski committed
11

12
Try it out on https://jwinf.de/!
Robert Czechowski's avatar
Robert Czechowski committed
13 14 15 16


## Translation

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
Currently there is no translation framework built into medal, but it is high on our todo list.

If you want to translate the platform or parts of it into another language, don't hesitate to let us know by opening a ticket or writing an email to jugendwettbewerb [a.t] bwinf.de.


## Folder structure (administration)

### `tasks/`

Contains all the tasks files and the contests.

Tasks are HTML files that are served directly and can reference other files (CSS, JS, images).

Contest are YAML files following a certain structure (see src/contestreader_yaml.rs). Upon start of the platform, the whole tasks directory and all subdirectories are scanned for .yaml files and every .yaml file is parsed as contest and inserted into the database or updated (if the filename stays the same).

#### `tasks/jwinf/` (using FIOI tasks)

In order to use the france-ioi-style tasks that are used on https://jwinf.de/, the wrappers files in `tasks/jwinf/` have to be used in contest definitions to wrap the tasks and allow for communication between task an plattform.
Robert Czechowski's avatar
Robert Czechowski committed
35

36
Also the repository https://github.com/France-ioi/bebras-modules.git has to be checked out, since the tasks depend on it. Usually it should be checked out at `tasks/jwinf/_common/modules`.
Robert Czechowski's avatar
Robert Czechowski committed
37

38
#### `tasks/teacher/`
Robert Czechowski's avatar
Robert Czechowski committed
39

40
The directory `tasks/teacher/` can contain an `index.html` file. This file is presented to teachers in the teacher area of the platfrom (in an iframe). Further sites or documents can be linked from it.
Robert Czechowski's avatar
Robert Czechowski committed
41 42


43 44 45 46 47 48 49 50
### `templates/`

The folder `templates/` contains the different template sets. The template set can be selected in `config.json` or via command line parameter. By default, the template set `default/` is chosen.

### `config.json`

The `config.json` configures the plattform (see src/config.rs).

Robert Czechowski's avatar
Robert Czechowski committed
51
## Running Medal
52

53
Needs `rustc` and `cargo` 1.40 (stable) or higher.
54

Robert Czechowski's avatar
Robert Czechowski committed
55
Rust can be obtained here: https://rustup.rs/
56

Robert Czechowski's avatar
Robert Czechowski committed
57
Running
58 59 60 61 62
```
make
```
compiles and runs a debug-/test-server.

Robert Czechowski's avatar
Robert Czechowski committed
63
For production use, a release binary should be compiled and served behind a reverse proxy (nginx, apache, …).
64 65 66 67 68 69 70
```
make release
```
compiles a release build with openssl statically linked for distribution.

The directories `tasks/` and `static/` can (and for throughput-purposes should) be served by the reverse proxy directly.

71 72
## Deploy

73 74 75 76 77 78 79 80 81 82 83
It is recommended to run the platform behind a reverse proxy, that is serving static files directly. However, the contest YAML files should not be served to the user!

The following configuration can be used for an Nginx webserver:

```
upstream medal {
  server [::1]:8000;
}

server {
  # Other server settings here
Robert Czechowski's avatar
Robert Czechowski committed
84

85 86 87 88 89 90 91 92 93 94
  location ~* \.(yaml)$ {
    deny all;
  }

  location /static {
    add_header Cache-Control "public, max-age=604800";
  }

  location /tasks {
    add_header Cache-Control "public, max-age=604800";
Robert Czechowski's avatar
Robert Czechowski committed
95
  }
96 97 98 99 100

  location / {
    proxy_pass http://medal;
  }
```
101 102 103 104 105 106 107

The following configuration can be used for an Apache 2.4 webserver:

```
  ServerSignature Off
  ProxyPreserveHost On
  AllowEncodedSlashes NoDecode
Robert Czechowski's avatar
Robert Czechowski committed
108

109 110 111 112 113
  ProxyPass /static/ !
  ProxyPass /tasks/ !
  ProxyPass /favicon.ico !
  ProxyPass / http://[::1]:8080/
  ProxyPassReverse / http://[::1]:8080/
Robert Czechowski's avatar
Robert Czechowski committed
114

115 116 117 118
  Alias "/tasks/" "/path/to/medal/tasks/"
  Alias "/static/" "/path/to/medal/static/"
  Alias "/favicon.ico" "/path/to/medal/static/images/favicon.png"

119
  <filesMatch "\.(css|jpe?g|png|gif|js|ico)$">
120 121
    Header set Cache-Control "max-age=604800, public"
  </filesMatch>
Robert Czechowski's avatar
Robert Czechowski committed
122

123 124 125
  <FilesMatch "\.yaml$">
    Deny from all
  </FilesMatch>
126 127 128 129

  <Directory "/path/to/medal/static/">
    Require all granted
  </Directory>
Robert Czechowski's avatar
Robert Czechowski committed
130

131 132 133 134 135
  <Directory "/path/to/medal/tasks/">
    Require all granted
  </Directory>
```

136 137


138 139 140 141
## Contributing

Please format your code with `rustfmt` and check it for warnings with `clippy`.

Robert Czechowski's avatar
Robert Czechowski committed
142
You can install those with
143
```
144
rustup component add rustfmt --toolchain nightly
145 146 147 148 149
rustup component add clippy
```

Format the code and check for warnings with
```
150
make format
151 152
make clippy
```
153

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
## Folder structure (development)

### `migrations/`

Contains all the database migrations. New database migrations are applied when the platform is started. This can be disabled in the config or via command line switch.

### `src/`
#### `src/main.rs`

Entry point of the program and contains all integration tests.

#### `src/core.rs`

The core logic of all http endpoint.

#### `src/webfw_iron.rs`

Connects the core logic to the webframework (in this case `iron`).

#### `src/db_conn.rs`, `src/db_objects.rs`

Provides a database abstraction for the core logic.

#### `src/db_conn_*.rs`

Implement the database abstraction for different database types.
180

181
The files `src/db_conn_*.rs` are generated by `generate_connectors.sh` from `src/db_conn.base.rs` and `src/db_conn_*.header.rs`.
182

183
#### Other
184

185 186 187 188
  * `helpers.rs` small helper functions
  * `config.rs` parse config file
  * `contestreader_yaml.rs` parse contest files
  * `db_apply_migrations.rs` read `migrations/` directory and apply found files to migration functions of db connectors