-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroutes.py
415 lines (352 loc) · 12.9 KB
/
routes.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
from app import app
from flask import render_template, request, redirect
from flask import session
from flask import flash
import modules.users as users
from sqlalchemy.sql import text
from db import db
from flask import abort
from os import getenv
# import base64 for image encoding
import base64
# for random texts in index.html
import modules.random_text_generator as random_text_generator
# module import for sending patches into general collection
import modules.sendpatch as sendpatch
# module for patch_view individual patch
import modules.patch_view as patch_view
# module for profile page
import modules.profile as profile_function
from PIL import Image
from io import BytesIO
import base64
@app.route("/")
def index():
# get previously displayed text
previous_text = session.get("random_text")
# get a new random text
random_text = random_text_generator.generate_random_text(previous_text)
# save the new text to session
session["random_text"] = random_text
return render_template("index.html", random_text=random_text)
# logged in page, shows all patches and user's own patches
@app.route("/patches")
def patches():
categories = sendpatch.get_categories()
# sort patches by id, default is ascending, can be changed by adding ?sort to the url
sort_order = request.args.get("sort")
search_argument = request.args.get("query")
category_argument = request.args.get("category")
# check if search argument is too long
try:
if len(search_argument) > 100:
return redirect("/patches")
except:
pass
params = {}
order_by_sql = ""
search_sql = ""
category_sql = ""
search_category_argument = ""
if sort_order == "asc":
order_by_sql = "ORDER BY id ASC"
elif sort_order == "desc":
order_by_sql = "ORDER BY id DESC"
if search_argument:
search_sql = "LOWER(name) LIKE LOWER(:search_argument)"
params["search_argument"] = f"%{search_argument}%"
if category_argument:
category_sql = "category_id = :category_id"
params["category_id"] = category_argument
if search_argument and category_argument:
search_category_argument = "WHERE " + " AND ".join((search_sql, category_sql))
search_sql = ""
category_sql = ""
elif search_argument:
search_sql = "WHERE " + search_sql
elif category_argument:
category_sql = "WHERE " + category_sql
base_query = text(
f"SELECT id, name, data FROM Patches {search_sql} {category_sql} {search_category_argument} {order_by_sql}"
)
results = db.session.execute(base_query, params).fetchall()
# Fetch image data for each patch, encode it to base64 and pass it to the template
patch_images = []
for patch in results:
image = patch[2]
if image:
image = base64.b64encode(image).decode("utf-8")
else:
image = None
patch_images.append(image)
category_searched = ""
if category_argument:
for category in categories:
if category[0] == int(category_argument):
category_searched = category[0]
break
return render_template(
"patches.html",
# zipping results and patch images together, so that they are together
results=zip(results, patch_images),
categories=categories,
search_argument=search_argument,
category_searched=category_searched,
sort_order=sort_order,
)
# individual patch view
@app.route("/merkki/<int:id>")
def merkki(id):
# referrer for patch site, because of navbar variable
try:
referring_page = request.referrer
referrer = ""
if "profile" in referring_page:
referrer = "profile"
elif "patches" in referring_page:
referrer = "patches"
except:
pass
# Fetch patch name and user id of the patch
try:
patch_name = patch_view.get_patch_name(id)
except Exception as e:
print(e)
flash("Merkkiä ei löytynyt", "error")
return redirect("/patches")
created_by_user = patch_view.get_created_by_user(id)
result_image = patch_view.get_image(id)
comments = patch_view.get_comments(id)
category = patch_view.get_category(id)
# Check if user is using a mobile device
user_agent = request.headers.get("User-Agent")
print(user_agent)
is_mobile = "Mobile" in user_agent
print(is_mobile)
try:
data = result_image.fetchone()[0] if result_image else None
except:
data = None
logged_in_username = users.get_username()
# If image data is found, upscale it and encode it to base64
if data is not None:
img = Image.open(BytesIO(data))
upscaled_img = img.resize((img.width * 3, img.height * 3), Image.BICUBIC)
output = BytesIO()
upscaled_img.save(output, format="JPEG")
output_value = output.getvalue()
encoded_output = base64.b64encode(output_value)
encoded_img = encoded_output.decode("utf-8")
return render_template(
"merkki.html",
nimi=patch_name,
created_by_user=created_by_user,
id=id,
photo=encoded_img,
comments=comments,
is_mobile=is_mobile,
category=category,
referrer=referrer,
)
return render_template(
"merkki.html",
nimi=patch_name,
created_by_user=created_by_user,
id=id,
comments=comments,
logged_in_username=logged_in_username,
is_mobile=is_mobile,
category=category,
referrer=referrer,
)
# adding a patch from general collection to user's own collection
@app.route("/send/new/to_collection", methods=["POST"])
def to_collection():
if session["csrf_token"] != request.form["csrf_token"]:
abort(403)
patch_id = request.form["id"]
user_id = users.user_id()
if patch_view.patch_into_collection(patch_id, user_id):
flash("Merkki lisätty omaan kokoelmaan onnistuneesti", "success")
else:
flash(
"Merkin lisääminen omaan kokoelmaan epäonnistui, merkki on jo kokoelmassasi",
"error",
)
return redirect("/patches")
# deleting a patch from general collection
@app.route("/deletepatch", methods=["POST"])
def delete_from_collection():
if session["csrf_token"] != request.form["csrf_token"]:
abort(403)
patch_id = request.form["id"]
patch_creator = patch_view.get_created_by_user(patch_id)
logged_in_username = users.get_username()
# if not the creator of the patch, ask for master password
if logged_in_username != patch_creator:
# check if master password is correct
masterpassword = request.form["masterpassword"]
# get master password from environment variable and check if it matches
if masterpassword != getenv("master_key"):
return redirect("/patches")
patch_view.delete_patch(patch_id)
flash("Merkki poistettu onnistuneesti", "success")
return redirect("/patches")
# add comment to patch
@app.route("/addcomment", methods=["POST"])
def addcomment():
if session["csrf_token"] != request.form["csrf_token"]:
abort(403)
patch_id = request.form["id"]
comment = request.form["comment"]
if len(comment) > 1000:
flash("Kommentti ei voi olla yli 1000 merkkiä pitkä", "error")
return redirect(f"/merkki/{patch_id}#commentform")
user_id = users.user_id()
patch_view.add_comment(patch_id, user_id, comment)
return redirect(f"/merkki/{patch_id}#commentform")
# adding patch to general collection for everyone to see
@app.route("/new/merkki", methods=["GET", "POST"])
def send():
if request.method == "GET":
categories = sendpatch.get_categories()
return render_template(
"new_merkki.html",
categories=categories,
)
elif request.method == "POST":
categories = sendpatch.get_categories()
name = request.form.get("nimi")
category = request.form.get("category")
if len(name) > 100:
flash("Merkkin nimi ei voi olla yli 100 merkkiä pitkä", "error")
return render_template(
"new_merkki.html",
categories=categories,
)
if len(name) == 0:
flash("Merkin nimi ei voi olla tyhjä", "error")
return render_template(
"new_merkki.html",
categories=categories,
)
if session["csrf_token"] != request.form["csrf_token"]:
abort(403)
if len(category) == 0:
flash("Valitse kategoria", "error")
return render_template(
"new_merkki.html",
categories=categories,
)
# get file from html form
file = request.files.get("file")
# check if file is empty
if file:
file_name = file.filename
# check if file is jpg or jpeg
if not file_name.lower().endswith((".jpg", ".jpeg", ".png")):
flash("Vain .jpg .jpeg .png tiedostot sallittu", "error")
return render_template(
"new_merkki.html",
categories=categories,
)
# get user id
userid = users.user_id()
# if file is empty, insert patch without image
if not file:
try:
sendpatch.insert_patch_into_generalcollection(name, userid, category)
except Exception as e:
print(e)
flash("Virhe tapahtui, merkin nimi on jo olemassa", "error")
return render_template(
"new_merkki.html",
categories=categories,
)
else:
try:
sendpatch.insert_patch_into_generalcollection(
name, userid, category, file
)
except Exception as e:
print(e)
if "Image is too large" in str(e):
flash("Kuvan maksimikoko on 10MB", "error")
elif "duplicate key value" in str(e):
flash("Virhe tapahtui, merkin nimi on jo olemassa", "error")
return render_template(
"new_merkki.html",
categories=categories,
)
# if all is okay return kirjautunut page
categories = sendpatch.get_categories()
flash("Merkki lisätty yhteiseen kokoelmaan onnistuneesti", "success")
return render_template(
"new_merkki.html",
categories=categories,
)
# registering user
@app.route("/register", methods=["GET", "POST"])
def register():
return users.handle_register(request)
# logging in user
@app.route("/login", methods=["GET", "POST"])
def login():
return users.handle_login(request)
# logging out user
@app.route("/logout")
def logout():
return users.logout()
# profile page
@app.route("/profile")
def profile():
username = users.get_username()
user_submitted_patches_amount = profile_function.user_submitted_patches_amount()
own_patches_result = profile_function.own_patches()
patch_images = []
for patch in own_patches_result:
image = patch[3]
if image:
image = base64.b64encode(image).decode("utf-8")
patch_images.append(image)
else:
patch_images.append(None)
return render_template(
"profile.html",
username=username,
own_patches_result=zip(own_patches_result, patch_images),
patch_amount=len(own_patches_result),
user_submitted_amount=(user_submitted_patches_amount),
)
# page to delete user's own patches
@app.route("/profile/deletepatch", methods=["GET", "POST"])
def delete_own_patch():
if request.method == "POST":
if session["csrf_token"] != request.form["csrf_token"]:
abort(403)
result_id = request.form["patch_id"]
user_id = users.user_id()
try:
patch_view.delete_patch_from_collection(result_id, user_id)
except Exception as e:
print(e)
flash("Merkkiä ei voitu poistaa", "error")
return redirect("/profile/deletepatch")
flash("Merkki poistettu onnistuneesti", "success")
return redirect("/profile/deletepatch")
elif request.method == "GET":
username = users.get_username()
own_patches_result = profile_function.own_patches()
patch_images = []
for patch in own_patches_result:
image = patch[3]
if image:
image = base64.b64encode(image).decode("utf-8")
patch_images.append(image)
else:
patch_images.append(None)
return render_template(
"delete_patch.html",
username=username,
own_patches_result=zip(own_patches_result, patch_images),
)