321 lines
12 KiB
Markdown
321 lines
12 KiB
Markdown
LQDOJ: Le Quy Don Online Judge
|
|
===
|
|
|
|
[![](https://github.com/DMOJ/online-judge/workflows/build/badge.svg)](https://lqdoj.edu.vn/)
|
|
[![Python](https://img.shields.io/pypi/pyversions/tensorflow.svg?style=plastic)](https://python.org)
|
|
[![OS](https://img.shields.io/badge/Ubuntu-16.04%20%7C%2018.04%20%7C%2020.04-brightgreen)](https://ubuntu.com/download)
|
|
[![License](https://img.shields.io/badge/license-AGPL--3.0-blue)](https://www.gnu.org/licenses/agpl-3.0.en.html)
|
|
|
|
## Overview
|
|
|
|
Homepage: [https://lqdoj.edu.vn](https://lqdoj.edu.vn)
|
|
|
|
Based on [DMOJ](https://dmoj.ca/).
|
|
|
|
Supported languages:
|
|
|
|
- Assembly (x64)
|
|
- AWK
|
|
- C
|
|
- C++03 / C++11 / C++14 / C++17 / C++20
|
|
- Java 11
|
|
- Pascal
|
|
- Perl
|
|
- Python 2 / Python 3
|
|
- PyPy 2 / PyPy 3
|
|
|
|
Support plagiarism detection via [Stanford MOSS](https://theory.stanford.edu/~aiken/moss/).
|
|
|
|
## Installation
|
|
|
|
Most of the setup are the same as DMOJ installations. You can view the installation guide of DMOJ here: https://docs.dmoj.ca/#/site/installation.
|
|
There is one minor change: Instead of `git clone https://github.com/DMOJ/site.git`, you clone this repo `git clone https://github.com/LQDJudge/online-judge.git`.
|
|
|
|
|
|
- Bước 1: cài các thư viện cần thiết
|
|
- $ ở đây nghĩa là sudo. Ví dụ dòng đầu nghĩa là chạy lệnh `sudo apt update`
|
|
|
|
```jsx
|
|
$ apt update
|
|
$ apt install git gcc g++ make python3-dev python3-pip libxml2-dev libxslt1-dev zlib1g-dev gettext curl redis-server
|
|
$ curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
|
$ apt install nodejs
|
|
$ npm install -g sass postcss-cli postcss autoprefixer
|
|
```
|
|
|
|
- Bước 2: tạo DB
|
|
- Server đang dùng MariaDB ≥ 10.5, các bạn cũng có thể dùng Mysql nếu bị conflict (anh chưa test version rõ lắm)
|
|
- Nếu các bạn chạy lệnh dưới này xong mà version mariadb bị cũ (< 10.5) thì có thể tra google cách cài MariaDB mới nhất (10.5 hoặc 10.6).
|
|
- Các bạn có thể thấy version MariaDB bằng cách gõ lệnh `sudo mysql` (Ctrl + C để quit)
|
|
|
|
```jsx
|
|
$ apt update
|
|
$ apt install mariadb-server libmysqlclient-dev
|
|
```
|
|
|
|
- Bước 3: tạo table trong DB
|
|
- Các bạn có thể thay tên table và password
|
|
|
|
```jsx
|
|
$ sudo mysql
|
|
mariadb> CREATE DATABASE dmoj DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
|
|
mariadb> GRANT ALL PRIVILEGES ON dmoj.* TO 'dmoj'@'localhost' IDENTIFIED BY '<password>';
|
|
mariadb> exit
|
|
```
|
|
|
|
- Bước 4: Cài đặt môi trường ảo (virtual env) và pull code
|
|
- Nếu `pip3 install mysqlclient` bị lỗi thì thử chạy `sudo pip3 install mysqlclient==2.1.1`
|
|
|
|
```jsx
|
|
$ python3 -m venv dmojsite
|
|
$ . dmojsite/bin/activate
|
|
|
|
(dmojsite) $ git clone https://github.com/LQDJudge/online-judge.git
|
|
(dmojsite) $ cd online-judge
|
|
(dmojsite) $ git submodule init
|
|
(dmojsite) $ git submodule update
|
|
(dmojsite) $ pip3 install -r requirements.txt
|
|
(dmojsite) $ pip3 install mysqlclient
|
|
(dmojsite) $ pre-commit install
|
|
```
|
|
|
|
- Bước 5: tạo local_settings.py. Đây là file để custom setting cho Django. Các bạn tạo file vào `online-judge/dmoj/local_settings.py`
|
|
- File mẫu: https://github.com/DMOJ/docs/blob/master/sample_files/local_settings.py
|
|
- Nếu bạn đổi tên hoặc mật khẩu table databases thì thay đổi thông tin tương ứng trong `Databases`
|
|
- Sau khi xong, chạy lệnh `(dmojsite) $ python3 manage.py check` để kiểm tra
|
|
- Bước 6: Compile CSS và translation
|
|
- Giải thích:
|
|
- Lệnh 1 và 2 gọi sau mỗi lần thay đổi 1 file css hoặc file js (file html thì không cần)
|
|
- Lệnh 3 và 4 gọi sau mỗi lần thay đổi file dịch
|
|
- Note: Sau khi chạy lệnh này, folder tương ứng với STATIC_ROOT trong local_settings phải được tạo. Nếu chưa được tạo thì mình cần tạo folder đó trước khi chạy 2 lệnh đầu.
|
|
|
|
```jsx
|
|
(dmojsite) $ ./make_style.sh
|
|
(dmojsite) $ python3 manage.py collectstatic
|
|
(dmojsite) $ python3 manage.py compilemessages
|
|
(dmojsite) $ python3 manage.py compilejsi18n
|
|
```
|
|
|
|
- Bước 7: Thêm dữ liệu vào DB
|
|
|
|
```jsx
|
|
(dmojsite) $ python3 manage.py migrate
|
|
(dmojsite) $ python3 manage.py loaddata navbar
|
|
(dmojsite) $ python3 manage.py loaddata language_small
|
|
(dmojsite) $ python3 manage.py loaddata demo
|
|
```
|
|
|
|
- Bước 8: Chạy site. Đến đây thì cơ bản đã hoàn thành (chưa có judge, websocket, celery). Các bạn có thể truy cập tại `localhost:8000`
|
|
|
|
```jsx
|
|
python3 manage.py runserver 0.0.0.0:8000
|
|
```
|
|
|
|
**Một số lưu ý:**
|
|
|
|
1. (WSL) có thể tải ứng dụng Terminal trong Windows Store
|
|
2. (WSL) mỗi lần mở ubuntu, các bạn cần chạy lệnh sau để mariadb khởi động: `sudo service mysql restart` (tương tự cho một số service khác như memcached, celery)
|
|
3. Sau khi cài đặt, các bạn chỉ cần activate virtual env và chạy lệnh runserver là ok.
|
|
|
|
```jsx
|
|
. dmojsite/bin/activate
|
|
python3 manage.py runserver
|
|
```
|
|
|
|
1. Quy trình dev:
|
|
1. Sau khi thay đổi code thì django tự build lại, các bạn chỉ cần F5
|
|
2. Một số style nằm trong các file .scss. Các bạn cần recompile css thì mới thấy được thay đổi.
|
|
|
|
**Optional:**
|
|
|
|
************Alias:************ Các bạn có thể lưu các alias này để sau này dùng cho nhanh
|
|
|
|
- mtrans: để generate translation khi các bạn add một string trong code
|
|
- trans: compile translation (sau khi bạn đã dịch tiếng Việt)
|
|
- cr: chuyển tới folder OJ
|
|
- pr: chạy server
|
|
- sm: restart service (chủ yếu dùng cho WSL)
|
|
- sd: activate virtual env
|
|
- css: compile các file css
|
|
|
|
```jsx
|
|
alias mtrans='python3 manage.py makemessages -l vi && python3 manage.py makedmojmessages -l vi'
|
|
alias pr='python3 manage.py runserver'
|
|
alias sd='source ~/LQDOJ/dmojsite/bin/activate'
|
|
alias sm='sudo service mysql restart && sudo service redis-server start && sudo service memcached start'
|
|
alias trans='python3 manage.py compilemessages -l vi && python3 manage.py compilejsi18n -l vi'
|
|
alias cr='cd ~/LQDOJ/online-judge'
|
|
alias css='./make_style.sh && python3 manage.py collectstatic --noinput'
|
|
```
|
|
|
|
**Memcached:** dùng cho in-memory cache
|
|
|
|
```jsx
|
|
$ sudo apt install memcached
|
|
```
|
|
|
|
**Websocket:** dùng để live update (như chat)
|
|
|
|
- Tạo file online-judge/websocket/config.js
|
|
|
|
```jsx
|
|
module.exports = {
|
|
get_host: '127.0.0.1',
|
|
get_port: 15100,
|
|
post_host: '127.0.0.1',
|
|
post_port: 15101,
|
|
http_host: '127.0.0.1',
|
|
http_port: 15102,
|
|
long_poll_timeout: 29000,
|
|
};
|
|
```
|
|
|
|
- Cài các thư viện
|
|
|
|
```jsx
|
|
(dmojsite) $ npm install qu ws simplesets
|
|
(dmojsite) $ pip3 install websocket-client
|
|
```
|
|
|
|
- Khởi động (trong 1 tab riêng)
|
|
|
|
```jsx
|
|
(dmojsite) $ node websocket/daemon.js
|
|
```
|
|
|
|
**************Celery:************** (dùng cho một số task như batch rejudge_
|
|
|
|
```jsx
|
|
celery -A dmoj_celery worker
|
|
```
|
|
|
|
**************Judge:**************
|
|
|
|
- Cài đặt ở 1 folder riêng bên ngoài site:
|
|
|
|
```jsx
|
|
$ apt install python3-dev python3-pip build-essential libseccomp-dev
|
|
$ git clone https://github.com/LQDJudge/judge-server.git
|
|
$ cd judge-server
|
|
$ sudo pip3 install -e .
|
|
```
|
|
|
|
- Tạo một file judge.yml ở bên ngoài folder judge-server (file mẫu https://github.com/DMOJ/docs/blob/master/sample_files/judge_conf.yml)
|
|
- Thêm judge vào site bằng UI: Admin → Judge → Thêm Judge → nhập id và key (chỉ cần thêm 1 lần) hoặc dùng lệnh `(dmojsite) $ python3 managed.py addjudge <id> <key>`.
|
|
- Chạy Bridge (cầu nối giữa judge và site) trong 1 tab riêng trong folder online-judge:
|
|
|
|
```jsx
|
|
(dmojsite) $ python3 managed.py runbridged
|
|
```
|
|
|
|
- Khởi động Judge (trong 1 tab riêng):
|
|
|
|
```jsx
|
|
$ dmoj -c judge.yml localhost
|
|
```
|
|
|
|
- Lưu ý: mỗi lần sau này muốn chạy judge thì mở 1 tab cho bridge và n tab cho judge. Mỗi judge cần 1 file yml khác nhau (chứa authentication khác nhau)
|
|
|
|
### Some frequent difficulties when installation:
|
|
|
|
1. Missing the `local_settings.py`. You need to copy the `local_settings.py` in order to pass the check.
|
|
2. Missing the problem folder in `local_settings.py`. You need to create a folder to contain all problem packages and configure in `local_settings.py`.
|
|
3. Missing static folder in `local_settings.py`. Similar to problem folder, make sure to configure `STATIC_FILES` inside `local_settings.py`.
|
|
4. Missing configure file for judges. Each judge must have a seperate configure file. To create this file, you can run `python dmojauto-conf`. Checkout all sample files here https://github.com/DMOJ/docs/blob/master/sample_files.
|
|
5. Missing timezone data for SQL. If you're using Ubuntu and you're following DMOJ's installation guide for the server, and you are getting the error mentioned in https://github.com/LQDJudge/online-judge/issues/45, then you can follow this method to fix:
|
|
```
|
|
mysql
|
|
-- You may have to do this if you haven't set root password for MySQL, replace mypass with your password
|
|
-- SET PASSWORD FOR 'root'@'localhost' = PASSWORD('mypass');
|
|
-- FLUSH PRIVILEGES;
|
|
exit
|
|
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -D mysql -u root -p
|
|
mysql -u root -p -e "flush tables;" mysql
|
|
```
|
|
6. Missing the chat secret key, you must generate a Fernet key, and assign a variable in `local_settings.py` like this
|
|
```python
|
|
CHAT_SECRET_KEY = "81HqDtbqAywKSOumSxxxxxxxxxxxxxxxxx="
|
|
```
|
|
|
|
|
|
## Usage
|
|
|
|
Suppose you finished all the installation. Everytime you want to run a local server, follow these steps:
|
|
|
|
1. Activate virtualenv:
|
|
```bash
|
|
source dmojsite/bin/activate
|
|
```
|
|
|
|
2. Run server:
|
|
```bash
|
|
python3 manage.py runserver 0.0.0.0:8000
|
|
```
|
|
|
|
3. Create a bridge (this is opened in a different terminal with the second step if you are using the same machine)
|
|
```bash
|
|
python3 manage.py runbridged
|
|
```
|
|
|
|
4. Create a judge (another terminal)
|
|
```bash
|
|
dmoj 0.0.0.0 -p 9999 -c <path to yml configure file>
|
|
```
|
|
Here we suppose you use the default port 9999 for bridge in `settings.py`. You can create multiple judges, each should be in a seperate terminal.
|
|
|
|
**Optional**
|
|
|
|
5. Run celery worker (This is server's queue. It may be necessary in some functions)
|
|
```bash
|
|
celery -A dmoj_celery worker
|
|
```
|
|
|
|
6. Run a live event server (So everything is updated lively like in the production)
|
|
```bash
|
|
node websocket/daemon.js
|
|
```
|
|
|
|
7. To use subdomain for each organization, go to admin page -> navigation bar -> sites, add domain name (e.g, "localhost:8000"). Then go to add `USE_SUBDOMAIN = True` to local_settings.py.
|
|
|
|
## Deploy
|
|
Most of the steps are similar to Django tutorials. Here are two usual steps:
|
|
|
|
1. Update vietnamese translation:
|
|
- If you add any new phrases in the code, ```python3 manage.py makemessages```
|
|
- go to `locale/vi`
|
|
- modify `.po` file
|
|
- ```python3 manage.py compilemessages```
|
|
- ```python3 manage.py compilejsi18n```
|
|
|
|
2. Update styles (using SASS)
|
|
- Change .css/.scss files in `resources` folder
|
|
- ```./make_style.sh && python3 manage.py collectstatic```
|
|
- Sometimes you need to press `Ctrl + F5` to see the new user interface in browser.
|
|
|
|
## Screenshots
|
|
|
|
### Leaderboard
|
|
|
|
Leaderboard with information about contest rating, performance points and real name of all users.
|
|
|
|
![](https://raw.githubusercontent.com/emladevops/LQDOJ-image/main/brave_SK67WA26FA.png#gh-light-mode-only)
|
|
![](https://raw.githubusercontent.com/emladevops/LQDOJ-image/main/brave_cmqqCnwaFc.png#gh-dark-mode-only)
|
|
|
|
### Admin dashboard
|
|
|
|
Admin dashboard helps you easily managing problems, users, contests and blog posts.
|
|
|
|
![](https://i.imgur.com/iccr3mh.png)
|
|
|
|
### Statement editor
|
|
|
|
You can write the problems' statement in Markdown with LaTeX figures and formulas supported.
|
|
|
|
![](https://i.imgur.com/CQVC754.png)
|
|
|
|
### Chat
|
|
|
|
Users can communicate with each other and can see who's online.
|
|
|
|
![](https://raw.githubusercontent.com/emladevops/LQDOJ-image/main/brave_kPsC5bJluc.png#gh-light-mode-only)
|
|
![](https://raw.githubusercontent.com/emladevops/LQDOJ-image/main/brave_AtrEzXzEAx.png#gh-dark-mode-only)
|