calendarwatch_backend/quickstart.py

226 lines
6.8 KiB
Python

from __future__ import print_function
import datetime
import dateutil.parser
import pickle
import json
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
visibleList = ['Hightower', 'Home', 'Office', 'Life', 'Social', 'Grey']
class Event:
def __init__(self, name_, start_, end_):
self.name = name_
self.eventColorId = 0
self.calendarColorId = 0
self.naturalColorId = 0
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")
else:
print(self.name + ": " + self.NaturalColorId)
class Calendar:
def __init__(self, summary_, calendarId_, color_):
self.summary = summary_
self.calendarId = calendarId_
self.color = color_
def calendarCredentials():
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('calendar', 'v3', credentials=creds)
return service
def getCalendarColors(service):
colors = service.colors().get().execute()
return colors
def getCalendars(service):
page_token = None
calendars = []
while True:
calendar_list = service.calendarList().list(pageToken=page_token).execute()
for calendar in calendar_list['items']:
calendars.append(Calendar(calendar['summary'], calendar['id'], calendar['colorId']))
page_token = calendar_list.get('nextPageToken')
if not page_token:
break
return calendars
def purgeCalendars(calendars):
purged = []
for calendar in calendars:
if calendar.summary in visibleList:
purged.append(calendar)
return purged
def getCalendarEvents(service, startDate, endDate):
calendars = getCalendars(service)
calendars = purgeCalendars(calendars)
all_events = []
for calendar in calendars:
events_result = service.events().list(calendarId=calendar.calendarId, timeMin=startDate,
timeMax=endDate,
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
for event in events_result.get('items', []):
# create simple event
name = event['summary']
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.calendarColorId = calendar.color
else:
newEvent.eventColorId = color
all_events.append(newEvent)
return all_events
def toCalendarColorId(colormap, colorId):
for remap in colormap['eventRemap']:
if remap['from'] == colorId:
return remap['to']
print(f"failed with {colorId}")
return colorId
def toNaturalColor(colormap, orgColor):
for remap in colormap['colors']:
if remap['api'] == orgColor:
return remap['natural']
print(f"failed with {orgColor}")
return orgColor
def colorizeEvents(allEvents, colors):
with open("colors.json") as f:
colormap = json.load(f)
for event in allEvents:
if event.calendarColorId != 0:
orgColor = colors['calendar'][event.calendarColorId]['background']
else:
calColorId = toCalendarColorId(colormap, event.eventColorId)
orgColor = colors['calendar'][calColorId]['background']
event.colorHex = toNaturalColor(colormap, orgColor)
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()
})
with open('./calendarevents.json', 'w') as outfile:
json.dump(data, outfile)
def printColors(colors):
for i in range(1, 25):
col = colors['event'][str(i)]['background']
print(f"{i}: {col}")
def main():
service = calendarCredentials()
# 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'
allEvents = getCalendarEvents(service, today, tomorrow)
colors = getCalendarColors(service)
colorizeEvents(allEvents, colors)
# if not events:
# print('No upcoming events found.')
toJson(allEvents)
if __name__ == '__main__':
main()