· 7 years ago · Oct 31, 2018, 11:22 AM
1from flask import Flask, render_template, session, request, redirect, flash, url_for
2from flask import jsonify
3import sqlite3
4import uuid
5import hashlib
6import random
7import platform
8from datetime import datetime
9
10# -------------------------------------------------------------------------------
11# SETTINGS for the Flask Web Application
12# -------------------------------------------------------------------------------
13DATABASE = '/home/18choym/mysite/test.sqlite'
14DEBUG = True
15
16SECRET_KEY = 'my random key can be anything' # this random sequence is required to encrypt Sessions
17app = Flask(__name__) # Creates a handle for the Flask Web Server
18app.config.from_object(__name__) # Set app configuration using above SETTINGS
19sep = ' | '
20# ---------------------------------------------------------------------------------------
21# DATABASE HELPER FUNCTIONS
22
23
24def connect_db():
25 return sqlite3.connect(app.config['DATABASE'])
26
27
28def make_dictionary(cursor, row):
29 return dict((cursor.description[idx][0], value)
30 for idx, value in enumerate(row))
31
32
33# ---------------------------------------------------------------------
34# Other helful functions!
35# ---------------------------------------------------------------------
36
37def hash_password(password):
38 # uuid is used to generate a random number
39 salt = uuid.uuid4().hex
40 return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
41
42
43# for decrypting the password in the database
44def check_password(hashed_password, user_password):
45 password, salt = hashed_password.split(':')
46 return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest()
47
48
49def verifyEmail(email):
50 atIndex = email.index('@')
51 dotIndex = email.index('.')
52 if atIndex > dotIndex:
53 if email[-3:] == 'com':
54 return True
55 else:
56 return False
57
58def update_access(username):
59 print(username)
60 fmt = "%d/%m/%Y %H:%M:%S"
61 datenow = datetime.now().strftime(fmt)
62 db = connect_db()
63 db.execute("UPDATE users SET lastaccess = ?, active = 1 where username = ?", (datenow, username))
64 # db.execute("UPDATE users SET lastaccess = ?", (datenow))
65 db.commit()
66 db.close()
67 return
68
69
70def get_active_users():
71 fmt = "%d/%m/%Y %H:%M:%S"
72 db = connect_db()
73 cursor = db.execute("SELECT username, lastaccess from users")
74 users = cursor.fetchall()
75 activeusers = [] # blank list
76 for user in users:
77 userdictionary = make_dictionary(cursor, user)
78 td = datetime.now() - datetime.strptime(userdictionary['lastaccess'], fmt)
79 if td.seconds < 120: # TODO when publishing this code, change this to 120
80 activeusers.append(userdictionary['username']) # makes a list of names
81 db.close()
82 return activeusers
83activeUsers = []
84deck = []
85
86def gen_cards():
87 global deck
88
89 card_val = ['ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'jack', 'queen', 'king']
90 card_face = ['spades', 'clubs', 'diamonds', 'hearts']
91
92 for i in card_face:
93 for j in card_val:
94 deck.append(j + '_of_' + i)
95 return deck
96
97
98def deal_card():
99 random_idx = random.randint(0, int(len(deck)))
100 random_idx -= 1
101 single_card = deck.pop(random_idx)
102 return single_card
103
104
105def deal_players(players):
106 for i in players:
107 i.append(deal_card())
108 return
109
110def deal_to_player(playerIndex):
111 global players
112 cardToDeal = deal_card()
113 players[playerIndex].append(cardToDeal)
114
115itercounter = 0
116numplayers = 0
117players = []
118
119my_dict = {'2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '10': '10',
120 'j': '10', 'q': '10', 'k': '10', 'a': '11'}
121def score_cards(card):
122 if type(card) == list:
123 score = 0
124 tmp = 0
125 for i in card:
126 if i[:2] == '10':
127 score += 10
128 else:
129 first_index = str(i[0])
130 print(str(type(first_index)))
131 tmp = int(my_dict[first_index])
132 score += tmp
133 else:
134 if card[:2] == '10':
135 score = 10
136 else:
137 first_index = str(card[0])
138 score = my_dict[first_index]
139 return score
140player_index = 0
141currentPlayer = 0
142gameSetupCompleted = False
143numActiveUsers = 0
144currentPlayerIndex = 0
145scores = []
146setupComplete = False
147exitCode = False
148playerLost = ''
149score = 0
150scores = []
151lost = []
152players = []
153
154def iteratePlayerIndex():
155 global currentPlayerIndex, scores
156 maxIdx = len(scores)-1
157 numNonZero = 0
158 for i in scores:
159 if i != 0:
160 numNonZero += 1
161 if numNonZero != 1:
162 currentPlayerIndex += 1
163 if currentPlayerIndex > maxIdx:
164 currentPlayerIndex = 0
165 # print(str(currentPlayerIndex) + '1')
166 if scores[-1] != 0:
167 while scores[currentPlayerIndex] == 0:
168 currentPlayerIndex += 1
169 # print(str(currentPlayerIndex) + '2')
170 if scores[-1] == 0 and currentPlayerIndex == maxIdx: #last element 0
171 currentPlayerIndex = 0
172 # print(str(currentPlayerIndex) + '3')
173 if scores[0] == 0 and currentPlayerIndex == 0:
174 currentPlayerIndex += 1
175 print(currentPlayerIndex)
176
177
178
179# HTTP Request Handlers------------------------------------------------------------------------
180# Homepage for the application
181
182
183@app.route('/blog', methods=['GET', 'POST'])
184def blog():
185 error = ""
186 return render_template('blog.html', error=error)
187username = ''
188
189
190@app.route('/', methods=['GET', 'POST']) # / means that homepage is referenced
191def login():
192 global username
193 if 'userid' in session:
194 return redirect("/page1")
195 if request.method == "POST":
196 username = request.form['username']
197 password = request.form['password']
198 update_access(username)
199 db = connect_db() # to database using predefined function
200 cursor = db.execute("Select * from users where username = ?", (username,))
201 row = cursor.fetchone()
202
203 if row is None:
204 flash("user does not exist")
205 else:
206 userdetails = make_dictionary(cursor, row) # makes a dictionary from the cursor
207 if userdetails['password'] != password:
208 flash("incorrect password")
209 # flash similar to print
210 else: # success
211 session['userid'] = userdetails['userid'] # setting a dictionary, saving cookies
212 session['permission'] = userdetails['permission'] # is the user an admin or not
213 session['username'] = username # simplifying user reference
214 return redirect('/page1')
215 db.close()
216 else:
217 flash("no data was posted")
218 return render_template('login.html')
219
220
221@app.route('/logoff')
222def logoff():
223 session.clear()
224 return redirect('/')
225
226
227@app.route('/page1', methods=['GET', 'POST'])
228def page1():
229 if 'userid' not in session:
230 return redirect('/')
231 return render_template('page1.html')
232
233
234@app.route('/register', methods=['GET', 'POST'])
235def register():
236 return render_template('register.html')
237
238
239@app.route('/registerData', methods=['GET', 'POST'])
240def registerData():
241 register = False
242 db = connect_db()
243
244 username = request.form['username']
245 password = request.form['password']
246 password2 = request.form['password2']
247 email = request.form['email']
248 fmt = "%d/%m/%Y %H:%M:%S"
249 datenow = datetime.now().strftime(fmt)
250 permission = 'user'
251 active = 1
252
253 cursor = db.execute("SELECT * FROM users WHERE active = 1")
254 row = cursor.fetchall()
255 for i in row: # check if the username already exists
256 if username == i[1] or verifyEmail(email) is True:
257 flash('Account created. If this is your account, you can log in. Otherwise, choose another username.')
258 register = True
259 return redirect('/register')
260 if verifyEmail(email) == False:
261 return redirect('/register')
262 if password != password2: # check if the passwords match
263 flash('Passwords do not match.')
264
265 else:
266 if register is False:
267 db.execute("INSERT INTO users (username, password, email, permission, lastaccess, active) VALUES "
268 "(?,?,?,?,?,?)", (username, password, email, permission, datenow, active))
269 db.commit()
270 # return(str(row))
271 return redirect('/')
272
273
274@app.route('/admin', methods=['GET', 'POST'])
275def admin():
276 db = connect_db() # to database using predefined function
277 cursor = db.execute("Select userid, username, email, lastAccess from users")
278 # cursor = db.execute('SELECT * from users')
279 usersTable = cursor.fetchall()
280
281 cursor = db.execute("Select * from moves")
282 movesTable = cursor.fetchall()
283
284 return render_template('admin.html', usersTable=usersTable, movesTable=movesTable)
285
286
287@app.route('/f', methods=['GET', 'POST'])
288def f():
289 db = connect_db()
290 cursor = db.execute('SELECT lastaccess from users')
291 row = cursor.fetchall()
292 return str(row)
293
294
295@app.route('/lobby', methods=['GET', 'POST'])
296def lobby():
297 activeUsers = get_active_users()
298 global numplayers
299 if 'userid' not in session:
300 return redirect('/')
301 if request.method == 'POST': # Returns updated list of activeUsers
302 requesttype = request.form.get('requesttype')
303 if requesttype == 'GetUsers':
304 numplayers = len(activeUsers)
305 username = request.form.get('username')
306 update_access(username)
307 numberOfPlayers = 3 # The number of players required to start the game
308 return jsonify({'userlist': activeUsers, 'numPlayers': numplayers,
309 'numberOfPlayers':numberOfPlayers})
310 return render_template('lobby.html')
311
312
313
314@app.route('/game', methods=['GET', 'POST'])
315def game():
316 global players, setupComplete, currentPlayerIndex, deck, scores, score
317 global lost, playerLost
318
319 scoreType = []
320 activeUsers = get_active_users()
321 numplayers = len(activeUsers)
322 if setupComplete is False:
323 players = [[] for i in range(int(numplayers))]
324 scores = []
325 lost = []
326 for i in range(numplayers):
327 scores.append(int(0))
328 for i in range(numplayers):
329 lost.append(False)
330 for i in range(numplayers):
331 scoreType.append(False)
332 gen_cards()
333 deal_players(players)
334 setupComplete = True
335 if request.method == 'POST':
336 # scoreType = []
337 # for i in score:
338 # scoreType.append(str(type(i)))
339
340 requesttype = request.form.get('requesttype')
341 # print(str(requesttype)+sep+'requesttype')
342 activeUsers = get_active_users()
343
344
345 if requesttype == 'lost':
346 '''
347 If the user's score is above 21, the lost requesttype is called.
348 '''
349 stringToPrint = 'You have lost!!'
350 username = request.form.get('username')
351 userIndex = activeUsers.index(str(username))
352 returnCode = 'Successful'
353 scores[int(userIndex)] = 0
354 return jsonify({'code': returnCode, 'userIndex':userIndex, 'scores':scores, 'lost':lost, 'stringToPrint':stringToPrint, 'scoreType':scoreType})
355
356
357 if requesttype == 'get cards':
358 '''
359 This requesttype is called often and updates the user's display.
360 '''
361 username = request.form.get('username')
362 print(str(activeUsers))
363 userIndex = activeUsers.index(str(username))
364 hand = players[userIndex]
365
366
367 # DEBUG
368 oldScores = scores[:]
369 # DEBUG
370 if scores[int(userIndex)] is not [0] or scores[int(userIndex)] is not '0' or scores[int(userIndex)] is not 0:
371 score = int(score_cards(hand))
372 scores[int(userIndex)] = score
373
374 lostSend = str(lost)
375 # return jsonify({'hand': hand, 'index': userIndex, 'score': score, 'username':username, 'scores':scores, 'players':players})
376 return jsonify({'hand': hand, 'index': userIndex, 'score': score, 'username':username, 'scores':scores, 'players':players, 'lost':lostSend, 'oldScores':oldScores, 'scoreType':scoreType})
377
378
379 if requesttype == 'validate move':
380 '''
381 request handler for updating a player's move.
382 '''
383 db = connect_db()
384 move = request.form.get('move')
385 print(str(move)+sep+'move')
386 username = request.form.get('username')
387 userIndex = activeUsers.index(str(username))
388 db.execute("INSERT INTO moves (username, move) VALUES "
389 "(?,?)", (username, move))
390 db.commit()
391 if move == 'hit':
392 deal_to_player(userIndex)
393 hand = players[userIndex]
394
395 if scores[int(userIndex)] is not [0] or scores[int(userIndex)] is not '0' or scores[int(userIndex)] is not 0:
396 scores[userIndex] = score_cards(hand)+1000
397 iteratePlayerIndex()
398 if scores[userIndex] > 21:
399 iteratePlayerIndex()
400 # return redirect('/')
401 elif scores[userIndex] == 0:
402 iteratePlayerIndex()
403 # return redirect('/')
404 if scores[userIndex] > 21:
405 scores[userIndex] = 0
406 iteratePlayerIndex()
407 elif move == 'stand':
408 iteratePlayerIndex()
409 return jsonify ({'hand':hand, 'players':players, 'scores':scores, 'scoreType':scoreType})
410
411
412 if requesttype == 'check if current user':
413 '''
414 updates buttons
415 '''
416 playerUsername = request.form.get('username')
417 currentUserIndex = activeUsers.index(str(playerUsername))
418 playerLost = request.form.get('lost')
419 if playerLost == 'True':
420 scores[currentUserIndex] = 0
421 return jsonify({'currentPlayer': 'True', 'redirect':'True', 'scoreType':scoreType})
422 if currentUserIndex == currentPlayerIndex:
423 return jsonify({'currentPlayer': 'True', 'redirect':'False', 'scoreType':scoreType})
424 else:
425 return jsonify({'currentPlayer': 'False', 'redirect':'False', 'scoreType':scoreType})
426 return render_template('game.html', numPlayers=numplayers, players=players, deck=deck, len=len(deck), activeUsers=activeUsers)
427
428@app.route('/fmt', methods=['GET', 'POST'])
429def fmt():
430 return render_template('ajopisf.html')
431
432@app.route('/machine', methods=['GET', 'POST'])
433def machine():
434 return str(platform.machine())
435 # x86_64 for server and mac
436
437@app.route('/layout')
438def layout():
439 return render_template('layout.html')
440
441@app.route('/html')
442def html():
443 return render_template('main.html')