我最近养了一只dragon,但是这只dragon有一些脑残,而且不太会说人话。
这是一个体系。
一个用django框架,python+html语言写成的,功能简单而且非常无聊的,只有智障才会用的辣鸡在线评测系统。
???你怎么还膨胀了?
你大概听不懂我在说什么,不过这并不重要。
为什么要写这个东西呢?那都要从一只叫犹豫激灵厕所亚香蕉牛奶终极恒的叽说起。
短一点的名字就是KuribohG神犇,这个OJ在github上的repo就是他的,
还有一位叫xuruifan的,就是id为gzotpa,绿色头像经常到我博客评论区刷屏然后被系统封号的神犇。两个都是NOI金牌爷,跟他们一比我简直是sb啊!哦,连比都不用比。
我们的分工?几乎所有看得见的东西都是我写的。主要后期这两个狗一直划水,不知道一天天在干些什么。
让我们先来看看这个OJ萌萌的界面。
不要吐槽界面丑!你给我钱请美工啊!?
说实话这个顶部header都是从UOJ上扒下来的,实在没有任何html基础……
我们不妨来看看它能够做什么。
作为一个OJ……它最最重要的功能,当然是卖萌交题辣!
很遗憾现在只资瓷C++……如果有好心人帮忙提供其他语言的编译器,那是坠吼的。
评测通过一个叫Lo-runner的东西进行,这大概是一个沙盒之类的东西,是github上的开源项目,作者lodevil。具体我并不太懂,请咨询叽神犇。不过也就是这个东西让我彻底放弃了在windows上写OJ的想法……
C++的评测机就是主目录下的judge.py。从github上可以看到,前期一直是他们俩写,一开始只有评测结果,后来我又加了结果统计和部分分。为了让界面更美观一些,我还将每个人题目列表中的题目增加了不同颜色,绿色代表AC过,红色代表有提交但是并没有AC。特别地,比赛进行时提交的题目一律为黄色。
听起来很高大上,如果你仔细查看template文件夹中的html代码……它们绝对丑到超乎你想象。不过能在网页中内嵌python代码也是很神奇啊。
好吧这个OJ确实有比赛系统,如果不是叽神犇强烈建议我估计我是不会写的……简直爆炸。
如下图。
首先每个比赛有开始和结束时间,这个时间格式转化就费了很大周折。
然后每个比赛相当于一个小型OJ,用户、比赛、提交什么的都需要重写……所以你现在能看到这一切并且听到我在这里讲解真是一个奇迹。
比赛的题目ID也是一大问题,有时候访问跳转网址不对会出错,一开始我们用了数字转字母的方式,后来为了防止比赛题目超过26道,就规定了比赛题目ID可以设置任意字符串。
比赛时只能看到提交,不能看到结果!代码长度也不行!Pending状态也不告诉你!你什么也不知道!
er…至少你知道了比赛时的提交是直接评测而不是统一评测。
然后这个比赛的Standings,本来是按最后一次非CE的提交算最终得分,但是似乎评测机也不能告诉你CE……所以还是统统算入,自己防作死吧。
然后我又智障一样想给成绩带来一点色彩感……
就像这样,比赛中自己提交过的题分数虽然看不到,但是能看到黄色,赛后看成绩能看到红色和绿色。结果就出了大问题……
获取分数需要在html里写脚本,但是这个脚本非常差,是一个长得很像python的辣鸡语言,python中的dict访问不能正常使用下标,只能用点,我需要在user的所有评测结果stat中找到这个problem的id对应的那一项,也就是user.stat.problem.id!
这个……stat是一个dict,所以其实应该是user.stat.(problem.id),但是这个括号显然是无法支持的!肿么办呢?
在被这个问题困扰了多天之后,我终于想到了办法,那就是使用大招,一个叫做template tags的玩意。
这个东西的神奇之处就在于它能够给这个非常差差差的html提供一个函数!很多受这个脚本限制解决不了的问题,通过调用函数解决,岂不美哉?
所以我专门为这个问题写了一个叫dot的template tag,然后刚才这个代码就可以写成user.stat|dot:problem.number,哈哈!当时感觉我机智得都要上天了。
到了contest阶段基本就是我一个人在写了,解决问题的能力几乎没有,所以效率奇低。这么简单的OJ估计有经验的一天就能写出来吧……
美中不足之处还是有的,比如Ranklist里所有人的通过提交比率都是666.00%,这个大概也可以写个template tag,但是可能存在保留小数的问题。我提议删除这个功能,但是叽神犇就是不同意,tmd真是一个……叽神犇说他并没有不同意,tmd真是一个……
还有一个问题就是提交代码者稍微用点黑科技就能把评测机关掉……现在没什么好办法,只能找出来后揍他一顿。
另外几个template tag:num2string是把数转成数字的字符串。num2letter是把1到26的数转换成对应的字母,现已弃用。djangomarkdown是在题目描述里使用markdown的,虽然代码换行存在问题……displaymarkdowncode是在查看代码时的代码高亮,其实就是在代码前后加几个“`”符号。这里感谢一下xuruifan对代码高亮做出的贡献……贴一下他的成果。
这个代码是我在UOJ上随便找的一个……只是为了测试一下效果。大概不会被原主看到吧。
说了这么多,这个OJ到底是如何工作的呢?
源码都在github上……想安装照着readme一步一步做就行了。/admin/页面就是管理后台,使用前需要先执行readme终端createsuperuser步骤创建管理员账号。虽然大概很多网站都把后台设置禁止访问了,但我并不知道怎么禁止。反正你们没有管理员账号啦啦啦
OJ现在分两大板块,主体和contest,这个在django里居然被称为app……每个app中起主要作用的文件有两个:views.py是页面文件,向html页面里传递一些变量,然后用那种什么也不支持的辣鸡python脚本访问。这就是动态页面的伟大之处!比我这个博客不知高明到哪里去了。models.py是模块文件,模块就是一个类,比如user,problem,submission,contest,里面很自然就有不同的成员变量和成员函数。我曾经把user的password显示在个人信息页面里,结果不知道为什么他们两个一起骂我。
另外两个文件夹,一个是mfpoj,里面主要改动的settings.py是控制引用django内置的一些东西,我只在实现使用页码的时候修改过一次,还有自己手写的template tags也要在这里声明才能使用。
还有几个url.py,当然是用来规定网址格式的,正则表达式什么的我可不会……照着抄一抄也可以。
大概就这些东西了,简单吧?
?????????
这个小傻龙一激动就犯病,胡言乱语,看我明天把它烤了吃。
实际上在真正使用的时候会遇到很多问题。readme中已经列举出了两个常见问题,其他问题可以请教网上大牛,内事问百度bing,外事问google。
如果遇到问题实在解决不了怎么办?这里有个好办法:
整个删除,重新clone!
er……关于这个服务器的问题,有一个东西叫什么apache好像可以用一用。但是我们三个中只有叽神犇成功用他的笔记本电脑开启了服务器,我们到学校的机房也开了服务器,只不过局域网IP只能内部访问,而我用大学的校园网尝试也失败了。鉴于现在没人有租ubuntu服务器的意向,这个mfpoj很遗憾就没有示例了……大家如果没有条件自己安装,就从图片当中欣赏和想象吧!
最后祝你