From 70197ee393e2b96d4d48df2a18c3f6e7e9300335 Mon Sep 17 00:00:00 2001 From: Raphael Maenle Date: Sat, 30 May 2020 23:05:46 +0200 Subject: [PATCH] Large changes in the seperation of backend and google handler - backend now takes care of all the recoloring, and communication with database - google handler takes care of the entire communication with google - colors selected on the front-end are now translated to the watch - Calendars in the database now directly save the color the user has set - only if the event has a different color than the calendar (event color from google is not 0) is the event color from google used. - No more passing around of google color ids, hex colors all the way --- backend | 2 +- routine.py | 17 ------ server.py | 3 - server/googleHandler.py | 121 ++++++++++++++++++++++++---------------- server/routes.py | 26 ++++----- 5 files changed, 85 insertions(+), 84 deletions(-) delete mode 100755 routine.py diff --git a/backend b/backend index b5cb352..87a229f 160000 --- a/backend +++ b/backend @@ -1 +1 @@ -Subproject commit b5cb35256cbecd125ff17c54ce983f850a31c705 +Subproject commit 87a229f791e2017898c1bba3b0e33a693a8d58fc diff --git a/routine.py b/routine.py deleted file mode 100755 index 3ce435e..0000000 --- a/routine.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python3 -from backend.Routine import Routine -import sched, time - -s = sched.scheduler(time.time, time.sleep) -routine = Routine() - -def run_routine(sc): - # do some stuff - routine.start() - - #schedule next routine - s.enter(600, 1, run_routine, (sc,)) - -routine.start() -s.enter(600, 1, run_routine, (s, )) -s.run() diff --git a/server.py b/server.py index 81a55a7..2aa35c4 100644 --- a/server.py +++ b/server.py @@ -1,8 +1,5 @@ # Configuration from server import app -from backend import routine - -# routine.start() if __name__ == "__main__": context = ('certificate/xip.io.crt', 'certificate/xip.io.key')#certificate and key files diff --git a/server/googleHandler.py b/server/googleHandler.py index e607926..70c7cef 100644 --- a/server/googleHandler.py +++ b/server/googleHandler.py @@ -1,8 +1,8 @@ import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery +from googleapiclient.discovery import build -import backend.caltojson as caltojson from oauthlib.oauth2 import WebApplicationClient import flask @@ -23,7 +23,8 @@ from flask_login import ( import requests from database.models import Calendar as dbCalendar -from server import db +from backend import Calendar, Event + # Configuration class GoogleClient(): def __init__(self): @@ -60,6 +61,7 @@ class GoogleClient(): GC = GoogleClient() +# stuff for OAuth login def login(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( @@ -115,59 +117,82 @@ def deleteAccount(user): print(result, flush=True) return -class Calendar: - def __init__(self, name, calendarId, toggle='False', color="#000000"): - self.name = name - self.color = color - self.toggle=toggle - self.calendarId = calendarId -# TODO move this to database -def calendarsFromDb(): - pyCalendars = [] - for calendar in current_user.calendars: - name = (calendar.name[:16] + '..') if len(calendar.name)> 18 else calendar.name - calendarId = calendar.calendar_id - toggle = calendar.toggle - color = calendar.color +def fetchCalendarEvents(user, calendars, startDate, endDate): - pyCalendars.append(Calendar(name, calendarId, toggle, color)) + client_token = GC.build_credentials(user.google_token.token, + user.google_token.refresh_token) + credentials = google.oauth2.credentials.Credentials(**client_token) - return pyCalendars - - -def updateCalendars(): - if 'credentials' not in flask.session: - return flask.redirect('login/google') - - # Load credentials from the session. - # credentials = google.oauth2.credentials.Credentials( - # **flask.session['credentials']) - # a = flask.session['credentials'] - # print(a, flush=True) - # print(current_user.getGoogleCredentials(), flush=True) - if current_user.google_token == None: - return + service = build(GC.API_SERVICE_NAME, GC.API_VERSION, credentials=credentials) + all_events = [] + for calendar in calendars: + if calendar.toggle == "True": + event_result = service.events().list(calendarId=calendar.calendar_id, + timeMin=startDate, + timeMax=endDate, + maxResults=10, + singleEvents=True, + orderBy='startTime').execute() + + for event in event_result.get('items', []): + + # create simple event + name = event.get('summary', '(no Title)') + start = event['start'].get('dateTime') + end = event['end'].get('dateTime') + newEvent = Event(name, start, end) + + # handle weird colors from google + color = event.get('colorId') + if color == None: + newEvent.calendarHex = calendar.color + newEvent.evnetColorId = None + else: + newEvent.eventColorId = color + + all_events.append(newEvent) + + colors = service.colors().get().execute() + + return all_events, colors + + +def fetchCalendars(): + # get client api service client_token = GC.build_credentials(current_user.google_token.token, current_user.google_token.refresh_token) credentials = google.oauth2.credentials.Credentials(**client_token) - calendars = caltojson.getCalendarList(credentials) - for calendar in calendars: - if not current_user.hasCalendar(calendar.calendarId): - c = dbCalendar(calendar_id=calendar.calendarId, - name = calendar.summary, - toggle = "False", - color = calendar.color) - db.session.add(c) - current_user.calendars.append(c) - - # Save credentials back to session in case access token was refreshed. - # ACTION ITEM: In a production app, you likely want to save these - # credentials in a persistent database instead. - # TODO add save updated token to database here - current_user.google_token.token = credentials.token - db.session.commit() + + service = build(GC.API_SERVICE_NAME, GC.API_VERSION, credentials=credentials) + + # get all calendars and put them into Calendar Class + page_token = None + calendars = [] + while True: + calendar_list = service.calendarList().list(pageToken=page_token).execute() + for calendar in calendar_list['items']: + calendars.append(Calendar(name=calendar['summary'], + calendarId=calendar['id'], + color=calendar['colorId'])) + page_token = calendar_list.get('nextPageToken') + if not page_token: + break + + + colors = service.colors().get().execute() + + return calendars, colors, credentials.token + + + +def getUserCredentials(user): + credentials = GC.build_credentials(user.google_token.token, + user.google_token.refresh_token) + googleCreds = google.oauth2.credentials.Credentials(**credentials) + return googleCreds + def credentials_to_dict(credentials): diff --git a/server/routes.py b/server/routes.py index 4b5f105..b9d6643 100644 --- a/server/routes.py +++ b/server/routes.py @@ -18,9 +18,9 @@ import requests import server.googleHandler as google -from backend.Routine import Routine from server import login_manager, app, db from server.forms import LoginForm, RegistrationForm, DeviceForm +import backend from database.models import User, Calendar, Device, GoogleToken os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' @@ -36,7 +36,11 @@ def privacy(): @app.route("/account") def index(): if current_user.is_authenticated: - google.updateCalendars() + gCalendars, colors, token = google.fetchCalendars() + current_user.google_token.token = token + db.session.commit() + backend.updateCalendars(current_user, gCalendars, colors) + return (flask.render_template('account.html', username = current_user.username, email = current_user.email, profile_img=current_user.profile_pic ) @@ -79,7 +83,7 @@ def devices(): @app.route("/calendar") @login_required def calendar(): - calendars = google.calendarsFromDb() + calendars = backend.calendarsFromDb(current_user) return flask.render_template('calendar.html', calendars=calendars) @app.route('/login/email', methods=['GET', 'POST']) @@ -177,14 +181,6 @@ def logout(): logout_user() return redirect(url_for("index")) -def credentials_to_dict(credentials): - return {'token': credentials.token, - 'refresh_token': credentials.refresh_token, - 'token_uri': credentials.token_uri, - 'client_id': credentials.client_id, - 'client_secret': credentials.client_secret, - 'scopes': credentials.scopes} - @app.route("/device//calendarevents.json") def downloader(device): @@ -199,12 +195,12 @@ def downloader(device): db.session.commit() request_user = db.session.query(User).filter(User.id==request_device.user_id).first() - routine = Routine() # TODO add test if googke token exists # if request_user.google_token != Null: - client_token = google.GC.build_credentials(request_user.google_token.token, - request_user.google_token.refresh_token) - calendarjson = routine.updateCalendar(request_user, client_token) + # TODO only pass along google calendars form user + startDate, endDate = backend.getTimeStamps() + events, colors = google.fetchCalendarEvents(request_user, request_user.calendars, startDate, endDate) + calendarjson = backend.generateJsonFromCalendarEntries(events, colors) return jsonify(calendarjson) @app.route("/devicefingerprint.json")