-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
658 lines (469 loc) · 20.3 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
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
from functions import check_password, github_api, check_extension, generate_primary_key, to_seconds, find_by_username, find_by_email
from db_functions import create_typing_test_table, add_typing_test, show_all_data, get_average_wpm_value, get_max_wpm_value, get_count_wpm
from send_email_file import send_email
from flask import Flask, request, render_template, redirect, url_for, make_response
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import os
application = Flask(__name__)
application.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
application.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(application)
class Users(db.Model):
user_id = db.Column(db.Integer, primary_key=True)
user_nickname = db.Column(db.String(30), nullable=False)
user_email = db.Column(db.String(30), nullable=False)
user_password = db.Column(db.String(30), nullable=False)
user_repeat_password = db.Column(db.String(30), nullable=False)
user_description = db.Column(db.Text, default="")
user_avatar = db.Column(db.String(50), default="Circle_Davys-Grey_Solid.svg.png")
user_first_name = db.Column(db.String(30), default="")
user_last_name = db.Column(db.String(30), default="")
user_phone_number = db.Column(db.String(30), default="")
user_github_link = db.Column(db.String(50), default="")
user_primary_key = db.Column(db.String(10), default="")
user_incoming_invitations = db.Column(db.Text, default="empty")
user_sent_invitations = db.Column(db.Text, default="empty")
user_friends_list = db.Column(db.Text, default="empty")
date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<Users %r>' % self.id
@application.route('/', methods=['POST', 'GET'])
@application.route('/home', methods=['POST', 'GET'])
def main_page():
if request.method == 'POST':
user_input = request.form['search-bar']
if '#' not in user_input:
return redirect('/home')
username, primary_key = user_input.split('#')
table = Users.query.all()
data = find_by_username(table, username)
best, average, count = get_max_wpm_value(data.user_id), get_average_wpm_value(data.user_id), get_count_wpm(data.user_id)
# Make response
response = make_response(render_template("profile/public-profile.html", data=data, best=best, average=average, count=count))
response.set_cookie("viewed_profile", data.user_nickname)
return response
elif request.method == 'GET':
if (request.cookies.get("logged_username")):
cookie_value = request.cookies.get("logged_username")
table = Users.query.all()
data = find_by_username(table, cookie_value)
# Find invites
if data.user_incoming_invitations.split() and '#' in data.user_incoming_invitations.split()[0]:
notifications = '!'
else:
notifications = ""
if data:
response = make_response(render_template("homelogin.html", data=data, notifications=notifications))
return response
return render_template('index.html')
@application.route('/typing-test/<string:username>/<int:wpm>', methods=['POST', 'GET'])
def get_request_from_page(username, wpm):
if request.method == 'POST':
# Find user
table = Users.query.all()
data = find_by_username(table, username)
add_typing_test(data.user_id, wpm)
return redirect('/home')
@application.route('/logout')
def logout():
response = make_response(redirect("/home"))
response.set_cookie("logged_username", "", 0)
return response
@application.route('/login', methods=['POST', 'GET'])
def login_page():
if request.method == 'POST':
user_login = request.form['login'] # Getting values from html
user_password = request.form['pass']
inputs = []
inputs.append(user_login)
inputs.append(user_password)
if not all(inputs):
alert = 'Fields cannot be empty'
return render_template('log-in.html', alert=alert)
table = Users.query.all()
for i in table: # Conditions for login
if (i.user_nickname == user_login or i.user_email == user_login) and i.user_password == user_password:
# Add user to cookie session
response = make_response(redirect("/home"))
response.set_cookie("logged_username", i.user_nickname, to_seconds(30))
return response
alert = 'Incorrect login or password'
return render_template('log-in.html', alert=alert)
elif request.method == 'GET':
return render_template('log-in.html')
@application.route('/sign-up', methods=['POST', 'GET'])
def sign_up():
if request.method == 'POST':
user_email = request.form['email']
user_password = request.form['password'] # Getting values from html
user_repeat_password = request.form['repeatpassword']
this_user_nickname = request.form['nickname']
inputs = []
result = ['', '', '']
inputs.append(user_email)
inputs.append(user_password)
inputs.append(user_repeat_password)
inputs.append(this_user_nickname)
if all(inputs) is False:
result[0] = 'Fields cannot be empty'
return render_template('sign-up.html', result=result)
list_nicknames, list_emails, list_primary_keys = [], [], []
table = Users.query.all()
for i in table:
list_nicknames.append(i.user_nickname)
list_emails.append(i.user_email)
list_primary_keys.append(i.user_primary_key)
info_nickname = f'Nickname {this_user_nickname} already is use'
info_email = f'Email {user_email} already registered'
info_password = "Passwords don't equals"
if this_user_nickname in list_nicknames:
result[0] = info_nickname
if user_email in list_emails:
result[1] = info_email
if user_password != user_repeat_password:
result[2] = info_password
if result != ['', '', '']:
return render_template('sign-up.html', result=result)
current_primary_key = generate_primary_key()
while current_primary_key in list_primary_keys: # Generation of a unique user key
current_primary_key = generate_primary_key()
users = Users(
user_nickname=this_user_nickname,
user_email=user_email,
user_password=user_password,
user_repeat_password=user_repeat_password,
user_primary_key=current_primary_key
)
try:
db.session.add(users) # Adding new data to SQL
db.session.commit()
except Exception as _ex:
return _ex
response = make_response(redirect("/home"))
response.set_cookie("logged_username", this_user_nickname, to_seconds(30))
return response
elif request.method == 'GET':
result = ['', '', '']
return render_template('sign-up.html', result=result)
@application.route('/users=<string:key>')
def users_list(key):
with open('keys/secret-key.txt', 'r', encoding='utf-8') as file:
output = file.readlines() # Reading the admin panel key
current_key = output[0]
string = f'{current_key} {key}'.split()
if string[0] == string[1]:
table = Users.query.all()
return render_template('admin.html', table=table)
else:
return '404 NOT FOUND'
@application.route('/profile')
def profile():
table = Users.query.all()
cookie_value = ""
# Get username from cookie
if request.cookies.get("logged_username"):
cookie_value = request.cookies.get("logged_username")
# Find user
data = find_by_username(table, cookie_value)
best, average, count = get_max_wpm_value(data.user_id), get_average_wpm_value(data.user_id), get_count_wpm(data.user_id)
if data:
return make_response(render_template("profile/profile.html", data=data, best=best, average=average, count=count))
return "Error"
@application.route('/edit-profile/', methods=['POST', 'GET'])
def edit_profile():
if request.method == 'POST':
file = request.files['file']
first_name = request.form['first-name']
last_name = request.form['last-name']
nickname = request.form['nickname'] # Getting values from html
email = request.form['email']
description = request.form['textarea']
phone_number = request.form['phone-number']
github_link = request.form['github']
flag = True
table = Users.query.all()
cookie_value = ""
# Get username from cookie
if request.cookies.get("logged_username"):
cookie_value = request.cookies.get("logged_username")
# Find user
current_user = find_by_username(table, cookie_value)
if not current_user:
return "Error"
if first_name == '':
first_name = current_user.user_first_name
if last_name == '':
last_name = current_user.user_last_name
if nickname == '':
nickname = current_user.user_nickname
if email == '': # If no value is specified, leave current
email = current_user.user_email
if description == '':
description = current_user.user_description
if phone_number == '':
phone_number = current_user.user_phone_number
if github_link == '':
github_link = current_user.user_github_link
if check_extension(file.filename) is False and file.filename != '':
return 'An error occurred, invalid file extension'
if file.filename == '': # If the image is not transferred, nothing needs to be saved
flag = False
if flag:
user_avatar_path = 'static/img/' + current_user.user_nickname + str(current_user.user_id) + file.filename
filename = current_user.user_nickname + str(current_user.user_id) + file.filename
current_user.user_avatar = filename
current_user.user_first_name = first_name
current_user.user_last_name = last_name
current_user.user_nickname = nickname
current_user.user_email = email # Writing data to the database
current_user.user_description = description
current_user.user_phone_number = phone_number
current_user.user_github_link = github_link
try:
db.session.commit()
except Exception as _ex:
return _ex
if flag:
list_image = os.listdir('static/img') # List files in img folder
for img in list_image:
if current_user.user_nickname + str(current_user.user_id) in img: # If this is the user's previous file
os.remove(f'static/img/{img}') # then it is removed
file.save(user_avatar_path) # Saving a picture
# Add new username to cookie
response = make_response(redirect("/home"))
response.set_cookie("logged_username", nickname, to_seconds(30))
return response
return redirect("/home")
elif request.method == 'GET':
table = Users.query.all()
cookie_value = ""
# Get username from cookie
if request.cookies.get("logged_username"):
cookie_value = request.cookies.get("logged_username")
# Find user
data = find_by_username(table, cookie_value)
if data:
return make_response(render_template("profile/profilesetting.html", data=data))
return "Error"
@application.route('/change-password', methods=['POST', 'GET'])
def change_password():
if request.method == 'POST':
table = Users.query.all()
if request.cookies.get:
username = request.cookies.get("logged_username")
data = find_by_username(table, username)
old_password = request.form['old-password']
password = request.form['password']
repeatpassword = request.form['repeatpassword']
if old_password == "" or password == "" or repeatpassword == "":
alert_up = 'The field cannot be empty'
return render_template('changepass.html', alert_up=alert_up, user=user, primary_key=primary_key, key=key)
if old_password.strip() != data.user_password:
alert_up = 'You entered the wrong password'
return render_template('changepass-page.html', alert_up=alert_up, user=user, primary_key=primary_key, key=key)
if password.strip() != repeatpassword.strip():
alert_down = "Passwords don't equals"
return render_template('changepass-page.html', alert_down=alert_down, user=user, primary_key=primary_key, key=key)
if password.strip() == data.user_password:
alert_down = 'The new password must not be the same as the old one'
return render_template('changepass-page.html', alert_down=alert_down, user=user, primary_key=primary_key, key=key)
data.user_password = password
data.user_repeat_password = password
try:
db.session.commit()
except Exception as _ex:
return _ex
return redirect('/edit-profile')
return "Error"
elif request.method == 'GET':
return render_template('changepass-page.html')
@application.route('/new-password', methods=['POST', 'GET'])
def new_password():
if request.method == 'GET':
return render_template('newpassword.html')
elif request.method == 'POST':
table = Users.query.all()
cookie_value = ""
if request.cookies.get("verify_email"):
cookie_value = request.cookies.get("verify_email")
data = find_by_email(table, cookie_value)
password = request.form['password']
repeat_password = request.form['repeat-password']
if password.strip() != repeat_password.strip():
alert = 'Passwords are not equal!'
return render_template('newpassword.html', alert=alert)
if password.strip() == data.user_password:
alert = 'The new password cannot be equal to the old one!'
return render_template('newpassword.html', alert=alert)
data.user_password = password
data.user_repeat_password = repeat_password
try:
db.session.commit()
except Exception as _ex:
return _ex
# Add user to cookie session
response = make_response(redirect("/home"))
response.set_cookie("logged_username", data.user_nickname, to_seconds(30))
return response
@application.route('/forgot-password/<string:page>')
def forgot_password(page):
table = Users.query.all()
username = ""
# Get username from cookie
if not request.cookies.get("verify_email"):
username = request.cookies.get("logged_username")
email = find_by_username(table, username).user_email
else:
email = request.cookies.get("verify_email")
if page == 'l': # Mode when the user enters from the login page
link_back = '/login'
elif page == 'c': # Mode when the user enters from the password change page
link_back = '/change-password'
return render_template('forgotpass.html', email=email, link_back=link_back)
@application.route('/enter-login', methods=['POST', 'GET'])
def enter_login():
if request.method == 'GET':
return render_template('enterlogin.html')
elif request.method == 'POST':
email = request.form['email']
if email == '':
alert = 'field cannot be empty!'
return render_template('enterlogin.html', alert=alert)
table = Users.query.all()
for i in table: # Search for the current user by his email address
if i.user_email == email:
data = i
break
else:
alert = 'this email is not registered'
return render_template('enterlogin.html', alert=alert)
response = make_response(redirect('/forgot-password/l'))
response.set_cookie("verify_email", email)
return response
@application.route('/enter-code', methods=['POST', 'GET'])
def enter_code():
if request.method == 'GET':
return render_template('entercode.html')
elif request.method == 'POST':
user_code = request.form['security-code']
if request.cookies.get("verify_code"):
code_from_cookie = request.cookies.get("verify_code")
table = Users.query.all()
if user_code.strip() != code_from_cookie:
alert = 'Wrong code'
return render_template('entercode.html', alert=alert)
return redirect('/new-password')
@application.route('/user-friends-list')
def friend_list():
table = Users.query.all()
cookie_value = ""
# Get username from cookie
if request.cookies.get("logged_username"):
cookie_value = request.cookies.get("logged_username")
# Find user
data = find_by_username(table, cookie_value)
# Return error if user undefined
if not data:
return "Error"
friends_list = data.user_friends_list.split() # Getting data about the user's friends
for i in range(len(friends_list)):
friends_list[i] = friends_list[i].split('#') # Dividing each friend into a tuple (avatar, nickname, key)
return render_template('friends-page.html', data=data, friends_list=friends_list)
@application.route('/send-invite')
def send_invite():
table = Users.query.all()
if request.cookies.get("logged_username") and request.cookies.get("viewed_profile"):
data = find_by_username(table, request.cookies.get("viewed_profile")) # Search for the current user by his unique key
previous_data = find_by_username(table, request.cookies.get("logged_username")) # Search for a previous user by their unique key
if data.user_incoming_invitations == 'empty': # Record data about friend invites
data.user_incoming_invitations = f'{previous_data.user_avatar}#{previous_data.user_nickname}#{previous_data.user_primary_key}'
elif f'{previous_data.user_avatar}#{previous_data.user_nickname}#{previous_data.user_primary_key}' not in data.user_incoming_invitations:
data.user_incoming_invitations += f' {previous_data.user_avatar}#{previous_data.user_nickname}#{previous_data.user_primary_key}'
try:
db.session.commit()
except Exception as _ex:
return _ex
return render_template("profile/public-profile.html", data=data)
return "Error"
@application.route('/invite-list')
def invite_list():
table = Users.query.all()
if request.cookies.get("logged_username"):
data = find_by_username(table, request.cookies.get("logged_username")) # Search for the current user by his unique key
invites_list = data.user_incoming_invitations.split() # split all invitations
for i in range(len(invites_list)):
invites_list[i] = invites_list[i].split('#') # Splitting elements into a tuple (avatar, nickname, key)
return render_template('invite-list.html', data=data, invites_list=invites_list)
return "Error"
@application.route('/accept/<string:username>')
def accept(username: str):
table = Users.query.all()
if request.cookies.get("logged_username"):
data = find_by_username(table, request.cookies.get("logged_username"))
user_from_invite = find_by_username(table, username)
invites_list = data.user_incoming_invitations.split() # Split per invite
for i in range(len(invites_list)):
invites_list[i] = invites_list[i].split('#') # Splitting elements into a tuple (avatar, nickname, key)
if invites_list[i][1] == username: # If this is the user we are accepting invite, remove him
invites_list[i] = ''
invites_list[i] = '#'.join(invites_list[i]) # Join element back by type avatar#nickname#key
invites_list = " ".join(invites_list) # Join all invites
if data.user_friends_list == 'empty': # default value
data.user_friends_list = f'{user_from_invite.user_avatar}#{user_from_invite.user_nickname}#{user_from_invite.user_primary_key}' # Adding as a friend and deleting an invitation after that
data.user_incoming_invitations = invites_list
elif f'{user_from_invite.user_avatar}#{user_from_invite.user_nickname}#{user_from_invite.user_primary_key}' not in data.user_friends_list:
data.user_friends_list += f' {user_from_invite.user_avatar}#{user_from_invite.user_nickname}#{user_from_invite.user_primary_key}'
data.user_incoming_invitations = invites_list
try:
db.session.commit()
except Exception as _ex:
return _ex
return redirect('/invite-list')
return "Error"
@application.route('/accept-send-code')
def accept_send_code():
table = Users.query.all()
cookie_value = ""
# Get username from cookie
if request.cookies.get("verify_email"):
cookie_value = request.cookies.get("verify_email")
# Find user
data = find_by_email(table, cookie_value)
verify_code = generate_security_key()
message = f'Your verify code is:\n{verify_code}'
recipient = data.user_email
output = send_email(message, recipient)
if output == 'Success':
response = make_response(redirect('/enter-code'))
response.set_cookie("verify_code")
return response
elif output == 'Email invalid':
alert = 'Email invalid'
return render_template('forgotpass.html', alert=alert)
return "Error"
@application.route('/decline/<string:username>')
def decline(username: str):
table = Users.query.all()
if request.cookies.get("logged_username"):
data = find_by_username(table, request.cookies.get("logged_username"))
invites_list = data.user_incoming_invitations.split() # Split per invite
for i in range(len(invites_list)):
invites_list[i] = invites_list[i].split('#') # Splitting elements into a tuple (avatar, nickname, key)
if invites_list[i][1] == username: # If this is the user we are declining invite, remove him
invites_list[i] = ''
invites_list[i] = '#'.join(invites_list[i]) # Join element back by type avatar#nickname#key
invites_list = " ".join(invites_list) # Join all invites
data.user_incoming_invitations = invites_list # Rewriting the invite list
try:
db.session.commit()
except Exception as _ex:
return _ex
return redirect('/invite-list')
return "Error"
if __name__ == '__main__':
#github_api('ViLsonCake')
#github_api('IsNAble')
#generate_admin_key('secret-key.txt')
#generate_users_key('users-key.txt')
application.run(debug=True)