I tried updating Google Calendar with CSV appointments using Python and Google APIs

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)

Google calendar operation code

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

Program to convert CSV for API

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.

Current bug

--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.

Points to be improved

--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.

at the end

Next time, I would like to improve the above points and update.

Recommended Posts

I tried updating Google Calendar with CSV appointments using Python and Google APIs
Create AtCoder Contest appointments on Google Calendar with Python and GAS
I tried web scraping using python and selenium
I tried object detection using Python and OpenCV
I tried Jacobian and partial differential with python
I tried using mecab with python2.7, ruby2.3, php7
I tried function synthesis and curry with python
I tried reading a CSV file using Python
I tried using Google Translate from Python and it was just too easy
I tried using google test and CMake in C
I tried to touch the CSV file with Python
I tried to access Google Spread Sheets using Python
I tried fp-growth with python
I tried scraping with Python
[Python] I tried using OpenPose
I tried gRPC with Python
I tried scraping with python
I tried using the Python library from Ruby with PyCall
I tried follow management with Twitter API and Python (easy)
[Python scraping] I tried google search top10 using Beautifulsoup & selenium
I tried to make GUI tic-tac-toe with Python and Tkinter
I tried web scraping with python.
I tried using Thonny (Python / IDE)
I played with PyQt5 and Python3
Reading and writing CSV with Python
I tried running prolog with python 3.8.2.
I tried SMTP communication with Python
[Python] I tried using YOLO v3
I tried scraping the ranking of Qiita Advent Calendar with Python
Edit Google Spread Sheets with Python (Low-cost RPA case with Google APIs and Python)
I tried to make a periodical process with Selenium and Python
I tried to make a todo application using bottle with python
I tried to easily detect facial landmarks with python and dlib
I tried using docomo speech recognition API and Google Speech API in Java
I tried using Amazon SQS with django-celery
I tried using Twitter api and Line api
I tried scraping Yahoo News with Python
I tried using Selenium with Headless chrome
I tried using PyEZ and JSNAPy. Part 2: I tried using PyEZ
Try using Python with Google Cloud Functions
I tried sending an email with python.
I tried using Bayesian Optimization in Python
I tried non-photorealistic rendering with Python + opencv
I tried using UnityCloudBuild API from Python
I tried recursion with Python ② (Fibonacci sequence)
I installed and used Numba with Python3.5
I'm using tox and Python 3.3 with Travis-CI
#I tried something like Vlookup with Python # 2
[Data science basics] I tried saving from csv to mysql with python
How to deal with OAuth2 error when using Google APIs from Python
[ML-Aents] I tried machine learning using Unity and Python TensorFlow (v0.11β compatible)
I tried using "Streamlit" which can do the Web only with Python
I tried to create a sample to access Salesforce using Python and Bottle
I tried using PyEZ and JSNAPy. Part 1: Overview
I tried "smoothing" the image with Python + OpenCV
I tried to make a periodical process with CentOS7, Selenium, Python and Chrome
I tried hundreds of millions of SQLite with python
Scraping tabelog with python and outputting to CSV
[Python] I introduced Word2Vec and played with it.
vprof --I tried using the profiler for Python
I tried "differentiating" the image with Python + OpenCV