-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautozoom.py
executable file
·173 lines (145 loc) · 5.19 KB
/
autozoom.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/python3
from datetime import datetime, timedelta, timezone
import pickle
import os.path
import re
import time
import logging
import webbrowser
from pathlib import Path
EMAIL = "" # leave blank to not filter by attendance status.
curdir = Path(__file__).parent.absolute()
try:
logging.basicConfig(format="%(asctime)s %(message)s", level="INFO")
logger = logging.getLogger()
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
except:
print(
"""Import dependencies failed. You need to run the following command:
pip install -r requirements.txt
"""
)
exit()
# If modifying these scopes, delete the file token.pickle.
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
CHECK_INTERVAL_MINUTES = 10
def getcreds():
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.
tokenpath = curdir / "token.pickle"
credspath = curdir / "credentials.json"
if os.path.exists(tokenpath):
with open(tokenpath, "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:
if not os.path.exists(credspath):
print(
"""Visit this page and click "create credentials" to obtain a credentials.json file:
https://developers.google.com/calendar/quickstart/python
"""
)
exit()
creds = InstalledAppFlow.from_client_secrets_file(
credspath, SCOPES
).run_local_server(port=0)
# Save the credentials for the next run
with open(tokenpath, "wb") as token:
pickle.dump(creds, token)
return creds
def attending(event):
if not EMAIL:
return True
attendees = [
a
for a in event.get("attendees", [])
if a.get("email") == EMAIL
]
if not attendees:
logger.warn("You are not invited to this event, how is it on your calendar?")
return attendees and attendees[0].get("responseStatus") == "accepted"
def getNextEvent(events):
for event in events:
title = event.get("summary", "<no summary>")
logger.info(f"Inspecting event '{title}'")
logger.debug(event)
zoomlink = getzoomlink(event)
if not zoomlink:
logger.info(f"zoomlink not found, skipping")
continue
waittime = timeuntilstart(event)
if waittime.total_seconds() < 0:
logger.info(f"event has already started, skipping. Zoomlink: {zoomlink}")
continue
if not attending(event):
logger.info(f"not attending, skipping")
continue
return zoomlink, waittime
else:
logger.info(f"Checked {len(events)} events!")
return "", timedelta(days=1)
def main():
service = build("calendar", "v3", credentials=getcreds())
while True:
zoomlink, waittime = getNextEvent(getevents(service))
if zoomlink and waittime.total_seconds() < CHECK_INTERVAL_MINUTES * 60:
logger.info(f"zoom-linked event starting in {waittime}...")
# connecting takes about seven seconds, so start connecting early
time.sleep(waittime.total_seconds())
logger.info(f"connecting now, link is {zoomlink}")
webbrowser.open(zoomlink)
else:
logger.info(
f"event is {waittime} away, will check again in {CHECK_INTERVAL_MINUTES} minutes."
)
time.sleep(CHECK_INTERVAL_MINUTES * 60)
def getevents(service, N=10):
# Call the Calendar API
now = datetime.utcnow().isoformat() + "Z" # 'Z' indicates UTC time
print("Getting the upcoming 10 events")
try:
events_result = (
service.events()
.list(
calendarId="primary",
timeMin=now,
maxResults=N,
singleEvents=True,
orderBy="startTime",
)
.execute()
)
events = events_result.get("items", [])
except Exception as e:
print(e)
return []
print(f"Retrieved {len(events)} events.")
return events
def getzoomlink(event):
text = ""
# logger.info(str(event))
for field in [
"location",
"summary",
"description",
"hangoutLink",
"conferenceData",
]:
text += str(event.get(field, "")) + " "
matches = re.findall(r"https://[A-Za-z0-9.-]+.zoom.us/j/[A-Za-z0-9?=]+", text)
matches += re.findall(r"https://meet.google.com/[a-zA-Z0-9_-]+", text)
return matches[0] if matches else None
def timeuntilstart(event):
start = datetime.fromisoformat(
event["start"].get("dateTime", event["start"].get("date"))
)
return start - datetime.now(timezone.utc) - timedelta(minutes=1)
if __name__ == "__main__":
main()