-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
115 lines (99 loc) · 3.67 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
from flask import Flask, request, redirect, url_for, render_template, session, Response, make_response
from functools import wraps
from config import SECRET_KEY
from db import *
import helper
def create_app(database_path='schema.db'):
app = Flask(__name__)
app.secret_key = SECRET_KEY
def logged_in(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'username' in session:
return f(*args, **kwargs)
else:
return make_response('you must be logged in to carry out this function', 401)
return decorated_function
@app.route('/')
def index():
return render_template('index.html', authenticated='username' in session)
# Login/ Logout
@app.route('/signup', methods=['POST'])
def signup():
users = UserTable(database_path)
username = request.form.get('username')
password = request.form.get('password')
if username is None or password is None:
return make_response('username or password was not input', 400)
if users.valid_username(username):
return redirect(url_for('index', error='account_exists'))
users.add_user(username, password)
return redirect(url_for('index'))
@app.route('/login', methods=['POST'])
def login():
error = None
users = UserTable(database_path)
username = request.form.get('username')
password = request.form.get('password')
if username is None or password is None:
return make_response('username or password was not input', 400)
if users.valid_username(username):
if users.valid_login(username, password):
session['username'] = username
else:
error = 'incorrect_password'
else:
error = 'nonexistent_username'
return redirect(url_for('index', error=error))
@app.route('/logout')
@logged_in
def logout():
session.pop('username', None)
return redirect(url_for('login'))
# Canvas
@app.route('/canvas')
def get_canvas():
canvas = CanvasTable(database_path)
if not canvas.canvas_exists():
canvas.create_canvas_table()
img_file = canvas.get_canvas_table()
img = img_file.getvalue()
return Response(response=img, mimetype='image/png')
# Pixel Data
@app.route('/canvas/<int:row>/<int:col>', methods=['PUT'])
@logged_in
def place_pixel(row, col):
hexcolor = request.args.get('hexcolor')
username = session.get('username')
print(hexcolor)
if hexcolor is None or hexcolor == '':
return make_response('Need to include hexcolor argument', 400)
if hexcolor[0] != '#':
return make_response('the first character must be "#"', 400)
try:
colors = bytes.fromhex(hexcolor[1:])
except ValueError:
return make_response(ValueError, 400)
if len(colors) != 3:
return make_response('the hex must contain exactly 3 colors', 400)
rgb = [color for color in colors]
canvas, pixel_table, countdown_table = CanvasTable(database_path), PixelTable(database_path), CountdownTable(database_path)
timestamp = helper.helper_datetime_utcnow()
time_waited = countdown_table.seconds_waited(username)
if time_waited >= 300:
canvas.update_canvas_pixel(row, col, rgb)
pixel_table.upsert_pixel_data(row, col, username, rgb, timestamp)
countdown_table.upsert_user_timestamp(username, timestamp)
return Response()
seconds_left = (300 - time_waited)
response = make_response(f'You have to wait {seconds_left} seconds more before placing your next tile!', 429)
response.mimetype = 'text/plain'
response.headers['Retry-After'] = seconds_left
return response
users, canvas, pixel_table, countdown_table = UserTable(database_path), CanvasTable(database_path), PixelTable(database_path), CountdownTable(database_path)
users.create_users_table()
if not canvas.canvas_exists():
canvas.create_canvas_table()
pixel_table.create_pixel_table()
countdown_table.create_countdown_table()
return app