Skip to content

Instantly share code, notes, and snippets.

@lhchavez
Created May 18, 2019 05:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lhchavez/49c48c7363ce497edbdbf40d575727f8 to your computer and use it in GitHub Desktop.
Save lhchavez/49c48c7363ce497edbdbf40d575727f8 to your computer and use it in GitHub Desktop.
omegaUp falso
#!/usr/bin/python3
import argparse
import cgi
import http.server
import itertools
import json
import os
import socketserver
import time
import urllib.parse
_SUBMISSIONS = 'submissions'
_CONTESTS = [
{
"alias":
"OMI2019DIA1",
"title":
"OMI 2019 - Día 1",
"problems": [
{
"alias": "OMI-2019-Resistencia",
"title": "Resistencia",
"languages": ["cat"],
},
{
"alias": "OMI-2019-Sumas",
"title": "La Loza de los Ravangers",
"languages": ["cpp11", "c"],
},
{
"alias": "OMI-2019-Spider-Man",
"title": "El amigable Hombre Araña",
"languages": ["cpp11", "c"],
},
],
},
{
"alias":
"OMIP2019DIA1",
"title":
"OMIP 2019 - Día 1",
"problems": [
{
"alias": "OMIPS-2019-Comprimiendo",
"title": "Comprimiendo",
"languages": ["kp", "kj"],
},
{
"alias": "OMIPS-2019-Pistas",
"title": "Pistas",
"languages": ["kp", "kj"],
},
{
"alias": "OMIPS-2019-Guantelete",
"title": "El Guantelete del Infinito",
"languages": ["kp", "kj"],
},
],
},
{
"alias":
"OMIS2019DIA1",
"title":
"OMIS 2019 - Día 1",
"problems": [
{
"alias": "OMIPS-2019-Comprimiendo",
"title": "Comprimiendo",
"languages": ["kp", "kj"],
},
{
"alias": "OMIPS-2019-Patron",
"title": "Repitiendo el Patrón",
"languages": ["kp", "kj"],
},
{
"alias": "OMIPS-2019-Guantelete",
"title": "El Guantelete del Infinito",
"languages": ["kp", "kj"],
},
],
},
]
_PROBLEMS = dict(
itertools.chain.from_iterable([(problem['alias'], problem['languages'])
for problem in contest['problems']]
for contest in _CONTESTS))
_CONTENTS = '''<!DOCTYPE html>
<html>
<head>
<title>omegaUp falso</title>
<style>
body {
font-family: sans-serif;
}
</style>
<script type="text/json" id="contest-payload">%s</script>
</head>
<body>
<h1>omegaUp falso</h1>
%s
<form method="POST" action="/">
<label>Concurso <select name="contest"><option value="">Elige tu concurso</option></select></label><br>
<label>Problema <select name="problem"></select></label><br>
<label>Lenguaje <select name="language"></select></label><br>
<textarea name="source" cols="80" rows="50"></textarea><br>
<button type="submit" disabled>Enviar</button>
</form>
<script type="text/javascript">
const payload = JSON.parse(document.getElementById('contest-payload').innerText);
const contestSelect = document.querySelector('select[name="contest"]');
const problemSelect = document.querySelector('select[name="problem"]');
const languageSelect = document.querySelector('select[name="language"]');
const sourceTextarea = document.querySelector('textarea');
const submitButton = document.querySelector('button');
const languageMapping = new Map([
['cpp11', 'C++'],
['c', 'C'],
['cat', 'Sólo salida'],
['kp', 'Karel (Pascal)'],
['kj', 'Karel (Java)'],
]);
contestSelect.addEventListener('change', (ev) => {
while (problemSelect.firstChild) {
problemSelect.removeChild(problemSelect.firstChild);
}
for (let contest of payload) {
if (ev.target.value != contest.alias) continue;
for (let problem of contest.problems) {
const problemOption = document.createElement('option');
problemOption.value = problem.alias;
problemOption.appendChild(document.createTextNode(problem.title));
problemSelect.appendChild(problemOption);
}
problemSelect.dispatchEvent(new Event('change'));
}
});
problemSelect.addEventListener('change', (ev) => {
while (languageSelect.firstChild) {
languageSelect.removeChild(languageSelect.firstChild);
}
for (let contest of payload) {
if (contestSelect.value != contest.alias) continue;
for (let problem of contest.problems) {
if (ev.target.value != problem.alias) continue;
for (let language of problem.languages) {
const languageOption = document.createElement('option');
languageOption.value = language;
languageOption.appendChild(document.createTextNode(languageMapping.get(language)));
languageSelect.appendChild(languageOption);
}
}
}
});
for (let contest of payload) {
const contestOption = document.createElement('option');
contestOption.value = contest.alias;
contestOption.appendChild(document.createTextNode(contest.title));
contestSelect.appendChild(contestOption);
}
function onContentUpdate() {
submitButton.disabled = sourceTextarea.value == '' || problemSelect.value == '';
}
contestSelect.addEventListener('change', onContentUpdate);
problemSelect.addEventListener('change', onContentUpdate);
sourceTextarea.addEventListener('change', onContentUpdate);
</script>
</body>
</html>
'''
class Handler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path != '/':
self.send_response(404)
return
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(
(_CONTENTS % (json.dumps(_CONTESTS), '')).encode('utf-8'))
def do_POST(self):
if self.path != '/':
self.send_response(404)
return
ctype, pdict = cgi.parse_header(self.headers.get('content-type'))
if ctype != 'application/x-www-form-urlencoded':
self.log_error('bad content-type: %s', ctype)
self.send_response(400)
return
length = int(self.headers.get('content-length'))
postvars = dict((key.decode('utf-8'), value.decode('utf-8'))
for key, value in urllib.parse.parse_qsl(
self.rfile.read(length), encoding='utf-8'))
if not postvars.get('problem', ''):
self.log_error('missing problem in request: %s', postvars)
self.send_response(400)
return
if not postvars.get('language', ''):
self.log_error('missing language in request: %s', postvars)
self.send_response(400)
return
if not postvars.get('source', ''):
self.log_error('missing source in request: %s', postvars)
self.send_response(400)
return
if postvars['problem'] not in _PROBLEMS:
self.log_error('unknown problem: %s', postvars['problem'])
self.send_response(400)
return
if postvars['language'] not in _PROBLEMS[postvars['problem']]:
self.log_error('unsupported language %s for problem: %s',
postvars['language'], postvars['problem'])
self.send_response(400)
return
path = os.path.join(
_SUBMISSIONS,
'%s_%d_%s.%s' % (self.address_string(), int(time.time()),
postvars['problem'], postvars['language']))
self.log_message('Writing submission to %s', path)
with open(path, 'x') as f:
f.write(postvars['source'])
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(
(_CONTENTS %
(json.dumps(_CONTESTS),
'<h2>Problema enviado exitosamente!</h2>')).encode('utf-8'))
def _main():
parser = argparse.ArgumentParser()
parser.add_argument('--port', type=int, default=80)
args = parser.parse_args()
os.makedirs(_SUBMISSIONS, exist_ok=True)
socketserver.TCPServer.allow_reuse_address = True
with socketserver.TCPServer(("", args.port), Handler) as httpd:
print("serving at port", args.port)
httpd.serve_forever()
if __name__ == '__main__':
_main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment