Python: Google Calendar のイベント情報を読み取るスクリプト
ライブラリのインストール
google-api-python-client を利用する。
google-api-python-client - Google APIs Client Library for Python - Google Project Hosting
$ sudo pip install google-api-python-client |
認証用のファイルを準備
- まずは Google APIs Console で Calendar API を有効にする。
Google APIs Console - そして、Google のチュートリアルに従ってみる。
Installation - Google APIs Client Library for Python — Google Developers
このような画面操作でサンプルを手に入れることができる。それを参考にする。
認証は、client_secrets.json というJSON形式のファイルを使うのが推奨されているようだ。
このファイルも手打ちする必要はなく、ダウンロードボタン一発で入手できる。
Client Secrets - Google APIs Client Library for Python — Google Developers
サンプルをたたくと、初回に client_secrets.json を元にFlow オブジェクトが生成される。
このとき、どのAPIにどのレベルでアクセスするかを指定する。
今回はカレンダーの読み取りだけなので、'https://www.googleapis.com/auth/calendar.readonly' があれば十分。
その内容が Storage オブジェクトとなり、ファイルに保存される。
今回は read_calendar.dat というファイル名にした。
認証情報(credentials)が完成したら、httplib2、build() 関数を使って Calendar API v3 にアクセスすればよい。
コード
今日一日の予定を出力するコード。
プログラムの第一引数に整数を入れれば、n日後の予定を取得できる。
対象のカレンダーIDは予め調べて、ハードコーディング。
予定の開始時刻、終了時刻、内容、作成者をソートして出力するため、OneDayEvent というクラスを作っている。
タイムゾーンの調整はしていない。(手抜き)
もっとコメント書いた方がいいけどこれも手抜き。
Calendar API のサービスを取得した後、
service.events()list(...).execute() で条件に見合ったイベントのリストを取得している。
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 | #!/usr/bin/env python # -*- coding: utf-8 -*- import httplib2 import os import sys import datetime from apiclient.discovery import build from oauth2client. file import Storage from oauth2client.client import AccessTokenRefreshError from oauth2client.client import flow_from_clientsecrets from oauth2client.tools import run # Calendar id for reading. CALENDAR_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxx@xxxxx.calendar.google.com' # Path to the credential files. BASE_DIR = lambda x: os.path.join(os.path.dirname(__file__), x) CLIENT_SECRETS_PATH = BASE_DIR( 'client_secrets.json' ) STORAGE_PATH = BASE_DIR( 'read_calendar.dat' ) # Set up a Flow object to be used for authentication. FLOW = flow_from_clientsecrets(CLIENT_SECRETS_PATH, scope = [ ]) def get_calendar_service(): storage = Storage(STORAGE_PATH) credentials = storage.get() if credentials is None or credentials.invalid: credentials = run(FLOW, storage) http = httplib2.Http() http = credentials.authorize(http) service = build( 'calendar' , 'v3' , http = http) return service class OneDayEvent( object ): def __init__( self , start_time, end_time, summary, creator): if start_time is None : assert (end_time is None ) self .start_time = start_time self .end_time = end_time self .summary = summary self .creator = creator def __lt__( self , that): if self .start_time is None and that.start_time is None : return self .summary < that.summary if self .start_time is None or that.start_time is None : return self .start_time is None return ( self .start_time, self .end_time, self .summary, self .creator) < ( that.start_time, that.end_time, that.summary, that.creator) def __str__( self ): if self .start_time is None : tm = u '終日' else : f = lambda x: datetime.datetime.strftime(x, '%H:%M' ) tm = '%s-%s' % (f( self .start_time), f( self .end_time)) return u '[%s] %s (%s)' % (tm, self .summary, self .creator) def read_events(date): """Returns sorted list of OneDayEvent objects.""" def format (x): return datetime.datetime.strftime(x, '%Y-%m-%dT%H:%M:%SZ' ) time_min = datetime.datetime.combine(date, datetime.time()) time_max = time_min + datetime.date.resolution time_min, time_max = map ( format , (time_min, time_max)) service = get_calendar_service() events = service.events(). list ( calendarId = CALENDAR_ID, timeMin = time_min, timeMax = time_max).execute() def f(x): y = x.get( 'dateTime' ) if y: z = datetime.datetime.strptime(y[: - 6 ], '%Y-%m-%dT%H:%M:%S' ) return datetime.datetime.combine(date, z.time()) ret = [OneDayEvent( f(event[ 'start' ]), f(event[ 'end' ]), event[ 'summary' ], event[ 'creator' ][ 'displayName' ]) for event in events[ 'items' ]] ret.sort() return ret def main(argv): offset = int (argv[ 1 ]) if len (argv) > = 2 else 0 for event in read_events( datetime.date.today() + datetime.date.resolution * offset): print ( unicode (event)) if __name__ = = '__main__' : main(sys.argv) |
- 出力例
[終日] 有給休暇 (James LaBrie)
[11:00-12:00] ○○様来社 (John Petrucci)
[14:00-15:00] [外出] △△訪問 (John Myung)
[17:30-22:00] □□勉強会 (Jordan Rudess)
[17:30-23:00] ☆☆飲み会 (Mike Mangini)
References