Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
19135364ff | |||
0e6f6058a0 | |||
5ff7354dc5 |
104
README.md
104
README.md
@ -0,0 +1,104 @@
|
|||||||
|
# ICPC-WEBPRINT
|
||||||
|
|
||||||
|
This platform helps contest participants to print their code using no drivers, only web application in any browser. Supports authorization, printing PDF for administrators and teachers.
|
||||||
|
|
||||||
|
Platform was already used on some events, like "The FPMI Cup : February, 2025" and "MIPT Open Programming Championship : April, 2025".
|
||||||
|
|
||||||
|
## Instalation
|
||||||
|
### Environment and Service
|
||||||
|
Both RX and TX servers have the same way to install dependencies. First, be sure to have venv globally installed on your system:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt install python3-venv
|
||||||
|
# or
|
||||||
|
python3 -m pip install venv
|
||||||
|
```
|
||||||
|
|
||||||
|
After that create virtual environment:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd print-tx # and then print-rx
|
||||||
|
python3 -m venv .venv
|
||||||
|
```
|
||||||
|
|
||||||
|
Enter environment and install dependencies from `requirements.txt`:
|
||||||
|
|
||||||
|
```
|
||||||
|
source .venv/bin/activate
|
||||||
|
python3 -m pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
Great! Now you have working system. You can start your project either running
|
||||||
|
```
|
||||||
|
python3 -m gunicorn wsgi_back:app -c gunicorn.py
|
||||||
|
```
|
||||||
|
in venv, or creating services on your Linux. Template could be found in `example.serivce` file. After that you can start your web app with running:
|
||||||
|
```
|
||||||
|
systemctl start example.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting Secrets
|
||||||
|
|
||||||
|
Change secret code, that is used to access RX server from TX in `server-tx.json` and `server-rx.json`.
|
||||||
|
Change salt and session secret key in `server-tx/app/config.py`:
|
||||||
|
```
|
||||||
|
_SALT = '$2b$12$DE09JKsqy6Ii/zAxEAA5n.' #edit
|
||||||
|
_SECRET_SESSION_KEY = "GAZAKBAYEV-AHMET-PROJECT" #edit
|
||||||
|
```
|
||||||
|
You can also to set super admin user (it can add and remove others):
|
||||||
|
```
|
||||||
|
_SUPER_ADMINS = ( #edit
|
||||||
|
"god"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Accounts with login:password like "god:god" will be checked and created if not exist, when application start.
|
||||||
|
|
||||||
|
### Setting ports
|
||||||
|
|
||||||
|
You can set port of TX part in file `gunicorn.py`, and RX part in config file `server-rx.json`. Using TX interface, in admin panel, you can configure RX server and get `server-rx.json` to load it.
|
||||||
|
|
||||||
|
### Setting default printer
|
||||||
|
|
||||||
|
Learn more about `lp` service in Linux ([Wiki](https://ru.wikipedia.org/wiki/Lp)).
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Four groups: Super Admin, Admin (create and remove users, set configuration), Tutor (print PDF and code), Team Member (default, print only code)
|
||||||
|
- Print code & PDF
|
||||||
|
- Create & Delete users
|
||||||
|
- Statistic of printed pages & last printing time of member
|
||||||
|
- Setting RX server using UI
|
||||||
|
- Setting TX configuration: PDF Watermark and limits.
|
||||||
|
|
||||||
|
## Setting user group
|
||||||
|
|
||||||
|
Groups are just team names! Use `$root` for Admins, `$tutor$` for Teachers and other names for members.
|
||||||
|
|
||||||
|
## Interface
|
||||||
|
|
||||||
|
### Team Member
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Tutor
|
||||||
|

|
||||||
|
|
||||||
|
### Админ Панель
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Создание и Редактирование пользователя
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Просмотреть данную галерею можно на [NextCloud](https://cloud.gazakbayev.net/index.php/s/gqzmo9S8KFGcQLi?dir=/) автора.
|
20
example.service
Normal file
20
example.service
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# NOTICE! Replace PATH_TO_SCRIPT with required directory!
|
||||||
|
# Paste content of this file into /etc/systemd/system/YOUR_NAME.service
|
||||||
|
#
|
||||||
|
|
||||||
|
# Suggested names for service: print-rx.service & print-tx.server
|
||||||
|
# REMEMBER to create virtual environment before using script (read README.md)
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Print Server TX/RX server script.
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
WorkingDirectory=PATH_TO_SCRIPT
|
||||||
|
ExecStart=PATH_TO_SCRIPT/.venv/bin/gunicorn wsgi_back:app -c gunicorn.py
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -29,6 +29,8 @@ def get_app():
|
|||||||
from app._tools.database import DataManager
|
from app._tools.database import DataManager
|
||||||
from app._tools.database import SessionManager
|
from app._tools.database import SessionManager
|
||||||
DataManager.init_table()
|
DataManager.init_table()
|
||||||
|
DataManager.check_admins()
|
||||||
SessionManager.init_table()
|
SessionManager.init_table()
|
||||||
|
|
||||||
|
|
||||||
return app
|
return app
|
@ -4,12 +4,15 @@ import json
|
|||||||
|
|
||||||
from app._tools.models.user import User
|
from app._tools.models.user import User
|
||||||
from app._tools.models.session import Session
|
from app._tools.models.session import Session
|
||||||
|
from app._tools import passhash as Hash
|
||||||
|
|
||||||
from app.config import _USER_DATABASE as U_DB_PATH
|
from app.config import _USER_DATABASE as U_DB_PATH
|
||||||
from app.config import _TOKEN_DATABASE as T_DB_PATH
|
from app.config import _TOKEN_DATABASE as T_DB_PATH
|
||||||
from app.config import _SERVER_CONFIG as S_CFG_PATH
|
from app.config import _SERVER_CONFIG as S_CFG_PATH
|
||||||
from app.config import _SCHEMA_USERS as SCHEMA_USERS
|
from app.config import _SCHEMA_USERS as SCHEMA_USERS
|
||||||
from app.config import _SCHEMA_TOKENS as SCHEMA_TOKENS
|
from app.config import _SCHEMA_TOKENS as SCHEMA_TOKENS
|
||||||
|
from app.config import _SUPER_ADMINS as SUPER_ADMINS
|
||||||
|
from app.config import _SALT as SALT
|
||||||
|
|
||||||
class ConnectManager:
|
class ConnectManager:
|
||||||
def __init__(self, db_file : str):
|
def __init__(self, db_file : str):
|
||||||
@ -96,6 +99,16 @@ class DataManager:
|
|||||||
c_man = ConnectManager(U_DB_PATH)
|
c_man = ConnectManager(U_DB_PATH)
|
||||||
c_man.execute(SCHEMA_USERS, close_connection = False)
|
c_man.execute(SCHEMA_USERS, close_connection = False)
|
||||||
c_man.execute("VACUUM;")
|
c_man.execute("VACUUM;")
|
||||||
|
def check_admins():
|
||||||
|
for k in SUPER_ADMINS:
|
||||||
|
if DataManager.get_user_by_name(k) == None:
|
||||||
|
DataManager.add_user(
|
||||||
|
k,
|
||||||
|
"$root$",
|
||||||
|
"Super Admin",
|
||||||
|
Hash.hashPassword(k, SALT)
|
||||||
|
)
|
||||||
|
print(f"Create super admin {k} with password {k}")
|
||||||
def get_user_by_name(username : str) -> User:
|
def get_user_by_name(username : str) -> User:
|
||||||
c_man = ConnectManager(U_DB_PATH)
|
c_man = ConnectManager(U_DB_PATH)
|
||||||
data = c_man.execute(
|
data = c_man.execute(
|
||||||
|
@ -8,7 +8,7 @@ _USER_DATABASE = "databases/users.db" #default
|
|||||||
_TOKEN_DATABASE = "databases/tokens.db" #default
|
_TOKEN_DATABASE = "databases/tokens.db" #default
|
||||||
_SERVER_CONFIG = "server-tx.json" #default
|
_SERVER_CONFIG = "server-tx.json" #default
|
||||||
_SALT = '$2b$12$DE09JKsqy6Ii/zAxEAA5n.' #edit
|
_SALT = '$2b$12$DE09JKsqy6Ii/zAxEAA5n.' #edit
|
||||||
_SECRET_SESSION_KEY = "fpmi_cup_event_2025_by_MMCFPMI_developed_by_gallahad_ru_Welcomeee!!!" #edit
|
_SECRET_SESSION_KEY = "GAZAKBAYEV-AHMET-PROJECT" #edit
|
||||||
_SUPER_ADMINS = ( #edit
|
_SUPER_ADMINS = ( #edit
|
||||||
"god"
|
"god"
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user