Goal: Link the calendar with other apps like Google Calendar ⇔ CSV file ⇔ another app. The following sequel.
I tried to put CSV appointments on Google Calendar using Python https://qiita.com/Octpascal/items/07e53bd89dfbca93bf3e
I made a program to update Google Calendar with the schedule described in the CSV file. ** Currently, CSV ⇒ Google Calendar is one way. ** **
CSV file is the same as last time, the following description
id,cid,summary,location,description,start,end
--id: Identification ID (str) in CSV --cid: ID (str) determined on Google Calendar when registered in the calendar --summary: event name (str) --location: Venue (str) --description: Details (str) --start: Start time (str Example: 2020/08/22 09:00 or 2020/08/22) --end: End time (same description as str start time, but must be aligned)
from __future__ import print_function
import datetime
import pickle
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']
CID = 'Calendar ID'
def check_token():
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 insert(event):
service = check_token()
# Call the Calendar API
create_event = service.events().insert(calendarId=CID, body=event).execute()
return create_event['id']
def get_lists():
service = check_token()
page_token = None
events = []
while True:
events_list = service.events().list(calendarId=CID, pageToken=page_token).execute()
page_token = events_list.get('nextPageToken')
events.extend(events_list['items'])
if not page_token:
break
return events
def update(eid, event):
service = check_token()
updated_event = service.events().update(calendarId=CID, eventId=eid, body=event).execute()
return (updated_event['updated'])
def delete(eid):
service = check_token()
service.events().delete(calendarId=CID, eventId=eid).execute()
Enter your calendar ID in the CID.
check_token From the sample code of the Google Calendar API. For API authentication.
insert Event registration. Receive and throw dictionary type.
get_list Get events that have already been registered. There is a limit to the number of lists that can be obtained at one time, but you can get the next list by sending nextPageToken.
update, delete Use as it is
import pandas as pd
import datetime
import gg_calendar
import sys
TIMEZONE = 'Japan'
def TransTime(t):
if len(t) > 11:
strtime = datetime.datetime.strptime(t, '%Y/%m/%d %H:%M').isoformat()
dictime = {
'dateTime': strtime,
'timeZone': TIMEZONE
}
else :
strtime = datetime.datetime.strptime(t, '%Y/%m/%d').isoformat()
dictime = {
'date': strtime[0:10],
'timeZone': TIMEZONE
}
return dictime
def get_list():
lists = gg_calendar.get_lists()
new_lists = []
for event in lists :
new_lists.append(
{
'id': event['id'],
'summary': event['summary'],
'location': event['location'],
'description': event['description'],
'start': event['start'],
'end': event['end']
}
)
return new_lists
def search_id(dics, skey, svalue):
df = pd.DataFrame(dics)
return (df[skey] == svalue).any()
csv = pd.read_csv('csv.csv')
csv_d = csv.to_dict(orient='index')
ex_lists = get_list()
# delete
for ex_list in ex_lists:
if not search_id(csv, 'cid', ex_list['id']):
print("delete from calendar id={}".format(ex_list['id']))
gg_calendar.delete(ex_list['id'])
# update, insert
for h, num in zip(csv_d.values(), csv_d.keys()):
h['start'] = TransTime(h['start'])
h['end'] = TransTime(h['end'])
if (search_id(ex_lists, 'id', h['cid'])):
del h['id']
cid = h['cid']
del h['cid']
print('updata')
gg_calendar.update(cid, h)
else:
del h['id']
del h['cid']
try:
event_id = gg_calendar.insert(h)
except:
print("Error: Can't put id={} on your calendar".format(csv.loc[num, 'id']))
else:
print("Put id={} on your calendar as calendar_id={}".format(csv.loc[num, 'id'], event_id))
csv.loc[num, 'cid'] = event_id
csv.to_csv('csv.csv',index=False)
TransTime Convert the above CSV format to the Google Calendar API format. For details, see Previous article.
get_lsit Get a list and make it a dictionary type with only necessary information.
search_id
** Determine if the dictionary has a value **
Determine if there is a value in a dictionary key (skey) of a dictionary type (dics).
Convert dictionary type to pandas DataFrame.
df [skey] == svalue
returns a Boolean pandas Series. (Example: True, False, False, False)
If there is even one True in the any () function, it will be True.
At first, the for statement was turned in the dictionary type, but this is probably the easiest to write.
delete Anything that disappears from CSV will be deleted from the calendar.
update, insert Those already registered in the calendar will be updated. If there is none, register it and add the returned event ID to CSV.
--An error will occur if there is no registration in the calendar. --Sufficient condition of dictionary type that registration in calendar is created by get_list function. For example, if there is an event with no location in the calendar, an error will occur. ⇒Currently, I am not using anything other than id, so I will solve it if I decide not to get it.
--All existing registered calendars are thrown to update. ⇒ Take measures such as not updating data whose end time is older than a certain amount. --All existing events on the calendar have been acquired, ⇒ We will also acquire them with a certain deadline.
Next time, I would like to improve the above points and update.
Recommended Posts