Esempio n. 1
0
class JudgeConsumer(threading.Thread):
    """
        判题请求队列
        请求格式:
            [operator (task)]
            [操作数 (任务消息)]

            0 None                            停止判题线程
            1 (sid, pid, uid, judge_type)     判题任务请求
    """

    def __init__(self, oj):
        super(JudgeConsumer, self).__init__()
        self.mysql = MySQL()
        self.oj = oj
        self.sid = None
        self.pid = None
        self.uid = None
        self.problem_id = None
        self.last_result = None
        self.language = None
        self.code = None

    def get_ready(self, info):
        self.sid, self.pid, self.uid, self.last_result = info
        self.mysql.update("UPDATE status_solve SET status = 'Judging' WHERE id = '%s'" % self.sid)
        result = self.mysql.query("SELECT language, code  FROM status_solve WHERE id = '%s'" % self.sid)
        self.language = result[0][0]
        self.code = result[0][1]
        result = self.mysql.query("SELECT problem_id  FROM problem_problem WHERE id = '%s'" % self.pid)
        self.problem_id = result[0][0]

    def judge(self):
        pass

    def judge_over(self):
        pass

    def run(self):
        while True:
            message = JudgeServer.judge_queue[self.oj].get()
            operator, info = message
            if operator == 0:
                return
            elif operator == 1:
                self.get_ready(info)
                self.judge()
                self.judge_over()
Esempio n. 2
0
class JudgeProducer(threading.Thread):
    def __init__(self, info):
        super(JudgeProducer, self).__init__()
        self.sid = info[0]
        self.rejudge = int(info[1])
        self.mysql = MySQL()
        self.oj = None
        self.pid = None
        self.uid = None
        self.judge_type = None
        self.get_info()
        self.update_status()

    def get_info(self):
        try:
            result = self.mysql.query("SELECT problem_id, user_id FROM status_solve WHERE id = '%s'" % self.sid)
        except MySQLQueryError:
            raise Exception
        try:
            self.pid = result[0][0]
            self.uid = result[0][1]
        except (IndexError, TypeError):
            raise Exception
        result = self.mysql.query("SELECT judge_type, oj FROM problem_problem WHERE id = '%s'" % self.pid)
        try:
            self.judge_type = result[0][0]
            self.oj = result[0][1]
        except IndexError:
            raise MySQLQueryError

    def update_status(self):
        self.mysql.update("UPDATE status_solve SET status = 'Queuing' WHERE id = '%s'" % self.sid)

    def run(self):
        try:
            JudgeServer.judge_queue[self.oj].put((1, (self.sid, self.pid, self.uid, self.judge_type)))
        except KeyError:
            pass
Esempio n. 3
0
class VirtualJudge(Judge):
    def __init__(self, username, password, last_sid, language, code, oj, problem_id, sid, cid=None):
        super(VirtualJudge, self).__init__(language, code)
        if oj == 'poj':
            self.code = base64.encodestring(self.code)
        if oj == 'hdu_std':
            self.code = std_encode(self.code)
        self.oj = oj
        self.pid = problem_id
        self.last_sid = last_sid
        self.username = username
        self.sid = sid
        self.cid = cid
        self.mysql = MySQL()
        self.ac = JudgeAccess(oj, username, password, cid)

    def judge(self):
        self.submit()
        sleep(0.5)
        try:
            self.search_sid()
        except JudgeSubmitError:
            status = "Judge ERROR"
            use_time = 0
            use_memory = 0
            self.update(status, use_time, use_memory)
            return
        status = self.refresh_status()
        while self.refresh_again(status[0]):
            sleep(0.2)
            status = self.refresh_status()
        if self.is_ce(status[0]):
            if self.cid is not None:
                url = URL_CE[self.oj] % (self.cid, self.last_sid)
            else:
                url = URL_CE[self.oj] + self.last_sid
            html = self.ac.visit(url)
            t = re.search(RE_Get_CE[self.oj], html, re.M | re.I | re.S)
            ce_info = t.group(1)
            self.save_ce(ce_info)

    def all_ready(self):
        return self.ac.is_login(self.cid)

    def submit(self):
        if self.cid is not None:
            url = URL_Submit[self.oj] % self.cid
            referer = URL_Referer[self.oj] % (self.cid, int(self.pid))
        else:
            url = URL_Submit[self.oj]
            referer = URL_Referer[self.oj] + str(self.pid)
        postdata = Submit_POST_Data[self.oj]
        postdata[Submit_POST_Data_List[self.oj][0]] = self.pid
        postdata[Submit_POST_Data_List[self.oj][1]] = VJ_Language_Map[self.oj][self.language]
        postdata[Submit_POST_Data_List[self.oj][2]] = self.code
        self.ac.visit(url, postdata, referer)

    def search_sid(self):
        sid = self.ac.get_last_sid()
        if int(sid) != int(self.last_sid):
            self.last_sid = sid
        else:
            raise JudgeSubmitError

    def refresh_status(self):
        if self.cid is not None:
            url = URL_Status[self.oj] % (self.cid, self.username)
        else:
            url = URL_Status[self.oj] + self.username
        html = self.ac.visit(url)
        match = re.search(RE_Judge_Status[self.oj] % self.last_sid, html, re.M | re.I | re.S)
        if match:
            status = match.group(1)
            use_time = match.group(2)
            use_memory = match.group(3)
        else:
            status = "Judge ERROR"
            use_time = 0
            use_memory = 0
        self.update(status, use_time, use_memory)
        return status, use_time, use_memory

    def refresh_again(self, s):
        status_list = [
            'Queuing',
            'Compiling',
            'Running',
            'Running & Judging',
            'Waiting',
        ]
        for i in status_list:
            if s == i:
                return True
        return False

    def is_ce(self, s):
        return s == 'Compilation Error'

    def update(self, status, use_time, use_memory):
        self.mysql.update(
            "UPDATE status_solve SET status = '%s', use_time = '%s', use_memory = '%s' WHERE id = '%s'" % (
                status, use_time, use_memory, self.sid
            )
        )

    def save_ce(self, ce_info):
        sql = "SELECT info FROM status_ce_info WHERE solve_id = '%s'" % self.sid
        result = self.mysql.query(sql)
        if result:
            sql = "UPDATE status_ce_info SET info = '%s' WHERE solve_id = '%s'" % (ce_info, self.sid)
            self.mysql.update(sql)
        else:
            sql = "INSERT INTO status_ce_info (info, solve_id) VALUES('%s', '%s')" % (ce_info, self.sid)
            self.mysql.update(sql)
Esempio n. 4
0
class Contest(threading.Thread):
    def __init__(self, oj, username, password, cid, contest_id):
        super(Contest, self).__init__()
        self.oj = oj
        self.cid = cid
        self.username = username
        self.password = password
        self.contest_id = contest_id
        self.ac = ContestProblemAccess(oj, username, password, cid)
        self.mysql = MySQL()

    def test_contest(self):
        if not self.ac.is_login(self.cid):
            return False
        try:
            self.ac.visit(URL_Problem[self.oj] % (1001, self.cid))
        except VisitError:
            return False
        except NoSuchProblem:
            return False
        return True

    def get_problem_number(self):
        if not self.test_contest():
            return 0
        try:
            html = self.ac.visit(OJ_Index[self.oj] % self.cid)
        except VisitError:
            return 0
        return len(re.findall(r'class=table_text align=center', html, re.M | re.I))

    def run(self):
        problem_list = []
        sql = "SELECT in_problem_id FROM contest_contest_problem WHERE contest_id='%d'" % self.contest_id
        in_problem_id_list = self.mysql.query(sql)
        for x in in_problem_id_list:
            in_problem_id = x[0]
            sql = "SELECT problem_new_id, problem_id FROM contest_in_problem WHERE id='%d'" % in_problem_id
            probelm_new_id, problem_id = self.mysql.query(sql)[0]
            problem = ContestProblem(self.oj, self.username, self.password, self.cid, int(probelm_new_id) + 1001,
                                     problem_id)
            problem.run()
            problem_list.append([in_problem_id, problem_id])
        try:
            html = self.ac.visit(OJ_Index[self.oj] % self.cid)
        except VisitError:
            return
        match = re.search(r'<h1.*?>(.*?)</h1>', html, re.M | re.I)
        title = match.group(1) if match else None
        if title is not None:
            sql = "UPDATE contest_contest SET title='%s' WHERE id='%d'" % (title, self.contest_id)
            self.mysql.update(sql)
        match = re.search(r'Start Time : (.*?)&nbsp;?', html, re.M | re.I)
        start_time = match.group(1) if match else None
        if start_time is not None:
            sql = "UPDATE contest_contest SET start_time='%s' WHERE id='%d'" % (start_time, self.contest_id)
            self.mysql.update(sql)
        match = re.search(r'End Time : (.*?)<br>', html, re.M | re.I)
        end_time = match.group(1) if match else None
        if end_time is not None:
            sql = "UPDATE contest_contest SET end_time='%s' WHERE id='%d'" % (end_time, self.contest_id)
            self.mysql.update(sql)
        for i in problem_list:
            in_problem_id = i[0]
            problem_id = i[1]
            sql = "SELECT title FROM problem_problem WHERE id='%d'" % problem_id
            title = self.mysql.query(sql)[0][0]
            title = self.mysql.db.escape_string(title)
            sql = "UPDATE contest_in_problem SET title = '%s' WHERE id = '%d'" % (title, in_problem_id)
            self.mysql.update(sql)
Esempio n. 5
0
class JudgeServer(threading.Thread):
    """
        Judge服务
        任务获取格式:
            [operator (task)]
            [操作数 (任务消息)]

            0 None              开启judge服务
            1 None              停止judge服务
            2 None              重启judge服务
            3 (sid, rejudge)    判题任务请求
    """

    RUN = False
    judge_task = None
    judge_queue = {}
    judge_consumers = {}

    def __init__(self):
        super(JudgeServer, self).__init__()
        self.mysql = MySQL()
        JudgeServer.judge_task = Queue(Task_Limit)

    def judge_start(self):
        if not len(JudgeServer.judge_consumers):
            self.make_judge_queue()
        JudgeServer.RUN = True

    def judge_stop(self):
        for oj in JudgeServer.judge_queue:
            for x in range(JudgeServer.judge_queue[oj].maxsize):
                JudgeServer.judge_queue[oj].put((0, None))
        while not self.all_stop():
            pass
        JudgeServer.judge_queue = {}
        JudgeServer.judge_consumers = {}
        JudgeServer.RUN = False

    def judge_restart(self):
        self.judge_stop()
        self.judge_start()

    def make_judge_queue(self):
        JudgeServer.judge_queue[OJ_NAME] = Queue(Local_Judge_Limit)
        JudgeServer.judge_consumers[OJ_NAME] = []
        for i in range(Local_Judge_Limit):
            JudgeServer.judge_consumers[OJ_NAME].append(LocalJudgeConsumer(OJ_NAME, path_index=i))
            JudgeServer.judge_consumers[OJ_NAME][-1].setDaemon(True)
            JudgeServer.judge_consumers[OJ_NAME][-1].start()
        oj_list = self.mysql.query("SELECT DISTINCT oj FROM core_judge_account WHERE defunct=0")
        for x in oj_list:
            oj = x[0]
            JudgeServer.judge_consumers[oj] = []
            judge_account = self.mysql.query(
                "SELECT username, password FROM core_judge_account WHERE oj='%s' AND defunct=0" % oj
            )
            JudgeServer.judge_queue[oj] = Queue(len(judge_account))
            for username, password in judge_account:
                JudgeServer.judge_consumers[oj].append(VirtualJudgeConsumer(oj, username=username, password=password))
                JudgeServer.judge_consumers[oj][-1].setDaemon(True)
                JudgeServer.judge_consumers[oj][-1].start()

    def all_stop(self):
        return "JudgeConsumer" not in "".join([str(x.__class__) for x in threading.enumerate()])

    def run(self):
        if not len(JudgeServer.judge_consumers):
            self.judge_start()
        while True:
            task = JudgeServer.judge_task.get()
            operator = task[0]
            info = task[1:]
            if operator == "0":
                self.judge_start()
            elif operator == "1":
                self.judge_stop()
            elif operator == "2":
                self.judge_restart()
            elif operator == "3":
                if JudgeServer.RUN:
                    new_judge = JudgeProducer(info)
                    new_judge.start()
            else:
                pass