-
-
Save geekypandey/cbe1ed09bdedfd9069adc12e1db89dff to your computer and use it in GitHub Desktop.
ecnerwala's CP template system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""Download and setup problems from Competitive Companion | |
Usage: | |
download_prob.py prob [<name>] | |
download_prob.py contest [<name>... | -n <number>] | |
download_prob.py samples | |
download_prob.py echo | |
Options: | |
-h --help Show this screen. | |
Contest flags: | |
-n COUNT, --number COUNT Number of problems. | |
""" | |
from docopt import docopt | |
import sys | |
import http.server | |
import json | |
from pathlib import Path | |
import subprocess | |
import re | |
# Returns unmarshalled or None | |
def listen_once(*, timeout=None): | |
json_data = None | |
class CompetitiveCompanionHandler(http.server.BaseHTTPRequestHandler): | |
def do_POST(self): | |
nonlocal json_data | |
json_data = json.load(self.rfile) | |
with http.server.HTTPServer(('127.0.0.1', 10046), CompetitiveCompanionHandler) as server: | |
server.timeout = timeout | |
server.handle_request() | |
if json_data is not None: | |
print(f"Got data {json.dumps(json_data)}") | |
else: | |
print("Got no data") | |
return json_data | |
def listen_many(*, num_items=None, timeout=None): | |
if num_items is not None: | |
return [listen_once(timeout=None) for _ in range(num_items)] | |
res = [listen_once(timeout=None)] | |
while True: | |
cnd = listen_once(timeout=timeout) | |
if cnd is None: | |
break | |
res.append(cnd) | |
return res | |
NAME_PATTERN = re.compile(r'^[A-Z][0-9]*\b') | |
def get_prob_name(data): | |
if 'USACO' in data['group']: | |
names = [data['input']['fileName'].rstrip('.in'), data['output']['fileName'].rstrip('.out')] | |
if len(set(names)) == 1: | |
return names[0] | |
patternMatch = NAME_PATTERN.search(data['name']) | |
if patternMatch is not None: | |
return patternMatch.group(0) | |
return input("What name to give? ") | |
def save_samples(data, probDir): | |
with open(probDir / 'problem.json', 'w') as f: | |
json.dump(data, f) | |
for i, t in enumerate(data['tests'], start=1): | |
with open(probDir / f'sample{i}.in', 'w') as f: | |
f.write(t['input']) | |
with open(probDir / f'sample{i}.out', 'w') as f: | |
f.write(t['output']) | |
def make_prob(data, name): | |
if name is None: | |
name = get_prob_name(data) | |
print(f"Creating problem {name}...") | |
MAKE_PROB = Path(sys.path[0]) / 'make_prob.sh' | |
try: | |
subprocess.check_call([MAKE_PROB, name], stdout=sys.stdout, stderr=sys.stderr) | |
except subprocess.CalledProcessError as e: | |
print(f"Got error {e}") | |
return | |
probDir = Path('.')/name | |
print("Saving samples...") | |
save_samples(data, probDir) | |
print() | |
def main(): | |
arguments = docopt(__doc__) | |
if arguments['echo']: | |
while True: | |
print(listen_once()) | |
elif arguments['prob']: | |
data = listen_once() | |
names = arguments['<name>'] | |
name = names[0] if names else None | |
make_prob(data, name) | |
elif arguments['contest']: | |
if names := arguments['<name>']: | |
datas = listen_many(num_items=len(names)) | |
for data, name in zip(datas, names): | |
make_prob(data, name) | |
elif cnt := arguments['--number']: | |
cnt = int(cnt) | |
datas = listen_many(num_items=cnt) | |
for data in datas: | |
make_prob(data, None) | |
else: | |
datas = listen_many(timeout=5) | |
for data in datas: | |
make_prob(data, None) | |
elif arguments['samples']: | |
data = listen_once() | |
save_samples(data, Path('.')) | |
if __name__ == '__main__': | |
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
DIR=$(dirname $0) | |
search_up () | |
( | |
while [[ $PWD != "/" ]]; do | |
if [[ -e "$1" ]]; then | |
pwd | |
if [[ ! -e "$1/$2" ]]; then | |
break | |
fi | |
fi | |
cd .. | |
done | |
) | |
TEMPLATE_DIR='.template' | |
PARENT_FILE='$PARENT' | |
IFS=$'\n' | |
TEMPLATE_DIRS=($(search_up "$TEMPLATE_DIR" "$PARENT_FILE" | tac)) | |
unset IFS | |
TEMPLATE_DIRS=(${TEMPLATE_DIRS[@]/%/\/"$TEMPLATE_DIR"}) | |
if hash rename.ul 2>/dev/null; then | |
RENAME=rename.ul | |
else | |
RENAME=rename | |
fi | |
for filepath in "$@"; do | |
PROBLEM_NAME=$(basename "$filepath") | |
if [[ -e "$filepath" ]]; then | |
echo "$filepath already exists. Remove it and retry." | |
continue | |
fi | |
# Copy files in | |
mkdir -p "$filepath" | |
for CURRENT_TEMPLATE_DIR in "${TEMPLATE_DIRS[@]}"; do | |
cp -r -T "$CURRENT_TEMPLATE_DIR" "$filepath/" | |
done | |
rm -f "$filepath/$PARENT_FILE" | |
# Rename PROBLEM_NAME in file names | |
find $filepath -type f -print0 | xargs -0 ${RENAME} "\$PROBLEM_NAME" "$PROBLEM_NAME" | |
# Envsubst PROBLEM_NAME in files | |
export PROBLEM_NAME | |
REPLACE_STRING='${PROBLEM_NAME}' | |
find $filepath -type f -print0 | xargs -0 -n1 -I{} bash -c\ | |
'TEMP=$(mktemp) && cat "$1" > "$TEMP" && envsubst '"'$REPLACE_STRING'"' < "$TEMP" > "$1" && rm "$TEMP"'\ | |
-- {} | |
pushd $filepath > /dev/null | |
if [[ -e "setup" ]]; then | |
echo "Running setup" | |
./setup | |
fi | |
popd > /dev/null | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment