From 7487bc39f561e6b7790e82754bbed4449dd82c87 Mon Sep 17 00:00:00 2001 From: Adnan Memic Date: Sat, 14 Mar 2020 17:03:05 +0000 Subject: [PATCH] docstrings --- image.png | Bin 22326 -> 0 bytes location_app/app/functions/auth/base.py | 87 ++++++++---- .../app/functions/auth/change_password.py | 39 ++++-- .../app/functions/auth/create_profile.py | 42 ++++-- location_app/app/functions/auth/login.py | 16 ++- .../app/functions/data_tools/data_getter.py | 127 +++++++++++++++--- location_app/app/mqtt/__init__.py | 7 +- location_app/app/mqtt/mqtt_message_handler.py | 54 +++++--- location_app/app/routes/__init__.py | 5 + location_app/app/routes/average.py | 11 +- location_app/app/routes/index.py | 8 +- location_app/app/routes/login.py | 53 ++++++-- location_app/app/routes/main.py | 25 +++- location_app/app/routes/map.py | 18 ++- location_app/app/routes/picture.py | 2 +- location_app/app/routes/profile.py | 22 ++- location_app/app/static/css/login/create.css | 68 +++++----- location_app/app/static/css/login/forgot.css | 10 +- location_app/app/static/css/login/index.css | 6 +- location_app/app/static/css/main/index.css | 23 +++- location_app/app/static/css/map/index.css | 31 +++++ location_app/app/static/css/profile/index.css | 34 ++++- location_app/app/static/js/map/index.js | 114 +++++++++++++++- location_app/app/static/js/math.js | 35 +++++ location_app/app/static/js/profile/index.js | 68 +++++++--- location_app/app/static/js/test.js | 4 - location_app/app/templates/login/create.html | 24 ++-- location_app/app/templates/login/forgot.html | 6 +- location_app/app/templates/login/index.html | 2 +- location_app/app/templates/main/index.html | 26 +++- location_app/app/templates/map/index.html | 26 ++-- location_app/app/templates/profile/index.html | 25 ++-- 32 files changed, 801 insertions(+), 217 deletions(-) delete mode 100644 image.png delete mode 100644 location_app/app/static/js/test.js diff --git a/image.png b/image.png deleted file mode 100644 index 1a1237df355d8d071162c5f790453e042f1e9aeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22326 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 diff --git a/location_app/app/functions/auth/base.py b/location_app/app/functions/auth/base.py index 494fcab..412809d 100644 --- a/location_app/app/functions/auth/base.py +++ b/location_app/app/functions/auth/base.py @@ -1,57 +1,87 @@ import sqlite3 as sql from datetime import datetime -"""Validation for fields""" -database_user = "app/databases/users.db" # Taking the databases -database_locations = 'app/databases/locations.db' +database_user = "app/databases/users.db" +database_locations = "app/databases/locations.db" + def create(): + """ + Creates a user database if it doesn't exist + """ with sql.connect(database_user) as cur: - try: # Tries the sql table - cur.execute("CREATE TABLE UserDatabase(username VARCHAR2(20), password VARCHAR2(20), realname VARCHAR2(20), dob VARCHAR2(20), weight VARCHAR2(20));") + try: + cur.execute(""" + CREATE TABLE UserDatabase(username VARCHAR2(20), + password VARCHAR2(20), + realname VARCHAR2(20), + dob VARCHAR2(20), + color VARCHAR2(20), + weight VARCHAR2(20)); + """) except: pass - -def user_exists(username): # Checks for username + +def user_exists(username): + """ + Returns true or false depending on if the user exists + """ with sql.connect(database_user) as cur: - com = f"SELECT count(*) FROM UserDatabase WHERE username='{username}';" - print(com) - res = cur.execute(com).fetchone()[0] - if res == 0: + res = cur.execute(f""" + SELECT count(*) + FROM UserDatabase + WHERE username='{username}'; + """) + if res.fetchone()[0] == 0: return False else: return True -def tid_exists(username): # Checks for tid +def tid_exists(username): + """ + Returns true or false depending on if there is any data + for that username in the database + """ with sql.connect(database_locations) as cur: - com = f"SELECT count(*) FROM Location WHERE tid='{username}';" - print(com) - res = cur.execute(com).fetchone()[0] - if res == 0: + res = cur.execute(f""" + SELECT count(*) + FROM Location + WHERE tid='{username}'; + """) + if res.fetchone()[0] == 0: return False else: return True -def compare(username, value_in, value_type): # Comparing +def compare(username, value_in, value_type): + """ + Takes in username, value and type and checks if they match with + the ones already saved in the database + """ with sql.connect(database_user) as cur: - com = f"SELECT {value_type} FROM UserDatabase WHERE username='{username}';" - print(com) - res = cur.execute(com).fetchone()[0] - print(f"comparing - {value_in} == {res}") - if value_in == res: + res = cur.execute(f""" + SELECT {value_type} + FROM UserDatabase + WHERE username='{username}'; + """) + if value_in == res.fetchone()[0]: return True else: return False - -def check_month(month, day): # Checks the month and day + +def check_month(month, day): + """ + Takes in month and day and checks if the day + is valid for that month + """ if month in [1, 3, 5, 7, 8, 10, 12]: if (day > 0 and day <= 31): return True else: return False elif month == 2: - if (day > 0 and day <= 28): # Checking February + if (day > 0 and day <= 28): return True else: return False @@ -61,7 +91,12 @@ def check_month(month, day): # Ch else: return False -def check_date(day, month, year): # Checks full date + +def check_date(day, month, year): + """ + Takes in a date and checks if it's in the future and then calls + check_month to see if the month/day are valid + """ today = datetime.today().strftime('%Y-%m-%d').split("-") if int(year) > int(today[0]): return False diff --git a/location_app/app/functions/auth/change_password.py b/location_app/app/functions/auth/change_password.py index 107a648..900ce4d 100644 --- a/location_app/app/functions/auth/change_password.py +++ b/location_app/app/functions/auth/change_password.py @@ -1,17 +1,25 @@ import sqlite3 as sql -from app.functions.auth import base # Imports base for later use +from app.functions.auth import base database_user = "app/databases/users.db" -def change_password(data): # Changing password + +def change_password(data): + """ + Function to allow password change + """ base.create() _status = check_pass_data(data) if _status == "success": - new_password(data) + update_password(data) return _status - -def check_pass_data(data): # Checking password data + + +def check_pass_data(data): + """ + Function to check password data is valid + """ _status = check_empty(data) if _status == "ok": if base.tid_exists(data['username']): @@ -26,7 +34,11 @@ def check_pass_data(data): # Checki return _status -def check_empty(data): # Checks the entry to see if empty + +def check_empty(data): + """ + Function to if the fields are empty + """ if data['username'] == "": return "empty_id" elif data['day'] == "0": @@ -42,12 +54,19 @@ def check_empty(data): # Checks else: return "ok" -def new_password(data): # Updates database with new password + + +def update_password(data): + """ + Function to update new password in the database + """ con = sql.connect(database_user) cur = con.cursor() - com = f"UPDATE UserDatabase SET password='{data['password']}' WHERE username='{data['username']}';" - print(com) - cur.execute(com) + cur.execute(f""" + UPDATE UserDatabase + SET password='{data['password']}' + WHERE username='{data['username']}'; + """) con.commit() cur.close() con.close() \ No newline at end of file diff --git a/location_app/app/functions/auth/create_profile.py b/location_app/app/functions/auth/create_profile.py index 7b925c5..54d63f5 100644 --- a/location_app/app/functions/auth/create_profile.py +++ b/location_app/app/functions/auth/create_profile.py @@ -1,25 +1,34 @@ -import sqlite3 as sql # Imports sql for use within database +import sqlite3 as sql from app.functions.auth import base database_user = "app/databases/users.db" -def create_profile(data): # Creating new data for a new user + +def create_profile(data): + """ + Function to create new profile + """ base.create() _status = check_prof_data(data) if _status == "success": make_user(data) return _status - -def check_prof_data(data): # Checking new - print(data) + + +def check_prof_data(data): + """ + Function to the validity of profile data + """ _status = check_empty(data) if _status == "ok": if base.tid_exists(data['username']): if not base.user_exists(data['username']): if not (data['password'] == data['r_password']): return "pass_no_match" - elif not base.check_date(data['day'], data['month'], data['year']): + elif not base.check_date(data['day'], + data['month'], + data['year']): return "wrong_date" else: return "success" @@ -29,7 +38,11 @@ def check_prof_data(data): # Ch return "no_id" return _status + def check_empty(data): + """ + Function to check if the fields are filled + """ if data['username'] == "": return "empty_id" elif data['realname'] == "": @@ -49,13 +62,24 @@ def check_empty(data): else: return "ok" + + def make_user(data): + """ + Function to add new user to the database + """ con = sql.connect(database_user) cur = con.cursor() _date = f"{data['day']}-{data['month']}-{data['year']}" - com = f"INSERT INTO UserDatabase values('{data['username']}','{data['password']}','{data['realname']}','{_date}','{data['weight']}');" - print(com) - cur.execute(com) + cur.execute(f""" + INSERT INTO UserDatabase + values('{data['username']}', + '{data['password']}', + '{data['realname']}', + '{_date}', + '{data['color']}', + '{data['weight']}'); + """) con.commit() cur.close() con.close() \ No newline at end of file diff --git a/location_app/app/functions/auth/login.py b/location_app/app/functions/auth/login.py index 067858e..933b71f 100644 --- a/location_app/app/functions/auth/login.py +++ b/location_app/app/functions/auth/login.py @@ -3,24 +3,38 @@ from app.functions.auth import base def login(data): + """ + Function to start to start the login + """ base.create() l_status = check_login_data(data) return l_status + + def check_login_data(data): + """ + Function to check the login data + """ _status = check_empty(data) if _status == "ok": if data['username'] == "admin": return "success" if not base.user_exists(data['username']): return "no_id" - if not base.compare(data['username'], data['password'], "password"): + if not base.compare(data['username'], + data['password'], + "password"): return "wrong_pass" return "success" else: return _status + def check_empty(data): + """ + Function to check whether the fields are filled + """ if data['username'] == "": return "empty_id" elif data['password'] == "": diff --git a/location_app/app/functions/data_tools/data_getter.py b/location_app/app/functions/data_tools/data_getter.py index 128e11e..7467641 100644 --- a/location_app/app/functions/data_tools/data_getter.py +++ b/location_app/app/functions/data_tools/data_getter.py @@ -2,34 +2,72 @@ import sqlite3 as sql import time -database_user = "app/databases/users.db" # Grabs the database +database_user = "app/databases/users.db" database_locations = "app/databases/locations.db" - # user -def get_user_for(username): +def get_user_for(username): + """ + Returns data from the database for the specified username + """ with sql.connect(database_user) as cur: - res = cur.execute(f"SELECT username, realname, dob, weight FROM UserDatabase WHERE username='{username}';").fetchone() - return [res, get_filtered_data_for(username)] # Returns required data - + res = cur.execute(f""" + SELECT username, realname, dob, color, weight + FROM UserDatabase + WHERE username='{username}'; + """) + user_data = res.fetchone() + return [user_data, get_filtered_data_for(username)] + +def update_data_for(username, data): + """ + Updates color and weight for the specified user + """ + con = sql.connect(database_user) + cur = con.cursor() + cur.execute(f""" + UPDATE UserDatabase + SET color = '{data['color']}', weight = '{data['weight']}' + WHERE username='{username}'; + """) + con.commit() + cur.close() + con.close() - # freq def get_all_tids(): + """ + Returns a list of all unique id's + """ with sql.connect(database_locations) as cur: - tids = cur.execute("SELECT DISTINCT tid From Location;") + tids = cur.execute(""" + SELECT DISTINCT tid + From Location; + """) tids_list = list(map(lambda x: x[0], tids)) return tids_list + def get_frequency_for(data_type, tid): + """ + Goes through a column and finds a value that is repeating + the most times and returns it with the percentage + """ with sql.connect(database_locations) as cur: - data = cur.execute(f"SELECT {data_type} From Location WHERE tid = '{tid}';") + data = cur.execute(f""" + SELECT {data_type} + From Location + WHERE tid = '{tid}'; + """) data_list = list(map(lambda x: x[0], data)) frequent_data = max(set(data_list), key = data_list.count) - frequency_data = str(int((data_list.count(frequent_data)/len(data_list)) * 100)) - return [frequent_data, frequency_data] - + frequency_data = data_list.count(frequent_data) / len(data_list) + return [frequent_data, int(frequency_data * 100)] + def get_filtered_data_for(tid): + """ + Gets frequencies for most visited road and city + """ data_city = get_frequency_for('city', tid) data_road = get_frequency_for('road', tid) return [data_city, data_road] @@ -37,12 +75,26 @@ def get_filtered_data_for(tid): # main def get_locations_for(username): + """ + Returns a full detailed list of all location entries for + the specified username, if the username is admin then it + returns a list of all location entries + """ locations = [] with sql.connect(database_locations) as cur: if username == 'admin': - res = cur.execute(f"SELECT DISTINCT * From Location ORDER BY tid, tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT * + From Location + ORDER BY tid, tst DESC; + """) else: - res = cur.execute(f"SELECT DISTINCT * From Location WHERE tid='{username}' ORDER BY tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT * + From Location + WHERE tid='{username}' + ORDER BY tst DESC; + """) for tid, lon, lat, city, road, _date, _time, tst, in res: locations.append([tid, lon, lat, city, road, _date, _time]) return locations @@ -50,23 +102,60 @@ def get_locations_for(username): # map def get_weight_for(username): + """ + Returns weight for the specified username + """ + with sql.connect(database_user) as cur: + res = cur.execute(f""" + SELECT weight + From UserDatabase + WHERE username='{username}'; + """) + _weight = res.fetchone()[0] + return int(_weight) + +def get_color_for(username): + """ + Returns hex code color for the specified username + """ with sql.connect(database_user) as cur: - res = cur.execute(f"SELECT weight From UserDatabase WHERE username='{username}';").fetchone()[0] - return int(res) + res = cur.execute(f""" + SELECT color + From UserDatabase + WHERE username='{username}'; + """) + _color = res.fetchone()[0] + return _color def get_map_locations_for(username): + """ + Returns a list of all location entries for that username + and sorts them by date + """ locations = [] with sql.connect(database_locations) as cur: - res = cur.execute(f"SELECT DISTINCT longitude, latitude, date, time From Location WHERE tid='{username}' ORDER BY tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT longitude, latitude, date, time + From Location + WHERE tid='{username}' + ORDER BY tst DESC; + """) for lon, lat, _date, _time, in res: locations.append([lon, lat, _date, _time]) return locations def get_map_location_dates(username): + """ + Returns a list of all unique dates from all location entries + """ date_list = [] with sql.connect(database_locations) as cur: - res = cur.execute(f"SELECT DISTINCT date From Location WHERE tid='{username}' ORDER BY tst DESC;") + res = cur.execute(f""" + SELECT DISTINCT date + From Location + WHERE tid='{username}' + ORDER BY tst DESC; + """) for _date, in res: date_list.append(_date) return date_list - diff --git a/location_app/app/mqtt/__init__.py b/location_app/app/mqtt/__init__.py index ba52a04..5bc0865 100644 --- a/location_app/app/mqtt/__init__.py +++ b/location_app/app/mqtt/__init__.py @@ -1,7 +1,12 @@ -from flask_mqtt import Mqtt # MQTT using flask +from flask_mqtt import Mqtt from app.mqtt import mqtt_message_handler + def init_app(app): + """ + Function to connect the mqtt to the app and setup + on connect and on message callbacks + """ mqtt = Mqtt(app) @mqtt.on_connect() diff --git a/location_app/app/mqtt/mqtt_message_handler.py b/location_app/app/mqtt/mqtt_message_handler.py index 3195779..7aa51a7 100644 --- a/location_app/app/mqtt/mqtt_message_handler.py +++ b/location_app/app/mqtt/mqtt_message_handler.py @@ -1,33 +1,51 @@ -from geopy.geocoders import Nominatim # Imports nominatim API +from geopy.geocoders import Nominatim import sqlite3 as sql import json, os, time database_locations = 'app/databases/locations.db' + def getMsg(msg): - con = sql.connect(database_locations) # connecys to db, amkes cursor + """ + Takes in a message from the mqtt and saves the data inside + a database if one exists, if not creates it + """ + con = sql.connect(database_locations) cur = con.cursor() - geolocator = Nominatim(user_agent="Web_app") # starts nominatim - try: # Tries SQL to create table - cur.execute("CREATE TABLE Location(tid VARCHAR2(2), longitude NUMBER(10,6), latitude NUMBER(10,6), city VARCHAR2(20), road VARCHAR2(30), date VARCHAR2(20), time VARCHAR2(20), tst INT(15));") + geolocator = Nominatim(user_agent = "Trackmaster") + try: + cur.execute(""" + CREATE TABLE Location(tid VARCHAR2(2), + longitude NUMBER(10,6), + latitude NUMBER(10,6), + city VARCHAR2(20), + road VARCHAR2(30), + date VARCHAR2(20), + time VARCHAR2(20), + tst INT(15)); + """) except: - pass + pass data = json.loads(msg.payload.decode("utf8")) - tid = data["tid"] - lat = data["lat"] - lon = data["lon"] location = geolocator.reverse(f"{data['lat']},{data['lon']}") - city = location.raw["address"]["city"] # Puts data into small array to be used later + city = location.raw["address"]["city"] road = location.raw["address"]["road"] tst = data["tst"] - _time = time.strftime('%H:%M:%S', time.localtime(tst))#sets time format - _date = time.strftime('%d-%m-%Y', time.localtime(tst)) - com = f"INSERT INTO Location values('{tid}','{lon}','{lat}','{city}','{road}','{_date}','{_time}','{tst}');" - print(com) - cur.execute(com) - - con.commit() # commits changes to db + _time = time.strftime("%H:%M:%S", time.localtime(tst)) + _date = time.strftime("%d-%m-%Y", time.localtime(tst)) + cur.execute(f""" + INSERT INTO Location values('{data["tid"]}', + '{data["lon"]}', + '{data["lat"]}', + '{city}', + '{road}', + '{_date}', + '{_time}', + '{tst}'); + """) + print(f"{data['tid']} -- {_date} {_time}") + con.commit() cur.close() - con.close()# # closes connection + con.close() \ No newline at end of file diff --git a/location_app/app/routes/__init__.py b/location_app/app/routes/__init__.py index 2764b46..f8accde 100644 --- a/location_app/app/routes/__init__.py +++ b/location_app/app/routes/__init__.py @@ -6,7 +6,12 @@ from .profile import prof_bl from .average import average_bl from .picture import picture_bl + def init_app(app): + """ + Registers all blueprints to the app with + the appropriate url prefix + """ app.register_blueprint(index_bl) app.register_blueprint(main_bl, url_prefix="/main") app.register_blueprint(map_bl, url_prefix="/map") diff --git a/location_app/app/routes/average.py b/location_app/app/routes/average.py index 36c22f2..0593cd1 100644 --- a/location_app/app/routes/average.py +++ b/location_app/app/routes/average.py @@ -1,10 +1,15 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, request, + url_for, escape, redirect, session) from app.functions.data_tools import data_getter -average_bl = Blueprint('average', __name__) +average_bl = Blueprint('average', __name__) @average_bl.route("/", methods = ["GET"]) def index(): + """ + Renders the average index page with locations from the user + """ + _locations = data_getter.get_locations_for(session['username']) return render_template("average/index.html", - locations = data_getter.get_locations_for(session['username'])) + locations = _locations) diff --git a/location_app/app/routes/index.py b/location_app/app/routes/index.py index 0b086ce..5bb5d26 100644 --- a/location_app/app/routes/index.py +++ b/location_app/app/routes/index.py @@ -1,10 +1,16 @@ from flask import Blueprint, url_for, redirect, session -index_bl = Blueprint('index', __name__) + +index_bl = Blueprint('index', __name__) @index_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + If there is user data saved in cookies it goes to + the main page otherwise it will go to the login page + """ user = session.get('username') + session['advanced'] = 0 if user: return redirect(url_for('main.index')) else: diff --git a/location_app/app/routes/login.py b/location_app/app/routes/login.py index 9d61769..18a4205 100644 --- a/location_app/app/routes/login.py +++ b/location_app/app/routes/login.py @@ -1,44 +1,77 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, request, + url_for, redirect, session) from app.functions.auth.login import login from app.functions.auth.create_profile import create_profile from app.functions.auth.change_password import change_password from datetime import datetime -login_bl = Blueprint('login', __name__) DAYS = [i for i in range(1,32)] -MONTHS = [("January", 1), ("February", 2), ("March", 3), ("April", 4), ("May", 5), ("June", 6), ("July", 7), ("August", 8), ("September", 9), ("October", 10), ("November", 11), ("December", 12)] -YEARS = list(reversed([i for i in range(1900, (int(datetime.today().strftime('%Y')) + 1))])) +MONTHS = [("January", 1), ("February", 2), + ("March", 3), ("April", 4), + ("May", 5), ("June", 6), + ("July", 7), ("August", 8), + ("September", 9), ("October", 10), + ("November", 11), ("December", 12)] +this_year = int(datetime.today().strftime('%Y')) +YEARS = list(reversed([i for i in range(1900, this_year + 1)])) + +login_bl = Blueprint('login', __name__) @login_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + Renders the login page, handles POST requests for logging in + and displays errors on the page also takes the user to the + main page after successful login + """ if request.method == "POST": _status = login(request.form) if _status == "success": session["username"] = request.form["username"] return redirect(url_for('main.index')) else: - return render_template("login/index.html", status = _status) - return render_template("login/index.html", status = "0") + return render_template("login/index.html", + status = _status) + return render_template("login/index.html", + status = "0") @login_bl.route("/create_account", methods = ["GET", "POST"]) def create_account(): + """ + Renders the login page, handles POST requests for creating + an account and displays errors on the page also takes the user + back to the login page after creating the account + """ if request.method == "POST": _status = create_profile(request.form) if _status == "success": return redirect(url_for('login.index')) else: - return render_template("login/create.html", status = _status, days = DAYS, months = MONTHS, years = YEARS) - return render_template("login/create.html", status = "0", days = DAYS, months = MONTHS, years = YEARS) + return render_template("login/create.html", + status = _status, + time = [DAYS, MONTHS, YEARS]) + return render_template("login/create.html", + status = "0", + time = [DAYS, MONTHS, YEARS]) @login_bl.route("/forgot_password", methods = ["GET", "POST"]) def forgot_password(): + """ + Renders the login page, handles POST requests + and displays errors on the page also takes the user back to + the login page after changing the password + """ if request.method == "POST": _status = change_password(request.form) if _status == "success": return redirect(url_for('login.index')) else: - return render_template("login/forgot.html", status = _status, days = DAYS, months = MONTHS, years = YEARS) - return render_template("login/forgot.html", status = "0", days = DAYS, months = MONTHS, years = YEARS) \ No newline at end of file + return render_template("login/forgot.html", + status = _status, + time = [DAYS, MONTHS, YEARS]) + return render_template("login/forgot.html", + status = "0", + time = [DAYS, MONTHS, YEARS]) \ No newline at end of file diff --git a/location_app/app/routes/main.py b/location_app/app/routes/main.py index dfaa3ec..02a3c47 100644 --- a/location_app/app/routes/main.py +++ b/location_app/app/routes/main.py @@ -1,14 +1,35 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, + url_for, redirect, session) from app.functions.data_tools import data_getter + main_bl = Blueprint('main', __name__) @main_bl.route("/") def index(): + """ + Renders the main page with users locations and preffered view + """ + _locations = data_getter.get_locations_for(session['username']) return render_template("main/index.html", - locations = data_getter.get_locations_for(session['username'])) + locations = _locations, + advanced = session['advanced']) + +@main_bl.route("/advanced") +def advanced(): + """ + Changes the preffered view and saves it in cookies + """ + if session['advanced'] == 0: + session['advanced'] = 1 + else: + session['advanced'] = 0 + return redirect(url_for('main.index')) @main_bl.route("/logout") def logout(): + """ + Deletes users data from cookies and goes to the login page + """ session['username'] = "" return redirect(url_for('index.index')) \ No newline at end of file diff --git a/location_app/app/routes/map.py b/location_app/app/routes/map.py index 7a48c0b..cf9010c 100644 --- a/location_app/app/routes/map.py +++ b/location_app/app/routes/map.py @@ -1,12 +1,22 @@ -from flask import Blueprint, render_template, request, session, url_for, escape, redirect +from flask import Blueprint, render_template, session from app.functions.data_tools import data_getter + map_bl = Blueprint('map', __name__) @map_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + Renders the map page with all the data + thats needed for calculations + """ + _locations = data_getter.get_map_locations_for(session['username']) + _dates = data_getter.get_map_location_dates(session['username']) + _weight = data_getter.get_weight_for(session['username']) + _color = data_getter.get_color_for(session['username']) return render_template("map/index.html", - locations = data_getter.get_map_locations_for(session['username']), - dates = data_getter.get_map_location_dates(session['username']), - weight = data_getter.get_weight_for(session['username'])) + locations = _locations, + dates = _dates, + weight = _weight, + color = _color) diff --git a/location_app/app/routes/picture.py b/location_app/app/routes/picture.py index 6e744ea..915b0d0 100644 --- a/location_app/app/routes/picture.py +++ b/location_app/app/routes/picture.py @@ -1,8 +1,8 @@ from flask import Blueprint, render_template, request, url_for, escape, redirect, session from app.functions.data_tools import data_getter -picture_bl = Blueprint('picture', __name__) +picture_bl = Blueprint('picture', __name__) @picture_bl.route("/", methods = ["GET"]) def index(): diff --git a/location_app/app/routes/profile.py b/location_app/app/routes/profile.py index d0ba9a0..749fa94 100644 --- a/location_app/app/routes/profile.py +++ b/location_app/app/routes/profile.py @@ -1,11 +1,25 @@ -from flask import Blueprint, render_template, request, url_for, escape, redirect, session +from flask import (Blueprint, render_template, request, + url_for, redirect, session) from app.functions.data_tools import data_getter prof_bl = Blueprint('prof', __name__) @prof_bl.route("/", methods = ["GET", "POST"]) def index(): + """ + Renders the profile page with user data and handles + changing of the weight and color through POST method + """ + if request.method == "POST": + data = request.form + data_getter.update_data_for(session['username'], data) + _user = data_getter.get_user_for(session['username']) + _locations = data_getter.get_map_locations_for(session['username']) + _dates = data_getter.get_map_location_dates(session['username']) return render_template("profile/index.html", - user = data_getter.get_user_for(session['username']), - locations = data_getter.get_map_locations_for(session['username']), - dates = data_getter.get_map_location_dates(session['username'])) + user = _user, + locations = _locations, + dates = _dates) + + + \ No newline at end of file diff --git a/location_app/app/static/css/login/create.css b/location_app/app/static/css/login/create.css index 54cd98e..16af9dc 100644 --- a/location_app/app/static/css/login/create.css +++ b/location_app/app/static/css/login/create.css @@ -3,8 +3,8 @@ display: grid; height: 100%; width: 100%; - grid-template-columns: 25% 50% 25%; - grid-template-rows: 5vh auto 5vh; + grid-template-columns: 1fr 2fr 1fr; + grid-template-rows: 5vw auto auto; grid-template-areas: '. . .' '. box .' @@ -16,7 +16,7 @@ grid-area: box; display: grid; grid-template-columns: 1fr 2.5fr 2.5fr 1fr; - grid-template-rows: 1fr 5fr 2fr auto auto 1fr; + grid-template-rows: 1fr 5fr 2fr auto auto 1.5fr; border-radius : 20px; grid-template-areas: '. . . .' @@ -50,21 +50,23 @@ } .form_inside { display: grid; - grid-template-columns: 2fr 2fr; - grid-template-rows: 0.25fr 1.5fr 0.15fr 1.5fr 0.15fr 1.5fr 0.15fr 1.5fr 0.15fr 1.5fr 1.5fr auto; + grid-template-columns: 1fr; + grid-template-rows: 1vw auto 1vw auto 1vw auto 1vw auto 1vw auto 1vw auto auto auto; grid-template-areas: - '. .' - 'user user' - '. .' - 'name name' - '. .' - 'dob dob' - '. .' - 'weight weight' - '. .' - 'pass pass' - 'r_pass r_pass' - 'c_button c_button'; + '.' + 'user' + '.' + 'name' + '.' + 'dob' + '.' + 'colorr' + '.' + 'weight' + '.' + 'pass' + 'r_pass' + 'c_button'; } .username { display: grid; @@ -72,57 +74,55 @@ align-content: center; grid-area: user; } -.username_text { - margin-bottom: 1px; - font-size: 1.5vw; -} .realname { display: grid; justify-content: center stretch; align-content: center; grid-area: name; } -.realname_text { - margin-bottom: 1px; - font-size: 1.5vw; -} .dob { display: grid; justify-content: center stretch; align-content: center; grid-area: dob; } -.dob_text { - margin-bottom: 1px; +.dob select { font-size: 1.5vw; } -.weight { +.colorr { display: grid; justify-content: center stretch; align-content: center; - grid-area: weight; + grid-area: colorr; +} +.colorr input { + height: 30px; } -.weight_text { +.text { margin-bottom: 1px; font-size: 1.5vw; } +.weight { + display: grid; + justify-content: center stretch; + align-content: center; + grid-area: weight; +} .password { display: grid; justify-content: center stretch; align-content: center; grid-area: pass; } -.password_text { - margin-bottom: 1px; - font-size: 1.5vw; -} .r_password { display: grid; + padding-top: 1vw; justify-content: center stretch; align-content: center; grid-area: r_pass; } .create_button_area { + padding-top: 1vw; align-content: center; grid-area: c_button; } diff --git a/location_app/app/static/css/login/forgot.css b/location_app/app/static/css/login/forgot.css index 9df056d..a6e6347 100644 --- a/location_app/app/static/css/login/forgot.css +++ b/location_app/app/static/css/login/forgot.css @@ -16,7 +16,7 @@ grid-area: box; display: grid; grid-template-columns: 1fr 2.5fr 2.5fr 1fr; - grid-template-rows: 1.5fr 5fr 2fr auto auto 1fr; + grid-template-rows: 1.5fr 5fr 2fr auto auto 1.5fr; border-radius : 20px; grid-template-areas: '. . . .' @@ -50,7 +50,7 @@ .form_inside { display: grid; grid-template-columns: 2fr 2fr; - grid-template-rows: 0.5fr 1.5fr 0.5fr 1.5fr 0.5fr 1.5fr 1.5fr auto; + grid-template-rows: 1vw auto 1vw auto 1vw auto auto auto; grid-template-areas: '. .' 'user user' @@ -77,6 +77,9 @@ align-content: center; grid-area: dob; } +.dob select { + font-size: 1.5vw; +} .dob_text { margin-bottom: 1px; font-size: 2vw; @@ -93,16 +96,17 @@ } .r_password { display: grid; + padding-top: 1vw; justify-content: center stretch; align-content: center; grid-area: r_pass; } .forgot_button_area { + padding-top: 1vw; grid-area: forgot_button; } .forgot_button { font-size: 2vw; - border-radius: 10em; } .error_text { color: red; diff --git a/location_app/app/static/css/login/index.css b/location_app/app/static/css/login/index.css index 6b09b89..65012b1 100644 --- a/location_app/app/static/css/login/index.css +++ b/location_app/app/static/css/login/index.css @@ -16,7 +16,7 @@ grid-area: box; display: grid; grid-template-columns: 1fr 2.5fr 2.5fr 1fr; - grid-template-rows: 1.5fr 5fr 2fr auto auto 1fr; + grid-template-rows: 1.5fr 5fr 2fr auto auto 1.5fr; border-radius : 20px; grid-template-areas: '. . . .' @@ -52,8 +52,7 @@ justify-content: start; align-content: center; grid-template-columns: 2fr 2fr; -/* grid-template-rows: 0.5fr 1.5fr 0.5fr 1.5fr 0.5fr 1.5fr 1.5fr; */ - grid-template-rows: 20px auto 20px auto 20px auto auto; + grid-template-rows: 1vw auto 1vw auto 1vw auto auto; grid-template-areas: '. .' 'user user' @@ -67,7 +66,6 @@ display: grid; grid-area: btns; grid-template-columns: 1fr 1fr 0.2fr 1fr; - grid-template-areas: 'f_pass f_pass . login_button'; } diff --git a/location_app/app/static/css/main/index.css b/location_app/app/static/css/main/index.css index e812c73..5a7a08c 100644 --- a/location_app/app/static/css/main/index.css +++ b/location_app/app/static/css/main/index.css @@ -1,19 +1,38 @@ +.content_main { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: auto auto; + grid-template-areas: + 'titl' + 'tablee'; +} .table_main { width: 100%; border-width: 0; + grid-area: tablee; } .table_title { + color: black; + text-decoration: none; margin: 1vh; + display: grid; font-size: 4vw; + grid-area: titl; + justify-content: center; } .table_main th { margin: 1vh; padding: 1vh; + font-size: 3vw; +} +.basic { + text-align: center; font-size: 2vw; + margin: 0.3vh; } -.table_main td { +.advanced { text-align: center; - font-size: 1.4vw; + font-size: 1.5vw; margin: 0.3vh; } .table_main tr:nth-child(even) { diff --git a/location_app/app/static/css/map/index.css b/location_app/app/static/css/map/index.css index e69de29..21e7183 100644 --- a/location_app/app/static/css/map/index.css +++ b/location_app/app/static/css/map/index.css @@ -0,0 +1,31 @@ +.content_main { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: auto auto; + grid-template-areas: + 'dates' + 'map'; +} +.map { + grid-area: map; +} +.dates { + grid-area: dates; + display: grid; + grid-template-columns: 3fr 1fr 2fr; + grid-template-rows: 1fr; + grid-template-areas: + 'selection . bm_1'; + padding-bottom: 30px; +} +.bm_1 { + grid-area: bm_1; +} +.selection { + grid-area: selection; + display: grid; + align-items: center; +} +.selection select { + font-size: 2vw; +} \ No newline at end of file diff --git a/location_app/app/static/css/profile/index.css b/location_app/app/static/css/profile/index.css index 8547669..27a4206 100644 --- a/location_app/app/static/css/profile/index.css +++ b/location_app/app/static/css/profile/index.css @@ -1,7 +1,7 @@ .content_main { display: grid; - grid-template-columns: 0.5fr 0.5fr 0.5fr 0.5fr; - grid-template-rows: 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr 0.5fr 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr 0.5fr auto 0.5fr 0.5fr 1fr 0.5fr 1fr; grid-template-areas: 'p_title p_title p_title p_title' '. . . .' @@ -10,7 +10,7 @@ 'date type p_pic p_pic' 'date1 type1 p_pic p_pic' 'colorr weight p_pic p_pic' - 'colorr1 weight1 p_pic p_pic' + 'updates updates p_pic p_pic' '. . . .' 'city tcal cal speed' 'city1 tcal1 cal1 speed1' @@ -53,6 +53,17 @@ .weight { grid-area: weight; } +.updates { + grid-area: updates; +} +.updates form { + grid-area: updates; + display: grid; + grid-template-columns: 2fr 1fr 1fr; + grid-template-rows: auto; + grid-template-areas: + 'colorr1 weight1 submit'; +} .city { grid-area: city; } @@ -86,12 +97,29 @@ .date1 { grid-area: date1; } +.submit { + grid-area: submit; +} +.submit button{ + font-size: 1.5vw; +} .weight1 { + display: grid; + align-content: center; grid-area: weight1; } .color1 { + display: grid; + align-content: center; grid-area: colorr1; } +.weight1 input{ + width: 70%; +} +.color1 input{ + height: 3vw; + width: 30%; +} .city1 { grid-area: city1; } diff --git a/location_app/app/static/js/map/index.js b/location_app/app/static/js/map/index.js index cb489d3..de74959 100644 --- a/location_app/app/static/js/map/index.js +++ b/location_app/app/static/js/map/index.js @@ -1,34 +1,43 @@ +//MAP var map; var locations; var state; var weight; -// IMAGES +// IMAGES FOR MAP OBJECTS var normalMarker = "/static/img/map/dot.svg"; var startMarker = "/static/img/map/start.svg"; var endMarker = "/static/img/map/end.svg"; -// SCALES +// SCALES FOR MAP OBJECTS var startScale = 2; var endScale = 0.7; var fScale = 0.6; var hScale = 1; var lineW = 5; -// COLORS +// COLORS FOR MAP OBJECTS var normalColor = "#ff0000"; var highStartMarker = "#ffffff"; var highEndMarker = "#000000"; var highLine = "#000000"; -// TIMERS +// TIMERS FOR MAP OBJECTS var timers = {}; var l_timers = {}; // MAP -function initialize_map(_locations, _weight) { + +/** + * Makes the map from the passed in data, sets click listeners + * and calls all map locations + */ +function initialize_map(_locations, _weight, _color) { locations = _locations; weight = _weight; + normalColor = _color; + set_other_colors(); + map = new ol.Map({ target: "map", layers: [ @@ -42,11 +51,26 @@ function initialize_map(_locations, _weight) { get_map_all_locations(); } +/** + * Sets other colors depending on the favourite color + */ +function set_other_colors() { + console.log(normalColor); +} + +/** + * Deletes everything on the map + */ function reset_map_layers() { layers = map.getLayers(); layers.a = [layers.a[0]]; } +/** + * Centers the map so it shows all the dots on the map + * or if the argument are two dots then it centers the map + * on them + */ function center_map(points = 0) { if(points == 0) { var dot_layers = []; @@ -75,7 +99,28 @@ function center_map(points = 0) { } } +// SELECTION + +/** + * Decides if all locations should be showed or just + * a specific date based on the value in the select form + */ +function get_map_for_selection() { + var div = document.getElementById("date"); + var date = div.options[div.selectedIndex].value; + if(date == "all") { + get_map_all_locations(); + } else { + get_map_for_date(date); + } +} + // ALL LOCATIONS + +/** + * Draws a marker for each location entry and stores the + * date and time in the marker + */ function get_map_all_locations() { state = 1; reset_map_layers(); @@ -92,6 +137,12 @@ function get_map_all_locations() { } // FOR DATE + +/** + * Draws marker for each location entry on a specified date + * and connects them with lines also stores data that can be + * later read by clicking on the marker or the line + */ function get_map_for_date(date) { state = 2; reset_map_layers(); @@ -148,6 +199,11 @@ function get_map_for_date(date) { } // MARKER + +/** + * Draws the marker with set properties and + * returns a reference to that marker + */ function draw_marker(pos1, pos2, _properties) { var marker = new ol.layer.Vector({ source: new ol.source.Vector({ @@ -162,6 +218,9 @@ function draw_marker(pos1, pos2, _properties) { return marker; } +/** + * Returns a marker style with specified values + */ function get_marker_style(color, scale, img, anchor = [0.5, 0.5]) { return new ol.style.Style({ image: new ol.style.Icon({ @@ -177,6 +236,12 @@ function get_marker_style(color, scale, img, anchor = [0.5, 0.5]) { } // LINE + +/** + * Connects 2 locations, does the distance, + * calories, speed and time calculations and stores + * them in line properties + */ function connect_two_locations(loc1, loc2, num) { var pos1 = ol.proj.fromLonLat([loc1[0], loc1[1]]); var pos2 = ol.proj.fromLonLat([loc2[0], loc2[1]]); @@ -195,6 +260,10 @@ function connect_two_locations(loc1, loc2, num) { draw_line(pos1, pos2, line_properties) } +/** + * Draws the line in between 2 positions and applies the + * properties to the line + */ function draw_line(pos1, pos2, _properties) { var line = new ol.layer.Vector({ source: new ol.source.Vector({ @@ -208,6 +277,9 @@ function draw_line(pos1, pos2, _properties) { map.addLayer(line); } +/** + * Returns a line style with specified color + */ function get_line_style(color) { return new ol.style.Style({ stroke: new ol.style.Stroke({ @@ -218,9 +290,17 @@ function get_line_style(color) { } // CLICK LISTENER + +/** + * Sets a click listener on the map which will monitor if a line + * or marker are clicked and in which state and based of that + * will show alerts displaying all the data that was stored + * in the properties of the clicked object + */ function set_click_listener() { map.getViewport().addEventListener("click", function(event) { - var layer = map.forEachFeatureAtPixel(map.getEventPixel(event), function(feature, layer) { + var layer = map.forEachFeatureAtPixel(map.getEventPixel(event), + function(feature, layer) { return layer; }); if(layer) { @@ -236,6 +316,9 @@ function set_click_listener() { }); } +/** + * Takes in an array of strings and makes an alert out of that + */ function show_alert(info) { var text = ""; for(i = 0; i < info.length; i++) { @@ -244,6 +327,10 @@ function show_alert(info) { alert(text); } +/** + * Shows marker data depending on which state it is and if + * it is a special marker + */ function get_dot_data(layer) { if(state == 1) { show_alert(["You were here on", @@ -270,6 +357,9 @@ function get_dot_data(layer) { } } +/** + * Shows line data - only accesible in state 2 + */ function get_line_data(layer) { show_alert(["Distance: " + layer.get('length'), "Time: " + layer.get('time'), @@ -277,6 +367,10 @@ function get_line_data(layer) { "Calories: " + layer.get('calories')]); } +/** + * Highlights the line for 4 seconds and updates it's timer + * in the dictionary based on its number + */ function highlight_line(line) { line.setStyle(get_line_style(highLine)); clearTimeout(l_timers[line.get('number')]); @@ -285,6 +379,10 @@ function highlight_line(line) { }, 4000); } +/** + * Highlights the marker for 4 seconds and updates it's timer + * in the dictionary based on its number + */ function highlight_marker(marker, color) { marker.setStyle(get_marker_style(color, hScale, normalMarker)); marker.setZIndex(100); @@ -294,6 +392,10 @@ function highlight_marker(marker, color) { }, 4000); } +/** + * Finds the start and the end of a line and if they aren't + * special markers it highlights them + */ function get_start_end(layer) { var start; var end; diff --git a/location_app/app/static/js/math.js b/location_app/app/static/js/math.js index e3b7a81..25de622 100644 --- a/location_app/app/static/js/math.js +++ b/location_app/app/static/js/math.js @@ -1,10 +1,17 @@ // TIME + +/** + * Returns a difference between 2 dates in seconds + */ function get_time(loc1, loc2) { var miliseconds = Math.abs(new Date('1998/01/01 ' + loc1[3]) - new Date('1998/01/01 ' + loc2[3])); return (miliseconds / 1000); } +/** + * Formats time given in seconds + */ function format_time(seconds) { var miliseconds = seconds * 1000; if(seconds > 60) { @@ -16,10 +23,18 @@ function format_time(seconds) { } // DISTANCE + +/** + * Transfers an angle from degrees to radians + */ function toRad(x) { return x * Math.PI / 180; } +/** + * Calculates distance in meters between 2 points + * using Haversine formula + */ function get_distance(loc1, loc2) { var x1 = loc2[1] - loc1[1]; var dLat = toRad(x1); @@ -33,6 +48,9 @@ function get_distance(loc1, loc2) { return (distance * 1000); } +/** + * Formats distance given in meters + */ function format_distance(distance) { if (distance > 1000) { return (Math.round((distance / 1000) * 100) / 100) + " kilometers"; @@ -42,6 +60,10 @@ function format_distance(distance) { } // SPEED + +/** + * Returns speed in km/h between 2 points + */ function get_speed(loc1, loc2) { var distance = get_distance(loc1, loc2); var time = get_time(loc1, loc2); @@ -50,11 +72,18 @@ function get_speed(loc1, loc2) { return (speed * 3.6); } +/** + * Formats speed given in km/h + */ function format_speed(speed) { return (Math.round(speed * 100) / 100) + " km/h"; } // CALORIES + +/** + * Returns MET based of users speed + */ function get_MET(speed) { if ( 1 <= speed && speed < 3) { return 2; @@ -75,6 +104,9 @@ function get_MET(speed) { } } +/** + * Returns calories burned between 2 points + */ function get_calories(loc1, loc2) { var speed = get_speed(loc1, loc2); var time = get_time(loc1, loc2); @@ -83,6 +115,9 @@ function get_calories(loc1, loc2) { return (((met * 3.5 * weight) / 200) * (time/60)); } +/** + * Formats calories given in cal + */ function format_calories(calories) { if (calories > 1000) { return (Math.round(calories / 10) / 100) + " kcal"; diff --git a/location_app/app/static/js/profile/index.js b/location_app/app/static/js/profile/index.js index fcf9a37..9cc0ccd 100644 --- a/location_app/app/static/js/profile/index.js +++ b/location_app/app/static/js/profile/index.js @@ -1,32 +1,37 @@ +// USER var locations; var weight; var dates; +// DATA var distance = 0; var calories = 0; var tdistance = 0; var tcalories = 0; var tspeed = 0; -var color; -function setup(_locations, _weight, _dates, _color) { +/** + * Runs the calculations for dates and displays the calculated data + * after the page loads + */ +function setup(_locations, _weight, _dates) { locations = _locations; weight = _weight; dates = _dates; - color = _color; - - window.onload = function(){ + window.onload = function() { cycle_through_dates(); - console.log(document.getElementById("qw").textContent); - document.getElementById("type").innerHTML = '

' + "Adventurer" + '

'; - document.getElementById("speed").innerHTML = '

' + format_speed(tspeed) + '

'; - document.getElementById("color").style.backgroundColor = color; - document.getElementById("tdist").innerHTML = '

' + format_distance(tdistance) + '

'; - document.getElementById("tcal").innerHTML = '

' + format_calories(tcalories) + '

'; - document.getElementById("cal").innerHTML = '

' + format_calories(calories) + '

'; - document.getElementById("dist").innerHTML = '

' + format_distance(distance) + '

'; + document.getElementById("type").innerHTML = get_type(); + document.getElementById("speed").innerHTML = format_speed(tspeed); + document.getElementById("tdist").innerHTML = format_distance(tdistance); + document.getElementById("tcal").innerHTML = format_calories(tcalories); + document.getElementById("cal").innerHTML = format_calories(calories); + document.getElementById("dist").innerHTML = format_distance(distance); }; } +/** + * Goes through all the dates and does the calculations + * for each date individually + */ function cycle_through_dates() { for(i = 0; i < dates.length; i++) { var this_date_loc = []; @@ -38,11 +43,15 @@ function cycle_through_dates() { } } for(j = 0; j < this_date_loc.length - 1; j++) { - var dis = get_distance(this_date_loc[j], this_date_loc[j + 1]); + var dis = get_distance(this_date_loc[j], + this_date_loc[j + 1]); this_date_dist += dis; - this_date_cal += get_calories(this_date_loc[j], this_date_loc[j + 1]); - var speed = get_speed(this_date_loc[j], this_date_loc[j + 1]); - var time = get_time(this_date_loc[j], this_date_loc[j + 1]); + this_date_cal += get_calories(this_date_loc[j], + this_date_loc[j + 1]); + var speed = get_speed(this_date_loc[j], + this_date_loc[j + 1]); + var time = get_time(this_date_loc[j], + this_date_loc[j + 1]); if(speed > tspeed && dis < 100 && time > 2) { tspeed = speed; } else if(speed > tspeed && time > 10) { @@ -59,3 +68,28 @@ function cycle_through_dates() { } } } + +/** + * Returns a type based on your top distance in a day + */ +function get_type() { + if(tdistance < 1000) { + return "Couch Potato" + } else if(tdistance < 3000) { + return "Couch Potato" + } else if(tdistance < 5000) { + return "Minimalist" + } else if(tdistance < 8000) { + return "Average Joe" + } else if(tdistance < 11000) { + return "Enjoyer" + } else if(tdistance < 14000) { + return "Adventurer" + } else if(tdistance < 17000) { + return "Long Legs" + } else if(tdistance < 21000) { + return "Extreme" + } else { + return "Top Dog" + } +} \ No newline at end of file diff --git a/location_app/app/static/js/test.js b/location_app/app/static/js/test.js deleted file mode 100644 index 6c6dbb7..0000000 --- a/location_app/app/static/js/test.js +++ /dev/null @@ -1,4 +0,0 @@ -function test() { - var a = document.getElementById("month") - console.log(a.options[a.selectedIndex].text); -} \ No newline at end of file diff --git a/location_app/app/templates/login/create.html b/location_app/app/templates/login/create.html index 62cb865..6c40f4b 100644 --- a/location_app/app/templates/login/create.html +++ b/location_app/app/templates/login/create.html @@ -5,7 +5,6 @@ {% block basejs %} - {% endblock %} @@ -23,14 +22,11 @@

Create Account

-
-

ID:


+

ID:


{% if status == 'no_id' %}

Wrong ID

@@ -41,30 +37,30 @@ {% endif %}
-

Name:


+

Name:


{% if status == 'empty_name' %}

Empty Name

{% endif %}
-

Birthday:


+

Birthday:


@@ -75,15 +71,19 @@

Empty Date

{% endif %}
+
+

Favourite Color:


+ +
-

Weight (kg):


+

Weight (kg):


{% if status == 'empty_weight' %}

Empty Weight

{% endif %}
-

Password:


+

Password:


{% if status == 'empty_pass' %}

Empty Password

diff --git a/location_app/app/templates/login/forgot.html b/location_app/app/templates/login/forgot.html index 301eedf..3306cb6 100644 --- a/location_app/app/templates/login/forgot.html +++ b/location_app/app/templates/login/forgot.html @@ -40,19 +40,19 @@
diff --git a/location_app/app/templates/login/index.html b/location_app/app/templates/login/index.html index 6c9b780..9d7e3b2 100644 --- a/location_app/app/templates/login/index.html +++ b/location_app/app/templates/login/index.html @@ -48,7 +48,7 @@
diff --git a/location_app/app/templates/main/index.html b/location_app/app/templates/main/index.html index c5afb5d..9bc864d 100644 --- a/location_app/app/templates/main/index.html +++ b/location_app/app/templates/main/index.html @@ -28,8 +28,9 @@ {% block body %}
+ {% if advanced %} + Your Locations - @@ -40,7 +41,7 @@ {% for item in locations %} - + @@ -51,6 +52,27 @@ {% endfor %}
Your Locations
ID LongitudeTime
{{ item[0] }} {{ item[1] }} {{ item[2] }}
+ {% else %} + Your Locations + + + + + + + + + {% for item in locations %} + + + + + + + + {% endfor %} +
IDCityRoadDateTime
{{ item[0] }}{{ item[3] }}{{ item[4] }}{{ item[5] }}{{ item[6] }}
+ {% endif %}
{% endblock %} diff --git a/location_app/app/templates/map/index.html b/location_app/app/templates/map/index.html index 79b6b9d..ef471e2 100644 --- a/location_app/app/templates/map/index.html +++ b/location_app/app/templates/map/index.html @@ -37,16 +37,26 @@ {% block body %} -
- +
- - {% for date in dates %} - - {% endfor%} +
+ +
+
+ +
+
+ +
+
{% endblock %} diff --git a/location_app/app/templates/profile/index.html b/location_app/app/templates/profile/index.html index 11a1560..95749f4 100644 --- a/location_app/app/templates/profile/index.html +++ b/location_app/app/templates/profile/index.html @@ -35,7 +35,7 @@ {% block body %}

My profile

@@ -44,7 +44,7 @@ profile
-

ID:

+

ID:

Name:

@@ -91,11 +91,18 @@

{{user[0][2]}}

-
-

{{user[0][3]}}

-
-
-

+
+ +
+ +
+
+ +
+
+ +
+

{{user[1][0][0]}}

@@ -112,8 +119,8 @@

???

-
-

???

+
+

???

???