Implement problem updating for admins
This commit is contained in:
parent
d9b69f7682
commit
e4392cf94e
5 changed files with 94 additions and 27 deletions
|
@ -3,4 +3,4 @@ mysql-python
|
||||||
Flask-SQLAlchemy
|
Flask-SQLAlchemy
|
||||||
SQLAlchemy
|
SQLAlchemy
|
||||||
gunicorn
|
gunicorn
|
||||||
requests
|
requests
|
||||||
|
|
|
@ -1,4 +1,19 @@
|
||||||
from flask import Blueprint
|
from flask import Blueprint, jsonify
|
||||||
from decorators import api_wrapper
|
from decorators import admins_only, api_wrapper, login_required
|
||||||
|
from models import db, Problems, Files
|
||||||
|
|
||||||
blueprint = Blueprint("admin", __name__)
|
blueprint = Blueprint("admin", __name__)
|
||||||
|
|
||||||
|
@blueprint.route("/problem/data", methods=["POST"])
|
||||||
|
#@api_wrapper # Disable atm due to json serialization issues: will fix
|
||||||
|
@admins_only
|
||||||
|
@login_required
|
||||||
|
def problem_data():
|
||||||
|
problems = Problems.query.add_columns("pid", "name", "category", "description", "hint", "value", "solves", "disabled", "flag").order_by(Problems.value).all()
|
||||||
|
jason = []
|
||||||
|
|
||||||
|
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], "name": problem[2] ,"category": problem[3], "description": problem[4], "hint": problem[5], "value": problem[6], "solves": problem[7], "disabled": problem[8], "flag": problem[9], "files": problem_files})
|
||||||
|
|
||||||
|
return jsonify(data=jason)
|
||||||
|
|
|
@ -19,7 +19,7 @@ def api_wrapper(f):
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
response = 200
|
response = 200
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
web_result = { "success": 0, "message": "Something went wrong! Please notify us about this immediately.", str(error): traceback.format_exc() }
|
web_result = { "success": 0, "message": "Something went wrong! Please notify us about this immediately. %s: %s" % (error, traceback.format_exc()) }
|
||||||
return json.dumps(web_result), response, { "Content-Type": "application/json; charset=utf-8" }
|
return json.dumps(web_result), response, { "Content-Type": "application/json; charset=utf-8" }
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
|
@ -70,10 +70,11 @@ def problem_delete():
|
||||||
def problem_update():
|
def problem_update():
|
||||||
pid = request.form["pid"]
|
pid = request.form["pid"]
|
||||||
name = request.form["name"]
|
name = request.form["name"]
|
||||||
|
category = request.form["category"]
|
||||||
description = request.form["description"]
|
description = request.form["description"]
|
||||||
hint = request.form["hint"]
|
hint = request.form["hint"]
|
||||||
flag = request.form["flag"]
|
flag = request.form["flag"]
|
||||||
disabled = request.form["disabled"]
|
disabled = request.form.get("disabled", 0)
|
||||||
value = request.form["value"]
|
value = request.form["value"]
|
||||||
|
|
||||||
problem = Problems.query.filter_by(pid=pid).first()
|
problem = Problems.query.filter_by(pid=pid).first()
|
||||||
|
|
|
@ -1,44 +1,95 @@
|
||||||
function render_problems() {
|
function render_problems() {
|
||||||
$.post("/api/problem/data", {
|
$.post("/api/admin/problem/data", {
|
||||||
}, function(data) {
|
}, function(data) {
|
||||||
data = data["data"];
|
data = data["data"];
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
files = data[i]["files"];
|
files = data[i]["files"];
|
||||||
|
var checked = "";
|
||||||
|
if (data[i]["disabled"]) {
|
||||||
|
checked = "checked";
|
||||||
|
}
|
||||||
problem =
|
problem =
|
||||||
`<div class=\"panel panel-info\">
|
`<div class="panel panel-info">
|
||||||
<div class=\"panel-heading\">
|
<form method="POST" onsubmit="return false;">
|
||||||
<h3 class=\"panel-title\">` + data[i]["name"] + ` | ` + data[i]["category"] + `<span style=\"float: right\">` + data[i]["value"] + ` points</span></h3>
|
<input type="hidden" name="pid" value="` + data[i]["pid"] + `">
|
||||||
</div>
|
<div class="panel-heading">
|
||||||
<div class=\"panel-body\">
|
<div class="row">
|
||||||
<p>` + data[i]["description"] + `</p>
|
<div class="col-md-6">
|
||||||
<div class=\"input-group\">
|
<input type="text" name="name" placeholder="Name" autocomplete="on" class="form-control" value="` + data[i]["name"] + `">
|
||||||
<input type=\"text\" class=\"form-control\" placeholder=\"Flag\">
|
</div>
|
||||||
<span class=\"input-group-btn\">
|
<div class="col-md-6">
|
||||||
<button class=\"btn btn-success\" id=\"hint\" type=\"button\" onclick=\"show_hint(\'` + data[i]["pid"] + `\');\">Hint</button>
|
<input type="text" name="category" placeholder="Category" autocomplete="on" class="form-control" value="` + data[i]["category"] + `">
|
||||||
<button class=\"btn btn-success\" type=\"button\">Submit!</button>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="panel-body">
|
||||||
<div class=\"panel-footer\">`
|
<textarea type="text" name="description" placeholder="Description" autocomplete="on" class="form-control">` + data[i]["description"] + `</textarea>
|
||||||
|
<br><br>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input type="text" name="flag" placeholder="Flag" autocomplete="off" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input type="text" name="hint" placeholder="Hint" autocomplete="off" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="row">
|
||||||
|
<input type="number" name="value" placeholder="Value" autocomplete="off" class="form-control-number">
|
||||||
|
<label><input type="checkbox" name="disabled" value="1"` + checked + `>Disabled</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">`
|
||||||
|
|
||||||
for (var j = 0; j < files.length; j++) {
|
for (var j = 0; j < files.length; j++) {
|
||||||
file_name = files[j].split("/").pop();
|
file_name = files[j].split("/").pop();
|
||||||
problem +=
|
problem +=
|
||||||
`<a href=\"` + files[j] + `\" class=\"filelink\" target=\"_blank\">
|
`<a href="` + files[j] + `" class="filelink" target="_blank">
|
||||||
<h4 class=\"probfile\">` + file_name + `</h4>
|
<h4 class="probfile">` + file_name + `</h4>
|
||||||
</a>`
|
</a>`
|
||||||
}
|
}
|
||||||
|
|
||||||
problem += `<br>
|
problem += `<br>
|
||||||
<div id=\"hint_` + data[i]["pid"] + `\" style=\"display:none\">` + data[i]["hint"] + `</div>
|
<div id="hint_` + data[i]["pid"] + `" style="display:none">` + data[i]["hint"] + `</div>
|
||||||
</div></div>`
|
<div class="row" id="status_` + data[i]["pid"] + `"></div><br>
|
||||||
|
<input class="btn btn-success" type="submit" name="update" value="Update!">
|
||||||
|
</div></form></div>`
|
||||||
$("#problems").append(problem);
|
$("#problems").append(problem);
|
||||||
}
|
}
|
||||||
|
$("[name=update]").click(function(e) {
|
||||||
|
var problem = $(this).parents("form:first");
|
||||||
|
var pid = $("input[name=pid]", problem).val();
|
||||||
|
var name = $("input[name=name]", problem).val();
|
||||||
|
var description = $("textarea[name=description]", problem).val();
|
||||||
|
var hint = $("input[name=hint]", problem).val();
|
||||||
|
var category = $("input[name=category]", problem).val();
|
||||||
|
var value = $("input[name=value]", problem).val();
|
||||||
|
var flag = $("input[name=flag]", problem).val();
|
||||||
|
var disabled = $("input[name=disabled]", problem).prop("checked") ? 1 : 0;
|
||||||
|
update_problem(pid, name, category, description, hint, flag, disabled, value);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_hint(pid) {
|
function update_problem (pid, name, category, description, hint, flag, disabled, value) {
|
||||||
$("#hint_" + pid).slideToggle(120, "swing");
|
$.post("/api/problem/update", {
|
||||||
|
pid: pid,
|
||||||
|
name: name,
|
||||||
|
category: category,
|
||||||
|
description: description,
|
||||||
|
hint: hint,
|
||||||
|
flag: flag,
|
||||||
|
disabled: disabled,
|
||||||
|
value: value
|
||||||
|
}, function(data) {
|
||||||
|
if (data.success == 1) {
|
||||||
|
display_message("status_" + pid, "success", data.message, function() {});
|
||||||
|
} else {
|
||||||
|
display_message("status_" + pid, "danger", data.message, function() {});
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready( render_problems() );
|
$(function() {
|
||||||
|
render_problems();
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue