-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
229 lines (211 loc) · 9.8 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
'''
My site has 2 types of users.
Regular users can be registered via the registration page like normal.
Admin users will be automatically directed to the admin dashboard after logging in.
The admin login details are as follows:
Username: admin
Password: chess123
I have inserted some dummy data into the participants table for the first 3 tournaments only.
Winners for each past tournament can be added via the admin dashboard.
'''
from flask import Flask, render_template, session, redirect, url_for, g, request
from database import get_db, close_db
from flask_session import Session
from werkzeug.security import generate_password_hash, check_password_hash
from forms import RegistrationForm, LoginForm, AddWinnerForm, AddNewsForm, AddTournamentForm
from functools import wraps
import datetime
app = Flask(__name__)
app.teardown_appcontext(close_db)
app.config["SECRET_KEY"] = "this-is-my-secret-key"
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
@app.before_request
def logged_in_user():
g.user = session.get("username", None)
def login_required(view):
@wraps(view)
def wrapped_view(*args, **kwargs):
if g.user is None:
return redirect(url_for("login", next=request.url))
return view(*args, **kwargs)
return wrapped_view
@app.route("/")
def index():
db = get_db()
news = db.execute("""SELECT * FROM news ORDER BY blog_id DESC;""").fetchall()
return render_template("index.html", news=news)
@app.route("/logout")
def logout():
session.clear()
return redirect(url_for("index"))
@app.route("/register", methods=["GET", "POST"])
def register():
form = RegistrationForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
password2 = form.password2.data
db = get_db()
possible_clashing_user = db.execute("""SELECT * FROM users
WHERE username = ?;""", (username,)).fetchone()
if possible_clashing_user is not None:
form.username.errors.append("Username is already taken!")
else:
db.execute("""INSERT INTO users (username, password, is_admin)
VALUES (?, ?, 0);""", (username, generate_password_hash(password)))
db.commit()
return redirect( url_for("login") )
return render_template("register.html", form=form, title="Create Account - Chess Tournaments")
@app.route("/store")
def store():
db = get_db()
tournaments = db.execute("""SELECT * FROM tournaments
WHERE date >= date('now') ORDER BY date ASC;""").fetchall()
return render_template("store.html", tournaments=tournaments, title="Store - Chess Tournaments")
@app.route("/tournament_details/<int:tournament_id>")
def tournament_details(tournament_id):
db = get_db()
tournament = db.execute("""SELECT * FROM tournaments
WHERE tournament_id = ?;""", (tournament_id,)).fetchone()
return render_template("tournament_details.html", tournament=tournament, title="Tournament Details - Chess Tournaments")
@app.route("/database")
def database():
db = get_db()
tournaments = db.execute("""SELECT * FROM tournaments
WHERE date <= date('now') ORDER BY date DESC;""").fetchall()
return render_template("database.html", tournaments=tournaments, title="Database - Chess Tournaments")
@app.route("/participants/<int:tournament_id>")
def participants(tournament_id):
db = get_db()
tournament = db.execute("""SELECT * FROM tournaments
WHERE tournament_id = ?;""", (tournament_id,)).fetchone()
participants = db.execute("""SELECT * FROM participants
WHERE tournament_id = ?;""", (tournament_id,)).fetchall()
return render_template("participants.html",tournament=tournament, participants=participants, title="Participants - Chess Tournaments")
@app.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
db = get_db()
possible_clashing_user = db.execute("""SELECT * FROM users
WHERE username = ?;""", (username,)).fetchone()
possible_admin_user = db.execute("""SELECT * FROM users
WHERE is_admin = 1 AND username = ?;""", (username,)).fetchone()
if possible_clashing_user is None:
form.username.errors.append("Username is not registered!")
elif not check_password_hash(possible_clashing_user["password"], password):
form.password.errors.append("Password is incorrect!")
elif possible_admin_user is not None:
session.clear()
session["username"] = username
next_page = request.args.get("next")
if not next_page:
next_page = url_for("admin")
return redirect(next_page)
else:
session.clear()
session["username"] = username
next_page = request.args.get("next")
if not next_page:
next_page = url_for("index")
return redirect(next_page)
return render_template("login.html", form=form, title="Login - Chess Tournaments")
@app.route("/cart")
@login_required
def cart():
if "cart" not in session:
session["cart"] = {}
items = {}
prices = {}
total = 0
db = get_db()
for tournament_id in session["cart"]:
tournament = db.execute("""SELECT * FROM tournaments
WHERE tournament_id = ?;""", (tournament_id,)).fetchone()
cost = db.execute("""SELECT entry_fee FROM tournaments
WHERE tournament_id = ?;""", (tournament_id,)).fetchone()
price = tournament["entry_fee"]
prices[tournament_id] = price
item = tournament["name"]
items[tournament_id] = item
total = sum(prices.values())
#I found this solution to adding up all values in a dictionary here,
#specifically the first answer: https://stackoverflow.com/questions/4880960/how-to-sum-all-the-values-in-a-dictionary
return render_template("cart.html", cart=session["cart"], items=items, prices=prices, total=total, title="Your Cart - Chess Tournaments")
@app.route("/add_to_cart/<int:tournament_id>")
@login_required
def add_to_cart(tournament_id):
if "cart" not in session:
session["cart"] = {}
if tournament_id not in session["cart"]:
session["cart"][tournament_id] = 1
else:
session["cart"][tournament_id] += 1
return redirect(url_for("cart"))
@app.route("/remove_from_cart/<int:tournament_id>")
@login_required
def remove_from_cart(tournament_id):
if "cart" not in session:
session["cart"] = {}
if tournament_id in session["cart"]:
del session["cart"][tournament_id]
return redirect(url_for("cart"))
@app.route("/checkout", methods=["GET", "POST"])
@login_required
def checkout():
for tournament_id in session["cart"]:
db = get_db()
db.execute("""INSERT INTO participants (tournament_id, name)
VALUES (?, ?);""", (tournament_id, session["username"]))
db.commit()
session["cart"] = {}
return render_template("checkout.html", title="Checkout - Chess Tournaments")
#Admin Dashboard
@app.route("/admin", methods=["GET", "POST"])
@login_required
def admin():
form = AddNewsForm()
form2 = AddTournamentForm()
form3 = AddWinnerForm()
db = get_db()
tournaments_select = db.execute("""SELECT * FROM tournaments
WHERE date <= date('now') AND winner IS NULL;""").fetchall()
form3.tournament.choices = [(tournament["tournament_id"], tournament["name"]) for tournament in tournaments_select]
# I found this solution to populating a select field with data from a database here, specifically the second answer:
# https://stackoverflow.com/questions/43548561/populate-a-wtforms-selectfield-with-an-sql-query
if form.submit1.data and form.validate_on_submit():
# I found this workaround to having multiple forms on one page here, specifically the first answer:
# https://stackoverflow.com/questions/18290142/multiple-forms-in-a-single-page-using-flask-and-wtforms
title = form.title.data
content = form.content.data
db = get_db()
db.execute("""INSERT INTO news (title, content, date)
VALUES (?, ?, ?);""", (title, content, datetime.date.today()))
db.commit()
return redirect(url_for("admin"))
if form2.submit2.data:
name = str(form2.name.data) # Casting the data from the form solved the problem of an error
date = str(form2.date.data) # being thrown when trying to insert the data into the database
start_time = str(form2.start_time.data)
entry_fee = str(form2.entry_fee.data)
prize_money = str(form2.prize_money.data)
description = str(form2.description.data)
db = get_db()
db.execute("""INSERT INTO tournaments (name, date, start_time, entry_fee, prize_money, description)
VALUES (?, ?, ?, ?, ?, ?);""", (name, date, start_time, entry_fee, prize_money, description))
db.commit()
return redirect(url_for("admin"))
if form3.submit3.data:
tournament_id = form3.tournament.data
winner = form3.name.data
db = get_db()
db.execute("""UPDATE tournaments
SET winner = ?
WHERE tournament_id = ?;""", (winner, tournament_id))
db.commit()
return redirect(url_for("admin"))
return render_template("admin.html", form=form, form2=form2, form3=form3, title="Admin Dashboard - Chess Tournaments")