Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question interface #134

Merged
merged 14 commits into from
Jun 3, 2019
Merged
70 changes: 70 additions & 0 deletions insert_dummy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import requests
import datetime
rsvarma95 marked this conversation as resolved.
Show resolved Hide resolved
import os


path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
question_dir = "files/questions"

with requests.Session() as session:
register = session.post(
"http://localhost:8080/register", data={"username": "test", "password": "test"}
)

login = session.post(
"http://localhost:8080/login", data={"username": "test", "password": "test"}
)

for i in range(1, 7, 1):
Question1 = session.post(
"http://localhost:8080/questionInput",
files={
"question": open(
os.path.join(question_dir, str(i), "inputs.txt"), "rb"
),
"answer": open(os.path.join(question_dir, str(i), "output.txt"), "rb"),
},
data={"statement": str(i)},
)

Contest1 = session.post(
"http://localhost:8080/contestInput",
data={
"code": "PRACTICE",
"description": "practice questions",
"start_time": datetime.datetime(day=1, month=1, year=1),
"end_time": datetime.datetime(day=1, month=1, year=9999),
"selection": [1, 2],
},
)
Contest2 = session.post(
"http://localhost:8080/contestInput",
data={
"code": "PASTCONTEST",
"description": "somewhere in the past",
"start_time": datetime.datetime(day=1, month=11, year=2018),
"end_time": datetime.datetime(day=1, month=12, year=2018),
"selection": [1, 2],
},
)
Contest3 = session.post(
"http://localhost:8080/contestInput",
data={
"code": "ONGOINGCONTEST",
"description": "somewhere in the present",
"start_time": datetime.datetime(day=1, month=4, year=2019),
"end_time": datetime.datetime(day=1, month=6, year=2019),
"selection": [3, 4],
},
)
Contest4 = session.post(
"http://localhost:8080/contestInput",
data={
"code": "FUTURECONTEST",
"description": "somewhere in the future",
"start_time": datetime.datetime(day=1, month=1, year=2020),
"end_time": datetime.datetime(day=1, month=10, year=2020),
"selection": [5, 6],
},
)
174 changes: 116 additions & 58 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,19 @@ class Contest(Model):
description = CharField()
start_time = DateTimeField()
end_time = DateTimeField()
creator = ForeignKeyField(User)
created_date_time = DateTimeField(default=datetime.datetime.now)

class Meta:
database = db


class Question(Model):
q_no = IntegerField(unique=True)
test_case_input = TextField()
test_case_output = TextField()
question_statement = CharField()
author = ForeignKeyField(User)
created_date_time = DateTimeField(default=datetime.datetime.now)

class Meta:
database = db
Expand Down Expand Up @@ -73,50 +78,6 @@ class Meta:
db.connect()
db.create_tables([User, Session, Submission, ContestProblems, Contest, Question])

# dummy contest data
practiceContest = Contest.get_or_create(
code="PRACTICE",
description="practice questions",
start_time=datetime.datetime(day=1, month=1, year=1),
end_time=datetime.datetime(day=1, month=1, year=9999),
)
pastContest = Contest.get_or_create(
code="PASTCONTEST",
description="somewhere in the past",
start_time=datetime.datetime(day=1, month=11, year=2018),
end_time=datetime.datetime(day=1, month=12, year=2018),
)
ongoingContest = Contest.get_or_create(
code="ONGOINGCONTEST",
description="somewhere in the present",
start_time=datetime.datetime(day=1, month=4, year=2019),
end_time=datetime.datetime(day=1, month=6, year=2019),
)
futureContest = Contest.get_or_create(
code="FUTURECONTEST",
description="somewhere in the future",
start_time=datetime.datetime(day=1, month=1, year=2020),
end_time=datetime.datetime(day=1, month=10, year=2020),
)

test = User.get_or_create(username="test", password="test")

q1 = Question.get_or_create(q_no=1, author=test[0])
q2 = Question.get_or_create(q_no=2, author=test[0])
q3 = Question.get_or_create(q_no=3, author=test[0])
q4 = Question.get_or_create(q_no=4, author=test[0])
q5 = Question.get_or_create(q_no=5, author=test[0])
q6 = Question.get_or_create(q_no=6, author=test[0])

ContestProblems.get_or_create(contest=practiceContest[0], question=q1[0])
ContestProblems.get_or_create(contest=practiceContest[0], question=q2[0])
ContestProblems.get_or_create(contest=pastContest[0], question=q1[0])
ContestProblems.get_or_create(contest=pastContest[0], question=q2[0])
ContestProblems.get_or_create(contest=ongoingContest[0], question=q3[0])
ContestProblems.get_or_create(contest=ongoingContest[0], question=q4[0])
ContestProblems.get_or_create(contest=futureContest[0], question=q5[0])
ContestProblems.get_or_create(contest=futureContest[0], question=q6[0])


def login_required(function):
def login_redirect(*args, **kwargs):
Expand Down Expand Up @@ -175,22 +136,106 @@ def statistics():
)


@app.get("/addQuestion")
@login_required
def addQuestion():
return bottle.template("addQuestion.html")


@app.post("/questionInput")
@login_required
def questionInput():
userid = bottle.request.session.user
uploaded_question = bottle.request.files.get("question").file.read()
uploaded_answer = bottle.request.files.get("answer").file.read()
uploaded_statement = bottle.request.forms.get("statement")
try:
Question.create(
test_case_input=uploaded_question,
test_case_output=uploaded_answer,
question_statement=uploaded_statement,
author=userid,
)
except Exception as e:
bottle.abort(500, str(e))
question_bank = (
Question.select(
Question.id,
Question.test_case_input,
Question.question_statement,
User.username,
Question.created_date_time,
)
.join(User, on=(Question.author == User.id))
.order_by(Question.created_date_time.desc())
.dicts()
)
return bottle.template("questionBank.html", question_bank=question_bank)


@app.get("/addContest")
@login_required
def addContest():
question_bank = (
Question.select(
Question.id,
Question.test_case_input,
Question.question_statement,
User.username,
Question.created_date_time,
)
.join(User, on=(Question.author == User.id))
.order_by(Question.created_date_time.desc())
.dicts()
)
return bottle.template("addContest.html", question_bank=question_bank)


@app.post("/contestInput")
@login_required
def contestInput():
userid = bottle.request.session.user
code = bottle.request.forms.get("code")
description = bottle.request.forms.get("description")
start_time = bottle.request.forms.get("start_time")
end_time = bottle.request.forms.get("end_time")
selection = bottle.request.forms.getall("selection")
try:
contest = Contest.get_or_create(
code=code,
description=description,
start_time=start_time,
end_time=end_time,
creator=userid,
)
except Exception as e:
bottle.abort(500, str(e))
for questions in selection:
ContestProblems.create(contest=contest[0], question=questions)
contests = Contest.select().order_by(Contest.start_time)
return bottle.template("dashboard.html", contests=contests)


@app.get("/contest/<code>/<number>")
@login_required
def question(code, number):
if (
not ContestProblems.select()
.where((Contest.code == code) & (Question.q_no == int(number)))
.where((Contest.code == code) & (Question.id == int(number)))
.join(Contest, on=(ContestProblems.contest == Contest.id))
.join(Question, on=(ContestProblems.question == Question.q_no))
.join(Question, on=(ContestProblems.question == Question.id))
.exists()
):
return bottle.abort(404, "no such contest problem")
contest = Contest.get(Contest.code == code)
if contest.start_time > datetime.datetime.now():
return "The contest had not started yet."
with open(os.path.join(question_dir, number, "statement.txt"), "rb") as fl:
statement = fl.read()
statement = (
Question.select(Question.question_statement)
.where(Question.id == number)
.dicts()
.get()
)
return bottle.template(
"question.html", question_number=number, contest=code, question=statement
)
Expand All @@ -208,9 +253,18 @@ def contest(code):
return bottle.template("contest.html", contest=contest, questions=contest.questions)


@app.get("/question/<path:path>")
def download(path):
return bottle.static_file(path, root=question_dir)
@app.get("/question/<id>")
def download(id):
try:
question_result = (
Question.select(Question.test_case_input)
.where(Question.id == id)
.dicts()
.get()
)
except:
bottle.abort(404, "No such question")
return question_result["test_case_input"]


@app.get("/static/<filepath:path>")
Expand Down Expand Up @@ -323,24 +377,28 @@ def file_upload(code, number):
try:
contestProblem = ContestProblems.get(
ContestProblems.contest == Contest.get(Contest.code == code),
ContestProblems.question == Question.get(Question.q_no == int(number)),
ContestProblems.question == Question.get(Question.id == int(number)),
)
except:
return bottle.abort(404, "no such contest problem")
user = Session.get(Session.token == bottle.request.get_cookie("s_id")).user
time = datetime.datetime.now()
uploaded = bottle.request.files.get("upload").file.read()
with open(os.path.join(question_dir, number, "output.txt"), "rb") as fl:
expected = fl.read()
expected = expected.strip()
expected = (
Question.select(Question.test_case_output)
.where(Question.id == number)
.dicts()
.get()
)
expected = expected["test_case_output"]
uploaded = uploaded.strip()
ans = uploaded == expected
try:
Submission.create(
user=user, contestProblem=contestProblem, time=time, is_correct=ans
)
except:
bottle.abort(500, "Error in inserting submission to database.")
except Exception as e:
bottle.abort(500, str(e))
if not ans:
return "Wrong Answer!!"
else:
Expand Down
58 changes: 58 additions & 0 deletions views/addContest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
% include('base.html', title="Add Contest")
<body>
<header class="text-center">
<h1>Contest Creation Page</h1>
</header>
<div class="container">
</br>
</br>
<form action="/contestInput" method = "post" enctype = "multipart/form-data">
Contest Code : <br/>
<input type="text" name="code" required /><br/><br/>
Contest Description : <br/>
<textarea name="description" rows = "3" cols = "80" required>Enter Description</textarea>
<br/><br/>
Start Time : <br/>
<input name="start_time" type='date'/><br/><br/>
End Time : <br/>
<input name="end_time" type='date'/>
<br/>
<br/>
</div>
<div class="container text-center">
<table class="table">
<thead>
<tr>
<th class="d-flex justify-content-center justify-content-center">List Of Questions</th>
</tr>
</thead>
</table>
<table class="table">
<tbody style="height:20rem;display:inline-block;overflow-y:scroll">
<tr style="font-weight:bold;">
<td style="padding-right:10rem">Question</td>
<td style="padding-right:6rem">Question Statement</td>
<td style="padding-right:10rem">Author</td>
<td style="padding-right:8rem">Time submitted</td>
<td style="padding-right:8rem">Selection</td>
</tr>
% for question in question_bank :
<tr>
<td style="padding-right:10rem">
<a href="/question/{{question['id']}}" role="button" class="btn btn-primary">
Download Question
</a>
</td>
<td name="statement" style="padding-right:10rem">{{question["question_statement"]}}</td>
<td style="padding-right:10rem">{{question["username"]}}</td>
<td style="padding-right:8rem">{{question["created_date_time"].strftime("%d-%m-%Y %H:%M")}}</td>
<td style="padding-right:8rem"><input type="checkbox" name="selection" value="{{question['id']}}"></td>
</tr>
% end
</tbody>
</table>
<button class="btn btn-primary" type="submit">Upload</button>
</form>
</div>
</body>

20 changes: 20 additions & 0 deletions views/addQuestion.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
% include('base.html', title="Add Question")
<body>
<header class="text-center">
<h1>Question Upload Page</h1>
</header>
<div class="container">
</br>
</br>
<form action="/questionInput" method = "post" enctype = "multipart/form-data">Question Upload : <br/>
<input type="file" name="question" required /><br/><br/>
Answer Upload : <br/>
<input type="file" name="answer" required /><br/><br/>
Statement : <br/>
<textarea name="statement" rows = "3" cols = "80" required>Enter Statement</textarea>
<br/>
<br/>
<button class="btn btn-primary" type="submit">Upload</button>
</form>
</div>
</body>
Loading