Ejemplo n.º 1
0
 def tdmaker_receive_judge_result(self, id):
     """
     [TDMaker]接收评测结果(写入全新的测试数据)
     :param sid: JudgeStatus ID
     :return:
     """
     self._action = kernel.const.VIEW_ACTION_JSON
     if not self._license_check():
         return
     result = self._request.POST.get("result")
     root = json.loads(result)
     tdq = ProblemMdl.TdmakerQueue.objects.filter(id=id)
     if tdq.exists():
         tdq = tdq[0]
         tdq.flag = root.get('exitcode', 8)
         tdq.memused = root.get('memused', 0)
         tdq.timeused = root.get('timeused', 0)
         tdq.save()
         session_id = root.get('session_id', '0')
         out_tmp_dir = kernel.LocalStorage(
             kernel.const.PROGRAM_RUN_OUTDATAS_TEMP, session_id)
         out_target_dir = kernel.LocalStorage(
             kernel.const.PROBLEM_TESTDATA_DIR, str(tdq.problem.id))
         testdata = tdq.problem.test_data.all()
         for td in testdata:
             handle = td.handle
             out_target_dir.clone_file(
                 "%s.out" % handle,
                 out_tmp_dir.get_file_path("%s.outdata" % handle))
         out_tmp_dir.delete('')  # 删除当前目录
         self._result = kernel.RESTStruct(True, data=True)
     else:
         self._result = kernel.RESTStruct(
             False, msg="Error: No tdmaker status found.")
Ejemplo n.º 2
0
 def _exchange_progrem_run_outdata(self, status, session_id, outdatas):
     """
     将程序输出结果复制到永久存储文件夹
     :param status:
     :param outdatas:
     :return:
     """
     out_tmp_dir = kernel.LocalStorage(
         kernel.const.PROGRAM_RUN_OUTDATAS_TEMP, session_id)
     out_target_dir = kernel.LocalStorage(kernel.const.PROGRAM_RUN_OUTDATAS,
                                          str(status.id))
     if outdatas is not None:
         for key, val in outdatas.iteritems():
             out_target_dir.clone_file(val, out_tmp_dir.get_file_path(val))
     out_tmp_dir.delete('')  # 删除当前目录
Ejemplo n.º 3
0
    def testdata_download(self, pid, handle, filetype='in'):
        # 测试数据下载接口
        self._action = kernel.const.VIEW_ACTION_DEFAULT

        if not self._check_login(ajax=True):
            return

        query = PBInc.ProblemBodyQuery()
        problem = query.get_problem_detail(pid, True)
        if problem is None:
            self._action = kernel.const.VIEW_ACTION_DEFAULT
            self._context = "[ERROR]未找到题目信息"
            return

        if not self.__check_permission(problem, True):
            return

        testdata = problem.test_data.filter(handle=handle)
        if not testdata.exists():
            self._action = kernel.const.VIEW_ACTION_DEFAULT
            self._context = "[ERROR]未找到测试数据信息"
            return

        td = testdata[0]
        self._action = kernel.const.VIEW_ACTION_DOWNLOAD
        self._context = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                            str(problem.id))
        self._template_file = "%s.%s" % (str(td.handle), filetype)
        self._download_filename = "%s.%s" % (str(td.name), filetype)
Ejemplo n.º 4
0
    def new_testdata(self, pid):
        # 新建测试数据接口
        self._action = kernel.const.VIEW_ACTION_JSON

        if not self._check_login(ajax=True):
            return

        query = PBInc.ProblemBodyQuery()
        problem = query.get_problem_detail(pid, True)
        if problem is None:
            self._result = kernel.RESTStruct(False, '题目信息未找到')
            return

        if not self.__check_permission(problem, True, owner_only=True):
            return

        order = problem.test_data.count() + 1

        td = ProblemMdl.TestData()
        td.handle = kernel.GeneralTools.get_my_handle_id()
        td.name = "Problem %s Testdata %d" % (str(problem.id), order)
        td.order = order
        td.available = True
        td.visible = False
        td.update_time = 0
        td.save()

        stor = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                   str(problem.id))
        stor.new_file("%s.in" % str(td.handle), '')
        stor.new_file("%s.out" % str(td.handle), '')

        problem.test_data.add(td)

        self._result = kernel.RESTStruct(True)
Ejemplo n.º 5
0
    def delete_testdata(self, pid, handle):
        # 删除测试数据接口
        self._action = kernel.const.VIEW_ACTION_JSON

        if not self._check_login(ajax=True):
            return

        query = PBInc.ProblemBodyQuery()
        problem = query.get_problem_detail(pid, True)
        if problem is None:
            self._result = kernel.RESTStruct(False, '题目信息未找到')
            return

        if not self.__check_permission(problem, True, owner_only=True):
            return

        testdata = problem.test_data.filter(handle=handle)
        if not testdata.exists():
            self._result = kernel.RESTStruct(False, '未找到测试数据信息')
            return

        td = testdata[0]
        stor = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                   str(problem.id))
        stor.delete("%s.in" % str(td.handle))
        stor.delete("%s.out" % str(td.handle))
        td.delete()

        if problem.test_data.count() == 0:
            problem.pause_judge = True
            problem.save()

        self._result = kernel.RESTStruct(True)
Ejemplo n.º 6
0
    def repository_new_folder(self, repo_handle):
        """
        新建文件夹
        :return:
        """
        self._action = kernel.const.VIEW_ACTION_JSON
        if not self._check_login(True):
            return
        if self._user_session.user_role < 2:
            self._result = kernel.RESTStruct(False, '当前账户没有操作权限')
            return

        repo = self._get_repository(repo_handle)
        if repo is None:
            self._result = kernel.RESTStruct(False, '找不到仓库')
            return
        if not self.__general_permission_check(repo, True):
            return

        stor = kernel.LocalStorage(kernel.const.EDU_REPOSITORY_ROOT_DIR, repo_handle)
        path = self._request.POST.get("path", "").replace("../", "").replace("..", "")
        stor = stor.get_child_dir_storage(path)
        print stor.get_current_path()
        folder_name = self._request.POST.get("folder_name", "")

        if folder_name.strip() == "":
            self._result = kernel.RESTStruct(False, '请输入新文件夹名')
            return
        stor.new_folder(folder_name)
        self._result = kernel.RESTStruct(True)
Ejemplo n.º 7
0
    def testdata_upload_api(self, pid, handle):
        # 测试数据上传接口
        self._action = kernel.const.VIEW_ACTION_JSON

        if not self._check_login(ajax=True):
            return

        query = PBInc.ProblemBodyQuery()
        problem = query.get_problem_detail(pid, True)
        if problem is None:
            self._result = kernel.RESTStruct(False, '题目信息未找到')
            return

        if not self.__check_permission(problem, True, owner_only=True):
            return

        testdata = problem.test_data.filter(handle=handle)
        if not testdata.exists():
            self._result = kernel.RESTStruct(False, '未找到测试数据信息')
            return

        td = testdata[0]
        try:
            file_in = self._request.FILES.get('uploadFileIn', None)
            file_out = self._request.FILES.get('uploadFileOut', None)
            th = td.handle

            stor = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                       str(problem.id))

            if file_in is not None:
                if file_in.size > 16 * 1024 * 1024:
                    self._result = kernel.RESTStruct(False, u'上传文件过大!')
                    return
                fp = stor.open_file("%s.in" % th, 'wb+')
                for chunk in file_in.chunks():
                    fp.write(chunk)
                fp.close()
                self._clear_BOM(stor, "%s.in" % th)

            if file_out is not None:
                if file_out.size > 16 * 1024 * 1024:
                    self._result = kernel.RESTStruct(False, u'上传文件过大!')
                    return
                fp = stor.open_file("%s.out" % th, 'wb+')
                for chunk in file_out.chunks():
                    fp.write(chunk)
                fp.close()
                self._clear_BOM(stor, "%s.out" % th)

            self._result = kernel.RESTStruct(True)
        except BaseException, ex:
            self._result = kernel.RESTStruct(False,
                                             msg="上传数据保存错误(%s)" % str(ex))
Ejemplo n.º 8
0
 def _get_repository_detail(self, handle, path):
     """
     读取仓库文件列表
     :param handle:
     :return:
     """
     if handle is None:
         return None
     stor = kernel.LocalStorage(kernel.const.EDU_REPOSITORY_ROOT_DIR, handle)
     return {
         "dirs": stor.get_dirs_list(path),
         "files": stor.get_files_list(path, with_info=True)
     }
Ejemplo n.º 9
0
    def testdata_view(self, pid, handle):
        # 查看测试数据
        if not self._check_login(ajax=True, no_redirect=True):
            return
        query = PBInc.ProblemBodyQuery()
        problem = query.get_problem_detail(pid, True)
        if problem is None:
            self._action = kernel.const.VIEW_ACTION_DEFAULT
            self._context = "[ERROR]未找到题目信息"
            return
        if not self.__check_permission(problem, no_redirect=True):
            return
        testdata = problem.test_data.filter(handle=handle)
        if not testdata.exists():
            self._action = kernel.const.VIEW_ACTION_DEFAULT
            self._context = "[ERROR]未找到测试数据信息"
            return
        td = testdata[0]

        stor = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                   str(problem.id))
        if stor.get_file_size("%s.in" % str(td.handle)) < 1048576:
            tdin = stor.read_file("%s.in" % str(td.handle))
        else:
            tdin = None
        if stor.get_file_size("%s.out" % str(td.handle)) < 1048576:
            tdout = stor.read_file("%s.out" % str(td.handle))
        else:
            tdout = None

        if tdin is None or tdout is None:
            self._action = kernel.const.VIEW_ACTION_DEFAULT
            self._context = "[ERROR] 测试数据过大,请考虑通过上传下载来处理"
        else:
            try:
                if tdin is not None:
                    tdin = tdin.encode("utf-8")
            except:
                tdin = '(数据加载失败,请勿点击保存按钮以防数据覆盖)'
            try:
                if tdout is not None:
                    tdout = tdout.encode("utf-8")
            except:
                tdout = '(数据加载失败,请勿点击保存按钮以防数据覆盖)'
            self._template_file = "problem/manager/testdata_view.html"
            self._context = {
                "td": td,
                "problem": problem,
                "in": tdin,
                "out": tdout
            }
Ejemplo n.º 10
0
    def repository_upload_file(self, repo_handle):
        """
        上传文件
        :return:
        """
        self._action = kernel.const.VIEW_ACTION_JSON
        if not self._check_login(True):
            return
        if self._user_session.user_role < 2:
            self._result = kernel.RESTStruct(False, '当前账户没有操作权限')
            return

        repo = self._get_repository(repo_handle)
        if repo is None:
            self._result = kernel.RESTStruct(False, '找不到仓库')
            return
        if not self.__general_permission_check(repo, True):
            return

        path = self._request.POST.get("path", "").replace("../", "").replace("..", "")
        stor = kernel.LocalStorage(kernel.const.EDU_REPOSITORY_ROOT_DIR, repo_handle)

        if not stor.exists(path):
            self._result = kernel.RESTStruct(False, '上传位置的文件夹不存在')
            return

        try:
            files = self._request.FILES.get('uploadFile', None)
            if files is None:
                self._result = kernel.RESTStruct(False, '无文件上传!')
                return

            if files.size == 0:
                self._result = kernel.RESTStruct(False, '无文件上传!')
                return

            if files.size > 1024*1024*1024:
                self._result = kernel.RESTStruct(False, '由于服务器硬盘空间大小限制,需要上传超过1G的文件请于管理员联系!')
                return

            file_name = "%s/%s" % (path, files.name.encode('utf-8'))

            destination = stor.open_file(file_name, "wb+")
            for chunk in files.chunks():
                destination.write(chunk)
            destination.close()

            self._result = kernel.RESTStruct(True)

        except BaseException, ex:
            self._result = kernel.RESTStruct(False, u'上传数据保存错误(%s)' % str(ex))
Ejemplo n.º 11
0
    def asgn_score_counter(self, course_id):
        """
        作业成绩统计提供程序
        :param course_id:
        :return:
        """
        if self._user_session.user_role not in [2, 99]:
            self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
            self._context = kernel.error_const.ERROR_ADMIN_PERMISSION_DENIED
            return
        course = self._get_course_by_id(course_id)
        if course is None:
            self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
            self._context = kernel.error_const.ERROR_EDU_COURSE_NOT_FOUND
            return
        asgn_ids = self._request.POST.getlist('aids')

        type = self._request.POST.get('type', 'all')
        if type == 'stucode':
            files = self._request.FILES.get('stuno_xls')
            if files is not None:
                stucodes = []
                path = "asgn_score_counter/%s.xls" % (uuid.uuid4())
                file_name = os.path.join(kernel.const.IMPORT_PROCESS_TEMP_DIR,
                                         path)
                destination = open(file_name, 'wb+')
                for chunk in files.chunks():
                    destination.write(chunk)
                destination.close()
                xls_sheet = xlrd.open_workbook(file_name)
                xls_table = xls_sheet.sheet_by_index(0)
                for i in range(1, xls_table.nrows):
                    stucodes.append(str(xls_table.row_values(i)[0]))
                print stucodes
            else:
                stucodes = None
        else:
            stucodes = None

        stu_score = self._asgn_score_count(course, asgn_ids, stucodes)
        fn, fp = self._export_score_to_xls(course, asgn_ids, stu_score,
                                           stucodes)

        self._action = kernel.const.VIEW_ACTION_DOWNLOAD
        self._context = kernel.LocalStorage(
            kernel.const.EXPORT_PROCESS_TEMP_DIR, 'asgn_score_counter')
        self._template_file = fn
        self._download_filename = "score.xls"
        return
Ejemplo n.º 12
0
    def save_testdata_view(self, pid):
        # 保存测试数据内容的接口
        self._action = kernel.const.VIEW_ACTION_JSON

        if not self._check_login(ajax=True):
            return

        query = PBInc.ProblemBodyQuery()
        problem = query.get_problem_detail(pid, True)
        if problem is None:
            self._result = kernel.RESTStruct(False, '题目信息未找到')
            return

        if not self.__check_permission(problem, True, owner_only=True):
            return

        handle = self._request.POST.get('handle', '')
        testdata = problem.test_data.filter(handle=handle)
        if not testdata.exists():
            self._result = kernel.RESTStruct(False, '未找到测试数据信息')
            return

        tdin = self._request.POST.get('in',
                                      '').replace("\r\n",
                                                  '\n').replace("\r", "\n")
        tdout = self._request.POST.get('out',
                                       '').replace("\r\n",
                                                   '\n').replace("\r", "\n")

        if tdin == u"(数据加载失败,请勿点击保存按钮以防数据覆盖)":
            self._result = kernel.RESTStruct(False, '防覆盖保护')
            return
        if tdout == u"(数据加载失败,请勿点击保存按钮以防数据覆盖)":
            self._result = kernel.RESTStruct(False, '防覆盖保护')
            return

        stor = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                   str(problem.id))
        stor.new_file("%s.in" % str(handle), tdin)
        stor.new_file("%s.out" % str(handle), tdout)

        self._result = kernel.RESTStruct(True)
Ejemplo n.º 13
0
 def asgn_zip_the_codes(self, asgn_id):
     """
     打包代码实现程序
     :param asgn
     :return:
     """
     self._action = kernel.const.VIEW_ACTION_JSON
     asgn = self._get_asgn_detail(asgn_id)
     if asgn is None:
         self._result = kernel.RESTStruct(False, u'未找到作业')
         return
     if not self.__check_permission(asgn, True):
         return
     encoding = self._request.POST.get('encoding', 'gbk')
     separators = self._request.POST.get('separators', '\\')
     if separators != '\\' and separators != '/':
         separators = '\\'
     filename = "%s.zip" % uuid.uuid4()
     filepath = "%s/%s/%s" % (kernel.const.EXPORT_PROCESS_TEMP_DIR,
                              'asgn_zip', filename)
     storage = kernel.LocalStorage(kernel.const.USER_UPLOADCODE_DIR, '')
     zf = zipfile.ZipFile(filepath, "w", zipfile.zlib.DEFLATED)
     judge_status = asgn.judge_status.filter(flag=0)
     for status in judge_status:
         if not storage.exists(status.code_path):
             return
         upload_code = storage.get_file_path(status.code_path)
         stor_name = u"%s_%s%c%s_%s.%s" % (
             status.author.id, status.author.realname, separators,
             status.problem.id, status.id,
             kernel.const.SOURCE_CODE_EXTENSION.get(status.lang))
         if encoding == 'utf-8':
             zf.write(upload_code, stor_name)
         else:
             zf.write(upload_code, stor_name.decode('utf-8').encode('gbk'))
     zf.close()
     self._result = kernel.RESTStruct(True, data=filename)
     return
Ejemplo n.º 14
0
    def delete_repository(self, repo_handle=None):
        """
        删除仓库
        :param repo_handle:
        :return:
        """
        self._action = kernel.const.VIEW_ACTION_JSON
        if not self._check_login(True):
            return
        if self._user_session.user_role < 2:
            self._result = kernel.RESTStruct(False, '当前账户没有操作权限')
            return
        repo = self._get_repository(repo_handle)
        if repo is None:
            self._result = kernel.RESTStruct(False, '找不到仓库')
            return
        if not self.__general_permission_check(repo, True):
            return

        repo.delete()
        stor = kernel.LocalStorage(kernel.const.EDU_REPOSITORY_ROOT_DIR, '')
        stor.delete(repo_handle)
        self._result = kernel.RESTStruct(True)
Ejemplo n.º 15
0
    def repository_delete_files(self, repo_handle):
        """
        删除仓库内的文件或文件夹
        :return:
        """
        self._action = kernel.const.VIEW_ACTION_JSON
        if not self._check_login(True):
            return
        if self._user_session.user_role < 2:
            self._result = kernel.RESTStruct(False, '当前账户没有操作权限')
            return

        repo = self._get_repository(repo_handle)
        if repo is None:
            self._result = kernel.RESTStruct(False, '找不到仓库')
            return
        if not self.__general_permission_check(repo, True):
            return

        path = self._request.GET.get("path", "").replace("../", "").replace("..", "")
        stor = kernel.LocalStorage(kernel.const.EDU_REPOSITORY_ROOT_DIR, repo_handle)
        stor.delete(path)
        self._result = kernel.RESTStruct(True)
Ejemplo n.º 16
0
    def mgr_code_compare(self, contest_id, ca_id):
        """
        代码查重列表
        :param contest_id:
        :return:
        """
        if not self._check_login():
            return

        contest = self._get_contest(contest_id)
        if contest is None:
            self._send_error_contest_doesnt_exists()
            return
        tflag, dsc = self._check_time_passed(contest)
        if tflag < 1:
            if not self._check_admin_permission(contest):
                self._send_error_contest_permission_denied()
                return

        ca = DCModel.ContestCodeAnalysis.objects.filter(contest=contest, id=ca_id)
        if not ca.exists():
            self._context = '没有找到指定的代码分析结果记录'
            self._action = kernel.const.VIEW_ACTION_DEFAULT
            return
        ca = ca[0]

        ls = kernel.LocalStorage(kernel.const.USER_UPLOADCODE_DIR, '')
        code1 = ls.read_file(ca.status1.code_path)
        code2 = ls.read_file(ca.status2.code_path)

        self._template_file = "contest/manager/code_compare.html"
        self._context = {
            'code_analysis': ca,
            'code1': code1,
            'code2': code2
        }
Ejemplo n.º 17
0
    def judge_detail(self, sid):
        """
        评测机报告页面
        :param sid: 评测状态记录
        :return:
        """

        # asgn_id = self._request.GET.get('asgn_id', None)
        # contest_id = self._request.GET.get('contest_id', None)
        if not self._user_session.is_logined():
            self._action = kernel.const.VIEW_ACTION_LOGIN_REQUEST
            self._redirect_url = self._request.path
            return

        status = self._get_judge_status_detail(sid)
        # 如果当前评测状态不存在
        if status is None:
            self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
            self._context = kernel.error_const.ERROR_READ_JUDGE_RESULT_FAILED
            return

        try:
            if status.callback is not None and status.callback.strip() != '':
                callback = json.loads(status.callback)
            else:
                callback = None
        except:
            callback = None

        asgn_id = None
        contest_id = None

        if callback is not None:
            if callback.get('provider', '') == 'asgn':
                asgn_id = callback.get('id')
            elif callback.get('provider', '') == 'contest':
                contest_id = callback.get('id')

        if contest_id is not None:
            contest = ContestModel.Contest.objects.filter(id=contest_id)
            if contest.exists():
                contest = contest[0]
                if self._user_session.user_id != contest.author.id and contest.end_time < int(
                        time.time()):
                    self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                    self._context = kernel.error_const.ERROR_CONTEST_VISIT_STATUS_AFTER_CONTEST_ENDED
                    return

        # 如果这个评测状态不是由当前用户生成的
        if self._user_session.user_id != status.author.id:
            # 如果这是一个比赛的评测状态
            if contest_id is not None:
                contest = ContestModel.Contest.objects.filter(id=contest_id)
                if contest.exists():
                    contest = contest[0]
                    referees = str(contest.referees).split('\n')
                    referees.append(str(contest.author.id))
                    if str(self._user_session.user_id) not in referees:
                        self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                        self._context = kernel.error_const.ERROR_JUDGE_RESULT_ONLY_USER
                        return
                else:
                    self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                    self._context = kernel.error_const.ERROR_JUDGE_RESULT_ONLY_USER
                    return
            else:
                # 如果当前用户不是老师、管理员中任意角色
                if self._user_session.user_role not in [2, 3, 99]:
                    if asgn_id is not None:
                        asgn = AsgnModel.Asgn.objects.filter(id=asgn_id)
                        if asgn.exists():
                            # 助教检查
                            if not asgn[0].course.assistants.filter(
                                    id=self._user_session.user_id).exists():
                                self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                                self._context = kernel.error_const.ERROR_JUDGE_RESULT_ONLY_USER
                                return
                        else:
                            self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                            self._context = kernel.error_const.ERROR_JUDGE_RESULT_ONLY_USER
                            return
                    else:
                        self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                        self._context = kernel.error_const.ERROR_JUDGE_RESULT_ONLY_USER
                        return
                # 如果当前用户是老师,但是题目设置了私有查看
                if (self._user_session.user_role !=
                        99) and (status.problem.is_private is True):
                    self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
                    self._context = kernel.error_const.ERROR_JUDGE_RESULT_ONLY_USER
                    return
        try:
            if status.result is not None and status.result != '':
                result = json.loads(status.result)
            else:
                result = {}

            upstor = kernel.LocalStorage(kernel.const.USER_UPLOADCODE_DIR, '')
            upload_code = upstor.read_file(status.code_path)

            testdata_detail = None

            if status.flag in [0, 1, 2, 3, 4, 5, 6]:  # 已有评测数据

                outdatas = result.get('outdatas', {})
                detail = result.get('result', {})
                odstor = kernel.LocalStorage(kernel.const.PROGRAM_RUN_OUTDATAS,
                                             str(status.id))
                tdstor = kernel.LocalStorage(kernel.const.PROBLEM_TESTDATA_DIR,
                                             str(status.problem.id))
                testdatas = status.problem.test_data.order_by('order')
                testdata_detail = []
                for td in testdatas:
                    v = detail.get(td.handle, {})
                    if v.get('result', -3) not in [0, 1, 2, 3, 4, 5, 6, 7, 8]:
                        continue
                    d = {
                        "memoryused":
                        v.get('memoryused', 0),
                        "timeused":
                        v.get('timeused', 0),
                        "result":
                        v.get('result', -3),
                        "handle":
                        td.handle,
                        "name":
                        td.name,
                        "signal":
                        v.get('re_signum', 0),
                        "signal_desc":
                        kernel.const.SIGNUM_DESC.get(v.get('re_signum', 0),
                                                     '未知'),
                    }
                    # 如果不是管理员或者老师,并且设置了隐藏测试数据
                    if (not td.visible) and (self._user_session.user_role
                                             not in [2, 3, 99]):
                        d['forbidden'] = True
                    else:
                        if v.get('result', -3) in [0, 1, 4, 6]:
                            infile_size = tdstor.get_file_size('%s.in' %
                                                               td.handle)
                            outfile_size = tdstor.get_file_size('%s.out' %
                                                                td.handle)
                            odfile_size = odstor.get_file_size('%s.outdata' %
                                                               td.handle)
                            if (infile_size > 2 * 100 * 1024) or (
                                    outfile_size > 2 * 100 * 1024) or (
                                        odfile_size > 2 * 100 * 1024):
                                d['too_large'] = True
                                testdata_detail.append(d)
                                continue
                            try:
                                d['in'] = tdstor.read_file(
                                    '%s.in' % td.handle).encode("utf-8")
                            except:
                                d['in'] = "出现错误的字符,系统无法解码,请检查程序输出"
                            try:
                                d['out'] = tdstor.read_file(
                                    '%s.out' % td.handle).encode("utf-8")
                            except:
                                d['out'] = "出现错误的字符,系统无法解码,请检查程序输出"
                            try:
                                d['outdata'] = odstor.read_file(
                                    '%s.outdata' % td.handle).encode("utf-8")
                            except:
                                d['outdata'] = "出现错误的字符,系统无法解码,请检查程序输出"

                    testdata_detail.append(d)

                pass

            self._template_file = "problem/status/detail.html"
            self._context = {
                'status': status,
                'result': result,
                'detail': testdata_detail,
                'upload_code': upload_code
            }

        except BaseException, ex:
            self._action = kernel.const.VIEW_ACTION_ERROR_PAGE
            self._context = kernel.error_const.ERROR_READ_JUDGE_RESULT_FAILED
            return
Ejemplo n.º 18
0
    def _save_submission(self, pid, force_judge=False):
        """
        保存提交(Control)
        :param pid: 问题ID
        :param force_judge: 是否强制开启评测
        :return:
        """

        if self._config.web_stop_judging and (not force_judge):
            return kernel.RESTStruct(False, msg='评测系统已经被管理员暂停,请稍后再试')

        problem = ProblemBodyQuery.get_problem_detail(pid)
        if problem is None:
            return kernel.RESTStruct(False, msg='题目信息不存在')

        if problem.pause_judge and (not force_judge):
            return kernel.RESTStruct(False, msg='当前题目暂停评测,请稍后再试')

        code_content = self._request.POST.get('content')
        code_lang = self._request.POST.get('lang')

        if not kernel.const.LANGUAGE_DESCRIPTION.has_key(code_lang):
            return kernel.RESTStruct(False, msg='不支持的评测语言')

        if len(code_content) < 40:
            return kernel.RESTStruct(False, msg='代码长度小于40个字符,无法进行评测')

        if str(code_lang) == 'java':
            if ('public class Main'
                    not in code_content) or ('public static void main'
                                             not in code_content):
                return kernel.RESTStruct(
                    False,
                    msg='Java语法错误:请注意,Java评测时类名必须为Main,并且类中应该定义程序入口main方法')
        else:
            if ('shutdown' in code_content) or ('system' in code_content) or (
                    '__asm__' in code_content) or ('reboot' in code_content):
                return kernel.RESTStruct(False, msg='非法关键字:检测到您的代码可能危害评测系统。')

        # 保存代码
        status_count = ProblemMdl.JudgeStatus.objects.count()
        pack_name = str(int(status_count / 1000))  # 每1000个分开存储
        file_name = "%s.%s" % (ProblemBody.__get_upload_code_only_name(),
                               kernel.const.SOURCE_CODE_EXTENSION[code_lang])
        full_path = "%s/%s" % (pack_name, file_name)

        storage = kernel.LocalStorage(kernel.const.USER_UPLOADCODE_DIR,
                                      pack_name)
        rel = storage.new_file(file_name, code_content)
        if not rel:
            return kernel.RESTStruct(False, msg='上传代码保存失败, 可能是系统的问题,请重试!')

        # 生成评测状态
        status = ProblemMdl.JudgeStatus()
        status.author = self._user_session.entity
        status.problem = problem
        status.timestamp = int(time.time())
        status.code_len = len(code_content)
        status.lang = code_lang
        status.code_path = full_path
        status.save()

        # 生成评测统计
        pv = ProblemMdl.ProblemVisited.objects.filter(
            problem=problem, author=self._user_session.entity)
        if pv.exists():
            pv = pv[0]
            pv.submissions = ProblemMdl.JudgeStatus.objects.filter(
                problem=problem, author=self._user_session.entity).count()
            pv.save()
        else:
            pv = ProblemMdl.ProblemVisited()
            pv.problem = problem
            pv.author = self._user_session.entity
            pv.submissions = 1
            pv.save()
        problem.total += 1
        problem.save()

        # 进入评测队列(暂时使用的队列系统)
        queue = ProblemMdl.JudgeQueue()
        queue.judge_status = status
        queue.save()

        return kernel.RESTStruct(True, data=status)