from __future__ import print_function import datetime import dateutil.parser import pickle import json import os.path from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from server import db from database.models import Calendar as dbCalendar # If modifying these scopes, delete the file token.pickle. SCOPES = ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/calendar.readonly", "openid"] API_SERVICE_NAME = 'calendar' API_VERSION = 'v3' class Calendar: def __init__(self, name, calendarId, calType, toggle='False', color="#000000"): self.name = name self.calType = calType self.color = color self.toggle=toggle self.calendarId = calendarId class Event: def __init__(self, name_, start_, end_): self.name = name_ self.eventColorId = None self.start = start_ self.end = end_ self.colorHex = '#adfff5' if self.start == None or self.end == None : self.allDay = True else: self.allDay = False def startDateTime(self): if self.allDay: return None return self.jsonFromDT(self.start) def stopDateTime(self): if self.allDay: return None return self.jsonFromDT(self.end) def jsonFromDT(self, string): sdt = dateutil.parser.parse(string) data = { 'date': { 'year': sdt.year, 'month': sdt.month, 'day': sdt.day }, 'time': { 'hour': sdt.hour, 'minute': sdt.minute, 'second': sdt.second } } return data def print(self): if self.allDay: print(self.name + "All Day") def updateCalendars(user, calendars, colors): if user == None or calendars == None or colors == None: return COLORS_FILE = os.path.join(os.path.dirname(__file__), 'colors.json') with open(COLORS_FILE) as f: colormap = json.load(f) # add all new calendars into the database # TODO update existing Name and Calendar ( do this in User class at db? ) # Take care, that you don't overwrite the custom color selection of the user for calendar in calendars: if not user.hasCalendar(calendar.calendarId): color = fromColorIdGetColor(calendar.color, colormap, colors) c = dbCalendar(calendar_id = calendar.calendarId, calendar_type = calendar.calType, name = calendar.name, toggle = "False", color = color) db.session.add(c) user.calendars.append(c) db.session.commit() def calendarsFromDb(user): pyCalendars = [] for calendar in user.calendars: name = (calendar.name[:16] + '..') if len(calendar.name)> 18 else calendar.name calendarId = calendar.calendar_id toggle = calendar.toggle color = calendar.color calType = calendar.calendar_type pyCalendars.append(Calendar(name, calendarId, calType, toggle, color)) return pyCalendars # removes not visible calendars from the list of all calendars def purgeCalendars(calendars, visibleCalendars): purged = [] for calendar in calendars: if calendar.calendarId in visibleCalendars: purged.append(calendar) return purged # remaps a event color id to a calendar color id # for google calendars def toCalendarColorId(colormap, colorId): for remap in colormap['eventRemap']: if remap['from'] == colorId: return remap['to'] print(f"failed with {colorId}") return colorId # remaps a calendar color ID to its natural color # for google calendars def toNaturalColor(colormap, orgColor): for remap in colormap['colors']: if remap['api'] == orgColor: return remap['natural'] print(f"failed with {orgColor}") return orgColor # uses the event color id to convert it to a hex color # does this for every event in events # this is used for Google Calendars def colorizeEvents(events, colors): COLORS_FILE = os.path.join(os.path.dirname(__file__), 'colors.json') with open(COLORS_FILE) as f: colormap = json.load(f) for event in events: if event.eventColorId != None: event.colorHex = forEventGetColor(event, colormap, colors) # returns a color for a specific calendar color id # for google calendars def fromColorIdGetColor(color, colormap, colors): return toNaturalColor(colormap, colors['calendar'][color]['background']) # generates the natural color for a event color id # for google calendars def forEventGetColor(event, colormap, colors): calColorId = toCalendarColorId(colormap, event.eventColorId) bg = colors['calendar'][calColorId]['background'] return toNaturalColor(colormap, bg) # exports all events into a jsonable format (excluding all day events) def toJson(events): data = {} data['kind'] = 'calendar#events' data['events'] = [] for event in events: if event.allDay: continue data['events'].append({ 'name': event.name, 'isAllDay': event.allDay, 'color': event.colorHex, 'startDateTime': event.startDateTime(), 'stopDateTime': event.stopDateTime() }) return data # debug functions which prints color names def printColors(colors): for i in range(1, 25): col = colors['event'][str(i)]['background'] print(f"{i}: {col}") def main(): return def getTimeStamps(): # define today and tomorrow now = datetime.datetime.now(datetime.timezone.utc).astimezone() today = now.replace(hour=0, minute=0, second = 0).isoformat() tomorrow = now.replace(hour=23, minute=59, second=59).isoformat() # + '+01:00' twodaysfromnow = datetime.datetime.today() + datetime.timedelta(days=2) twodaysfromnow = twodaysfromnow.replace(hour=23, minute=59, second=59).astimezone().isoformat() return today, twodaysfromnow def generateJsonFromCalendarEntries(events, colors): # fix all colors in events that have a different event color colorizeEvents(events, colors) # if not events: # print('No upcoming events found.') return toJson(events) if __name__ == '__main__': main()