「日程くん」から得られたスケジュールをGoogleカレンダーにインポートする

## 概要
* [「日程くん」の結果をスクレイピングする](https://qiita.com/r_beginners/items/0d9608f86cdf82907074)

上記の投稿で、Jリーグの日程が取得できたので活用したいと思います。
日頃使っているカレンダーアプリにインポートできれば、逐一入力する手間が省けます。そこで
Google カレンダーにインポートできる形式のファイルを作成しましょう。

## iCalender形式について
* [iCalender (Wikipedia)](https://ja.wikipedia.org/wiki/ICalendar)
* [RFC-5545](https://tools.ietf.org/html/rfc5545)

### 基本形
```sample.ics
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART;TZID=Asia/Tokyo:20200223T130000
DTEND;TZID=Asia/Tokyo:20200223T150000
SUMMARY;LANGUAGE=jp-JP:第１節第３日 FC東京
DESCRIPTION;LANGUAGE=jp-JP:キックオフ:13:00\n
	スタジアム：アイスタ\n
	クラブ:http://www.fctokyo.co.jp/\n
	JAL：https://www.jal.co.jp/\n
	ANA：https://www.ana.co.jp/\n
END:VEVENT
END:VCALENDAR
```
* `BEGIN:VCALENDAR VERSION:2.0`がヘッダー行で、`END:VCALENDAR`がフッター行で構成される。
* `BEGIN:VEVENT`と`END:VEVENT`で一つのスケジュールを記述する。アイテムが複数あればこの繰り返しが必要になる。
* `DTSTART:`開始時間、`DTEND：`終了時間、時間の表示形式は`%Y%m%dT%H%M%S`です。例：20200223T130000
* タイムゾーンは`;TZID=Asia/Tokyo`と指定する。
* 言語は`;LANGUAGE=jp-JP`と指定する。
* `DESCRIPTION`で複数行に分けたい場合は、`\n`を行末に付与する。内容については、例では航空会社2社を追加していますが、宿泊サービスやスタジアムの位置情報などがあれば便利です。

## コード
```schedule_all.py
import datetime
import pandas as pd

# 'https://data.j-league.or.jp/'の日程結果から取得する
data = pd.read_csv('./csv/Game_Schedule_2020.csv', sep=',', encoding='utf-8')
```
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126042/c67f7e66-fb1b-1662-c9e1-f20b9578cdb8.png)

```schedule_all.py
# クラブHPのアドレスを収集したローカルファイルを準備する
club = pd.read_csv('./csv/master_club_2020.csv', sep=',', encoding='utf-8')
```
対戦するクラブのアドレスを詳細データに入れるために、独自で作成したデータを準備しました。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126042/69334cfa-5552-f9ff-fbc0-56268f26ef18.png)

```schedule_all.py
yyyy = 2020
# 抽出したいチーム名を指定する
team = data[(data['ホーム'] == 'チーム名') | (data['アウェイ'] == 'チーム名')]
```
「チーム名」を取得したいチーム名に変更する。

```schedule_all.py
# 固定文字列を作成する
header = (r'BEGIN:VCALENDAR' + '\n'
            r'VERSION:2.0' + '\n')

footer = (r'END:VCALENDAR')

info = ('	JAL：https://www.jal.co.jp/\\n\n'
        '	ANA：https://www.ana.co.jp/\\n')

timezone = ';TZID=Asia/Tokyo'
language = ';LANGUAGE=jp-JP'
```
テンプレートを構成する文字列を作成する。

```schedule_all.py
schedule_all = []

for i in range(len(team)):
    if team['KO時刻'].iloc[i] == '●未定●':
        break
    # 特定チームデータから節単位に以下の項目を作成する
    # start_datetime, end_datetime, section, home or away team, kick_off, stadium, club HP
    tmp_date = team['試合日'].iloc[i]
    tmp_date = str(yyyy) + '/' + tmp_date[:5]
    start_time = team['KO時刻'].iloc[i]
    tmp_date_time = tmp_date + ' ' + start_time + ':00'
    tmp_dtstart = datetime.datetime.strptime(tmp_date_time, '%Y/%m/%d %H:%M:%S')
    tmp_dtend = tmp_dtstart + datetime.timedelta(hours=2)
    # start_datetime
    dtstart = tmp_dtstart.strftime('%Y%m%dT%H%M%S')
    # end_datetime
    dtend = tmp_dtend.strftime('%Y%m%dT%H%M%S')
    # section
    sec = team['節'].iloc[i]
    # team name
    team_name = team['アウェイ'].iloc[i] if team['ホーム'].iloc[i] == 'チーム名' else team['ホーム'].iloc[i]
    # kick off
    kickoff = str(team['KO時刻'].iloc[i])
    # stadium
    stadium = team['スタジアム'].iloc[i]
    # club HP
    club_url = club[club['略称'] == team_name]['オフィシャルサイトURL']

    # 節単位のデータからiCalender形式で文字列を作成する。
    begin = 'BEGIN:VEVENT'
    dstart = 'DTSTART' + timezone + ':' + dtstart
    dend = 'DTEND' + timezone + ':' + dtend
    summary = 'SUMMARY' + language + ':' + sec + ' ' + team_name
    description1 = r'DESCRIPTION' + language + ':' + 'キックオフ:' + kickoff + '\\n'
    description2 = r'	スタジアム：' + stadium + '\\n'
    description3 = r'	クラブ:' + club_url.values[0] + '\\n\n' + info
    end = 'END:VEVENT' + '\n'
    
    # 節単位のデータをリスト化する
    contents = [begin, dstart, dend, summary, description1, description2, description3, end]
    schedule_all.append(contents)
```
* 後半戦はキックオフ時間がまだ未定のため、KO時刻が決定しているデータのみ作成
* イベントの終了時間は、`datetime.timedelta(hours=2)`で2時間後と指定
* 節単位のデータを`schedule_all`に追加

```schedule_all.py
# カレンダーファイルの作成
path = './csv/schedule_all_2020.ics'
with open(path, mode='a', encoding='utf-8') as f:
    f.write(header)
    for s in schedule_all:
        f.write('\n'.join(s))
    f.write(footer)
```
最後は、節単位のリストをループ処理し、テキストファイルを作成する。（※説明のため、節データの作成するループ処理とテキストファイルを作成するループ処理に分けました。）
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126042/7428b799-9555-3816-6744-955a92aa855a.png)



## 参考にさせていただいた記事
* [カレンダーに使われるiCalendar形式について part1](https://qiita.com/TomOse/items/31b5fb4782f06d19af79)