Files
cov-to-ics/main.py
2018-09-25 14:39:37 +01:00

118 lines
3.6 KiB
Python

import requests
from bs4 import BeautifulSoup
from datetime import datetime, timezone
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
import pytz
URL = open("timetableurl").read().strip()
def parse_events(page_data):
soup = BeautifulSoup(page_data, features="html.parser")
source = ""
for script in soup.head.findAll("script", {"type": "text/javascript"}):
if not script.has_attr("src"):
source = script.text
break
events_data = source.split("events:")[1].split("]")[0] +"]"
# Replace date objects with tuples, easier to parse
events_data = events_data.replace("new Date", "")
cleaned_data = ""
# Remove comments, properties to keys
for line in events_data.split("\n"):
comment_pos = line.find("//")
if comment_pos != -1:
line = line[:comment_pos]
if ":" in line:
line_values = line.split(":")
line = "'" + line_values[0] + "': " + line_values[1]
cleaned_data += line + "\n"
parsed_data = eval(cleaned_data)
# Parse the datetime info
for event in parsed_data:
if "start" in event:
event["start"] = list(event["start"])
event["start"][1] += 1
event["start"].append(0)
event["start"] = datetime(*event["start"])
event["start"] = pytz.timezone("Europe/London").localize(event["start"])
if "end" in event:
event["end"] = list(event["end"])
event["end"][1] += 1
event["end"].append(0)
event["end"] = datetime(*event["end"])
event["end"] = pytz.timezone("Europe/London").localize(event["end"])
return parsed_data
def get_timetable_data(url):
return requests.get(url).text
def create_google_event(event):
new_event = event.copy()
if not new_event:
return new_event
# Make the event the correct format
new_event["summary"] = event["moduleDesc"] + " - " + event["title"]
new_event["description"] = event["lecturer"] + " - " + event["room"]
new_event["end"] = {"dateTime": str(event["end"].isoformat()), "timeZone": "Europe/London"}
new_event["start"] = {"dateTime": str(event["start"].isoformat()), "timeZone": "Europe/London"}
new_event["reminders"] = {'useDefault': False,
'overrides': [{'method': 'popup', 'minutes': 30}]}
return new_event
# If modifying these scopes, delete the file token.json.
SCOPES = 'https://www.googleapis.com/auth/calendar'
def main():
"""Shows basic usage of the Google Calendar API.
Prints the start and name of the next 10 events on the user's calendar.
"""
type_to_color = {}
color_queue = list(range(0, 12))
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('calendar', 'v3', http=creds.authorize(Http()))
cov_events = parse_events(get_timetable_data(URL))
for event in cov_events:
new_event = create_google_event(event)
color_type = new_event["mainColor"]
if color_type in type_to_color:
colorId = type_to_color[color_type]
else:
colorId = color_queue.pop(0)
color_queue.append(colorId)
type_to_color[color_type] = colorId
new_event["colorId"] = colorId
service.events().insert(body=new_event, calendarId='primary').execute()
main()