12 changed files with 324 additions and 296 deletions
-
14gapi/__init__.py
-
0gapi/apis/__init__.py
-
6gapi/apis/base_api.py
-
5gapi/apis/calendar_api/__init__.py
-
98gapi/apis/calendar_api/calendar_api.py
-
136gapi/apis/calendar_api/models.py
-
22gapi/apis/calendar_api/utils.py
-
0gapi/apis/drive_api/__init__.py
-
0gapi/apis/drive_api/drive_api.py
-
279gapi/calendar_api.py
-
14gapi/config.py
-
46tests/event_class.py
@ -0,0 +1,14 @@ |
|||||
|
import os |
||||
|
|
||||
|
import appdirs |
||||
|
|
||||
|
app_dirs = appdirs.AppDirs("gapi") |
||||
|
config_dir = app_dirs.user_config_dir |
||||
|
cache_dir = app_dirs.user_cache_dir |
||||
|
log_dir = app_dirs.user_log_dir |
||||
|
state_dir = app_dirs.user_state_dir |
||||
|
|
||||
|
|
||||
|
for dir in (config_dir, cache_dir, log_dir, state_dir): |
||||
|
if not os.path.exists(dir): |
||||
|
os.makedirs(dir) |
||||
@ -0,0 +1,5 @@ |
|||||
|
import os |
||||
|
|
||||
|
|
||||
|
from .models import Event |
||||
|
from .calendar_api import calendar_api |
||||
@ -0,0 +1,98 @@ |
|||||
|
import os |
||||
|
|
||||
|
from googleapiclient.errors import HttpError |
||||
|
|
||||
|
import gapi |
||||
|
from gapi.apis.base_api import API |
||||
|
|
||||
|
APPLICATION_NAME = "Google Calendar API Python" |
||||
|
|
||||
|
|
||||
|
class calendar_api(API): |
||||
|
def __init__( |
||||
|
self, |
||||
|
app_name, |
||||
|
client_secret_file=os.path.join(gapi.state_dir, "client_secret.json"), |
||||
|
credentials_dir=gapi.state_dir, |
||||
|
scopes="https://www.googleapis.com/auth/calendar", |
||||
|
version="v3", |
||||
|
): |
||||
|
super().__init__( |
||||
|
"calendar", scopes, app_name, client_secret_file, credentials_dir, version |
||||
|
) |
||||
|
|
||||
|
self.calendars = self.get_calendars() |
||||
|
self.ids = dict( |
||||
|
(calendar["summary"].lower(), calendar["id"]) for calendar in self.calendars |
||||
|
) |
||||
|
|
||||
|
def create_event(self, calendar_id, body): |
||||
|
|
||||
|
try: |
||||
|
calendar_id = self.ids[calendar_id] |
||||
|
except KeyError: |
||||
|
pass |
||||
|
service = self.service |
||||
|
event_service = service.events() |
||||
|
event = event_service.insert(calendarId=calendar_id, body=body).execute() |
||||
|
return event["id"] |
||||
|
|
||||
|
def update_event(self, calendar_id, event_id, body): |
||||
|
try: |
||||
|
calendar_id = self.ids[calendar_id] |
||||
|
except KeyError: |
||||
|
pass |
||||
|
|
||||
|
service = self.service |
||||
|
event_service = service.events() |
||||
|
try: |
||||
|
event = event_service.get( |
||||
|
calendarId=calendar_id, eventId=event_id |
||||
|
).execute() |
||||
|
except HttpError as e: |
||||
|
if e.resp.status == 404: |
||||
|
return self.create_event(calendar_id, body) |
||||
|
|
||||
|
updated_event = ( |
||||
|
service.events() |
||||
|
.update(calendarId=calendar_id, eventId=event["id"], body=body) |
||||
|
.execute() |
||||
|
) |
||||
|
return updated_event["id"] |
||||
|
|
||||
|
def get_calendars(self): |
||||
|
page_token = None |
||||
|
cl = [] |
||||
|
first = True |
||||
|
while page_token or first: |
||||
|
first = False |
||||
|
calendar_list_service = self.service.calendarList() |
||||
|
calendar_list = calendar_list_service.list(pageToken=page_token).execute() |
||||
|
cl += list(calendar_entry for calendar_entry in calendar_list["items"]) |
||||
|
page_token = calendar_list.get("nextPageToken") |
||||
|
return cl |
||||
|
|
||||
|
def get_events(self, cal_id): |
||||
|
service = self.service |
||||
|
try: |
||||
|
cal_id = self.ids[cal_id] |
||||
|
except KeyError: |
||||
|
pass |
||||
|
page_token = None |
||||
|
ret = [] |
||||
|
while True: |
||||
|
event_service = service.events() |
||||
|
events = event_service.list( |
||||
|
calendarId=cal_id, pageToken=page_token |
||||
|
).execute() |
||||
|
ret += events["items"] |
||||
|
page_token = events.get("nextPageToken") |
||||
|
if not page_token: |
||||
|
break |
||||
|
return ret |
||||
|
|
||||
|
def get_event_by_id(self, cal_id, event_id): |
||||
|
"""Retrieves event from cal_id and event_id""" |
||||
|
service = self.service |
||||
|
event_service = service.events() |
||||
|
return event_service.get(calendarId=cal_id, eventId=event_id).execute() |
||||
@ -0,0 +1,136 @@ |
|||||
|
from enum import IntEnum |
||||
|
import datetime |
||||
|
import re |
||||
|
|
||||
|
from dateutil import rrule |
||||
|
|
||||
|
from .calendar_api import calendar_api |
||||
|
from .utils import to_dateTime, from_dateTime |
||||
|
|
||||
|
|
||||
|
class weekdays(IntEnum): |
||||
|
SUN = 6 |
||||
|
MON = 0 |
||||
|
TUE = 1 |
||||
|
WED = 2 |
||||
|
THU = 3 |
||||
|
FRI = 4 |
||||
|
SAT = 5 |
||||
|
|
||||
|
|
||||
|
class Calendar: |
||||
|
"""Model for representing a Google calendar""" |
||||
|
|
||||
|
pass |
||||
|
|
||||
|
|
||||
|
class Event: |
||||
|
"""Model for a calendar event that can be uploaded""" |
||||
|
|
||||
|
def __init__( |
||||
|
self, |
||||
|
start, |
||||
|
end, |
||||
|
name, |
||||
|
description=None, |
||||
|
recurrence=None, |
||||
|
reminders=None, |
||||
|
attendees=None, |
||||
|
location=None, |
||||
|
id=None, |
||||
|
): |
||||
|
self.start = start |
||||
|
self.attendees = attendees |
||||
|
self.end = end |
||||
|
self.name = name |
||||
|
self.description = description |
||||
|
self.location = location |
||||
|
self.recurrence = recurrence |
||||
|
self.id = id |
||||
|
if reminders is None: |
||||
|
self.reminders = {"useDefault": True} |
||||
|
else: |
||||
|
self.reminders = reminders |
||||
|
|
||||
|
def add_reminder(self, until, method="popup"): |
||||
|
"""Add a reminder minutes before an event. |
||||
|
Use either a notification (popup) or email""" |
||||
|
assert method in ("email", "popup") |
||||
|
self.reminders["useDefault"] = False |
||||
|
if isinstance(until, datetime.timedelta): |
||||
|
minutes_until = until.days * 24 * 60 |
||||
|
minutes_until += until.seconds // 60 |
||||
|
else: |
||||
|
minutes_until = until |
||||
|
self.reminders.setdefault("overrides", []).append( |
||||
|
{"method": method, "minutes": minutes_until} |
||||
|
) |
||||
|
|
||||
|
def add_weekly_recurrence(self, until: datetime.datetime, *days): |
||||
|
if not until.tzinfo: |
||||
|
until = until.astimezone() |
||||
|
ret = rrule.rrule( |
||||
|
freq=rrule.WEEKLY, |
||||
|
dtstart=self.start, |
||||
|
wkst=weekdays.SUN, |
||||
|
until=until, |
||||
|
byweekday=days, |
||||
|
) |
||||
|
ret_str = str(ret).split("\n")[-1] |
||||
|
ret_str = re.sub(r"(UNTIL=[^;]+)", r"\1Z", ret_str) |
||||
|
if self.recurrence is None: |
||||
|
self.recurrence = [] |
||||
|
self.recurrence.append(ret_str) |
||||
|
|
||||
|
def to_json(self): |
||||
|
keys = ("attendees", "description", "location", "recurrence", "reminders") |
||||
|
ret = { |
||||
|
"summary": self.name, |
||||
|
"start": to_dateTime(self.start), |
||||
|
"end": to_dateTime(self.end), |
||||
|
} |
||||
|
for key in keys: |
||||
|
try: |
||||
|
value = self.__getattribute__(key) |
||||
|
if value: |
||||
|
ret[key] = value |
||||
|
except AttributeError: |
||||
|
pass |
||||
|
return ret |
||||
|
|
||||
|
def add_attendees(self): |
||||
|
pass |
||||
|
|
||||
|
@classmethod |
||||
|
def from_json(cls, body): |
||||
|
args = {} |
||||
|
args["name"] = body.get("summary", "unnamed") |
||||
|
args["start"] = from_dateTime(body["start"]) |
||||
|
args["end"] = from_dateTime(body["end"]) |
||||
|
keys = ("attendees", "description", "location", "recurrence", "reminders", "id") |
||||
|
for key in keys: |
||||
|
try: |
||||
|
args[key] = body[key] |
||||
|
except KeyError: |
||||
|
pass |
||||
|
instance = cls(**args) |
||||
|
return instance |
||||
|
|
||||
|
@classmethod |
||||
|
def from_id(cls, api: calendar_api, calendar_id, event_id): |
||||
|
"""creates an event model from specified calendar and event_id""" |
||||
|
event = api.get_event_by_id(calendar_id, event_id) |
||||
|
return cls.from_json(event) |
||||
|
|
||||
|
def upload(self, api: calendar_api, calendar_id): |
||||
|
"""Upload an event to calendar. |
||||
|
Either modifies an event in place or creates a new event.""" |
||||
|
if self.id is not None: |
||||
|
event_id = api.update_event(calendar_id, self.id, self.to_json()) |
||||
|
else: |
||||
|
event_id = api.create_event(calendar_id, self.to_json()) |
||||
|
self.id = event_id |
||||
|
return event_id |
||||
|
|
||||
|
def delete(self, api: calendar_api): |
||||
|
pass |
||||
@ -0,0 +1,22 @@ |
|||||
|
import datetime |
||||
|
|
||||
|
import tzlocal |
||||
|
from dateutil import tz |
||||
|
from dateutil.parser import parse as date_parse |
||||
|
|
||||
|
|
||||
|
def to_dateTime(datetime: datetime.datetime): |
||||
|
"""converts a datetime into json format for rest api""" |
||||
|
if not datetime.tzinfo: |
||||
|
datetime = datetime.astimezone() |
||||
|
zone = tzlocal.get_localzone().zone |
||||
|
datetime = datetime.isoformat(timespec="seconds") |
||||
|
return {"timeZone": zone, "dateTime": datetime} |
||||
|
|
||||
|
|
||||
|
def from_dateTime(dateTime): |
||||
|
"""converts to a datetime from json format returned by rest api""" |
||||
|
timezone = tz.gettz(dateTime["timeZone"]) |
||||
|
datetime = date_parse(dateTime["dateTime"]) |
||||
|
datetime.replace(tzinfo=timezone) |
||||
|
return datetime |
||||
@ -1,279 +0,0 @@ |
|||||
import os |
|
||||
from dateutil import rrule, tz |
|
||||
from oauth2client import tools |
|
||||
from googleapiclient.errors import HttpError |
|
||||
from dateutil.parser import parse as date_parse |
|
||||
import re |
|
||||
import tzlocal |
|
||||
import argparse |
|
||||
import datetime |
|
||||
|
|
||||
if __name__ == "__main__": |
|
||||
from api import API |
|
||||
else: |
|
||||
from gapi.api import API, config |
|
||||
|
|
||||
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() |
|
||||
APPLICATION_NAME = "Google Calendar API Python" |
|
||||
|
|
||||
SUN = 6 |
|
||||
MON = 0 |
|
||||
TUE = 1 |
|
||||
WED = 2 |
|
||||
THU = 3 |
|
||||
FRI = 4 |
|
||||
SAT = 5 |
|
||||
|
|
||||
|
|
||||
def to_dateTime(datetime: datetime.datetime): |
|
||||
"""converts a datetime into json format for rest api""" |
|
||||
if not datetime.tzinfo: |
|
||||
datetime = datetime.astimezone() |
|
||||
zone = tzlocal.get_localzone().zone |
|
||||
datetime = datetime.isoformat(timespec="seconds") |
|
||||
return {"timeZone": zone, "dateTime": datetime} |
|
||||
|
|
||||
|
|
||||
def from_dateTime(dateTime): |
|
||||
"""converts to a datetime from json format returned by rest api""" |
|
||||
timezone = tz.gettz(dateTime["timeZone"]) |
|
||||
datetime = date_parse(dateTime["dateTime"]) |
|
||||
datetime.replace(tzinfo=timezone) |
|
||||
return datetime |
|
||||
|
|
||||
|
|
||||
class calendar_api(API): |
|
||||
def __init__( |
|
||||
self, |
|
||||
app_name, |
|
||||
client_secret_file=os.path.join(config.state_dir, "client_secret.json"), |
|
||||
credentials_dir=config.state_dir, |
|
||||
scopes="https://www.googleapis.com/auth/calendar", |
|
||||
version="v3", |
|
||||
): |
|
||||
super().__init__( |
|
||||
"calendar", scopes, app_name, client_secret_file, credentials_dir, version |
|
||||
) |
|
||||
|
|
||||
self.calendars = self.get_calendars() |
|
||||
self.ids = dict( |
|
||||
(calendar["summary"].lower(), calendar["id"]) for calendar in self.calendars |
|
||||
) |
|
||||
|
|
||||
def create_event(self, calendar_id, body): |
|
||||
|
|
||||
try: |
|
||||
calendar_id = self.ids[calendar_id] |
|
||||
except KeyError: |
|
||||
pass |
|
||||
service = self.service |
|
||||
event_service = service.events() |
|
||||
event = event_service.insert(calendarId=calendar_id, body=body).execute() |
|
||||
return event["id"] |
|
||||
|
|
||||
def update_event(self, calendar_id, event_id, body): |
|
||||
try: |
|
||||
calendar_id = self.ids[calendar_id] |
|
||||
except KeyError: |
|
||||
pass |
|
||||
|
|
||||
service = self.service |
|
||||
event_service = service.events() |
|
||||
try: |
|
||||
event = event_service.get( |
|
||||
calendarId=calendar_id, eventId=event_id |
|
||||
).execute() |
|
||||
except HttpError as e: |
|
||||
if e.resp.status == 404: |
|
||||
return self.create_event(calendar_id, body) |
|
||||
|
|
||||
updated_event = ( |
|
||||
service.events() |
|
||||
.update(calendarId=calendar_id, eventId=event["id"], body=body) |
|
||||
.execute() |
|
||||
) |
|
||||
return updated_event["id"] |
|
||||
|
|
||||
def get_calendars(self): |
|
||||
page_token = None |
|
||||
cl = [] |
|
||||
first = True |
|
||||
while page_token or first: |
|
||||
first = False |
|
||||
calendar_list_service = self.service.calendarList() |
|
||||
calendar_list = calendar_list_service.list(pageToken=page_token).execute() |
|
||||
cl += list(calendar_entry for calendar_entry in calendar_list["items"]) |
|
||||
page_token = calendar_list.get("nextPageToken") |
|
||||
return cl |
|
||||
|
|
||||
def get_events(self, cal_id): |
|
||||
service = self.service |
|
||||
try: |
|
||||
cal_id = self.ids[cal_id] |
|
||||
except KeyError: |
|
||||
pass |
|
||||
page_token = None |
|
||||
ret = [] |
|
||||
while True: |
|
||||
event_service = service.events() |
|
||||
events = event_service.list( |
|
||||
calendarId=cal_id, pageToken=page_token |
|
||||
).execute() |
|
||||
ret += events["items"] |
|
||||
page_token = events.get("nextPageToken") |
|
||||
if not page_token: |
|
||||
break |
|
||||
return ret |
|
||||
|
|
||||
def get_event_by_id(self, cal_id, event_id): |
|
||||
"""Retrieves event from cal_id and event_id""" |
|
||||
service = self.service |
|
||||
event_service = service.events() |
|
||||
return event_service.get(calendarId=cal_id, eventId=event_id).execute() |
|
||||
|
|
||||
|
|
||||
class Event: |
|
||||
"""Model for a calendar event that can be uploaded""" |
|
||||
|
|
||||
def __init__( |
|
||||
self, |
|
||||
start, |
|
||||
end, |
|
||||
name, |
|
||||
description=None, |
|
||||
recurrence=None, |
|
||||
reminders=None, |
|
||||
attendees=None, |
|
||||
location=None, |
|
||||
id=None, |
|
||||
): |
|
||||
self.start = start |
|
||||
self.attendees = attendees |
|
||||
self.end = end |
|
||||
self.name = name |
|
||||
self.description = description |
|
||||
self.location = location |
|
||||
self.recurrence = recurrence |
|
||||
self.id = id |
|
||||
if reminders is None: |
|
||||
self.reminders = {"useDefault": True} |
|
||||
else: |
|
||||
self.reminders = reminders |
|
||||
|
|
||||
def add_reminder(self, until, method="popup"): |
|
||||
"""Add a reminder minutes before an event. |
|
||||
Use either a notification (popup) or email""" |
|
||||
assert method in ("email", "popup") |
|
||||
self.reminders["useDefault"] = False |
|
||||
if isinstance(until, datetime.timedelta): |
|
||||
minutes_until = until.days * 24 * 60 |
|
||||
minutes_until += until.seconds // 60 |
|
||||
else: |
|
||||
minutes_until = until |
|
||||
self.reminders.setdefault("overrides", []).append( |
|
||||
{"method": method, "minutes": minutes_until} |
|
||||
) |
|
||||
|
|
||||
def add_weekly_recurrence(self, until: datetime.datetime, *days): |
|
||||
if not until.tzinfo: |
|
||||
until = until.astimezone() |
|
||||
ret = rrule.rrule( |
|
||||
freq=rrule.WEEKLY, dtstart=self.start, wkst=SUN, until=until, byweekday=days |
|
||||
) |
|
||||
ret_str = str(ret).split("\n")[-1] |
|
||||
ret_str = re.sub(r"(UNTIL=[^;]+)", r"\1Z", ret_str) |
|
||||
if self.recurrence is None: |
|
||||
self.recurrence = [] |
|
||||
self.recurrence.append(ret_str) |
|
||||
|
|
||||
def to_json(self): |
|
||||
keys = ("attendees", "description", "location", "recurrence", "reminders") |
|
||||
ret = { |
|
||||
"summary": self.name, |
|
||||
"start": to_dateTime(self.start), |
|
||||
"end": to_dateTime(self.end), |
|
||||
} |
|
||||
for key in keys: |
|
||||
try: |
|
||||
value = self.__getattribute__(key) |
|
||||
if value: |
|
||||
ret[key] = value |
|
||||
except AttributeError: |
|
||||
pass |
|
||||
return ret |
|
||||
|
|
||||
def add_attendees(self): |
|
||||
pass |
|
||||
|
|
||||
@classmethod |
|
||||
def from_json(cls, body): |
|
||||
args = {} |
|
||||
args["name"] = body.get("summary", "unnamed") |
|
||||
args["start"] = from_dateTime(body["start"]) |
|
||||
args["end"] = from_dateTime(body["end"]) |
|
||||
keys = ("attendees", "description", "location", "recurrence", "reminders", "id") |
|
||||
for key in keys: |
|
||||
try: |
|
||||
args[key] = body[key] |
|
||||
except KeyError: |
|
||||
pass |
|
||||
instance = cls(**args) |
|
||||
return instance |
|
||||
|
|
||||
@classmethod |
|
||||
def from_id(cls, api: calendar_api, calendar_id, event_id): |
|
||||
"""creates an event model from specified calendar and event_id""" |
|
||||
event = api.get_event_by_id(calendar_id, event_id) |
|
||||
return cls.from_json(event) |
|
||||
|
|
||||
def upload(self, api: calendar_api, calendar_id): |
|
||||
"""Upload an event to calendar. |
|
||||
Either modifies an event in place or creates a new event.""" |
|
||||
if self.id is not None: |
|
||||
event_id = api.update_event(calendar_id, self.id, self.to_json()) |
|
||||
else: |
|
||||
event_id = api.create_event(calendar_id, self.to_json()) |
|
||||
return event_id |
|
||||
|
|
||||
|
|
||||
if __name__ == "__main__": |
|
||||
import os |
|
||||
|
|
||||
# ~~BODY EXAMPLE~~##~~BODY EXAMPLE~~ |
|
||||
example = { |
|
||||
"attendees": [{"email": "lpage@example.com"}, {"email": "sbrin@example.com"}], |
|
||||
"description": "A chance to hear more about Google's\ |
|
||||
developer products.", |
|
||||
"end": { |
|
||||
"dateTime": "2015-05-28T17:00:00-07:00", |
|
||||
"timeZone": "America/Los_Angeles", |
|
||||
}, |
|
||||
"location": "800 Howard St., San Francisco, CA 94103", |
|
||||
"recurrence": ["RRULE:FREQ=DAILY;COUNT=2"], |
|
||||
"reminders": { |
|
||||
"overrides": [ |
|
||||
{"method": "email", "minutes": 1440}, |
|
||||
{"method": "popup", "minutes": 10}, |
|
||||
], |
|
||||
"useDefault": False, |
|
||||
}, |
|
||||
"start": { |
|
||||
"dateTime": "2015-05-28T09:00:00-07:00", |
|
||||
"timeZone": "America/Los_Angeles", |
|
||||
}, |
|
||||
"summary": "Google I/O 2015", |
|
||||
} |
|
||||
e = Event( |
|
||||
date_parse("march 16, 2019 10:00 am"), |
|
||||
date_parse("march 16, 2019 3:30 pm"), |
|
||||
"Hang out with Matt", |
|
||||
) |
|
||||
path = r"C:\Users\Raphael\Documents\local_repo\cred" |
|
||||
my_api = my_api = calendar_api( |
|
||||
"python", os.path.join(path, "client_secret.json", path), path |
|
||||
) |
|
||||
cal_id = "raphael.roberts48@gmail.com" |
|
||||
e2 = Event.from_id(my_api, cal_id, "qmrsd88ma8ko67ri98d8pbhd7s") |
|
||||
until = datetime.datetime.today() + datetime.timedelta(days=20) |
|
||||
e2.add_weekly_recurrence(until, MON, TUE) |
|
||||
# e2.upload(my_api, cal_id) |
|
||||
@ -1,14 +0,0 @@ |
|||||
import os |
|
||||
|
|
||||
import appdirs |
|
||||
|
|
||||
app_dirs = appdirs.AppDirs("gapi") |
|
||||
config_dir = app_dirs.user_config_dir |
|
||||
cache_dir = app_dirs.user_cache_dir |
|
||||
log_dir = app_dirs.user_log_dir |
|
||||
state_dir = app_dirs.user_state_dir |
|
||||
|
|
||||
|
|
||||
for dir in (config_dir, cache_dir, log_dir, state_dir): |
|
||||
if not os.path.exists(dir): |
|
||||
os.makedirs(dir) |
|
||||
@ -0,0 +1,46 @@ |
|||||
|
from dateutil.parser import parse as date_parse |
||||
|
|
||||
|
from gapi.apis.calendar_api.models import weekdays, Event |
||||
|
from gapi.apis.calendar_api import calendar_api |
||||
|
import datetime |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
|
||||
|
MY_API = calendar_api("fuck google") |
||||
|
# ~~BODY EXAMPLE~~##~~BODY EXAMPLE~~ |
||||
|
example = { |
||||
|
"attendees": [{"email": "lpage@example.com"}, {"email": "sbrin@example.com"}], |
||||
|
"description": "A chance to hear more about Google's\ |
||||
|
developer products.", |
||||
|
"end": { |
||||
|
"dateTime": "2015-05-28T17:00:00-07:00", |
||||
|
"timeZone": "America/Los_Angeles", |
||||
|
}, |
||||
|
"location": "800 Howard St., San Francisco, CA 94103", |
||||
|
"recurrence": ["RRULE:FREQ=DAILY;COUNT=2"], |
||||
|
"reminders": { |
||||
|
"overrides": [ |
||||
|
{"method": "email", "minutes": 1440}, |
||||
|
{"method": "popup", "minutes": 10}, |
||||
|
], |
||||
|
"useDefault": False, |
||||
|
}, |
||||
|
"start": { |
||||
|
"dateTime": "2015-05-28T09:00:00-07:00", |
||||
|
"timeZone": "America/Los_Angeles", |
||||
|
}, |
||||
|
"summary": "Google I/O 2015", |
||||
|
} |
||||
|
e = Event( |
||||
|
date_parse("march 16, 2019 10:00 am"), |
||||
|
date_parse("march 16, 2019 3:30 pm"), |
||||
|
"Hang out with Matt", |
||||
|
) |
||||
|
CAL_ID = "raphael.roberts48@gmail.com" |
||||
|
event = Event.from_json(example) |
||||
|
id = event.upload(MY_API, CAL_ID) |
||||
|
print(id) |
||||
|
e2 = Event.from_id(MY_API, CAL_ID, id) |
||||
|
until = datetime.datetime.today() + datetime.timedelta(days=20) |
||||
|
e2.add_weekly_recurrence(until, weekdays.MON, weekdays.TUE) |
||||
|
e2.upload(MY_API, CAL_ID) |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue