def test_languages(self): # All languages are described. for lang in LANGUAGES: assert lang in LANGUAGE_NAMES assert lang in LANGUAGE_TO_SOURCE_EXT_MAP # This isn't true, as not all languages need headers. # assert lang in LANGUAGE_TO_HEADER_EXT_MAP # All default languages are languages. for lang in DEFAULT_LANGUAGES: assert lang in LANGUAGES # All keys are languages. for lang in LANGUAGE_TO_SOURCE_EXT_MAP.iterkeys(): assert lang in LANGUAGES for lang in LANGUAGE_TO_HEADER_EXT_MAP.iterkeys(): assert lang in LANGUAGES # All values are languages. for lang in SOURCE_EXT_TO_LANGUAGE_MAP.itervalues(): assert lang in LANGUAGES # Extensions are sane. for lang in LANGUAGES: assert LANGUAGE_TO_SOURCE_EXT_MAP[lang][0] == "." assert lang == \ SOURCE_EXT_TO_LANGUAGE_MAP[LANGUAGE_TO_SOURCE_EXT_MAP[lang]] for ext in SOURCE_EXT_TO_LANGUAGE_MAP: assert ext[0] == "."
def submission_handler(self): if local.data['action'] == 'list': task = local.session.query(Task)\ .filter(Task.name == local.data['task_name']).first() if task is None: return 'Not found' if local.user is None: return 'Unauthorized' subs = local.session.query(Submission)\ .filter(Submission.user_id == local.user.id)\ .filter(Submission.task_id == task.id)\ .order_by(desc(Submission.timestamp)).all() submissions = [] for s in subs: submission = dict() submission['id'] = s.id submission['task_id'] = s.task_id submission['timestamp'] = make_timestamp(s.timestamp) submission['files'] = [] for name, f in s.files.iteritems(): fi = dict() if s.language is None: fi['name'] = name else: fi['name'] = name.replace('%l', s.language) fi['digest'] = f.digest submission['files'].append(fi) result = s.get_result() for i in ['compilation_outcome', 'evaluation_outcome']: submission[i] = getattr(result, i, None) if result is not None and result.score is not None: submission['score'] = round(result.score, 2) submissions.append(submission) local.resp['submissions'] = submissions elif local.data['action'] == 'details': s = local.session.query(Submission)\ .filter(Submission.id == local.data['id']).first() if s is None: return 'Not found' if local.user is None or s.user_id != local.user.id: return 'Unauthorized' submission = dict() submission['id'] = s.id submission['task_id'] = s.task_id submission['timestamp'] = make_timestamp(s.timestamp) submission['language'] = s.language submission['files'] = [] for name, f in s.files.iteritems(): fi = dict() if s.language is None: fi['name'] = name else: fi['name'] = name.replace('%l', s.language) fi['digest'] = f.digest submission['files'].append(fi) result = s.get_result() for i in ['compilation_outcome', 'evaluation_outcome', 'compilation_stdout', 'compilation_stderr', 'compilation_time', 'compilation_memory']: submission[i] = getattr(result, i, None) if result is not None and result.score is not None: submission['score'] = round(result.score, 2) if result is not None and result.score_details is not None: tmp = json.loads(result.score_details) if len(tmp) > 0 and 'text' in tmp[0]: subt = dict() subt['testcases'] = tmp subt['score'] = submission['score'] subt['max_score'] = 100 submission['score_details'] = [subt] else: submission['score_details'] = tmp for subtask in submission['score_details']: for testcase in subtask['testcases']: data = json.loads(testcase['text']) testcase['text'] = data[0] % tuple(data[1:]) else: submission['score_details'] = None local.resp = submission elif local.data['action'] == 'new': if local.user is None: return 'Unauthorized' lastsub = local.session.query(Submission)\ .filter(Submission.user_id == local.user.id)\ .order_by(desc(Submission.timestamp)).first() if lastsub is not None and \ make_datetime() - lastsub.timestamp < timedelta(seconds=20): return 'submission.short_interval' try: task = local.session.query(Task)\ .filter(Task.name == local.data['task_name'])\ .filter(Task.access_level >= local.access_level).first() except KeyError: return 'Not found' def decode_file(f): f['data'] = f['data'].split(',')[-1] f['body'] = b64decode(f['data']) del f['data'] return f if len(local.data['files']) == 1 and \ 'submission' in local.data['files']: archive_data = decode_file(local.data['files']['submission']) del local.data['files']['submission'] temp_archive_file, temp_archive_filename = \ tempfile.mkstemp(dir=config.temp_dir) with os.fdopen(temp_archive_file, "w") as temp_archive_file: temp_archive_file.write(archive_data['body']) archive_contents = extract_archive(temp_archive_filename, archive_data['filename']) if archive_contents is None: return 'Invalid archive!' files_sent = dict([(i['filename'], i) for i in archive_contents]) else: files_sent = \ dict([(k, decode_file(v)) for k, v in local.data['files'].iteritems()]) # TODO: implement partial submissions (?) # Detect language files = [] sub_lang = None for sfe in task.submission_format: f = files_sent.get(sfe.filename) if f is None: return 'Some files are missing!' if len(f['body']) > config.max_submission_length: return 'The files you sent are too big!' f['name'] = sfe.filename files.append(f) if sfe.filename.endswith('.%l'): language = None for ext, l in SOURCE_EXT_TO_LANGUAGE_MAP.iteritems(): if f['filename'].endswith(ext): language = l if language is None: return 'The language of the files you sent is not ' + \ 'recognized!' elif sub_lang is not None and sub_lang != language: return 'The files you sent are in different languages!' else: sub_lang = language # Add the submission timestamp = make_datetime() submission = Submission(timestamp, sub_lang, user=local.user, task=task) for f in files: digest = self.file_cacher.put_file_content( f['body'], 'Submission file %s sent by %s at %d.' % ( f['name'], local.user.username, make_timestamp(timestamp))) local.session.add(File(f['name'], digest, submission=submission)) local.session.add(submission) local.session.commit() # Notify ES self.evaluation_service.new_submission( submission_id=submission.id ) # Answer with submission data local.resp['id'] = submission.id local.resp['task_id'] = submission.task_id local.resp['timestamp'] = make_timestamp(submission.timestamp) local.resp['compilation_outcome'] = None local.resp['evaluation_outcome'] = None local.resp['score'] = None local.resp['files'] = [] for name, f in submission.files.iteritems(): fi = dict() if submission.language is None: fi['name'] = name else: fi['name'] = name.replace('%l', submission.language) fi['digest'] = f.digest local.resp['files'].append(fi) else: return 'Bad request'
def submission_handler(self): if local.data['action'] == 'list': task = local.session.query(Task)\ .filter(Task.name == local.data['task_name']).first() if task is None: return 'Not found' if local.user is None: return 'Unauthorized' subs = local.session.query(Submission)\ .filter(Submission.participation_id == local.participation.id)\ .filter(Submission.task_id == task.id)\ .order_by(desc(Submission.timestamp)).all() submissions = [] for s in subs: submission = dict() submission['id'] = s.id submission['task_id'] = s.task_id submission['timestamp'] = make_timestamp(s.timestamp) submission['files'] = [] for name, f in s.files.iteritems(): fi = dict() if s.language is None: fi['name'] = name else: fi['name'] = name.replace('%l', s.language) fi['digest'] = f.digest submission['files'].append(fi) result = s.get_result() for i in ['compilation_outcome', 'evaluation_outcome']: submission[i] = getattr(result, i, None) if result is not None and result.score is not None: submission['score'] = round(result.score, 2) submissions.append(submission) local.resp['submissions'] = submissions elif local.data['action'] == 'details': s = local.session.query(Submission)\ .filter(Submission.id == local.data['id']).first() if s is None: return 'Not found' if local.user is None or s.participation_id != local.participation.id: return 'Unauthorized' submission = dict() submission['id'] = s.id submission['task_id'] = s.task_id submission['timestamp'] = make_timestamp(s.timestamp) submission['language'] = s.language submission['files'] = [] for name, f in s.files.iteritems(): fi = dict() if s.language is None: fi['name'] = name else: fi['name'] = name.replace('%l', s.language) fi['digest'] = f.digest submission['files'].append(fi) result = s.get_result() for i in ['compilation_outcome', 'evaluation_outcome', 'compilation_stdout', 'compilation_stderr', 'compilation_time', 'compilation_memory']: submission[i] = getattr(result, i, None) if result is not None and result.score is not None: submission['score'] = round(result.score, 2) if result is not None and result.score_details is not None: tmp = json.loads(result.score_details) if len(tmp) > 0 and 'text' in tmp[0]: subt = dict() subt['testcases'] = tmp subt['score'] = submission['score'] subt['max_score'] = 100 submission['score_details'] = [subt] else: submission['score_details'] = tmp for subtask in submission['score_details']: for testcase in subtask['testcases']: data = json.loads(testcase['text']) testcase['text'] = data[0] % tuple(data[1:]) else: submission['score_details'] = None local.resp = submission elif local.data['action'] == 'new': if local.user is None: return 'Unauthorized' lastsub = local.session.query(Submission)\ .filter(Submission.participation_id == local.participation.id)\ .order_by(desc(Submission.timestamp)).first() if lastsub is not None and \ make_datetime() - lastsub.timestamp < timedelta(seconds=20): return 'Too frequent submissions!' try: task = local.session.query(Task)\ .join(SocialTask)\ .filter(Task.name == local.data['task_name'])\ .filter(SocialTask.access_level >= local.access_level).first() except KeyError: return 'Not found' def decode_file(f): f['data'] = f['data'].split(',')[-1] f['body'] = b64decode(f['data']) del f['data'] return f if len(local.data['files']) == 1 and \ 'submission' in local.data['files']: archive_data = decode_file(local.data['files']['submission']) del local.data['files']['submission'] # Create the archive. archive = Archive.from_raw_data(archive_data["body"]) if archive is None: return 'Invalid archive!' # Extract the archive. unpacked_dir = archive.unpack() for name in archive.namelist(): filename = os.path.basename(name) body = open(os.path.join(unpacked_dir, filename), "r").read() local.data['files'][filename] = { 'filename': filename, 'body': body } files_sent = local.data['files'] archive.cleanup() else: files_sent = \ dict([(k, decode_file(v)) for k, v in local.data['files'].iteritems()]) # TODO: implement partial submissions (?) # Detect language files = [] sub_lang = None for sfe in task.submission_format: f = files_sent.get(sfe.filename) if f is None: return 'Some files are missing!' if len(f['body']) > config.get("core", "max_submission_length"): return 'The files you sent are too big!' f['name'] = sfe.filename files.append(f) if sfe.filename.endswith('.%l'): language = None for ext, l in SOURCE_EXT_TO_LANGUAGE_MAP.iteritems(): if f['filename'].endswith(ext): language = l if language is None: return 'The language of the files you sent is not ' + \ 'recognized!' elif sub_lang is not None and sub_lang != language: return 'The files you sent are in different languages!' else: sub_lang = language # Add the submission timestamp = make_datetime() submission = Submission(timestamp, sub_lang, participation=local.participation, task=task) for f in files: digest = self.file_cacher.put_file_content( f['body'], 'Submission file %s sent by %s at %d.' % ( f['name'], local.user.username, make_timestamp(timestamp))) local.session.add(File(f['name'], digest, submission=submission)) local.session.add(submission) local.session.commit() # Notify ES self.evaluation_service.new_submission( submission_id=submission.id ) # Answer with submission data local.resp['id'] = submission.id local.resp['task_id'] = submission.task_id local.resp['timestamp'] = make_timestamp(submission.timestamp) local.resp['compilation_outcome'] = None local.resp['evaluation_outcome'] = None local.resp['score'] = None local.resp['files'] = [] for name, f in submission.files.iteritems(): fi = dict() if submission.language is None: fi['name'] = name else: fi['name'] = name.replace('%l', submission.language) fi['digest'] = f.digest local.resp['files'].append(fi) else: return 'Bad request'
import functools import shutil import tempfile import yaml import logging from cms import utf8_decoder, SOURCE_EXT_TO_LANGUAGE_MAP, \ LANGUAGE_TO_SOURCE_EXT_MAP, LANGUAGE_TO_HEADER_EXT_MAP, LANG_PASCAL from cms.grading import get_compilation_commands from cmstaskenv.Test import test_testcases, clean_test_env from cmscommon.terminal import move_cursor, add_color_to_string, \ colors, directions SOL_DIRNAME = 'sol' SOL_FILENAME = 'soluzione' SOL_EXTS = SOURCE_EXT_TO_LANGUAGE_MAP.keys() CHECK_DIRNAME = 'cor' CHECK_EXTS = SOL_EXTS TEXT_DIRNAME = 'testo' TEXT_TEX = 'testo.tex' TEXT_PDF = 'testo.pdf' TEXT_AUX = 'testo.aux' TEXT_LOG = 'testo.log' INPUT0_TXT = 'input0.txt' OUTPUT0_TXT = 'output0.txt' GEN_DIRNAME = 'gen' GEN_GEN = 'GEN' GEN_BASENAME = 'generatore' GEN_EXTS = ['.py', '.sh', '.cpp', '.c', '.pas'] VALIDATOR_BASENAME = 'valida' GRAD_BASENAME = 'grader'
def submission_handler(self): if local.data["action"] == "list": task = local.session.query(Task).filter(Task.name == local.data["task_name"]).first() if task is None: return "Not found" if local.user is None: return "Unauthorized" subs = ( local.session.query(Submission) .filter(Submission.user_id == local.user.id) .filter(Submission.task_id == task.id) .order_by(desc(Submission.timestamp)) .all() ) submissions = [] for s in subs: submission = dict() submission["id"] = s.id submission["task_id"] = s.task_id submission["timestamp"] = make_timestamp(s.timestamp) submission["files"] = [] for name, f in s.files.iteritems(): fi = dict() if s.language is None: fi["name"] = name else: fi["name"] = name.replace("%l", s.language) fi["digest"] = f.digest submission["files"].append(fi) result = s.get_result() for i in ["compilation_outcome", "evaluation_outcome"]: submission[i] = getattr(result, i, None) if result is not None and result.score is not None: submission["score"] = round(result.score, 2) submissions.append(submission) local.resp["submissions"] = submissions elif local.data["action"] == "details": s = local.session.query(Submission).filter(Submission.id == local.data["id"]).first() if s is None: return "Not found" if local.user is None or s.user_id != local.user.id: return "Unauthorized" submission = dict() submission["id"] = s.id submission["task_id"] = s.task_id submission["timestamp"] = make_timestamp(s.timestamp) submission["language"] = s.language submission["files"] = [] for name, f in s.files.iteritems(): fi = dict() if s.language is None: fi["name"] = name else: fi["name"] = name.replace("%l", s.language) fi["digest"] = f.digest submission["files"].append(fi) result = s.get_result() for i in [ "compilation_outcome", "evaluation_outcome", "compilation_stdout", "compilation_stderr", "compilation_time", "compilation_memory", ]: submission[i] = getattr(result, i, None) if result is not None and result.score is not None: submission["score"] = round(result.score, 2) if result is not None and result.score_details is not None: tmp = json.loads(result.score_details) if len(tmp) > 0 and "text" in tmp[0]: subt = dict() subt["testcases"] = tmp subt["score"] = submission["score"] subt["max_score"] = 100 submission["score_details"] = [subt] else: submission["score_details"] = tmp for subtask in submission["score_details"]: for testcase in subtask["testcases"]: data = json.loads(testcase["text"]) testcase["text"] = data[0] % tuple(data[1:]) else: submission["score_details"] = None local.resp = submission elif local.data["action"] == "new": if local.user is None: return "Unauthorized" lastsub = ( local.session.query(Submission) .filter(Submission.user_id == local.user.id) .order_by(desc(Submission.timestamp)) .first() ) if lastsub is not None and make_datetime() - lastsub.timestamp < timedelta(seconds=20): return "Too frequent submissions!" try: task = ( local.session.query(Task) .filter(Task.name == local.data["task_name"]) .filter(Task.access_level >= local.access_level) .first() ) except KeyError: return "Not found" def decode_file(f): f["data"] = f["data"].split(",")[-1] f["body"] = b64decode(f["data"]) del f["data"] return f if len(local.data["files"]) == 1 and "submission" in local.data["files"]: archive_data = decode_file(local.data["files"]["submission"]) del local.data["files"]["submission"] # Create the archive. archive = Archive.from_raw_data(archive_data["body"]) if archive is None: return "Invalid archive!" # Extract the archive. unpacked_dir = archive.unpack() for name in archive.namelist(): filename = os.path.basename(name) body = open(os.path.join(unpacked_dir, filename), "r").read() self.request.files[filename] = [{"filename": filename, "body": body}] files_sent = dict([(i["filename"], i) for i in archive_contents]) archive.cleanup() else: files_sent = dict([(k, decode_file(v)) for k, v in local.data["files"].iteritems()]) # TODO: implement partial submissions (?) # Detect language files = [] sub_lang = None for sfe in task.submission_format: f = files_sent.get(sfe.filename) if f is None: return "Some files are missing!" if len(f["body"]) > config.max_submission_length: return "The files you sent are too big!" f["name"] = sfe.filename files.append(f) if sfe.filename.endswith(".%l"): language = None for ext, l in SOURCE_EXT_TO_LANGUAGE_MAP.iteritems(): if f["filename"].endswith(ext): language = l if language is None: return "The language of the files you sent is not " + "recognized!" elif sub_lang is not None and sub_lang != language: return "The files you sent are in different languages!" else: sub_lang = language # Add the submission timestamp = make_datetime() submission = Submission(timestamp, sub_lang, user=local.user, task=task) for f in files: digest = self.file_cacher.put_file_content( f["body"], "Submission file %s sent by %s at %d." % (f["name"], local.user.username, make_timestamp(timestamp)), ) local.session.add(File(f["name"], digest, submission=submission)) local.session.add(submission) local.session.commit() # Notify ES self.evaluation_service.new_submission(submission_id=submission.id) # Answer with submission data local.resp["id"] = submission.id local.resp["task_id"] = submission.task_id local.resp["timestamp"] = make_timestamp(submission.timestamp) local.resp["compilation_outcome"] = None local.resp["evaluation_outcome"] = None local.resp["score"] = None local.resp["files"] = [] for name, f in submission.files.iteritems(): fi = dict() if submission.language is None: fi["name"] = name else: fi["name"] = name.replace("%l", submission.language) fi["digest"] = f.digest local.resp["files"].append(fi) else: return "Bad request"
import subprocess import copy import functools import shutil import tempfile import yaml import logging from cms import utf8_decoder, SOURCE_EXT_TO_LANGUAGE_MAP, LANGUAGE_TO_SOURCE_EXT_MAP, LANGUAGE_TO_HEADER_EXT_MAP from cms.grading import get_compilation_commands from cmstaskenv.Test import test_testcases, clean_test_env from cmscommon.terminal import move_cursor, add_color_to_string, colors, directions SOL_DIRNAME = "sol" SOL_FILENAME = "soluzione" SOL_EXTS = SOURCE_EXT_TO_LANGUAGE_MAP.keys() CHECK_DIRNAME = "cor" CHECK_EXTS = SOL_EXTS TEXT_DIRNAME = "testo" TEXT_TEX = "testo.tex" TEXT_PDF = "testo.pdf" TEXT_AUX = "testo.aux" TEXT_LOG = "testo.log" INPUT0_TXT = "input0.txt" OUTPUT0_TXT = "output0.txt" GEN_DIRNAME = "gen" GEN_GEN = "GEN" GEN_BASENAME = "generatore" GEN_EXTS = [".py", ".sh", ".cpp", ".c", ".pas"] VALIDATOR_BASENAME = "valida" GRAD_BASENAME = "grader"