Thanks ArgumentParser.

This commit is contained in:
Michael Zhang 2016-03-10 01:29:27 -06:00
parent 1433048512
commit c33a124834
10 changed files with 141 additions and 61 deletions

View file

@ -10,7 +10,6 @@ The directory *must* contain a `problem.json`; this information will be loaded i
{
"pid": "survey", // required
"title": "Survey", // required
"description": "Take our survey.", // required - can use HTML
"hint": "No hint!", // optional - defaults to ""
"category": "Miscellaneous", // required
"autogen": false, // optional - defaults to false
@ -22,6 +21,10 @@ The directory *must* contain a `problem.json`; this information will be loaded i
}
```
## `description.md`
The directory *must* contain a `description.md`. Just write your description here in Markdown. If you're using `autogen: true`, you can include `${}` variables to produce dynamic content.
## `grader.py`
The directory must *also* contain a `grader.py`; this script must contain a `grade` function that takes in two parameters: `tid`, the team ID and `answer`, their attempted answer. The function must return a dict containing the following keys:
@ -98,7 +101,7 @@ Bonus points encourage teams to finish solving a problem first. Rather than an a
| 4 | 6% | 8% | 10% |
| 5 | 8% | 12% | 20% |
The table indicates how many percent bonus a team should receive if they solve a problem first, second, or third. Low problems such as the survey should not yield bonus points; only high-valued points should have bonus points in order to encourage teams t o solve them first.
The table indicates how many percent bonus a team should receive if they solve a problem first, second, or third. Low problems such as the survey should not yield bonus points; only high-valued points should have bonus points in order to encourage teams to solve them first.
## Problem Unlocking

View file

@ -0,0 +1 @@
Take our survey.

View file

@ -1,6 +1,6 @@
{
"pid": "survey",
"title": "Survey",
"description": "Take our survey.",
"hint": "No hint!",
"category": "Miscellaneous",
"autogen": false,

View file

@ -0,0 +1 @@
Help! I started growing this array culture, but it outgrew its petri dish! Using standard array syntax (either JavaScript or Python), indicate which element of the array contains the value ${value}.

View file

@ -0,0 +1,12 @@
{
"pid": "cancer",
"title": "Cancer",
"hint": "No hint!",
"category": "Miscellaneous",
"autogen": false,
"programming": false,
"value": 20,
"bonus": 0,
"threshold": 0,
"weightmap": { }
}

View file

@ -5,4 +5,5 @@ import problem
import user
import stats
import team
import tools
import utils

View file

@ -130,3 +130,7 @@ def problem_data():
jason.append({"pid": problem[1], "name": problem[2] ,"category": problem[3], "description": problem[4], "hint": problem[5], "value": problem[6], "solves": problem[7], "files": problem_files})
return jsonify(data=jason)
def insert_problem(data):
print data
pass

0
server/api/tools.py Normal file
View file

View file

@ -1,3 +1,5 @@
#!/usr/bin/python
from argparse import ArgumentParser
from flask import Flask
@ -6,6 +8,7 @@ app = Flask(__name__)
import api
import config
import json
import logging
import os
from api.decorators import api_wrapper
@ -34,12 +37,65 @@ api.logger.initialize_logs()
def api_main():
return { "success": 1, "message": "The API is online." }
if __name__ == "__main__":
def run(args):
with app.app_context():
parser = ArgumentParser(description="EasyCTF Server Configuration")
parser.add_argument("-d", "--debug", action="store_true", help="Run the server in debug mode.", default=False)
args = parser.parse_args()
keyword_args, _ = dict(args._get_kwargs()), args._get_args()
app.debug = keyword_args["debug"]
app.run(host="0.0.0.0", port=8000)
def load_problems(args):
if not os.path.exists(config.PROBLEM_DIR):
logging.critical("Problems directory doesn't exist.")
return
for (dirpath, dirnames, filenames) in os.walk(config.PROBLEM_DIR):
if "problem.json" in filenames:
json_file = os.path.join(dirpath, "problem.json")
contents = open(json_file).read()
try:
data = json.loads(contents)
except ValueError as e:
logging.warning("Invalid JSON format in file {filename} ({exception})".format(filename=json_file, exception=e))
continue
if not isinstance(data, dict):
logging.warning("{filename} is not a dict.".format(filename=json_file))
continue
missing_keys = []
for key in ["pid", "title", "category", "value"]:
if key not in data:
missing_keys.append(key)
if len(missing_keys) > 0:
logging.warning("{filename} is missing the following keys: {keys}".format(filename=json_file, keys=", ".join(missing_keys)))
continue
relative_path = os.path.relpath(dirpath, config.PROBLEM_DIR)
logging.info("Found problem '{}'".format(data["title"]))
try:
api.problem.insert_problem(data)
except Exception as e:
logging.warning("Problem '{}' was not added to the database. Error: {}".format(data["title"], e))
if __name__ == "__main__":
parser = ArgumentParser(description="EasyCTF Server Management")
subparser = parser.add_subparsers(help="Select one of the following actions.")
parser_problems = subparser.add_parser("problems", help="Manage problems.")
subparser_problems = parser_problems.add_subparsers(help="Select one of the following actions.")
parser_problems_load = subparser_problems.add_parser("load", help="Load all problems into database.")
parser_problems_load.set_defaults(func=load_problems)
parser_run = subparser.add_parser("run", help="Run the server.")
parser_run.add_argument("-d", "--debug", action="store_true", help="Run the server in debug mode.", default=False)
parser_run.set_defaults(func=run)
args = parser.parse_args()
keyword_args, _ = dict(args._get_kwargs()), args._get_args()
logging.getLogger().setLevel(logging.INFO)
if "func" in args:
args.func(args)
else:
parser.print_help()

View file

@ -23,3 +23,5 @@ CTF_END = 0 # To be used later
MG_HOST = ""
MG_API_KEY = ""
ADMIN_EMAIL = ""
PROBLEM_DIR = "../problems"