-
Notifications
You must be signed in to change notification settings - Fork 29
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
Documentation of Server File Source Code #133
base: master
Are you sure you want to change the base?
Changes from all commits
b8c47c8
085c4f1
495cc55
758b0aa
3c88eb6
d83a355
b3b933b
d2410eb
c13deb0
f180a21
d1f82b0
74e8681
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ | |
|
||
db = SqliteDatabase(DATABASE_NAME) | ||
|
||
|
||
class User(Model): | ||
username = CharField(unique=True) | ||
password = CharField() | ||
|
@@ -22,6 +21,11 @@ class Meta: | |
|
||
|
||
class Session(Model): | ||
""" | ||
For every new user ,random token is generated,so that the | ||
token is unique for every user | ||
""" | ||
|
||
def random_token(): | ||
return "".join([random.choice(string.ascii_letters) for _ in range(20)]) | ||
|
||
|
@@ -45,9 +49,14 @@ class Meta: | |
|
||
|
||
class Question(Model): | ||
<<<<<<< HEAD | ||
q_no = IntegerField(unique=True) | ||
======= | ||
|
||
test_case_input = TextField() | ||
test_case_output = TextField() | ||
question_statement = CharField() | ||
>>>>>>> main3 | ||
author = ForeignKeyField(User) | ||
created_date_time = DateTimeField(default=datetime.datetime.now) | ||
|
||
|
@@ -56,6 +65,11 @@ class Meta: | |
|
||
|
||
class ContestProblems(Model): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new. Perhaps this docstring can explain WHY this model is necessary and what all features exist in PyJudge because of this model |
||
All contest problems belong to a Contest and are itself a question. | ||
contest defines the instance of Contest Class it belongs | ||
question defines the questions that belongs to that contest. | ||
""" | ||
contest = ForeignKeyField(Contest, backref="questions") | ||
question = ForeignKeyField(Question) | ||
|
||
|
@@ -65,19 +79,79 @@ class Meta: | |
|
||
|
||
class Submission(Model): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new |
||
Submoission classdefines the submission of solution of a Question | ||
Stores the information about: | ||
User that submits the Solution | ||
Time of Submission | ||
Contest to whish The question belongs | ||
Whether the soolution is correct | ||
""" | ||
user = ForeignKeyField(User) | ||
time = DateTimeField() | ||
contestProblem = ForeignKeyField(ContestProblems) | ||
is_correct = BooleanField() | ||
|
||
class Meta: | ||
database = db | ||
#define the database in the main class | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new |
||
indexes = ((("user", "time"), True),) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this line does not explain itself completely. A comment pointing to the right section of the peewee docs would be VERY helpful here. |
||
|
||
|
||
#Establish a Connection with Database | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise |
||
db.connect() | ||
|
||
"""Create Tables with specied fields in Databse""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please don't leave strings lying around in the code. Either use a comment or a docstring. |
||
db.create_tables([User, Session, Submission, ContestProblems, Contest, Question]) | ||
|
||
<<<<<<< HEAD | ||
# 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]) | ||
|
||
|
||
======= | ||
>>>>>>> main3 | ||
|
||
def login_required(function): | ||
def login_redirect(*args, **kwargs): | ||
|
@@ -90,6 +164,7 @@ def login_redirect(*args, **kwargs): | |
return login_redirect | ||
|
||
|
||
|
||
@app.route("/") | ||
def changePath(): | ||
return bottle.redirect("/home") | ||
|
@@ -105,6 +180,9 @@ def home(): | |
@app.get("/dashboard") | ||
@login_required | ||
def dashboard(): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise |
||
Return the dashboard template to the user | ||
""" | ||
contests = Contest.select().order_by(Contest.start_time) | ||
return bottle.template("dashboard.html", contests=contests) | ||
|
||
|
@@ -219,6 +297,20 @@ def contestInput(): | |
@app.get("/contest/<code>/<number>") | ||
@login_required | ||
def question(code, number): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new |
||
Checks if the question and Contest it belongs does exists. | ||
If exists : it checks the current status of the contest | ||
And then returns the question state ment along with question numbers | ||
and contest code to the Template | ||
|
||
: paran code : Contest code | ||
: type code: int | ||
: paran Question : Question no | ||
: type Question: int | ||
: return : Html template for Individual Question | ||
|
||
""" | ||
|
||
if ( | ||
not ContestProblems.select() | ||
.where((Contest.code == code) & (Question.id == int(number))) | ||
|
@@ -241,9 +333,19 @@ def question(code, number): | |
) | ||
|
||
|
||
|
||
@app.get("/contest/<code>") | ||
@login_required | ||
def contest(code): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new |
||
Checks if contest exists by validating the contest id. | ||
Checks the the current staus of code | ||
|
||
: param code : Contest code | ||
: return : Html template for Contest | ||
|
||
""" | ||
|
||
try: | ||
contest = Contest.get(Contest.code == code) | ||
except Contest.DoesNotExist: | ||
|
@@ -253,6 +355,7 @@ def contest(code): | |
return bottle.template("contest.html", contest=contest, questions=contest.questions) | ||
|
||
|
||
|
||
@app.get("/question/<id>") | ||
def download(id): | ||
try: | ||
|
@@ -267,13 +370,32 @@ def download(id): | |
return question_result["test_case_input"] | ||
|
||
|
||
|
||
@app.get("/static/<filepath:path>") | ||
def server_static(filepath): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new |
||
Static files for server | ||
|
||
: param path : path to download from | ||
:return : Static Files | ||
""" | ||
return bottle.static_file(filepath, root=os.path.join(dir_path, "static")) | ||
|
||
|
||
@app.get("/ranking/<code>") | ||
def contest_ranking(code): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nothing new. Perhaps if we had multiple rankings then it would have made sense to add a docstring here. IDK. Right now this docstring repeats what the code does. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think here i am explaing how contest ranking are created , i thin it would the reader to understand it more. |
||
Generates rankinks of users in a Contest i.e the Contest results | ||
Validates the Sumbission And Contest. | ||
Checks the number of correct submissions for each user and Added to | ||
list with tuples of Username Along with thier Scores . The tuples | ||
are added to list in descending order of the score .Then rankings are | ||
given to each Username in the list. | ||
|
||
|
||
:param code : Contest Code | ||
:return : Html Template For Displaying Rankings | ||
""" | ||
order = ( | ||
Submission.select( | ||
User.username, fn.count(Submission.contestProblem.distinct()).alias("score") | ||
|
@@ -295,8 +417,15 @@ def contest_ranking(code): | |
return bottle.template("rankings.html", people=order) | ||
|
||
|
||
|
||
@app.get("/ranking") | ||
def rankings(): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a better thing to do would have been to rename the function something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right now this docstring is noise |
||
Overall Ranking of the user over all the Contest. | ||
|
||
:param None | ||
:return : Ranking Template with Overall Ranking | ||
""" | ||
order = ( | ||
Submission.select( | ||
User.username, fn.count(Submission.contestProblem.distinct()).alias("score") | ||
|
@@ -316,6 +445,7 @@ def rankings(): | |
|
||
|
||
def logggedIn(): | ||
|
||
if not bottle.request.get_cookie("s_id"): | ||
return False | ||
return ( | ||
|
@@ -325,7 +455,9 @@ def logggedIn(): | |
) | ||
|
||
|
||
|
||
def createSession(username): | ||
|
||
try: | ||
session = Session.create(user=User.get(User.username == username)) | ||
except IntegrityError: | ||
|
@@ -340,6 +472,7 @@ def createSession(username): | |
|
||
@app.post("/login") | ||
def login(): | ||
|
||
username = bottle.request.forms.get("username") | ||
password = bottle.request.forms.get("password") | ||
if ( | ||
|
@@ -351,8 +484,10 @@ def login(): | |
return createSession(username) | ||
|
||
|
||
|
||
@app.post("/register") | ||
def register(): | ||
|
||
username = bottle.request.forms.get("username") | ||
password = bottle.request.forms.get("password") | ||
try: | ||
|
@@ -364,16 +499,20 @@ def register(): | |
return createSession(username) | ||
|
||
|
||
|
||
@app.get("/logout") | ||
def logout(): | ||
|
||
Session.delete().where(Session.token == bottle.request.get_cookie("s_id")).execute() | ||
bottle.response.delete_cookie("s_id") | ||
return bottle.redirect("/home") | ||
|
||
|
||
|
||
@app.post("/check/<code>/<number>") | ||
@login_required | ||
@login_required | ||
def file_upload(code, number): | ||
|
||
try: | ||
contestProblem = ContestProblems.get( | ||
ContestProblems.contest == Contest.get(Contest.code == code), | ||
|
@@ -393,20 +532,44 @@ def file_upload(code, number): | |
expected = expected["test_case_output"] | ||
uploaded = uploaded.strip() | ||
ans = uploaded == expected | ||
|
||
try: | ||
Submission.create( | ||
user=user, contestProblem=contestProblem, time=time, is_correct=ans | ||
<<<<<<< HEAD | ||
) | ||
except: | ||
bottle.abort(500, "Error in inserting submission to database.") | ||
|
||
if not ans: | ||
======= | ||
<<<<<<< HEAD | ||
)# Add Submission For User | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise |
||
except: | ||
bottle.abort(500, "Error in inserting submission to database.") | ||
|
||
if not ans: # if Answer is Wrong | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise |
||
======= | ||
) | ||
except Exception as e: | ||
bottle.abort(500, str(e)) | ||
if not ans: | ||
>>>>>>> 67730ed88a8c14fc1e4381f0bde6ee55f81aef12 | ||
>>>>>>> main3 | ||
return "Wrong Answer!!" | ||
else: | ||
return "Solved! Great Job! " | ||
|
||
|
||
|
||
@app.error(404) | ||
def error404(error): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise |
||
Handles Error | ||
|
||
:param error : Error returned the App | ||
:return : Redirects to Template which Display Error | ||
""" | ||
return template("error.html", errorcode=error.status_code, errorbody=error.body) | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see, this comment does not tell me anything new. What it says I can read in the code. A good docstring would let me know WHY the string being random is necessary.