-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
337 lines (315 loc) · 13.9 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
import sqlite3
from flask import Flask, render_template, request, g, session, redirect, url_for, escape
#DATA
DATABASE="./assignment3.db"
#Connects to the DATABASE file
def get_db():
# if there is a database, use it
db = getattr(g, '_database', None)
if db is None:
# otherwise, create a database to use
db = g._database = sqlite3.connect(DATABASE)
return db
# converts the tuples from get_db() into dictionaries
def make_dicts(cursor, row):
return dict((cursor.description[idx][0], value)
for idx, value in enumerate(row))
# given a query, executes and returns the result
def query_db(query, args=(), one=False):
cur = get_db().execute(query, args)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
#APP
app = Flask(__name__)
app.secret_key=b'secretkey'
# tears down the database connection when flask app closes.
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
# close the database if we are connected to it
db.close()
def cannot_view(): #error page, when you don't have permission to view.
return '''
<form action ="/">
<p>You cannot view this page!
<p><input value ="Go back to Homepage!" type = "submit">
</form>
'''
@app.route('/')
def index():
if 'student' in session: #will render template for students homepage view
db = get_db()
db.row_factory=make_dicts
remark = query_db('SELECT * FROM Remarks where username==?', [session['student']], one=False)
db.close()
return render_template('student_index.html', student=session['student'], remark=remark)
elif 'instructor' in session: #instructor #will render instructor homepage view
return render_template('instructor_index.html', instructor=session['instructor'])
else: #not logged in
return render_template('index.html') #homepage for guests viewing the site.
@app.route('/register', methods=['GET', 'POST'])
def register():
#will not allow logged in users to see register page.
if ('student' in session or 'instructor' in session):
return cannot_view()
if request.method=='POST':
db = get_db()
db.row_factory=make_dicts
new_user = request.form
if (new_user['username'] == "" or new_user['password'] == ""): #if inputed empty username/password
return '''
<form action ="/register">
<p>This username/password cannot be empty! Try again!"
<p><input value ="Back to Register page" type = "submit">
</form>
'''
#asked to try again!
sql = """
SELECT *
FROM Users
"""#selecting all users and checking if similar username in database.
accs = query_db(sql, args=(), one=False)
# What if input none for username and password ?need to add some cases here
for acc in accs:
if acc['username'] == new_user['username']:
return '''
<form action ="/register">
<p>This username already exists! Try a new one!"
<p><input value ="Back to Register page" type = "submit">
</form>
'''
num_accs = len(accs) + 1
cur = db.cursor()
#inserting to user table
cur.execute('INSERT INTO Users VALUES (?, ?, ?, ?)', [num_accs, new_user['username'], new_user['password'], new_user['type']])
#if user is of type student
if request.form['type'] == 'student':
sql = """
SELECT *
FROM Students
"""
num_students = len(query_db(sql, args=(), one=False)) + 1 #new student id
#insert into students table
cur.execute('INSERT INTO Students VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
num_students, new_user['username'], new_user['fname'], new_user['lname'],
0, 0, 0, 0, 0, 0, 0, 0
]) #inserting into students table of new user.
#type instructor => add to instructor table
else: #inserting into instructors table of new user info.
sql = """
SELECT *
FROM Instructors
"""
num_instrs = len(query_db(sql, args=(), one=False)) + 1 #new instructor id
cur.execute('INSERT INTO Instructors VALUES (?, ?, ?, ?)', [
num_instrs, new_user['username'], new_user['fname'], new_user['lname'],
]) #inserting into instructors table
db.commit() #save changes
cur.close()
return '''
<form action="/login">
<p>Successfully registered!
<p><input value ="Login Now!" type = "submit">
</form>
'''
else:
#register page
return render_template("register.html")
@app.route('/login',methods=['GET','POST'])
def login():
#already logged in
if ('student' in session or 'instructor' in session):
return cannot_view()
#submitted
if request.method=='POST': #button clicked to login.
sql = """
SELECT *
FROM Users
"""
new_login = request.form
results = query_db(sql, args=(), one=False)
for result in results:
if result[1]==new_login['username']: # authenticating user
if result[2]==new_login['password']:
if result[3]=='student':
session['student'] = new_login['username']
else:
session['instructor'] = new_login['username']
return redirect(url_for('index'))
else: #incorrect password
return '''
<form action="/login">
<p>Incorrect password! Try again
<p><input value ="Back to Login page" type = "submit">
</form>
'''
#not found in database
return '''
<form action ="/register">
<p>Username does not exist.
<p>New to here?
<p><input value ="Register" type = "submit">
</form>
'''
else:
return render_template('login.html') #not logged in
@app.route('/logout')
def logout():
if 'student' in session: #remove session of type student
session.pop('student', None)
elif 'instructor' in session: #remove session of type instructor
session.pop('instructor', None)
else:
#cannot logout when youre not even logged in..
return '''
<form action="/login">
<p>"You are not logged in! You cannot log out!"
<p><input value ="Back to Login page" type = "submit">
</form>
'''
return redirect(url_for('index')) #redirect to homepage.
@app.route('/marks', methods=['GET', 'POST']) #post for remarks requests
def marks():
if 'student' in session:
db = get_db()
db.row_factory=make_dicts
if request.method=='POST': #remark request submitted from student
remarks = query_db("SELECT * FROM Remarks", args=(), one=False)
num_remarks = len(remarks) #gettting total remarks in remarks table to add new remark (unique id)
num_remarks += 1
cur = db.cursor()
new_remark = request.form
status = "ongoing"
for rem in remarks:
if rem['what']==new_remark['what'] and rem['username']==session['student']:
#already submitted request of this assignment (one per assessment, cannot request for another after)
return '''
<form action ="/marks">
<p>Already submitted a request of this assignment/quiz. Cannot resubmit!
<p><input value ="Go back to Marks page" type = "submit">
</form>
'''
#adding new remark to table
cur.execute('INSERT INTO Remarks VALUES (?, ?, ?, ?, ?)', [num_remarks, session['student'],
new_remark['what'], new_remark['why'],status])
db.commit()
cur.close()
db.close()
return render_template('submit.html')
else: #displaying marks for the specific student logged in
student = query_db('SELECT * FROM Students where username==?', [session['student']], one=False)
db.close()
return render_template('marks.html', student=student)
elif 'instructor' in session: #type instructor logged in, show class grades.
db = get_db()
db.row_factory=make_dicts
student = query_db("SELECT * FROM Students", args=(), one=False)
db.close()
return render_template('allmark.html',student=student)
else:
return cannot_view()
@app.route('/viewrequests', methods=['GET', 'POST'])
def viewrequests(): #view remark requests from students to only instructors...
if ('instructor' in session):
db = get_db()
db.row_factory=make_dicts
remarks = query_db("SELECT * FROM Remarks", args=(), one=False)
db.close()
return render_template('viewrequests.html',remarks=remarks)
else:
return cannot_view()
@app.route('/remark', methods=['GET', 'POST'])
def remark():
if not ('instructor' in session): #students cannot view remark page (for instructors only)
return cannot_view()
db = get_db()
db.row_factory=make_dicts
if request.method=='POST': #if button clicked for remark request
cur = db.cursor()
user = request.form
if (user['newmark'] == ""):
return "Marks field cannot be empty!"
sql = ""
#get info from database depending on the remark option selected from student
if (user['which'] == "q1"):
sql='UPDATE Students SET q1=? WHERE username==?'
elif (user['which'] == "q2"):
sql = 'UPDATE Students SET q2=? WHERE username==?'
elif (user['which'] == "q3"):
sql = 'UPDATE Students SET q3=? WHERE username==?'
elif (user['which'] == "q4"):
sql = 'UPDATE Students SET q4=? WHERE username==?'
elif (user['which'] == "a1"):
sql = 'UPDATE Students SET a1=? WHERE username==?'
elif (user['which'] == "a2"):
sql = 'UPDATE Students SET a2=? WHERE username==?'
elif (user['which'] == "a3"):
sql = 'UPDATE Students SET a3=? WHERE username==?'
else:
sql = 'UPDATE Students SET final=? WHERE username==?'
cur.execute(sql,[user['newmark'],user['stud']]) #update student mark
cur.execute('UPDATE Remarks SET status=? WHERE username==? and what==?',["closed",user['stud'],user['which']])
#update remarks table (close request)
db.commit() #save changes
cur.close()
db.close()
return render_template('submit.html')
else:
student = query_db("SELECT * FROM Students", args=(), one=False)
db.close()
return render_template('remark.html',student=student)
@app.route('/feedback', methods=['GET', 'POST'])
def feedback():
if 'student' in session:
db = get_db()
db.row_factory=make_dicts
if request.method=='POST': #submit pressed
feedbacks = query_db("SELECT * FROM Feedback", args=(), one=False)
#find # of feedbacks in db
num_feedbacks = len(feedbacks)
num_feedbacks += 1
cur = db.cursor()
new_feedback = request.form
cur.execute('INSERT INTO Feedback VALUES (?, ?, ?, ?, ?, ?)', [num_feedbacks,new_feedback['username'],
new_feedback['q1'], new_feedback['q2'], new_feedback['q3'], new_feedback['q4']])
db.commit()
cur.close()
db.close()
return render_template('submit.html')
else: #on page
sql = """
SELECT *
FROM
((SELECT username
FROM Users
WHERE type=="instructor")
NATURAL JOIN
Instructors)
"""
instructors = query_db(sql, args=(), one=False)
db.close()
return render_template('feedback.html', instructors=instructors)
elif 'instructor' in session:
db = get_db()
db.row_factory=make_dicts
#getting feedbacks to instructor (specificly)
feedbacks = query_db("SELECT * FROM Feedback where username==?", [session['instructor']], one=False)
db.close()
return render_template('viewfeedback.html',instructor=session['instructor'],feedbacks=feedbacks)
else:
return cannot_view() #error page
@app.route('/<file>')
#include only files that do not have their own functions that render their templates..
#render other templates where session type does not matter (for both student and instructors)
def render_templates(file):
html_files = ['assignments', 'labs', 'lectures', 'links', 'news', 'office', 'team', 'tests']
if file in html_files:
return render_template(file + '.html')
return '''
<form action ="/">
<p>This page does not exist!
<p><input value ="Go back to Homepage!" type = "submit">
</form>
''' #non existent route/page