2017年11月28日火曜日

Googleカレンダーから祝日リストを取得する

Pythonで祝日を取得する方法としては、内閣府の国民の祝日についてにある祝日リストのcsvが使えるが、このリストには振り替え休日がないので自分で計算する必要がある。他の方法としては、Googleカレンダーの「日本の祝日」から祝日を取得する方法がある。これは日本の祝日がイベントとして登録されたカレンダーで、ちゃんと振り替え休日も登録されている。PythonでGoogleカレンダーの「日本の祝日」から祝日リストを取得してみる。


環境


OSはRaspbian Jessie。



Googleカレンダーを使うための前準備


Googleカレンダーのイベントは、図書館の休館日をGoogleカレンダーに自動登録するでやったようにGoogle Calendar APIで取得できる。はじめにこのGoogle Calendar APIを有効にして認証キー(client_secret.json)を取得しておく必要がある。

続いて「日本の祝日」のカレンダーIDを確認する。Googleカレンダーにブラウザでアクセスし、「日本の祝日」右の三角マークをクリックしてメニューを表示し、「カレンダー設定」を選択する。カレンダーアドレスの欄でカレンダーIDを確認できる。後でこのカレンダーIDを使うので、これをどこかにコピペしておく。


更に、Google APIを使うためのモジュールgoogle-api-python-clientをpipでインストールする。



コーディング


Googleカレンダーからイベントを取得するサンプルコードがPython Quickstartのステップ3にある(quickstart.py)。これを元にGoogleカレンダーの「日本の祝日」から祝日を取得するコードを作成する。quickstart.pyのmain関数を変更して、「日本の祝日」から2018年1月1日~2018年12月31日のイベントを取得するようにした。ここでコピペしておいた「日本の祝日」のカレンダーIDを使う。
import httplib2
import os

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage

import datetime

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# カレンダーへのアクセス権は読み取りのみ
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
# 認証キーのファイル名
CLIENT_SECRET_FILE = 'client_secret.json'
# アプリケーション名(任意)
APPLICATION_NAME = 'Application name'


def get_credentials():
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'calendar-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def main():
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('calendar', 'v3', http=http)

    # 2018年1月1日(UTC)のISO 8601 形式
    sdt = datetime.datetime(2018, 1, 1, tzinfo=datetime.timezone.utc).isoformat()
    # 2018年12月31日(UTC)のISO 8601 形式
    edt = datetime.datetime(2018, 12, 31, tzinfo=datetime.timezone.utc).isoformat()

    # calendarIdに「日本の祝日」のカレンダーIDを指定して、
    # 2018年1月1日から2018年12月31日までのイベントを取得する
    eventsResult = service.events().list(
        calendarId='ja.japanese#holiday@group.v.calendar.google.com', timeMin=sdt, timeMax=edt,
     singleEvents=True, orderBy='startTime').execute()

    events = eventsResult.get('items', [])

    if not events:
        print('No events found.')
    for event in events:
        start = event['start'].get('dateTime', event['start'].get('date'))
        print(start, event['summary'])

if __name__ == '__main__':
    main()


祝日の取得


Pythonコード(sample.py)と認証キーファイル(client_secret.json)をディレクトリに置く。初回実行時は認証情報を保存するのでブラウザで開いてコードを取得する必要があるが、ターミナルで実行する場合はブラウザを使えない。そこで--noauth_local_webserverオプションを使う。実行するとURLが表示されるので、それをコピーして、PCなどのブラウザで開くとコードが表示される。そのコードをコピーして、ターミナルのコード入力欄にペーストする。


コードをペーストするとPythonコードが実行され、以下のように振り替え休日込みの祝日一覧が表示される。


1度実行するとホームディレクトリに.credentialsというディレクトリが作成され、その配下に認証情報ファイルが作成される。2回目以降は、すでに認証情報ファイルが作成されているのでターミナルでも--noauth_local_webserverオプションは不要。


0 件のコメント:

コメントを投稿