docker 搭建 hustoj
hustoj 是個GPL開源的OJ,其提供了docker形式的安裝方式。
為執行方便,選擇使用aliyun提供的docker鏡像來加速安裝。
拉取鏡像
docker pull registry.cn-shanghai.aliyuncs.com/shiningrise/hustoj
執行鏡像
docker run -d -it --name hustoj -p 9900:80 --privileged registry.cn-shanghai.aliyuncs.com/shiningrise/hustoj:latest
9900 是物理機針對docker image 80端口的映射。
訪問本機如下地址即可開始使用 hustoj
http://127.0.0.1:9900
下載題庫
https://github.com/zhblue/freeproblemset/
提供了免費的題庫下載,如果覺得不夠用,
還可以去 http://tk.hustoj.com/ 作者提供的付費網站下載更多。
使用本地磁盤volumn
docker因為每次啟動都是全新,為持久化,可以掛載一個本地目錄給docker image。
標准執行方式
docker run -d -it \
-v /data/docker/docker-wxy/data:/data \
--privileged \
--name hustoj \
-p 80:80 shiningrise/hustoj:latest
docker測試安裝
docker run -d -it --name hustoj -p 80:80 --privileged shiningrise/hustoj:latest
僅安裝C++版本
docker run -d -it --name hustoj -p 80:80 --privileged shiningrise/hustoj:cpp
執行docker shell
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f111112222333 registry.cn-shanghai.aliyuncs.com/shiningrise/hustoj:latest "/usr/local/bin/dock…" About an hour ago Up About an hour 0.0.0.0:9900->80/tcp hustoj
docker exec -it f111112222333 bash ## f111112222333 是當前docker 映像執行的實例id
進去之后可以通過 mysql 執行數據庫操作等。
hustoj 配置其它語言
https://blog.csdn.net/yybird_/article/details/46050023
配置python
python默認即支持,但,有一些詭異的小地方。
默認執行py是使用py3
需要在開頭注釋寫個 # python2
才行
主要judge_client會讀取源碼,通過如下語句判斷py是何種版本:
void run_solution(int & lang, char * work_dir, int & time_lmt, int & usedtime,
int & mem_lmt) {
nice(19);
int py2=execute_cmd("/bin/grep 'python2' Main.py");
// now the user is "judger"
chdir(work_dir);
....
if(!py2){
execl("/python2", "/python2", "Main.py", (char *) NULL);
}else{
execl("/python3", "/python3", "Main.py", (char *) NULL);
}
配置golang
To be done
源碼閱讀
hustoj 的模塊拆分很清晰:
- web // php后端邏輯 + html/css/js前端
- core 判題邏輯模塊
- judged 判題后台服務
- judge_client 判題工作模塊
- shim 源碼相似度檢查(據說是外部引入)
修改源碼去除公告
為方便理解源碼,也方便自己使用搭建的oj,引入一個小任務,去除晃眼的公告。
看到公告,第一反應是,先用chrome開發工具台找到飄來飄去的元素ID。它叫 <marquee>
。
搜下源碼,看到在 contest-header.php
里面有涉及。
直接注掉 $view_marquee_msg
相關部分。
<?php
// php-comment
// $view_marquee_msg=file_get_contents($OJ_SAE?"saestor://web/msg.txt":"./admin/msg.txt");
?>
<!-- html
<div id=broadcast>
<marquee id=broadcast scrollamount=1 direction=up scrolldelay=250 onMouseOver='this.stop()' onMouseOut='this.start()';>
<?php echo $view_marquee_msg?>
</marquee>
</div>
-->
點擊頁面,依然沒搞定。
再找,發現 template/bs3/js.php
里面才是真正生成消息元素的部分。
<?php
if(file_exists("./admin/msg.txt"))
$view_marquee_msg=file_get_contents($OJ_SAE?"saestor://web/msg.txt":"./admin/msg.txt");
if(file_exists("../admin/msg.txt"))
$view_marquee_msg=file_get_contents($OJ_SAE?"saestor://web/msg.txt":"../admin/msg.txt");
?>
<script>
$(document).ready(function(){
var msg="<marquee style='margin-top:10px' id=broadcast direction='up' scrollamount=3 scrolldelay=50 onMouseOver='this.stop()'"+
" onMouseOut='this.start()' class=toprow>"+<?php echo json_encode($view_marquee_msg); ?>+"</marquee>";
$(".jumbotron").prepend(msg);
$("form").append("<div id='csrf' />");
$("#csrf").load("<?php echo $path_fix?>csrf.php");
$("body").append("<div id=footer class=center >GPLv2 licensed by <a href='https://github.com/zhblue/hustoj' >HUSTOJ</a> "+(new Date()).getFullYear()+" </div>");
$("body").append("<div class=center > <img src='http://hustoj.com/wx.jpg' width='96px'><img src='http://hustoj.com/alipay.png' width='96px'><br> 歡迎關注微信公眾號onlinejudge</div>");
});
///// .... 省略
</script>
將上面的php和js都給注掉,搞定。
源碼理解
php 部分為方便理解,大概可以拆分如下2個模塊:
- 用戶界面
- admin界面
為方便自定義,同時穿插了一套簡單的主題模塊。
即,所有的css、js等前端相關,都使用了如下幾個模板來嵌套。
- bs bootstrap2?
- bs3 bootstrap3
- classic 經典款
- ie IE兼容
- sae 新浪SAE模式
而php則通過主要的配置文件 include/db_info.inc.php
來指導工作。