Implement problem viewing and problem submitting
This commit is contained in:
parent
bc6c1247e1
commit
34fe70600b
5 changed files with 110 additions and 23 deletions
|
@ -31,4 +31,4 @@ def initialize_logs():
|
|||
def log(logname, message, level=INFO):
|
||||
logger = logging.getLogger(logname)
|
||||
message = "[%s] %s" % (datetime.datetime.now().strftime("%m/%d/%Y %X"), message)
|
||||
logger.log(level, message)
|
||||
logger.log(level, message)
|
||||
|
|
|
@ -166,9 +166,8 @@ class Files(db.Model):
|
|||
self.location = location
|
||||
|
||||
class Solves(db.Model):
|
||||
__table_args__ = (db.UniqueConstraint("pid", "tid"), {})
|
||||
sid = db.Column(db.Integer, primary_key=True)
|
||||
pid = db.Column(db.Integer)
|
||||
pid = db.Column(db.String(32))
|
||||
tid = db.Column(db.Integer)
|
||||
date = db.Column(db.Integer, default=utils.get_time_since_epoch())
|
||||
correct = db.Column(db.Boolean)
|
||||
|
@ -214,7 +213,7 @@ class TeamInvitations(db.Model):
|
|||
|
||||
class Settings(db.Model):
|
||||
sid = db.Column(db.Integer, primary_key=True)
|
||||
key = db.Column(db.Text, unique=True)
|
||||
key = db.Column(db.Text)
|
||||
value = db.Column(db.Text)
|
||||
|
||||
def __init__(self, key, value):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import hashlib
|
||||
import imp
|
||||
import logger
|
||||
import os
|
||||
import shutil
|
||||
|
@ -115,38 +116,51 @@ def problem_submit():
|
|||
|
||||
problem = Problems.query.filter_by(pid=pid).first()
|
||||
team = Teams.query.filter_by(tid=tid).first()
|
||||
solved = Solves.query.filter_by(pid=pid, tid=tid, correct=1).first()
|
||||
if solved:
|
||||
raise WebException("You already solved this problem.")
|
||||
if problem:
|
||||
if flag == problem.flag:
|
||||
solve = Solves(pid, tid)
|
||||
team.score += problem.value
|
||||
problem.solves += 1
|
||||
grader = imp.load_source("grader.py", problem.grader)
|
||||
if grader.grade(flag):
|
||||
solve = Solves(pid, tid, flag, True)
|
||||
db.session.add(solve)
|
||||
db.session.add(team)
|
||||
db.session.add(problem)
|
||||
db.session.commit()
|
||||
|
||||
logger.log(__name__, logger.WARNING, "%s has solved %s by submitting %s" % (team.name, problem.title, flag))
|
||||
logger.log(__name__, "%s has solved %s by submitting %s" % (team.teamname, problem.title, flag), level=logger.WARNING)
|
||||
return { "success": 1, "message": "Correct!" }
|
||||
|
||||
else:
|
||||
logger.log(__name__, logger.WARNING, "%s has incorrectly submitted %s to %s" % (team.name, flag, problem.title))
|
||||
solve = Solves(pid, tid, flag, False)
|
||||
db.session.add(solve)
|
||||
db.session.commit()
|
||||
logger.log(__name__, "%s has incorrectly submitted %s to %s" % (team.teamname, flag, problem.title), level=logger.WARNING)
|
||||
raise WebException("Incorrect.")
|
||||
|
||||
else:
|
||||
raise WebException("Problem does not exist!")
|
||||
|
||||
@blueprint.route("/data", methods=["POST"])
|
||||
#@api_wrapper # Disable atm due to json serialization issues: will fix
|
||||
@blueprint.route("/data", methods=["GET"])
|
||||
@login_required
|
||||
@api_wrapper
|
||||
def problem_data():
|
||||
problems = Problems.query.add_columns("pid", "name", "category", "description", "hint", "value", "solves").order_by(Problems.value).filter_by(disabled=False).all()
|
||||
jason = []
|
||||
problems = Problems.query.order_by(Problems.value).all()
|
||||
problems_return = []
|
||||
|
||||
for problem in problems:
|
||||
problem_files = [ str(_file.location) for _file in Files.query.filter_by(pid=int(problem.pid)).all() ]
|
||||
jason.append({"pid": problem[1], "title": problem[2] ,"category": problem[3], "description": problem[4], "hint": problem[5], "value": problem[6], "solves": problem[7], "files": problem_files})
|
||||
|
||||
return jsonify(data=jason)
|
||||
solves = Solves.query.filter_by(pid=problem.pid, correct=1).count()
|
||||
solved = Solves.query.filter_by(pid=problem.pid, tid=session.get("tid", None), correct=1)
|
||||
solved = ["Solved", "Unsolved"][solved is None]
|
||||
problems_return.append({
|
||||
"pid": problem.pid,
|
||||
"title": problem.title,
|
||||
"category": problem.category,
|
||||
"description": problem.description,
|
||||
"hint": problem.hint,
|
||||
"value": problem.value,
|
||||
"solves": solves,
|
||||
"solved": solved
|
||||
})
|
||||
return { "success": 1, "problems": problems_return }
|
||||
|
||||
def insert_problem(data, force=False):
|
||||
with app.app_context():
|
||||
|
|
|
@ -48,6 +48,10 @@ app.config(function($routeProvider, $locationProvider) {
|
|||
templateUrl: "pages/settings.html",
|
||||
controller: "settingsController"
|
||||
})
|
||||
.when("/problems", {
|
||||
templateUrl: "pages/problems.html",
|
||||
controller: "problemsController"
|
||||
})
|
||||
.when("/forgot", {
|
||||
templateUrl: "pages/forgot.html",
|
||||
controller: "resetController"
|
||||
|
@ -271,6 +275,16 @@ app.controller("settingsController", ["$controller", "$scope", "$http", function
|
|||
});
|
||||
}]);
|
||||
|
||||
app.controller("problemsController", ["$controller", "$scope", "$http", function($controller, $scope, $http) {
|
||||
$controller("loginController", { $scope: $scope });
|
||||
api_call("GET", "/api/problem/data", {}, function(result) {
|
||||
if (result["success"] == 1) {
|
||||
$scope.problems = result["problems"];
|
||||
}
|
||||
$scope.$apply();
|
||||
});
|
||||
}]);
|
||||
|
||||
$.fn.serializeObject = function() {
|
||||
var a, o;
|
||||
o = {};
|
||||
|
|
|
@ -5,7 +5,67 @@
|
|||
3) remove these instructions (:P)
|
||||
-->
|
||||
<div class="fade_in">
|
||||
<h1 class="heading1 text-center">Problems</h1>
|
||||
<div id="problems"></div>
|
||||
<h1 class="text-center">Problems</h1>
|
||||
<div ng-repeat="problem in problems">
|
||||
<div class="panel-group">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" data-toggle="collapse" data-target="#{{ problem['pid'] }}_body">
|
||||
<h4 class="panel-title">
|
||||
{{ problem["title"] }} {{ problem["value"] }} points
|
||||
<div class="pull-right">{{ problem["category"] }} - {{ problem["solved"] }} ({{ problem["solves"] }} {{ problem["solves"] === 1 ? "solve" : "solves" }})</div>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="{{ problem['pid'] }}_body" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div hidden id="{{ problem['pid'] }}_hint">{{ problem['hint'] }}</div>
|
||||
<div hidden id="{{ problem['pid'] }}_status"/>
|
||||
{{ problem["description"] }}
|
||||
</div>
|
||||
<form id="{{ problem['pid'] }}_form" class="horizontal-form" onsubmit="submit_problem(this.id); return false;">
|
||||
<div class="input-group">
|
||||
<input hidden name="pid" value="{{ problem['pid'] }}"/>
|
||||
<input class="form-control" name="flag" placeholder="Flag"/>
|
||||
<span class="input-group-btn">
|
||||
<input onclick="toggle_hint(this.closest('form').id); return false;" type="button" class="btn btn-success" value="Hint"/>
|
||||
</span>
|
||||
<span class="input-group-btn">
|
||||
<input type="submit" class="btn btn-success" value="Submit"/>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/problems.js">
|
||||
|
||||
<script>
|
||||
var toggle_hint = function(form) {
|
||||
pid = form.split("_")[0];
|
||||
$("#" + pid + "_hint").slideToggle("fast", function() {});
|
||||
}
|
||||
|
||||
var submit_problem = function(form) {
|
||||
var input = "#" + form + " input";
|
||||
var data = $("#" + form).serializeObject();
|
||||
pid = data["pid"];
|
||||
$(input).attr("disabled", "disabed");
|
||||
api_call("POST", "/api/problem/submit", data, function(result) {
|
||||
if (result["success"] == 1) {
|
||||
display_message(pid + "_status", "success", result["message"], function() {
|
||||
$(input).removeAttr("disabled");
|
||||
});
|
||||
} else {
|
||||
display_message(pid + "_status", "danger", result["message"], function() {
|
||||
$(input).removeAttr("disabled");
|
||||
});
|
||||
}
|
||||
console.log(result["error"]);
|
||||
}, function(jqXHR, status, error) {
|
||||
var result = jqXHR["responseText"];
|
||||
display_message(pid + "_status", "danger", "Error " + jqXHR["status"] + ": " + result["message"], function() {
|
||||
$(input).removeAttr("disabled");
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue