ぺーぱーふぇいす

雑記と備忘録。私はプログラマ。

【Python + Google Calendar API】colorIdを調べる方法

f:id:PaperFace:20181127234045p:plain:w800

Googleカレンダーでは予定とかに色を指定できる。
GoogleカレンダーAPIを使って予定を追加する時、APIに渡すJSONcolorIdとして対応するID(文字列)を与えれば、該当する色を設定できます。
このcolorIdなる文字列と対応する配色をPythonから調べる手順。

サンプル

JSONで認証したりとかAPIを使う準備は済んでいるものとします。
API上で使えるcolorIdとその配色を図としてHTMLファイルとして出力させるサンプルです。

get_color_id.p

from googleapiclient.discovery import build
from oauth2client import client
from oauth2client import tools
from oauth2client import file
from httplib2 import Http

def create_colorid_res_body():
    """colorId一覧を出力するHTMLのメインボディ
    """
    html_doc = """\
<!DOCTYPE html> 
<html lang="ja"> 
<head> 
    <meta charset="UTF-8" /> 
    <title>colorId List</title> 
</head> 
<body> 
    <p> 
        colorId 
    </p> 
    <h2>calendar</h2>
    <table> 
        <tr> 
            <th>colorId</th> 
            <th colspan="2">backColor</th> 
            <th colspan="2">foreColor</th> 
            <th>sample</th> 
        </tr> 
        {0}
    </table> 
    <br>
    <h2>event</h2>
    <table>
        <tr> 
            <th>colorId</th> 
            <th colspan="2">backColor</th> 
            <th colspan="2">foreColor</th> 
            <th>sample</th> 
        </tr> 
        {1}
    </table>
</body> 
</html>
    """
    return html_doc

def create_colorid_tableline(color_id, background_color, foreground_color):
    """colorId出力時のHTMLのテーブル
    
    Arguments:
        color_id {str} -- colorId
        background_color {str} -- 背景色
        foreground_color {str} -- 前景色
    """

    line = """\
            <tr> 
                <td>"{0}"</td> 
                <td style="background:{1}" width=30px></td> 
                <td>{1}</td>
                <td style="background:{2}" width=30px></td> 
                <td>{2}</td>
                <td style="background:{1}"><font color="{2}">colorId = "{0}"</font></td> 
            </tr>\n"""

    return line.format(color_id, background_color, foreground_color)

def output_color_id():
    """HTMLでcolorIdを出力
    """
    SCOPE = 'https://www.googleapis.com/auth/calendar.readonly'
    TOKEN_FILE = 'token.json'
    CRED_FILE = 'client_secret.json'

    store = file.Storage(TOKEN_FILE)
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets(CRED_FILE, SCOPE)
        creds = tools.run_flow(flow, store)
    service = build('calendar', 'v3', http=creds.authorize(Http()))

    colors = service.colors().get().execute()

    calendar_color_tb = ""
    for id, color in colors['calendar'].items():
        calendar_color_tb += create_colorid_tableline(id, color['background'], color['foreground'])
        calendar_color_tb += '\n'

    event_color_tb = ""
    for id, color in colors['event'].items():
        event_color_tb += create_colorid_tableline(id, color['background'], color['foreground'])
        event_color_tb += '\n'

    html = create_colorid_res_body()
    html = html.format(calendar_color_tb, event_color_tb)

    with open('result.html', 'w') as f:
        f.write(html)

if __name__ == '__main__':
    output_color_id()

使い方は、認証用のJSONclient_secret.jsonとして、このスクリプトget_color_id.pyと同一のディレクトリに設置して実行します。
すると、同一ディレクトリにresult.htmlというhtmlが出力されるので、中を観てcolorIdと配色を確認します。

出力結果

ついでに出力例(2018/11/27時点)。
result.htmlとして出力された箇所から該当のソースを引っこ抜いて、このエントリにそのまま貼り付けた。
予定の色追加に使う方はeventのほうかな。

result.html

calendar
colorId backColor foreColor sample
"1" #ac725e #1d1d1d colorId = "1"
"2" #d06b64 #1d1d1d colorId = "2"
"3" #f83a22 #1d1d1d colorId = "3"
"4" #fa573c #1d1d1d colorId = "4"
"5" #ff7537 #1d1d1d colorId = "5"
"6" #ffad46 #1d1d1d colorId = "6"
"7" #42d692 #1d1d1d colorId = "7"
"8" #16a765 #1d1d1d colorId = "8"
"9" #7bd148 #1d1d1d colorId = "9"
"10" #b3dc6c #1d1d1d colorId = "10"
"11" #fbe983 #1d1d1d colorId = "11"
"12" #fad165 #1d1d1d colorId = "12"
"13" #92e1c0 #1d1d1d colorId = "13"
"14" #9fe1e7 #1d1d1d colorId = "14"
"15" #9fc6e7 #1d1d1d colorId = "15"
"16" #4986e7 #1d1d1d colorId = "16"
"17" #9a9cff #1d1d1d colorId = "17"
"18" #b99aff #1d1d1d colorId = "18"
"19" #c2c2c2 #1d1d1d colorId = "19"
"20" #cabdbf #1d1d1d colorId = "20"
"21" #cca6ac #1d1d1d colorId = "21"
"22" #f691b2 #1d1d1d colorId = "22"
"23" #cd74e6 #1d1d1d colorId = "23"
"24" #a47ae2 #1d1d1d colorId = "24"

event
colorId backColor foreColor sample
"1" #a4bdfc #1d1d1d colorId = "1"
"2" #7ae7bf #1d1d1d colorId = "2"
"3" #dbadff #1d1d1d colorId = "3"
"4" #ff887c #1d1d1d colorId = "4"
"5" #fbd75b #1d1d1d colorId = "5"
"6" #ffb878 #1d1d1d colorId = "6"
"7" #46d6db #1d1d1d colorId = "7"
"8" #e1e1e1 #1d1d1d colorId = "8"
"9" #5484ed #1d1d1d colorId = "9"
"10" #51b749 #1d1d1d colorId = "10"
"11" #dc2127 #1d1d1d colorId = "11"

解説

Google Calendar API上で使う色情報は、ColorsというAPIgetメソッドで取得できるようです。

Colors: get  |  Calendar API  |  Google Developers
https://developers.google.com/calendar/v3/reference/colors/get

上記リファレンスを読むと……というか、このエントリのサンプル中でも普通に記述してますが、APIで使う色の指定に使う情報はcalendareventという種別ごとにcolorIdという文字列によって識別され、BackgroundForegroundの2つの色情報を持つみたいです。
リファレンスには丁寧にPythonを含む各言語のサンプルが載っており、取得したカラーコード(文字列)をコンソールに羅列してくれるみたいです。
ただ、私はカラーコードを見ただけで「あ~こんな感じの色ね」っていう素敵なスキルを持ってないので、色覚的にわかりやすいようにHTMLに出力結果をまとめてしまいました。

今後、Googleカレンダー上で使える色が増えたり変わったりした時も実行し直せばこのスクリプトで取得し直せるかな?(APIの仕様が大きく変わらないことを願う)

まあ、下図のようなWEBブラウザから適当に予定を追加してみて選択できるこの色(ちょっと色味が違う気がするのは気のせい?)。

f:id:PaperFace:20181127231304p:plain:w240

これらがどのcoIorIdに該当するかってのを調べただけの話。
少し気になるのが、GoogleカレンダーのWEB版とかAndroidアプリとかでも予定を作ると、基本的にBackgroundの背景色で予定が出力されるのに対し、Foregroundの色要素は何処に使われているんだろう?
「前景色なのでフォントカラーなのかな?」とか思ったけど……

f:id:PaperFace:20181127231703p:plain:w200

予定のタイトルは白文字なんだよね。何処の色なんだろ……🤔

【追記】やっぱり色違くなぁい?

(2018/11/28追記)
WEBとかスマホGoogleカレンダーアプリと、色が違う気がする。というか違う。
もう論より証拠というか、colorId111を指定してAPIから予定を追加してみる。

f:id:PaperFace:20181128223841p:plain

んで、めんどくさいけどブラウザのカラーピッカー的な拡張機能で色を拾って並べてみる。
左がAPIから取得してきたカラーコードに基づく配色。右がGoogleカレンダーに追加された予定をカラーピッカーで採取したカラーコードに基づく配色。

colorId API_Color_Info Color_Pick
"1" #a4bdfc #7a86cb
"2" #7ae7bf #33b679
"3" #dbadff #8e24aa
"4" #ff887c #e67c73
"5" #fbd75b #f6nf25
"6" #ffb878 #f4521d
"7" #46d6db #039be5
"8" #e1e1e1 #616161
"9" #5484ed #3f51b5
"10" #51b749 #0a8043
"11" #dc2127 #d50001

うん、違うね😇
色の系統は一緒だけど、「濃さが足りない」ってところだろうか。
んーこの違いはなんだろう? とりあえず、自分で作ったAPIcolorIdを意識する時はこれをカンペにすることが多くなりそう。

余談

Web系に疎いのでAPIとかあんまり使う機会が無かったのですが、いろいろいじってて楽しい。
Googleカレンダーもそうだけど、APIを通じてメジャーなサービスと連携できるようなアプリを作ることができるのは中々充足感があります。

ググって断片的な情報を集めて、詳細はリファレンスとにらめっこすればどうにかなる。あんまり英語は得意じゃないですが……
いろいろ英語学習アプリ的なのをスマホに入れてはいるけど長続きしない……なんかこう、アニメの英語吹替版に字幕解説付けてくれる学習サービスとか、コスプレしたネイティブの女の子とかが講師になってくれる英会話プランとか無いだろうか(→このサービスは生きているのか?)