first commit

This commit is contained in:
2025-10-11 11:23:58 +08:00
commit e8774085f8
48 changed files with 3087 additions and 0 deletions

271
python/entity.py Executable file
View File

@@ -0,0 +1,271 @@
import string, os, stat, threading, logging, bz2
import unittest
from engineconfig import getConfig
from judgescript import InternalJudge, ExternalJudge
class Problem:
def __init__(self, datasource, row):
self.tests = None
self.presetcodes = {}
self.datafiles = None
self.datasource = datasource
self.id = row['id']
self.timemodified = row['timemodified']
self.vcode = row['validator_code']
if not isinstance(self.vcode, (str, unicode)):
self.vcode = self.vcode.__str__()
self.vtype = row['validator_type']
self.vlang = row['validator_lang']
self.gcode = row['generator_code']
if not isinstance(self.gcode, (str, unicode)):
self.gcode = self.vcode.__str__()
self.gtype = row['generator_type']
self.standard_code = row['standard_code']
if row.has_key('input_filename') and row['input_filename']:
self.input_filename = row['input_filename']
else:
self.input_filename = None
if row.has_key('output_filename') and row['output_filename']:
self.output_filename = row['output_filename']
else:
self.output_filename = None
def get_judge_script(self):
if self.vtype == 'comparetext':
return InternalJudge()
elif self.vtype == 'comparetextwithpe':
return InternalJudge(allowpe = True)
elif self.vtype == 'comparefile':
code = open('scripts/compare-file.py').read()
return ExternalJudge(self.id, 'python-2.5', code)
elif self.vtype == 'customized':
return ExternalJudge(self.id, self.vlang, self.vcode)
def get_testcases(self):
if not self.tests:
self.tests = self.datasource.get_tests(self.id, False)
for testcase in self.tests:
testcase.problem = self
return self.tests
def get_input_filename(self):
return self.input_filename
def get_output_filename(self):
return self.output_filename
def get_presetcodes(self, lang):
if not self.presetcodes.has_key(lang):
codes = self.datasource.get_presetcodes(self.id, lang)
for code in codes: code.problem = self
self.presetcodes[lang] = codes
return self.presetcodes[lang]
def get_datafiles(self):
if not self.datafiles:
self.datafiles = self.datasource.get_datafiles(self.id)
return self.datafiles
class Submit:
def __init__(self, datasource, row):
self.datasource = datasource
self.problem = None
self.id = row['id']
self.problem_id = row['problem_id']
self.language = row['language']
self.code = row['code']
def get_problem(self):
if not self.problem:
self.problem = self.datasource.get_problem(self.problem_id)
return self.problem
def get_testcases(self):
return self.get_problem().get_testcases()
def get_judge_script(self):
return self.get_problem().get_judge_script()
def get_input_filename(self):
return self.get_problem().get_input_filename()
def get_output_filename(self):
return self.get_problem().get_output_filename()
def get_presetcodes(self):
return self.get_problem().get_presetcodes(self.language)
def set_compilemessage(self, msg):
return self.datasource.update_submit_compilemessage(self.id, msg)
def set_status(self, newstatus):
return self.datasource.update_submits_status(self.id, newstatus)
def get_status(self):
return self.datasource.get_submit_status(self.id)
def get_compilemessage(self):
return self.datasource.get_submit_compilemessage(self.id)
def update_test_results(self, results):
config = getConfig()
newresults = []
for r in results:
# stdout
f = file(r[4], 'r')
r[4] = f.read(config.output_sendback_size_limit)
f.close()
# stderr
f = file(r[5], 'r')
r[5] = f.read(config.output_sendback_size_limit)
f.close()
# strip stdout and stderr send back to datasource
# preventing post data too big
if len(r[4]) > config.output_sendback_size_limit:
r[4] = r[4][0:config.output_sendback_size_limit]
if len(r[5]) > config.output_sendback_size_limit:
r[5] = r[5][0:config.output_sendback_size_limit]
newresults.append({ 'test_id' : r[0],
'judge_result' : r[1],
'exitcode' : r[2],
'signal' : r[3],
'stdout' : r[4],
'stderr' : r[5],
'timeused' : r[6],
'memused' : r[7] })
return self.datasource.update_submit_test_results(self.id, newresults)
class TestCase:
write_lock = threading.Lock()
def __init__(self, datasource, row):
config = getConfig()
logger = logging.getLogger('main')
self.id = row['id']
self.problem_id = row['problem_id']
self.timemodified = row['timemodified']
#self.input = string.replace(row['input'], '\r\n', '\n')
#self.output = string.replace(row['output'], '\r\n', '\n')
self.timelimit = row['timelimit']
if not self.timelimit:
self.timelimit = 1
self.memlimit = row['memlimit']
if not self.memlimit:
self.memlimit = config.maxmem
if row.has_key('nproc') and row['nproc']:
self.nproc = string.atoi(row['nproc'])
else:
self.nproc = 0
config = getConfig()
testdir = os.path.join(config.datadir, 'testcase')
if not os.path.exists(testdir): os.mkdir(testdir)
self.infile = os.path.join(testdir, self.id + '.in')
self.outfile = os.path.join(testdir, self.id + '.out')
TestCase.write_lock.acquire()
if os.path.exists(self.infile):
inmtime = os.stat(self.infile)[stat.ST_MTIME]
else:
inmtime = 0
if os.path.exists(self.outfile):
outmtime = os.stat(self.outfile)[stat.ST_MTIME]
else:
outmtime = 0
logger.debug("inmtime=%d outmtime=%d timemodified=%d" % (inmtime, outmtime, self.timemodified))
if inmtime <= self.timemodified or outmtime <= self.timemodified:
logger.debug('Creating input/output file %s and %s' % (self.infile, self.outfile))
row = datasource.get_test(self.id)
input = string.replace(row['input'], '\r\n', '\n')
output = string.replace(row['output'], '\r\n', '\n')
f = file(self.infile, 'w')
f.write(input)
if len(input) > 0 and input[-1] != '\n': f.write('\n')
f.close()
f = file(self.outfile, 'w')
f.write(output)
if len(output) > 0 and output[-1] != '\n': f.write('\n')
f.close()
logger.debug('Finished')
else:
logger.debug('Skip input/output file creation')
TestCase.write_lock.release()
def get_input_file(self):
return self.infile
def get_output_file(self):
return self.outfile
class PresetCode:
def __init__(self, datasource, row):
self.datasource = datasource
self.problem = None
self.id = row['id']
self.name = row['name']
self.code = row['code']
self.isheader = row['isheader']
class DataFile:
write_lock = threading.Lock()
def __init__(self, datasource, row):
self.datasource = datasource
self.problem = None
# Data passed from datasource
self.id = row['id']
self.problem_id = row['problem_id']
self.filename = row['filename']
self.type = row['type']
self.timemodified = row['timemodified']
# Save datafile
config = getConfig()
testdir = os.path.join(config.datadir, 'testcase')
if not os.path.exists(testdir): os.mkdir(testdir)
self.absolute_path = os.path.join(
testdir, self.problem_id + '.' + self.filename)
DataFile.write_lock.acquire()
mtime = 0
if os.path.exists(self.absolute_path):
mtime = os.stat(self.absolute_path)[stat.ST_MTIME]
if mtime < self.timemodified:
data = datasource.get_datafile_data(self.id)
data = bz2.decompress(data)
if self.type == 'text':
f = open(self.absolute_path, 'w')
f.write(string.replace(data, '\r\n', '\n'))
f.close()
else:
f = open(self.absolute_path, 'wb')
f.write(data)
f.close()
DataFile.write_lock.release()
if __name__ == '__main__':
unittest.main()
# vim: set expandtab tabstop=4 shiftwidth=4: