Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database works, UI got an upgrade, authentication not done yet #1

Merged
merged 25 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0501da3
Made the database and adding markers work!
ArondenOuden May 2, 2024
5f450de
Added datetime and spots to table and the popups
ArondenOuden May 2, 2024
70aef99
Changed location permission, button still not working
ArondenOuden May 2, 2024
0b7d9f1
Made the button work. Made formated time string, Made custom markers …
ArondenOuden May 2, 2024
e549d45
Added current location marker
ArondenOuden May 2, 2024
96dd78f
Organized static folder into subfolders (img, css, js)
ArondenOuden May 2, 2024
e64beec
Updating map on page load
ArondenOuden May 3, 2024
0e0fe18
Started with 'near you' functionality
ArondenOuden May 3, 2024
5fbcc09
Made the near you overlay look better, put styling in css file
ArondenOuden May 3, 2024
4c22c3e
Small changes, fixed database issue, changed near you line color, mad…
ArondenOuden May 3, 2024
a175fe2
Did some more styling on the leaflet popup
ArondenOuden May 4, 2024
13b42fd
More css pop styling, popups look good for now
ArondenOuden May 4, 2024
6146832
changed "spots" to "spot" when there's only one spot
ArondenOuden May 4, 2024
06e46c2
Made a beginning with near you divs creation
ArondenOuden May 4, 2024
09acab5
Add nearby divs, looking good
ArondenOuden May 6, 2024
b1bf98b
'Near you' now uses PostGIS to actually get the closest stickers. Loc…
ArondenOuden May 8, 2024
785f608
Near you now uses correct location. Reveals act weird and location pr…
ArondenOuden May 11, 2024
60926be
Update .gitignore: ignore uploads
ArondenOuden May 11, 2024
5c510b7
near you things
ArondenOuden May 27, 2024
1ea0300
added pycache to gitignore
ArondenOuden Sep 24, 2024
6944dd4
re added sample.env
ArondenOuden Sep 24, 2024
46ac39a
split up main.js file
ArondenOuden Sep 24, 2024
42ead69
deleted uploads content
ArondenOuden Sep 24, 2024
bb91dd8
changed sticky board color
ArondenOuden Sep 24, 2024
c00c95d
Create uploads folder if it doesn't exist
ArondenOuden Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ fabric.properties
# .NET
obj/
bin/

# Ignore user uploads
uploads/
SilasPeters marked this conversation as resolved.
Show resolved Hide resolved
41 changes: 0 additions & 41 deletions sample.env
ArondenOuden marked this conversation as resolved.
Show resolved Hide resolved

This file was deleted.

126 changes: 106 additions & 20 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,44 @@
import psycopg2
import time
import json
from decimal import Decimal
import os
from werkzeug.utils import redirect, secure_filename
import random
from dotenv import load_dotenv
import secrets
import datetime

# Load env file for variable
load_dotenv()

# Create flask app
app = flask.Flask(__name__)

POSTGRES_HOST = os.getenv("POSTGRES_HOST")
POSTGRES_DBNAME = os.getenv("POSTGRES_DBNAME")
POSTGRES_USER = os.getenv("POSTGRES_USER")
POSTGRES_PASS = os.getenv("POSTGRES_PASS")
POSTGRES_PORT = os.getenv("POSTGRES_PORT")

BOARD_COLOR = os.getenv("STICKER_MAP_COLOR")
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
UPLOAD_DIRECTORY = "static/uploads"


con = psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT)

cursor = con.cursor()

cursor.execute("CREATE TABLE IF NOT EXISTS stickers (stickerID SERIAL PRIMARY KEY, stickerLat Decimal(8,6), stickerLon Decimal(9,6), logoID INT, pictureUrl VARCHAR(255), adderEmail VARCHAR(255), postTime TIMESTAMP, spots INT, verified INT)")
# cursor.execute("INSERT INTO stickers (stickerLat, stickerLon, logoId, pictureUrl, adderEmail, verified) VALUES (52.1630587, 5.402001, 1, 'zwart 1920x1080.png', '[email protected]', 1)")

con.commit()

cursor.close()
con.close()


@app.route('/')
def stickerMap():
if os.getenv('STICKER_MAP_REQUIRE_LOGIN') == "True":
Expand Down Expand Up @@ -72,7 +92,7 @@ def auth():
if 'credentials_type' not in tokenResponse:
return redirect('/auth', code=302)
# Connect to db
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
cursor = con.cursor()
# Check if the user already has (normal) key stored. (Admin refresh session)
token = ""
Expand Down Expand Up @@ -121,10 +141,15 @@ def uploadSticker():
# Save file
file.save(os.path.join(UPLOAD_DIRECTORY, filename))
# create db entry
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
emailCode = random.randrange(9999999, 999999999)

sampleEmail = "[email protected]"
currentTime = str(datetime.datetime.now())

cursor = con.cursor()
cursor.execute("INSERT INTO stickers (stickerLat, stickerLon, logoId, pictureUrl, adderEmail) VALUES (%s,%s,%s,%s,%s)", (request.form['lat'], request.form['lon'], request.form['logoId'], os.path.join(UPLOAD_DIRECTORY, filename), emailCode))
# cursor.execute("INSERT INTO stickers (stickerLat, stickerLon, logoId, pictureUrl, adderEmail) VALUES (%s,%s,%s,%s,%s)", (request.form['lat'], request.form['lon'], request.form['logoId'], os.path.join(UPLOAD_DIRECTORY, filename), emailCode))
cursor.execute("INSERT INTO stickers (stickerLat, stickerLon, logoId, pictureUrl, adderEmail, postTime, spots, verified) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)", (request.form['lat'], request.form['lon'], 1, os.path.join(UPLOAD_DIRECTORY, filename), emailCode, currentTime, 0, 1))
con.commit()
return json.dumps({'status': '200', 'error': 'Sticker added to database.', 'emailCode': emailCode}), 200
else:
Expand All @@ -140,13 +165,13 @@ def uploadSticker():
@app.route('/logos', methods=['GET'])
def getLogos():
# Check token if required
if os.getenv('STICKER_MAP_REQUIRE_LOGIN') == "True":
if not checkToken(request.args.get('token')):
# if os.getenv('STICKER_MAP_REQUIRE_LOGIN') == "True":
# if not checkToken(request.args.get('token')):
return json.dumps({'status': '403', 'error': 'Not authenticated or cookies disabled.'}), 405
with psycopg2.connect() as con:
cursor = con.cursor()
results = cursor.execute('SELECT * FROM logos ORDER BY logoTitle DESC').fetchall()
return json.dumps(results)
# with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# cursor = con.cursor()
# results = cursor.execute('SELECT * FROM logos ORDER BY logoTitle DESC').fetchall()
# return json.dumps(results)
ArondenOuden marked this conversation as resolved.
Show resolved Hide resolved


@app.route('/editLogo', methods=['PATCH'])
Expand All @@ -156,7 +181,7 @@ def editLogo():
return json.dumps({'status': '403', 'error': 'Token invalid, expired, or not available'}), 403
if request.args.get("id") == None or request.args.get('name') == None or request.args.get('color') == None:
return json.dumps({'status': '400', 'error': 'Invalid or missing arguments.'}), 400
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
cursor = con.cursor();
cursor.execute('UPDATE logos SET logoTitle=%s, logoColor=%s WHERE logoId=%s', (request.args.get('name'), request.args.get('color'), request.args.get('id')))
con.commit()
Expand All @@ -170,7 +195,7 @@ def deleteLogo():
return json.dumps({'status': '403', 'error': 'Token invalid, expired, or not available'}), 403
if request.args.get("id") is None:
return json.dumps({'status': '400', 'error': 'Invalid or missing arguments.'}), 400
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
ArondenOuden marked this conversation as resolved.
Show resolved Hide resolved
cursor = con.cursor()
cursor.execute('DELETE FROM logos WHERE logoId=%s', (request.args.get('id'),))
con.commit()
Expand All @@ -184,7 +209,7 @@ def addLogo():
return json.dumps({'status': '403', 'error': 'Token invalid, expired, or not available'}), 403
if request.args.get('name') == None or request.args.get('color') == None:
return json.dumps({'status': '400', 'error': 'Invalid or missing arguments.'}), 400
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
cursor = con.cursor()
cursor.execute('INSERT INTO logos (logoTitle, logoColor) VALUES (%s,%s)', (request.args.get('name'), request.args.get('color')))
con.commit()
Expand All @@ -200,7 +225,7 @@ def addEmail():
if request.form['email'] != '':
if request.form['token'] != '':
# Check if the token is in the database
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
cursor = con.cursor()
result = cursor.execute('SELECT * FROM stickers WHERE adderEmail=%s', (request.form['token'],)).fetchall()
if len(result) != 0:
Expand All @@ -224,12 +249,49 @@ def getStickers():
return json.dumps({'status': '403', 'error': 'Not authenticated or cookies disabled.'}), 405
if (request.args.get('west') != '' and request.args.get('east') != '' and request.args.get('north') != '' and request.args.get('south') != ''):
# Get all the stickers within the bounding box
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# create cursor
cursor = con.cursor()
# find results
rows = cursor.execute("SELECT * FROM stickers WHERE stickerLat BETWEEN %s AND %s AND stickerLon BETWEEN %s AND %s AND verified='1'", (request.args.get('south'), request.args.get('north'), request.args.get('west'), request.args.get('east'))).fetchall()
SilasPeters marked this conversation as resolved.
Show resolved Hide resolved
return json.dumps(rows)
cursor.execute("SELECT * FROM stickers WHERE stickerLat BETWEEN %s AND %s AND stickerLon BETWEEN %s AND %s", (request.args.get('south'), request.args.get('north'), request.args.get('west'), request.args.get('east')))

rows = cursor.fetchall()

return json.dumps(rows, default=str)
else:
return json.dumps({'status': '400', 'error': 'Bounding box not defined or incomplete.'}), 400

@app.route('/getNearYouStickers', methods=['GET'])
def getNearYouStickers():
# Check token if required
if os.getenv('STICKER_MAP_REQUIRE_LOGIN') == "True":
if not checkToken(request.cookies.get('token')):
return json.dumps({'status': '403', 'error': 'Not authenticated or cookies disabled.'}), 405
if (request.args.get('lon') != '' and request.args.get('lat') != ''):
# Get all the stickers within the bounding box
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# create cursor
cursor = con.cursor()
# find results
# cursor.execute("""SELECT *, ST_DistanceSphere(
# ST_MakePoint(5.172445, 52.086240),
# ST_MakePoint(stickerLon, stickerLat)
# ) AS distance
# FROM stickers
# ORDER BY distance ASC
# LIMIT 10""")

cursor.execute("""SELECT *, ST_DistanceSphere(
ST_MakePoint(%s, %s),
ST_MakePoint(stickerLon, stickerLat)
) AS distance
FROM stickers
ORDER BY distance ASC
LIMIT 10""", (float(request.args.get('lon')), float(request.args.get('lat'))))

rows = cursor.fetchall()

return json.dumps(rows, default=str)
else:
SilasPeters marked this conversation as resolved.
Show resolved Hide resolved
return json.dumps({'status': '400', 'error': 'Bounding box not defined or incomplete.'}), 400

Expand All @@ -240,7 +302,7 @@ def getUnverifiedStickers():
if not checkAdminToken(request.cookies.get('adminToken')):
return json.dumps({'status': '403', 'error': 'Token invalid, expired, or not available'}), 403
# Get all unverified stickers'
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# create cursor
cursor = con.cursor()
# find results
Expand All @@ -255,7 +317,7 @@ def setSticker():
return json.dumps({'status': '403', 'error': 'Token invalid, expired, or not available'}), 403
if request.args.get("id") == None or request.args.get('state') == None:
return json.dumps({'status': '400', 'error': 'Invalid or missing arguments.'})
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# create a cursor
cursor = con.cursor()
# Get the email address of the user
Expand All @@ -274,6 +336,30 @@ def setSticker():
return json.dumps({'status': '400', 'error': 'Invalid card state'})


@app.route('/updateStickerSpots', methods=['POST'])
def updateStickerSpots():
# Check token if required
if os.getenv('STICKER_MAP_REQUIRE_LOGIN') == "True":
if not checkToken(request.cookies.get('token')):
return json.dumps({'status': '403', 'error': 'Not authenticated or cookies disabled.'}), 405

data = request.get_json()
stickerID = data.get('stickerID')

if (stickerID != ''):
# Get all the stickers within the bounding box
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# create cursor
cursor = con.cursor()
# Increase spot count
cursor.execute("UPDATE stickers SET spots = spots + 1 WHERE stickerID = %s", (stickerID,))

return json.dumps({'status': '200', 'error': 'Updated spots count'}), 200
else:
return json.dumps({'status': '400', 'error': 'Updating sticker spots failed'}), 400



def sendEmailUpdate():
return 0 # TODO not implemented

Expand All @@ -282,7 +368,7 @@ def checkToken(token):
# print(token)
if token is None:
return False
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
cursor = con.cursor()
cursor.execute("SELECT * FROM tokens WHERE token=%s", (token,))
rows = cursor.fetchall()
Expand All @@ -297,7 +383,7 @@ def checkAdminToken(token):
if token is None:
return False
# Connect with database
with psycopg2.connect() as con:
with psycopg2.connect(host=POSTGRES_HOST, dbname=POSTGRES_DBNAME, user=POSTGRES_USER, password=POSTGRES_PASS, port=POSTGRES_PORT) as con:
# Remove invalid keys from the database
cursor = con.cursor()
cursor.execute("DELETE FROM adminTokens WHERE %s > expirationTime", (time.time(),))
Expand Down
Loading