Handlers/ProblemListHandler.py
class ProblemListHandler(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(10)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):

        # oj=&problem_id=&problem_title=&problem_source=

        oj = self.get_argument('oj', '%')
        problem_id = self.get_argument('problem_id', '%')
        problem_title = self.get_argument('problem_title', '%')
        problem_source = self.get_argument('problem_source', '%')

        issearch = self.get_argument('issearch', None)

        index = self.get_argument('index', None)

        if issearch is not None:
            oj = str(oj).replace(' ', '%')
            problem_id = str(problem_id).replace(' ', '%')
            problem_title = str(problem_title).replace(' ', '%')
            problem_source = str(problem_source).replace(' ', '%')

            # rember cookie
            index = 0  # to avoid delay
            self.set_cookie('pl_index', '0')
            self.set_cookie('pl_oj', oj)
            self.set_cookie('pl_problem_id', problem_id)
            self.set_cookie('pl_problem_title', problem_title)
            self.set_cookie('pl_problem_source', problem_source)

        if index is None:
            index = self.get_cookie('pl_index', None)
            if index is None:
                self.set_cookie('pl_index', '0')
                index = self.get_cookie('pl_index')

        print('the index: ', index)

        d = dict()

        if len(oj) == 0 or oj == 'ALL': oj = '%'
        d['originOJ'] = oj
        if len(problem_id) == 0: problem_id = '%'
        d['originProb'] = problem_id
        if len(problem_source) == 0: problem_source = '%'
        d['source'] = problem_source
        if len(problem_title) == 0: problem_title = '%'
        d['title'] = problem_title

        print('oj:', oj, 'problem_id:', problem_id, 'problem_title:', problem_title, 'problem_source:', problem_source,
              'index:', index)

        uid = self.get_secure_cookie('uid',None)
        if uid is not None : uid = uid.decode()

        rs,ac,tr = yield self.getStauts(index, d, uid)

        # for r in rs : print(r)

        current_user = self.get_secure_cookie("username")
        if current_user is None: current_user = ''

        hasNext = True
        if len(rs) == 21:
            rs = rs[:-1]
        else:
            hasNext = False

        # print(hasNext)
        for key in d.keys():
            if d[key] == '%': d[key]=' '
            #print(key,'--->',d[key])


        self.render("problemList.html", current_user=current_user,tr=tr,ac=ac, rs=rs, hasNext=hasNext,d=d)

    @run_on_executor
    def getStauts(self, index, data, uid):
        # where clause

        whereclause = ''

        for key in data:
            if len(whereclause) != 0:
                whereclause = whereclause + ' and '
            whereclause = whereclause + key + ' LIKE "%' + data[key] + '%"'

        ordclause = 'originProb'

        if index == '%': index = '0'
        if index is None: index = '0'

        sql = getPageLimitSQL('problem', whereclause, ordclause, index, 21)

        print(sql)
        rs = FetchAll(sql)

        ac = list()

        tr = [0 for i in range(len(rs))]
        ac = [ 0 for i in range(len(rs))]
        if uid is None :
            pass
        else :
            '''
            for r in rs :
                x = CheckIfAccept(uid,r[0])
                ac.append(x)
            '''
            ac = [ 0 for i in range(len(rs))]
            for i in range(len(rs)) :
                if uid is not None :
                    ac[i] = CheckIfAccept(uid,rs[i][0])[0]
                    if ac[i]==1: tr[i]=1
                    else : tr[i] = CheckIfTry(uid,rs[i][0])[0]

        print('rs size: ', len(rs))

        '''
        ac = [ x[0] for x in ac ]
        tr = [ x[0] for x in tr ]
        '''

        return rs,ac,tr
Handlers/LogOutHandler.py
class LogOutHandler(tornado.web.RequestHandler):
    def post(self, *args, **kwargs):
        self.set_secure_cookie('username', '', 0)
        self.set_secure_cookie('uid', '', 0)
        self.write(renderMSG('LogOut Success'))
Handlers/CreateContestHandler.py
class CreateContestHandler(BaseHandler):
    executor = ThreadPoolExecutor(10)

    def get(self):
        self.get_current_user()
        if len(self.current_user) == 0:
            self.write(renderMSG('Please LogIn First!!'))
            return
        now = datetime.datetime.now()
        now = now + datetime.timedelta(minutes=10)

        self.render('createcontest.html', year=now.year, hour=now.hour, month=now.month, day=now.day, minute=now.minute)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        self.get_current_user()
        if len(self.current_user) == 0:
            self.write(renderMSG('Please LogIn First!!'))
            self.finish()
            return

        d = self.request.arguments
        for x in d: d[x] = d[x][0].decode()

        if self.check_args(d) == False:
            self.write(renderMSG('create fail some arguments miss'))
            self.finish()
            return

        uid = self.get_secure_cookie('uid').decode()
        data = self.getContestData(uid, d)

        if 'error' in data:
            self.write(data['error'])
            self.finish()
            return

        cid = yield self.CreateNewContest(data)

        self.MakePendingContestTempFile(cid, data)

        self.write(renderMSG('create success !!'))
        self.finish()

    def MakePendingContestTempFile(self, cid, data):

        file = open(PendingContestFile + '/contest_' + str(cid) + '.pkl', 'wb')

        dt = dict()
        dt['cid'] = cid
        dt['ctitle'] = data['ctitle']
        dt['begintime'] = data['begintime']
        dt['endtime'] = data['endtime']
        dt['cstatus'] = data['cstatus']
        dt['submitlist'] = list()
        dt['ranklist'] = list()

        pickle.dump(dt, file)

    def check_args(self, d):
        L = ['contestname', 'syear', 'smonth', 'sday', 'shour',
             'sminute', 'ssecond', 'lday', 'lhour', 'lminute',
             'lsecond', 'contesttype', 'password', 'hide']
        for x in L:
            if x not in d: continue
            if len(d[x]) == 0:
                if x == 'password' and d['contesttype'] == '0':
                    continue
                return False
        return True

    def getContestData(self, uid, d):

        data = dict()
        data['cuid'] = uid
        data['ctitle'] = d['contestname']

        if 'contesttype' not in d or len(d['contesttype']) == 0:
            data['ispublic'] = "0"

        data['ispublic'] = d['contesttype']

        print(data['ispublic'])
        if data['ispublic'] == "1":
            data['password'] = d['password']

        data['cdescription'] = d['cdescription']

        d1 = datetime.datetime(int(d['syear']), int(d['smonth']), int(d['sday']), int(d['shour']), int(d['sminute']))
        dt = datetime.timedelta(days=int(d['lday']), hours=int(d['lhour']), minutes=int(d['lminute']));

        now = datetime.datetime.now()

        if (d1 - now).total_seconds() < 0:
            data['error'] = 'wrong begin time'
        if dt.total_seconds() > 2700000:
            data['error'] = 'to long'

        d2 = d1 + dt

        data['begintime'] = str(d1)
        data['endtime'] = str(d2)
        data['cstatus'] = 0

        return data

    @run_on_executor
    def CreateNewContest(self, data):

        sql = getInserSQL('contest', data)

        print('exeSQL: Create Contest!! ', sql)
        conn = ConnPool.connect()
        cur = conn.cursor()
        cur.execute(sql)

        sql = LAST_INSERT_ID()
        cur.execute(sql)
        id = cur.fetchone()[0]

        cur.close()
        conn.close()

        return id
UIModule/HeaderModule.py
class TitleModule(tornado.web.UIModule):
    def render(self):
        html1 = '''
        <div id="title" class="span">
            <a href="/" class="filter-item selected text-center">
                <h1>The VirtualJudgePY</h1>
            </a>
        </div>

        <table class="flex-table">
            <tr>
                <td>
                    <a href="/problemlist">
                        <button class="btn btn-outline" type="button">Problem</button>
                    </a>
                </td>
                <td>
                    <a href="/status">
                        <button class="btn btn-outline" type="button">Status</button>
                    </a>
                </td>
                <td>
                    <a href="/authorsranklist">
                        <button class="btn btn-outline" type="button">Authors Ranklist</button>
                    </a>
                </td>
                <td>
                    <a href="/contestlist">
                        <button class="btn btn-outline" type="button">Contest</button>
                    </a>
                </td>
                <td>
                    <a href="/crawleronline">
                        <button class="btn btn-outline" type="button">Crawler Online</button>
                    </a>
                </td>
            </tr>
        </table>
        '''

        return html1
Handlers/IndexHandler.py
class IndexHandler(BaseHandler):
    def get(self):
        name = self.get_secure_cookie('username')
        if name is None: name = ''

        self.render('index.html', current_user=name)
Handlers/ContestShowHandler.py
class ContestShowHandler(BaseHandler):
    executor = ThreadPoolExecutor(MID_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        cid = self.get_argument('cid', None)

        uid = self.get_secure_cookie('uid',None)
        if uid is not None : uid = uid.decode()

        contestdetail = yield self.getContestsDetail(cid)
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        cstatus = contestdetail[10]

        if cstatus == 0:
            self.write(renderMSG('Not Start'))
            self.finish()
            return

        rs,ac,totalsubmit,acsubmit,tr = yield self.getProblemList(cid,uid)
        print(contestdetail)

        self.render('contestshow.html',
                    begintime=contestdetail[5], endtime=contestdetail[6],
                    cstatus=contestdetail[10], ctitle=contestdetail[1],
                    now=now, rs=rs, cid=cid,ac=ac,totalsubmit=totalsubmit,acsubmit=acsubmit,tr=tr,
                    )

    def post(self):
        pass

    @run_on_executor
    def getContestsDetail(self, cid):
        wherecluse = ' cid = {} '.format(cid)
        ordclause = ' cid  '

        sql = getQuerySQL('contest', wherecluse, ordclause)
        rs = FetchOne(sql)


        return rs

    @run_on_executor
    def getProblemList(self, cid,uid):
        wherecluse = ' cid = {} '.format(cid)
        ordclause = ' cpid '

        sql = getQuerySQL(' cproblem ', wherecluse, ordclause)

        print(sql)
        rs = FetchAll(sql)

        ac = [ 0 for i in range(len(rs)) ]
        tr = [ 0 for i in range(len(rs)) ]

        for i in range(len(rs)) :
            if uid is not None :
                ac[i] = CheckContestIfAccept(uid,rs[i][2],cid)[0]
                if ac[i]==1: tr[i]=1
                else : tr[i] = CheckContestIfTry(uid,rs[i][2],cid)[0]


        totalsubmit = CountContestSubmitNum(cid)
        acsubmit = CountContestACNum(cid)

        td = dict()
        ad = dict()
        for x in totalsubmit: td[x[0]] = x[1]
        for x in acsubmit : ad[x[0]] = x[1]

        '''
        print(rs)
        print(ac)
        print(td)
        print(ad)
        '''

        return rs,ac,td,ad,tr
Handlers/RegisterHandler.py
class RegisterHandler(tornado.web.RequestHandler):

    executor = ThreadPoolExecutor(SML_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self, *args, **kwargs):

        dt = dict()

        dt['username'] = self.get_argument("username", None)
        dt['password'] = self.get_argument("password", None)
        repassword = self.get_argument("repassword", None)
        dt['email'] = self.get_argument("email", None)
        dt['school'] = self.get_argument('school', None)
        dt['localstatus'] = 0

        if dt['password'] != repassword:
            self.render('register.html')
        else:
            ret = yield self.AddUser(dt)
            if ret == 1:
                ''' success '''
                self.write(renderMSG('Regiest Success!!'))
                self.finish()
            else:
                ''' fail '''
                self.write(renderMSG('Regiest Fail !!!'))
                self.finish()
                return

    def get(self):
        self.render('register.html')

    @run_on_executor
    def AddUser(self,d):
        return AddUser(d)
UIModule/SolvedProblemModule.py
class SolvedProblemModule(tornado.web.UIModule):
    def render(self, username, rs):

        print(username,rs)

        sz = len(rs)

        html = '<table><tbody>'

        for i in range(0, sz):
            if i % 10 == 0:
                if i != 0: html += '</tr>'
                html += '<tr>'

            '''
            html += '<td><h5><a href="/problem/' + str(rs[i][0]) + '/' + str(rs[i][1]) + '">' + str(rs[i][0]) + str(
                rs[i][1]) + '</a></h5></td>'
            '''
            html += '<td><h5><a href="/status?problem_id='+str(rs[i][1])+'&user_name='+username+'&oj='+str(rs[i][0])+\
                    '&status=accept&language=&isSearch=isSearch&cid=%">'+ str(rs[i][0])+str(rs[i][1])+'</a></h5></td>'
            html += '<td width="10px"></td>'

            if i == sz - 1:
                html += '</tr>'

        html += '</tbody></table>'

        return html
Handlers/SubmitHandler.py
class SubmitHandler(BaseHandler):
    executor = ThreadPoolExecutor(10)

    def prepare(self):
        self.AS = AutoSubmit()

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, *args, **kwargs):

        cid = self.get_argument('cid', -1)
        OJ = self.get_argument('OJ', None)
        Prob = self.get_argument('Prob', None)
        pid = self.get_argument('pid', None)
        self.get_current_user()

        if OJ is None or Prob is None or pid is None:
            self.finish()
            return

        cstatus = -1
        if cid != -1:
            cstatus = yield self.getContestStatus(cid)

        if cstatus == 2:
            self.write(renderMSG('contest {} is end!'.format(cid)))
            self.finish()
            return

        if cstatus == 0:
            self.write(renderMSG('contest {} is not Begin!'.format(cid)))
            self.finish()
            return

        ret = str(self.current_user) + OJ + Prob

        if len(self.current_user) == 0:
            self.write(renderMSG('Please LogIn first!!!'))
            self.finish()
        else:
            self.render('submit.html', OJ=OJ, Prob=Prob, pid=pid, cid=cid)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self, *args, **kwargs):

        self.get_current_user()
        pid = self.get_argument('pid', None)
        Prob = self.get_argument('Prob', None)
        lang = self.get_argument('language', None)
        code = self.get_argument('usercode', None)
        oj = self.get_argument('OJ', None)
        cid = self.get_argument('cid', -1)

        if lang is None or len(code) == 0 or oj is None or code is None or pid is None:
            self.write(renderMSG('Submit Error!!'))
        else:
            print('lang: ', lang, ' oj: ', oj, ' Prob: ', Prob, ' code ', code, 'user: ', self.current_user)
            yield self.SubmmitCollector(pid=pid, oj=oj, Prob=Prob, lang=lang, code=code, cid=cid)
            # insert into DB
            self.write(renderMSG('Submit Success!!'))

        self.finish()

    @run_on_executor
    def SubmmitCollector(self, pid, oj, Prob, lang, code, cid):

        code = self.AddRandomSpace(code)

        vj_username = self.AS.SubmmitSelector(oj=oj, prob=Prob, lang=lang, code=code)

        # Write Record into db
        self.InsertStatusToDB(pid=pid, oj=oj, Prob=Prob, lang=lang, code=code, cid=cid,vj_username=vj_username)

    @run_on_executor
    def getContestStatus(self, cid):

        sql = getQuerySQL('contest', ' cid = {} '.format(cid), ' cid ')

        # print(sql)
        rs = FetchOne(sql)

        return rs[10]

    def AddRandomSpace(self, code):
        # Add RandomSpace to avoid missjudge
        s = 'From VirtualJudge.PY '
        n = random.randint(1, 50)
        code += '\n/*\n'
        for i in range(n): code += s[i % 21]
        code += '\n*/'
        return code

    def InsertStatusToDB(self, pid, oj, Prob, lang, code, cid,vj_username):
        data = dict()

        data['pid'] = pid
        data['cid'] = cid
        data['language'] = lang
        data['originOJ'] = oj
        data['originProb'] = Prob
        data['source'] = UTF8StrToBase64Str(code)
        data['username'] = self.current_user
        data['uid'] = str(self.get_secure_cookie('uid').decode('utf-8'))
        data['timesubmit'] = time.strftime('%Y-%m-%d %H:%M:%S')
        data['isdisplay'] = 1
        data['isopen'] = 1
        data['status'] = 'Pending'
        data['codelenth'] = str(len(code))

        sql = getInserSQL('status', data)

        conn = ConnPool.connect()
        cur = conn.cursor()
        cur.execute(sql)

        ''' create a pkl file'''
        file = SID_DATA_FILE+'/sid_{}.pkl'
        cur.execute(LAST_INSERT_ID())
        sid = cur.fetchone()[0]

        pkl = dict()
        pkl['sid'] = sid
        pkl['codelenth'] = data['codelenth']
        pkl['originOJ'] = data['originOJ']
        pkl['originProb'] = data['originProb']
        pkl['language'] = data['language']
        pkl['vj_username'] = vj_username
        pkl['looplimit'] = 10

        print('vj_username: ',vj_username)

        fw = open(file.format(sid), 'wb')
        pickle.dump(pkl, fw)

        cur.close()
        conn.close()

        print('status_sql: ', sql)
Handlers/UserStatusHandler.py
class UserStatusHander(BaseHandler):
    executor = ThreadPoolExecutor(MID_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        username = self.get_argument('username')
        rs = yield self.getUserInfo(username)
        if rs is None:
            self.write(renderMSG('Can\'t find user {}'.format(username)))
            self.finish()

        uid = rs[0]
        nickname = rs[2]
        email = str(rs[4])
        school = rs[5]
        urlpart = hashlib.md5(email.lower().encode('utf-8')).hexdigest()

        rs = yield self.getUserACSubmit(username=username)

        rs2 = yield self.getSubmitInfo(uid=uid)

        rankinfo = yield self.getRankInfo(uname=username)
        '''
        submitdata = ''
        for x in rs2 :
            if len(submitdata) != 0 :
                submitdata += ',\n'
            submitdata += '{value:'+str(x[1])+',name:"'+str(x[0])+'"}'
        '''
        submitdata = rs2

        self.get_current_user()
        showpsw = False
        if self.current_user == username : showpsw= True

        self.render("userstatus.html", uid=uid, uname=username,nickname=nickname, email=email, school=school, urlpart=urlpart, rs=rs,
                    submitdata=submitdata,rank=rankinfo,showpsw=showpsw)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        uid = self.get_argument('uid')
        username = self.get_argument('username')
        password = self.get_argument('password')
        newpassword = self.get_argument('newpassword')
        email = self.get_argument('email')
        school = self.get_argument('school')
        nickname = self.get_argument('nickname')

        # Check Password

        rs = yield self.CheckPasswrod(username=username, password=password)

        if rs[0] == 0:
            self.write(renderMSG('Wrong Password for user {}. Can\'t modify.'.format(username)))
            self.finish()

        # Update user Info
        data = dict()
        data['email'] = email
        data['school'] = school
        data['nickname'] = nickname

        if newpassword is not None and len(newpassword) != 0:
            data['password'] = SHA512(username+'@'+newpassword)

        isOK = yield self.UpdateUserInfo(uid=uid, data=data)

        if isOK == False:
            self.write(renderMSG('Update False!'))
        else:
            self.write(renderMSG('Update Success!'))

        self.finish()

    @run_on_executor
    def getUserInfo(self, username):

        if len(username) == 0:
            return None

        where = ' username = "{}" '.format(username)
        sql = getQuerySQL('user', whereclause=where, ordclause=' uid ')
        rs = FetchOne(sql)

        print(rs)

        return rs

    @run_on_executor
    def getUserACSubmit(self, username):

        where = 'username = "{}" and status LIKE "%Accept%"'.format(username)
        select = ' DISTINCT originOJ,originProb '
        sql = getQueryDetailSQL('status', selectitem=select, whereclause=where, ordclause=' originOJ,originProb ')

        print('sql: ', sql)
        rs = FetchAll(sql)

        return rs

    @run_on_executor
    def CheckPasswrod(self, username, password):

        sql = checkUserSQL(username=username, password=password)
        rs = FetchOne(sql)

        return rs

    @run_on_executor
    def UpdateUserInfo(self, uid, data):

        sql = getUpdateSQL('user', data=data, clause=' uid={} '.format(uid))

        print('sql: ', sql)

        try:
            ExeSQL(sql)
        except Exception:
            return False

        return True

    @run_on_executor
    def getSubmitInfo(self, uid):

        sql = 'SELECT status,count(status) from status WHERE uid = {} GROUP BY status ORDER BY status'.format(uid)
        rs = FetchAll(sql)

        return rs

    @run_on_executor
    def getRankInfo(self,uname):
        return GetUserRank(username=uname)
Handlers/CrawlerOnlineHandler.py
class CrawlerOnlineHandler(BaseHandler):

    executor = ThreadPoolExecutor(MID_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        self.render('crawleronline.html')


    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        if self.request.files is not None and len(self.request.files.keys())!=0:
            csv_meta = self.request.files
            content = csv_meta['csv'][0]['body'].decode()
            problemlist = content.split('\n')
            if len(problemlist) > 20 :
                self.write(renderMSG('Too many Problem to Crawler'))
                self.finish()
            else :
                nt = yield self.CrawlerCSV(problemlist)
                self.write(renderMSG('{} problem crawler success'.format(nt)))
                self.finish()
            return

        vj = self.get_argument('VJ',None)
        oj = self.get_argument('oj',None)
        prob = self.get_argument('prob',None)

        if oj is None or vj is None or prob is None or oj == 'ALL' :
            self.finish()
            return


        isok = yield self.CrawlerIt(vj,oj,prob)
        msg = renderMSG('Crawler Success! Visit <a href="/problem/{}/{}">here</a> enjoy it!'.format(oj,prob),waittime=1000000)
        self.write(msg)
        self.finish()

    @run_on_executor
    def CrawlerIt(self,vj,oj,prob):


        if vj == 'BNUVJ':
            if oj == 'ZOJ' : oj = 'ZJU'
            bvc = BnuVJCrawler()
            bvc.CrawlerProblem(originOJ=oj,originProb=prob)
        elif vj == 'HUST':
            huc = HustCrawler()
            huc.CrawlerProblem(oj,prob)

        time.sleep(3)
        return True

    @run_on_executor
    def CrawlerCSV(self,problemlist):
        nt=0
        for line in problemlist :
            item = line.split(',')
            if len(item) == 2 :
                oj = item[0]
                prob = item[1]
                if self.CrawlerIt('HUST',oj,prob) : nt+=1
            time.sleep(2)
        return nt
Handlers/ContestListHandler.py
class ContestListHandler(BaseHandler):
    executor = ThreadPoolExecutor(BIG_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):

        page = self.get_argument('page', 0)
        rs = yield self.getContestsDetail(page)

        hasNext = True

        if len(rs) != PAGE_LIMIT + 1:
            hasNext = False
        else:
            rs = rs[:-1]

        self.render('contestlist.html',
                    rs=rs, hasNext=hasNext, page=page
                    )

    def post(self):
        pass

    @run_on_executor
    def getContestsDetail(self, page):

        From = int(page) * PAGE_LIMIT

        sql = 'SELECT *,(SELECT username FROM user WHERE uid = contest.cuid) as username FROM contest ORDER BY contest.cid DESC LIMIT {} , {} '.format(
            From, PAGE_LIMIT + 1)

        print(sql)

        rs = FetchAll(sql)

        return rs
Handlers/ShowCodeHandler.py
class ShowCodeHandler(BaseHandler):
    executor = ThreadPoolExecutor(MID_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        self.get_current_user()
        sid = self.get_argument('sid', -1)

        if sid == -1:
            self.write(renderMSG('wrong sid'))
            self.finish()
            return

        rs = yield self.getSubmitData(sid)


        isopen = int(rs[9])

        cid = int(rs[6])
        if cid == -1 :
            pass
        else :
            cstatus = yield self.getContestStatus(cid)
            if cstatus <= 1 : isopen = 0

        uid = int(rs[10])
        cookie_uid = self.get_secure_cookie('uid', None)
        if isopen == 0:
            if cookie_uid is None:
                pass
            elif int(cookie_uid) == uid:
                isopen = 1


        if isopen == 0:
            self.write(renderMSG('submit not public'))
            self.finish()
            return

        OJ = rs[12]
        Prob = rs[13]
        Code = Base64StrToUTF8Str(rs[8])
        Status = rs[2]
        Timesubmit = rs[1]
        PID = rs[5]
        Author = rs[11]
        language = rs[7]

        self.render('showcode.html', OJ=OJ, Prob=Prob, Code=Code, Status=Status,
                    Timesubmit=Timesubmit, PID=PID, Author=Author, language=language)

    def post(self):
        pass

    @run_on_executor
    def getSubmitData(self, sid):

        sql = getQuerySQL('status', ' sid = {} '.format(sid), ' sid ')
        rs = FetchOne(sql)

        return rs

    @run_on_executor
    def getContestStatus(self,cid):

        sql = getQueryDetailSQL(' contest ',' cstatus ',' cid = {} '.format(cid),' 1=1 ')
        rs = FetchOne(sql)

        return rs[0]
Handlers/ManageContestHandler.py
class ManageContestHandler(BaseHandler):
    executor = ThreadPoolExecutor(20)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, *args, **kwargs):

        action = self.get_argument('action')
        cid = self.get_argument('cid')

        if action == 'modify':
            # modify contest
            rs = yield self.getContestDetail(cid)
            d1 = rs[5]
            d2 = rs[6]
            dt = d2 - d1

            '''
            print(rs)
            print(d1.year,d1.month,d1.day,d1.hour,d1.minute)
            print(dt.days,dt.seconds)
            mm,ss = divmod(dt.seconds,60)
            hh,mm = divmod(mm,60)
            print(hh,mm,ss)
            '''

            lday = dt.days
            lmm, lss = divmod(dt.seconds, 60)
            lhh, lmm = divmod(lmm, 60)

            contesttype = int(rs[8])

            password = ''

            check1 = 'checked'
            check2 = ''

            if contesttype == 1:
                password = rs[4]
                check1 = ''
                check2 = "checked"

            ctitle = rs[1]
            cdescription = rs[2]

            problemlist = yield self.getContestProblem(cid)
            problemlisttxt = self.getProblemTxt(problemlist)

            self.render('contestdetail.html',
                        cid=cid,
                        check1=check1, check2=check2,
                        ctitle=ctitle, cdescription=cdescription,
                        year=d1.year, month=d1.month, day=d1.day, hour=d1.hour, minute=d1.minute,
                        lday=lday, lhour=lhh, lminute=lmm, lsecond=lss, password=password,
                        problemlist=problemlist, problemlisttxt=problemlisttxt
                        )


        elif action == 'delete':

            if cid is None:
                self.write(renderMSG('Wrong CID'))
                self.finish()
                return

            flag = yield  self.DeleteContest(cid)

            if flag == True :
                self.write(renderMSG('Delete Success!'))
            else :
                self.write(renderMSG('Can\'t delete'))

            self.finish()

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        action = self.get_argument('action', None)

        if action is None:
            self.write(renderMSG('Error Manage Operation!!'))
            self.finish()
            return

        if action == 'updateproblem':

            cid = self.get_argument('cid', None)
            txt = self.get_argument('problemlist', None)

            if cid is None:
                self.write(renderMSG('Wrong CID'))
                self.finish()
                return

            CD = yield self.getContestDetail(cid)
            cstatus = CD[10]

            if cstatus == 1 or cstatus == 2:
                self.write(renderMSG('Contest is frost can\'t modify'))
                self.finish()
                return

            problemlist = self.getProblem(txt)

            log = yield self.UpdateProblem(cid, problemlist)

            self.write(renderMSG(log))
            self.finish()
            return

        elif action == 'updatedetail':

            d = self.request.arguments
            for x in d: d[x] = d[x][0].decode()
            cid = d['cid']

            if self.check_args(d) == False:
                self.write(renderMSG('create fail some arguments miss'))
                self.finish()
                return

            uid = self.get_secure_cookie('uid').decode()
            data = self.getContestData(uid, d)

            if 'error' in data:
                self.write(renderMSG(data['error']))
                self.finish()
                return

            CD = yield self.getContestDetail(cid)
            cstatus = CD[10]

            if cstatus == 1 or cstatus == 2:
                self.write(renderMSG('Contest is frost can\'t modify'))
                self.finish()
                return

            yield self.updateContestDetail(cid, data)
            self.MakePendingContestTempFile(cid, data)

            self.write(renderMSG('Update Success'))
            self.finish()
            return

        elif action=='delete' :
            cid = self.get_argument('cid', None)

            if cid is None:
                self.write(renderMSG('Wrong CID'))
                self.finish()
                return

            yield  self.DeleteContest(cid)

            self.write(renderMSG('Delete Success!'))
            self.finish()

    def check_args(self, d):
        L = ['contestname', 'syear', 'smonth', 'sday', 'shour',
             'sminute', 'ssecond', 'lday', 'lhour', 'lminute',
             'lsecond', 'contesttype', 'password', 'hide']
        for x in L:
            if x not in d: continue
            if len(d[x]) == 0:
                if x == 'password' and d['contesttype'] == '0':
                    continue
                return False
        return True

    def getContestData(self, uid, d):

        data = dict()
        data['cuid'] = uid
        data['ctitle'] = d['contestname']

        if 'contesttype' not in d or len(d['contesttype']) == 0:
            data['ispublic'] = "0"

        data['ispublic'] = d['contesttype']

        print(data['ispublic'])
        if data['ispublic'] == "1":
            data['password'] = d['password']

        data['cdescription'] = d['cdescription']

        d1 = datetime.datetime(int(d['syear']), int(d['smonth']), int(d['sday']), int(d['shour']), int(d['sminute']))
        dt = datetime.timedelta(days=int(d['lday']), hours=int(d['lhour']), minutes=int(d['lminute']));

        now = datetime.datetime.now()

        if (d1 - now).total_seconds() < 0:
            data['error'] = 'wrong begin time'
        if dt.total_seconds() > 2700000:
            data['error'] = 'to long'

        d2 = d1 + dt

        data['begintime'] = str(d1)
        data['endtime'] = str(d2)
        data['cstatus'] = 0

        return data

    @run_on_executor
    def updateContestDetail(self, cid, data):

        wherecluse = ' cid = {} '.format(cid)
        sql = getUpdateSQL('contest', data, wherecluse)
        print(sql)
        ExeSQL(sql)


    def MakePendingContestTempFile(self, cid, data):

        file = open(PendingContestFile + '/contest_' + str(cid) + '.pkl', 'wb')

        dt = dict()
        dt['cid'] = cid
        dt['ctitle'] = data['ctitle']
        dt['begintime'] = data['begintime']
        dt['endtime'] = data['endtime']
        dt['cstatus'] = data['cstatus']
        dt['submitlist'] = list()
        dt['ranklist'] = list()

        pickle.dump(dt, file)

    def getProblem(self, txt):

        Li = txt.split('\r\n')
        data = list()
        for item in Li:
            di = dict()
            ii = item.split(' ')
            if len(ii) == 2:
                di['originOJ'] = ii[0]
                di['originProb'] = ii[1]
                if di not in data:
                    data.append(di)

        return data

    def getProblemTxt(self, list):
        ret = ''
        for x in list:
            ret += x[4] + ' ' + x[5] + '\n'
        return ret

    @run_on_executor
    def getContestDetail(self, cid):

        whereclause = ' cid = {} '.format(cid)
        sql = getQuerySQL('contest', whereclause, ' cid ')
        rs = FetchOne(sql)

        return rs

    @run_on_executor
    def getContestProblem(self, cid):

        whereclause = ' cid = {} '.format(cid)
        sql = getQuerySQL('cproblem', whereclause, ' cpid ')
        rs = FetchAll(sql)

        return rs

    @run_on_executor
    def UpdateProblem(self, cid, data):

        # clear old problem in contest

        whereclause = ' cid = {} '.format(cid)
        sql = getDeletSQL('cproblem', whereclause)

        conn = ConnPool.connect()
        cur = conn.cursor()
        cur.execute(sql)

        log = ''

        for item in data:

            # get pid
            whereclause = ' originOJ = "{originOJ}" and originProb = "{originProb}" '.format(**item)
            sql = getQueryDetailSQL('problem', '*', whereclause, ' pid ')
            num = cur.execute(sql)

            if num == 0:
                log += 'Error when add Problem OJ: {originOJ} Pid: {originProb}<br>'.format(**item)
                log += '\n'
            else:

                rs = cur.fetchone()
                pid = rs[0]
                title = rs[1]
                originOJ = rs[4]
                originProb = rs[5]

                # insert into cproblem

                data = dict()
                data['cid'] = cid
                data['pid'] = pid
                data['title'] = title
                data['originOJ'] = originOJ
                data['originProb'] = originProb

                sql = getInserSQL('cproblem', data)
                cur.execute(sql)

        cur.close()
        conn.close()

        if len(log) == 0:
            log += 'All problem add into contest {} successfully. <br>'.format(cid)
        else:
            log += 'some error happend.<br> May be some problem can\'t find this problem in database...<br>'

        return log

    @run_on_executor
    def DeleteContest(self,cid):

        whereclause = ' cid = {} '.format(cid)

        conn = ConnPool.connect()
        cur = conn.cursor()

        sql = getQueryDetailSQL('contest',' cstatus ',whereclause,'1=1')
        cur.execute(sql)
        r = cur.fetchone()

        if r[0] != 0 :
            return False


        sql = getDeletSQL('cproblem', whereclause)

        cur.execute(sql)
        sql = getDeletSQL('contest',whereclause=whereclause)

        cur.execute(sql)


        sql = getDeletSQL('contest', whereclause)

        cur.execute(sql)
        cur.close()

        return True
Handlers/AuthorsRanklistHandler.py
class AuthorsRanklistHandler(BaseHandler):

    executor = ThreadPoolExecutor(MID_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):

        page = self.get_argument('page',0)
        page = int(page)
        if page < 0 : page = 0

        rs = yield self.getRankList(page=page,pagelimit=PAGE_LIMIT)
        hasnext = True

        if len(rs) == PAGE_LIMIT+1 : rs = rs[:-1]
        else : hasnext = False

        print('page: ',page,type(page))
        self.render('authorsranklist.html',
                    rs=rs,hasNext=hasnext,page=page,prepage=page-1,nxtpage=page+1)


    @run_on_executor
    def getRankList(self,page,pagelimit):
        rs = GetAuthorsRank(page,pagelimit)
        print(rs)
        return rs
Handlers/ReportBugHandler.py
class ReportBugHandler(BaseHandler):

    def get(self):
        self.render("reportbug.html")

    def post(self, *args, **kwargs):
        pass
UIModule/ContestItemModule.py
class ContestItemModule(tornado.web.UIModule):
    def render(self, r):
        cid = r[0]
        ctitle = r[1]
        begintime = r[5]
        endtime = r[6]

        status = ''
        color = ''
        if r[10] == 0:
            status = 'Pending'
            color = 'green'
        elif r[10] == 1:
            status = 'Running'
            color = 'red'
        elif r[10] == 2:
            status = 'Ended'
            color = 'grey'

        return self.render_string('module/contestitem.html',
                                  cid=cid, ctitle=ctitle, begintime=begintime,
                                  endtime=endtime, status=status, color=color)
Handlers/RankListHandler.py
class RankLishHandler(BaseHandler):
    executor = ThreadPoolExecutor(SML_THREAD_POOL_SIZE)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):

        cid = self.get_argument('cid', -1)

        if cid == -1:
            self.write(renderMSG('wrong contest id'))
            self.finish()

        contestInfo = yield self.getContestInfo(cid)
        now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        statusdata = yield self.getStatusInfo(cid)
        problemlist = yield self.getProblemList(cid)
        begintime = contestInfo[5]
        ranklist = yield self.CaluRankList(begintime, statusdata, problemlist)

        self.render('ranklist.html',
                    ctitle=contestInfo[1], begintime=contestInfo[5], endtime=contestInfo[6],
                    now=str(now), cstatus=contestInfo[10], cid=cid, ranklist=ranklist
                    )

    def post(self):
        pass

    @run_on_executor
    def CaluRankList(self, begintime, statusdata, problemlist):

        print('status data: ')
        print(statusdata)
        print('problem list : ')
        print(problemlist)

        begintime = datetime.datetime.strptime(str(begintime), '%Y-%m-%d %H:%M:%S')

        np = len(problemlist)

        if np == 0:
            return tuple()

        mincpi = int(problemlist[0][0])

        pInC = dict()
        for prob in problemlist:
            pInC[prob[1]] = int(prob[0]) - mincpi

        userList = list()

        for x in statusdata:

            uid = x[10]
            username = x[11]

            dt = dict()
            dt['uid'] = uid
            dt['username'] = username

            # 初始化AC数组和罚时数组
            dt['aclist'] = [0 for row in range(np)]
            dt['ptimelist'] = [0 for row in range(np)]
            dt['submit'] = [0 for row in range(np)]
            dt['firstblood'] = [ 0 for row in range(np)]
            dt['totalaccept'] = 0
            dt['totaltime'] = 0

            if dt not in userList:
                # print(dt)
                userList.append(dt)

        ranklist = list()
        for user in userList:

            for status in statusdata:
                if status[10] == user['uid'] and status[11] == user['username']:

                    pid = status[5]

                    id = pInC[pid]

                    # 已经ac不计算之后的提交
                    if user['aclist'][id] == 1: continue

                    result = str(status[2]).strip().lower()
                    user['submit'][id] += 1

                    if result == 'accept' or result == 'accepted':
                        # ac 标记该题已经ac

                        user['aclist'][id] = 1

                        timesubmit = status[1]
                        timesubmit = datetime.datetime.strptime(str(timesubmit), '%Y-%m-%d %H:%M:%S')
                        deta = timesubmit - begintime

                        user['ptimelist'][id] += deta.total_seconds()
                    else:
                        # 没有ac加上罚时间20*60s
                        user['ptimelist'][id] += 1200

            # 统计总罚时和ac数
            for i in range(0, np):
                if user['aclist'][i] == 1:
                    user['totalaccept'] += 1
                    user['totaltime'] += user['ptimelist'][i]



            ranklist.append(user)
            # print('user: ',user)
            # print('\n')


        # 计算firstblood
        for i in range(np):
            userid = None
            for j in range(len(ranklist)) :
                if ranklist[j]['aclist'][i] == 1 :
                    if userid is None or ranklist[j]['ptimelist'][i] < ranklist[userid]['ptimelist'][i] :
                            userid = j
            if userid is not None :
                ranklist[userid]['firstblood'][i] = 1

        for user in ranklist :
            print(user)

        ranklist = sorted(ranklist, key=lambda user: - user['totalaccept'] * 1000000000000 + user['totaltime'])

        return ranklist

    @run_on_executor
    def getContestInfo(self, cid):

        whereclause = ' cid = {} '.format(cid)

        sql = getQuerySQL('contest', whereclause=whereclause, ordclause=' cid ')
        rs = FetchOne(sql)

        return rs

    @run_on_executor
    def getStatusInfo(self, cid):

        whereclause = ' cid = {} '.format(cid)
        ordclause = ' sid '

        sql = getQuerySQL('status', whereclause=whereclause, ordclause=ordclause)
        rs = FetchAll(sql)

        return rs

    @run_on_executor
    def getProblemList(self, cid):

        whereclause = ' cid = {} '.format(cid)
        ordclause = ' cpid '
        selectitem = ' cpid,pid '

        sql = getQueryDetailSQL('cproblem', selectitem=selectitem, whereclause=whereclause, ordclause=ordclause)
        rs = FetchAll(sql)

        return rs
UIModule/StatusItemModule.py
class StatusItemModule(tornado.web.UIModule):
    def render(self, r):

        d = dict()
        d['sid'] = r[0]
        d['username'] = r[11]
        d['oj'] = r[12]
        d['prob'] = r[13]
        d['status'] = r[2]
        if d['status'] == 'Accepted':
            d['color'] = 'red'
        else:
            d['color'] = 'blue'
        d['runmemory'] = r[4]
        d['runtime'] = r[3]
        d['codelength'] = r[17]
        d['submittime'] = str(r[1])
        d['language'] = r[7]

        return self.render_string('module/StatusItem.html', d=d)
Handlers/LogInHandler.py
class LogInHandler(BaseHandler):
    executor = ThreadPoolExecutor(4)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        username = self.get_argument('username', 'None')
        password = self.get_argument('password', 'None')

        print(username, '   ', password)

        if argCheck(username) and argCheck(password):
            isOK = yield self.checkPasswd(username, password)
            if isOK is not None:
                self.set_secure_cookie('username', username)
                print('isOK: ', isOK)
                self.set_secure_cookie('uid', str(isOK))
                self.write(renderMSG(msg='LogIn Success'))
            else:
                self.write(renderMSG(msg='LogIn Fail'))

        self.finish()

    @run_on_executor
    def checkPasswd(self, username, password):
        conn = ConnPool.connect()
        cur = conn.cursor()
        sql = checkUserSQL(username, password)
        print('exe: ', sql)
        cur.execute(sql)
        ans = cur.fetchall()
        print(ans)
        print(ans[0][0])

        if ans[0][0] == 1:
            sql = getUserUid(username)
            cur.execute(sql)
            uid = cur.fetchone()[0]
            cur.close()
            conn.close()
            return uid
        else:
            return None
Handlers/ProblemHandler.py
class ProblemHandler(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(10)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, oj=None, pid=None):

        cid = self.get_argument('cid', -1)

        print('oj: ' + oj + ' pid: ' + pid)
        D = yield self.getProblem(oj, pid)

        if D is None :
            yield self.CrawlerOnLine(oj,pid)
            D = yield self.getProblem(oj, pid)

        if D is None :
            self.write(renderMSG('Can\'t find this problem',waittime=1000000))
            self.finish()
            return

        clearkeys = list()
        for x in D.keys():
            lenth = len(str(D[x]))
            if lenth == 0 : clearkeys.append(x)

        for x in clearkeys :    del D[x]

        current_user = self.get_secure_cookie('username')
        self.render('problem.html', D=D, current_user=current_user, cid=cid)

    @run_on_executor
    def CrawlerOnLine(self,oj,pid):
        BVC = BnuVJCrawler()
        BVC.CrawlerProblem(oj,pid)

    @run_on_executor
    def getProblem(self, oj, problemid):

        # get pid
        conn = ConnPool.connect()
        cur = conn.cursor()

        sql = 'SELECT * FROM problem WHERE ( originOJ LIKE "{}" and originProb LIKE "{}" )'.format(oj, problemid)
        cur.execute(sql)
        rt = cur.fetchone()

        # error
        if rt is None:
            return None

        d = dict()

        d['originOJ'] = oj
        d['originProb'] = problemid

        if rt[0] is not None:
            d['pid'] = rt[0]
        if rt[1] is not None:
            d['title'] = rt[1]
        if rt[2] is not None:
            d['source'] = rt[2]
        if rt[3] is not None:
            d['url'] = rt[3]

        sql = 'SELECT * FROM problemdetail WHERE pid = {}'.format(d['pid'])
        cur.execute(sql)
        rt = cur.fetchone()

        print(sql)
        print(rt)

        if rt[2] is not None:
            d['description'] = Base64StrToUTF8Str(rt[2])
        if rt[3] is not None:
            d['input'] = Base64StrToUTF8Str(rt[3])
        if rt[4] is not None:
            d['output'] = Base64StrToUTF8Str(rt[4])
        if rt[5] is not None:
            d['sampleinput'] = Base64StrToUTF8Str(rt[5])
        if rt[6] is not None:
            d['sampleoutput'] = Base64StrToUTF8Str(rt[6])
        if rt[7] is not None:
            d['hint'] = Base64StrToUTF8Str(rt[7])
        if rt[8] is not None:
            d['author'] = Base64StrToUTF8Str(rt[8])
        if rt[10] is not None:
            d['updatetime'] = str(rt[10])
        if rt[11] is not None:
            d['memorylimit'] = rt[11]
        if rt[12] is not None:
            d['timelimit'] = rt[12]
        if rt[13] is not None:
            d['specialjudge'] = rt[13]

        cur.close()
        conn.close()
        return d
UIModule/OJSelectModule.py
class OJSelectModule(tornado.web.UIModule):
    def render(self,firstoj='ALL'):
        if firstoj==' ': firstoj='ALL'
        html = '<select size="1" name="oj">'
        html += '<option value="'+firstoj+'" selected="">'+firstoj+'</option>'
        for OJ in SUPPORT_OJ_LIST:
            if OJ == firstoj : OJ = 'ALL'
            html += '<option value="{}">{}</option>'.format(OJ, OJ)
        html += '</select>'
        return html
UIModule/ServerTimeModule.py
class ServerTimeModule(tornado.web.UIModule):

    def render(self, *args, **kwargs):
        TIMEFORMATE = '%Y-%m-%d %X'
        return "Server Time(GMT+8): "+time.strftime(TIMEFORMATE,time.localtime())
Handlers/ManageContestListHandler.py
class ManageContestListHandler(BaseHandler):
    executor = ThreadPoolExecutor(20)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, *args, **kwargs):
        self.get_current_user()

        if len(self.current_user) == 0:
            self.write(renderMSG('please log in first !!'))
            self.finish()
            return

        uid = self.get_secure_cookie('uid').decode()

        rs = yield self.getContests(uid)

        self.render('managecontestlist.html', rs=rs)

    @run_on_executor
    def getContests(self, uid):
        whereclause = ' cuid = {}'.format(uid)
        ordclause = ' cid desc '

        sql = getPageLimitSQL('contest', whereclause, ordclause, 0, 100000)
        rs = FetchAll(sql)

        return rs
Handlers/RedirectorHandler.py
class RedirectorHandler(tornado.web.RequestHandler):
    def get(self):
        pass

    def post(self, *args, **kwargs):

        msg = self.get_argument('msg', None)

        if msg is None:
            print('msg is None')
            return

        returl = '/'
        if msg[:3] == 'pl_':
            returl = self.ProblemListSolution(msg)
        elif msg[:3] == 'st_':
            returl = self.StatusListSolution(msg)

        self.redirect(returl)

    def StatusListSolution(self, msg):

        index = self.get_cookie('st_index', '0')
        index = int(index)

        if msg == 'st_prev':
            index = index - 20
        elif msg == 'st_next':
            index = index + 20
        elif msg == 'st_top':
            index = 0

        if index < 0: index = 0
        index = str(index)

        st_oj = self.get_cookie('st_oj', '')
        st_problem_id = self.get_cookie('st_problem_id', '')
        st_status = self.get_cookie('st_status', '')
        st_username = self.get_cookie('st_username', '')
        st_language = self.get_cookie('st_language', '')
        st_cid = self.get_cookie('st_cid', -1)

        self.set_cookie('st_index', index)

        redr_url = '/status?problem_id={}&user_name={}&oj={}&status={}&language={}&index={}&cid={}' \
            .format(st_problem_id, st_username, st_oj, st_status, st_language, index, st_cid)

        print(index, ' -----> ', redr_url)

        return redr_url

    def ProblemListSolution(self, msg):

        index = self.get_cookie('pl_index', '0')
        index = int(index)

        if msg == 'pl_prev':
            index = index - 20
        elif msg == 'pl_next':
            index = index + 20
        elif msg == 'pl_top':
            index = 0

        if index < 0: index = 0
        index = str(index)

        pl_oj = self.get_cookie('pl_oj', '')
        pl_problem_id = self.get_cookie('pl_problem_id', '')
        pl_problem_title = self.get_cookie('pl_problem_title', '')
        pl_problem_source = self.get_cookie('pl_problem_source', '')

        self.set_cookie('pl_index', index)

        redr_url = '/problemlist?oj={}&problem_id={}&problem_title={}&problem_source={}&index={}' \
            .format(pl_oj, pl_problem_id, pl_problem_title, pl_problem_source, index)

        return redr_url
Handlers/StatusHandler.py
class StatusHandler(BaseHandler):
    executor = ThreadPoolExecutor(40)

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):

        oj = self.get_argument('oj', '%')
        problem_id = str(self.get_argument('problem_id', '%')).replace(' ', '%')
        user_name = str(self.get_argument('user_name', '%')).replace(' ', '%')
        status = str(self.get_argument('status', '%')).replace(' ', '%')
        language = str(self.get_argument('language', '%')).replace(' ', '%')
        isSearch = self.get_argument('isSearch', None)
        index = str(self.get_argument('index', '0')).replace(' ', '%')
        cid = str(self.get_argument('cid', -1)).replace(' ', '')

        if len(index) == 0:
            index = '0'

        if isSearch is not None:
            index = 0
            self.set_cookie('st_index', '0')
            self.set_cookie('st_problem_id', problem_id)
            self.set_cookie('st_language', language)
            self.set_cookie('st_status', status)
            self.set_cookie('st_oj', oj)
            self.set_cookie('st_username', user_name)
            self.set_cookie('st_cid', cid)

        d = dict()
        d['index'] = index
        d['originProb'] = problem_id
        d['language'] = language
        d['status'] = status
        d['username'] = user_name
        d['originOJ'] = oj
        d['cid'] = cid

        # print('isSearch:%s'%(isSearch))
        # print('oj:%s prob:%s username:%s status:%s language:%s'%(oj,problem_id,user_name,status,language))

        self.get_current_user()

        rs = yield self.getMsgs(d)

        hasNext = True

        print(len(rs))

        if len(rs) <= 20:
            hasNext = False
        else:
            rs = rs[:-1]

        print('cid',cid)

        for key in d.keys():
            if d[key] == '%': d[key]=''

        self.render('status.html', rs=rs, hasNext=hasNext,cid=cid,d=d)

    @run_on_executor
    def getMsgs(self, Data):

        '''
        for key in Data :
            print(key,' ----> ',Data[key])
        '''

        wherecluse = ''

        for key in Data:
            if key == 'index':
                continue
            else:
                if len(wherecluse) != 0:
                    wherecluse += ' and '
                wherecluse += ' {} like "%{}%" '.format(key, Data[key])

        ordercluse = ' timesubmit desc '

        sql = getPageLimitSQL('status', wherecluse, ordercluse, Data['index'], 21)

        print(sql)
        rs = FetchAll(sql)

        return rs
UIModule/RanklistTableModule.py
class RankListTableModule(tornado.web.UIModule):
    def render(self, ranklist):

        raw = len(ranklist)
        print('raw: ', raw)
        if raw == 0:
            html = '<table border="1" class="flex-table-item-primary" bordercolor="#FFFFFF" class="text-center"> <tbody> <tr class="tbheader" style="background-color: #1A5CC8; color: #FFFFFF">'
            html += '</tr></tbody></table>'

            return html

        col = len(ranklist[0]['submit'])

        html = '<table border="1" class="flex-table-item-primary text-center" bordercolor="#FFFFFF" class="text-center"> <tbody> <tr class="tbheader" style="background-color: #1A5CC8; color: #FFFFFF">'

        # table head
        html += '<td>Rank</td>'
        html += '<td>User</td>'
        html += '<td>Solved</td>'
        html += '<td>Penalty</td>'
        for i in range(0, col):
            html += '<td>' + str(i + 1000) + '</td>'
        html += '</tr>'

        rank = 1
        for r in ranklist:

            html += '<tr align="center" bgcolor="#f0f8ff">'

            html += '<td>' + str(rank) + '</td>'
            html += '<td><a href="/userstatus?username='+str(r['username'])+'">' + str(r['username']) + '</a></td>'
            html += '<td>' + str(r['totalaccept']) + '</td>'
            html += '<td>' + self.change(int(r['totaltime'])) + '</td>'

            for i in range(0, col):
                html += '<td bgcolor='

                color = '"#f0f8ff"'
                content = ''
                if r['aclist'][i] == 0:
                    if r['submit'][i]==0 :
                        content += ''
                    else :
                        color = '#FFECF5'
                        content += '(-' + str(r['submit'][i]) + ')'
                elif r['aclist'][i] == 1:
                    content += self.change(int(r['ptimelist'][i]))
                    content += '(' + str(r['submit'][i]) + ')'
                    color = "#E0F8EC"
                    if r['firstblood'][i] == 1 :
                        color = "#04B431"

                html += color + '>'
                html += content
                html += '</td>'

            html += '</tr>'

            rank += 1

        html += '</tbody></table>'

        return html

    def change(self,x):
        h,m,s,=x//3600,(x%3600)//60,x%60
        return "%02d:%02d:%02d"%(h,m,s)
UIModule/ProblemListModule.py
class ProblemListModule(tornado.web.UIModule):
    def render(self, t,ac,tr):
        problemID = t[5]
        OJ = t[4]
        title = t[1]
        source = t[2]
        url = '/problem/' + OJ + '/' + problemID
        color = '#f0f8ff'
        if ac == 1 : color = '#E0F8EC'
        elif tr==1 : color='#FFECF5'
        return self.render_string('module/problemList.html',color = color, oj=OJ, id=problemID, title=title, source=source, url=url)
Handlers/DebugHandler.py
class DebugHandler(BaseHandler):
    def get(self):
        self.render('webdebug.html')

    def post(self):
        id = self.get_argument("id", None)
        print('webdebug get id: ', id)
UIModule/ContestProblemListModule.py
class ContestProblemListModule(tornado.web.UIModule) :

    def render(self,tr,cid,nt,r,a,totalsubmit,acsubmit):

        tn = totalsubmit.get(r[2],0)
        an = acsubmit.get(r[2],0)

        d = 0.0
        if tn!=0 : d = an*100/tn

        if a == 1 : color = '#E0F8EC'
        radio = '{}%({}/{})'.format(d,an,tn)

        color = '#f0f8ff'
        ac = ''
        if a == 1 :
            ac = 'Y'
            color = '#E0F8EC'
        elif tr==1 :
            ac = 'N'
            color = '#FFECF5'

        return self.render_string('module/ContestProblemList.html',ac=ac,cid=cid,nt=nt,color=color,radio=radio,r=r)


Question: import os.path
import tornado.web
import pymysql
from tornado.options import options, define
from Handlers.IndexHandler import IndexHandler
from Handlers.LogInHandler import LogInHandler
from Handlers.LogOutHandler import LogOutHandler
from Handlers.RegisterHandler import RegisterHandler
from Handlers.ProblemHandler import ProblemHandler
from Handlers.StatusHandler import StatusHandler
from Handlers.DebugHandler import DebugHandler
from Handlers.ProblemListHandler import ProblemListHandler
from Handlers.RedirectorHandler import RedirectorHandler
from Handlers.SubmitHandler import SubmitHandler
from Handlers.ContestListHandler import ContestListHandler
from Handlers.CreateContestHandler import CreateContestHandler
from Handlers.ManageContestHandler import ManageContestHandler
from Handlers.ManageContestListHandler import ManageContestListHandler
from Handlers.ContestShowHandler import ContestShowHandler
from Handlers.RankListHandler import RankLishHandler
from Handlers.ShowCodeHandler import ShowCodeHandler
from Handlers.UserStatusHandler import UserStatusHander
from Handlers.CrawlerOnlineHandler import CrawlerOnlineHandler
from Handlers.AuthorsRanklistHandler import AuthorsRanklistHandler
from Handlers.ReportBugHandler import ReportBugHandler
from UIModule.HeaderModule import TitleModule
from UIModule.ProblemListModule import ProblemListModule
from UIModule.StatusItemModule import StatusItemModule
from UIModule.ContestItemModule import ContestItemModule
from UIModule.RanklistTableModule import RankListTableModule
from UIModule.OJSelectModule import OJSelectModule
from UIModule.SolvedProblemModule import SolvedProblemModule
from UIModule.ServerTimeModule import ServerTimeModule
from UIModule.ContestProblemListModule import ContestProblemListModule



define('port', default=48888, help='the open port', type=int)




class AppInit(tornado.web.Application):
    def __init__(self):
        # Url To Handler
        handlers = [
            (r'/', IndexHandler),

Answer:             (r'/login\/{0,1}', LogInHandler),