calendarwatch_frontend/server/routes.py

295 lines
9.5 KiB
Python
Raw Permalink Normal View History

# Python standard libraries
import json
import os
import time
# Third-party libraries
import flask
from flask import render_template, flash
from flask import Flask, redirect, request, url_for, jsonify
from flask_login import (
LoginManager,
current_user,
login_required,
login_user,
logout_user,
)
2020-07-10 10:11:31 +02:00
from random_words import RandomWords
import requests
import backend.icalHandler as ical
import server.googleHandler as google
from server import login_manager, app, db
from server.forms import LoginForm, RegistrationForm, DeviceForm, CalendarForm
import backend
2020-05-27 20:06:43 +02:00
from database.models import User, Calendar, Device, GoogleToken
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
@app.route("/")
def startpage():
return flask.render_template('startpage.html')
2020-05-29 20:30:37 +02:00
@app.route("/privacy")
def privacy():
return flask.render_template('privacy.html')
@app.route("/login")
def login():
if current_user.is_authenticated:
return redirect(url_for('account'))
return flask.render_template('login.html')
@app.route("/account")
def account():
if current_user.is_authenticated:
calendars = []
gCalendars, colors, token = google.fetchCalendars()
if token != None:
current_user.google_token.token = token
db.session.commit()
calendars.extend(gCalendars)
backend.updateCalendars(current_user, calendars, colors)
return (flask.render_template('account.html',
username = current_user.username, email = current_user.email, profile_img=current_user.profile_pic
)
)
else:
return redirect(url_for("login"))
2020-05-21 15:38:22 +02:00
@app.route("/view")
def view():
if not current_user.is_authenticated:
return flask.render_template('login.html')
else:
return (flask.render_template('view.html'))
@app.route("/devices", methods=['GET', 'POST'])
def devices():
if not current_user.is_authenticated:
return flask.render_template('login.html')
# if this is a post request from the 'unlink' submittion form
# delete this device from the list
2020-07-10 10:11:31 +02:00
form = DeviceForm()
if request.method == 'POST':
2020-07-10 10:11:31 +02:00
if request.form.get("submit") == "Unlink":
device = db.session.query(Device).filter(Device.deviceName==request.form.get("device")).first()
db.session.delete(device)
db.session.commit()
# if this is part of the device form
2020-07-10 10:11:31 +02:00
elif form.validate_on_submit():
device = db.session.query(Device).filter(Device.deviceName==form.deviceName.data).first()
current_user.devices.append(device)
db.session.commit()
return flask.render_template('devices.html',
devices=current_user.devices,
form=form)
@app.route("/calendar", methods=['GET', 'POST', 'DELETE'])
def calendar():
2020-07-25 19:45:37 +02:00
if not current_user.is_authenticated:
return flask.render_template('login.html')
calendars = backend.calendarsFromDb(current_user)
form = CalendarForm()
if request.method == 'POST':
2020-07-25 19:45:37 +02:00
if request.form.get("submit") == "Remove":
calendar = db.session.query(Calendar).filter(Calendar.calendar_id==request.form.get("calendar")).first()
db.session.delete(calendar)
db.session.commit()
return flask.redirect(url_for('calendar'))
2020-07-25 19:45:37 +02:00
elif form.validate_on_submit():
ical.icalToCalendarDb(form.iCalURL.data, form.calName.data, current_user)
return flask.redirect(url_for('calendar'))
# otherwise it is a javascript POST
else:
2020-07-25 19:45:37 +02:00
try:
calId = request.json.get('calendar_id')
color = request.json.get('color', None)
toggle = request.json.get('toggle', None)
except:
return flask.render_template('calendar.html', calendars=calendars, form=form)
if color != None:
current_user.updateCalendar(calId, color=color)
if toggle != None:
current_user.updateCalendar(calId, toggle=toggle)
# toggle specific calendar of user
2020-07-25 19:45:37 +02:00
try:
calId = request.json.get('calendar_id')
color = request.json.get('color', None)
toggle = request.json.get('toggle', None)
except:
return flask.render_template('calendar.html', calendars=calendars, form=form)
if color != None:
current_user.updateCalendar(calId, color=color)
if toggle != None:
current_user.updateCalendar(calId, toggle=toggle)
# toggle specific calendar of user
return flask.render_template('calendar.html', calendars=calendars, form=form)
# POST
@app.route('/login/email', methods=['GET', 'POST'])
def emaillogin():
if current_user.is_authenticated:
return redirect(url_for('account') )
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.checkPassword(form.password.data):
flash('invalid username or password')
return redirect(url_for('emaillogin'))
login_user(user, remember=form.remember_me.data)
return redirect(url_for('account'))
return render_template('emaillogin.html', title='Sign In', form=form)
@app.route('/register', methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('account'))
form = RegistrationForm()
if form.validate_on_submit():
user = User(userid=form.username.data,
username=form.username.data,
email=form.email.data)
user.setPassword(form.password.data)
db.session.add(user)
db.session.commit()
flash('Congratulations, you are now a registered user!')
return redirect(url_for('emaillogin'))
return flask.render_template('register.html', title='Register', form=form)
2020-05-22 10:47:28 +02:00
@app.route("/delete_account")
def deleteAccount():
if not current_user.is_authenticated:
return redirect(url_for('account'))
if current_user.google_token != None:
google.deleteAccount(current_user)
2020-05-27 20:06:43 +02:00
db.session.delete(current_user)
2020-05-22 10:47:28 +02:00
db.session.commit()
2020-05-27 20:06:43 +02:00
logout_user()
2020-05-22 10:47:28 +02:00
return redirect(url_for('account'))
@app.route("/login/google")
def googlelogin():
2020-05-29 20:30:37 +02:00
if current_user.is_authenticated and current_user.google_token != None:
return redirect(url_for('account'))
authorization_url = google.login()
return flask.redirect(authorization_url)
@app.route("/login/google/callback")
def callback():
session, credentials = google.verifyResponse()
userinfo = session.get('https://www.googleapis.com/userinfo/v2/me').json()
# Create a user in your db with the information provided
# by Google
# Doesn't exist? Add it to the database.
2020-05-27 20:06:43 +02:00
if not db.session.query(User).filter(User.userid==userinfo['id']).first():
gc = GoogleToken(token=credentials.get("token"),
refresh_token=credentials.get("refresh_token"))
db.session.add(gc)
newser = User(
2020-05-27 20:06:43 +02:00
userid=userinfo['id'],
username=userinfo['name'],
email=userinfo['email'],
profile_pic=userinfo['picture'],
2020-05-27 20:06:43 +02:00
password_hash="",
google_token = gc
)
db.session.add(newser)
db.session.commit()
2020-05-27 20:06:43 +02:00
user = db.session.query(User).filter(User.userid==userinfo['id']).first()
# Begin user session by logging the user in
login_user(user)
2020-05-27 20:06:43 +02:00
return flask.redirect(flask.url_for('account'))
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(url_for("startpage"))
@app.route("/device/<path:device>/calendarevents.json")
def downloader(device):
path = "/home/calendarwatch/device/" + device + "/"
request_device = db.session.query(Device).filter(Device.deviceName==device).first()
if request_device == None:
return jsonify(kind="not found")
if request_device.user_id == None:
return jsonify(kind="unregistered")
request_device.lastConnection=int(round(time.time()))
request_device.connection=True
db.session.commit()
request_user = db.session.query(User).filter(User.id==request_device.user_id).first()
2020-05-29 20:30:37 +02:00
# TODO add test if googke token exists
# if request_user.google_token != Null:
# TODO only pass along google calendars form user
startDate, endDate = backend.getTimeStamps()
events, colors = google.fetchCalendarEvents(request_user, request_user.calendars, startDate, endDate)
events.extend(ical.fetchCalendarEvents(request_user.calendars, startDate, endDate))
calendarjson = backend.generateJsonFromCalendarEntries(events, colors)
2020-05-27 20:36:05 +02:00
return jsonify(calendarjson)
@app.route("/devicefingerprint.json")
def generateDeviceFingerprint():
# Create Three Random Words
r = RandomWords()
while True:
fingerprint = ""
length = 3
2020-07-10 10:11:31 +02:00
randos = r.random_words(count=length)
for i in range(len(randos)):
fingerprint += randos[i]
if i < length-1:
fingerprint += "-"
# check not in Device Database
if not db.session.query(Device).filter(Device.deviceName==fingerprint).first():
# Save as new Device
device = Device(deviceName=fingerprint, connection=False)
device.lastConnection = int(round(time.time()))
db.session.add(device)
db.session.commit()
break;
# Send to Device
return jsonify(deviceName=fingerprint)