ical データをテキスト化する Python プログラム

　OS X のカレンダーやGoogle Calendar をエクスポートしたデータは ical形式になっていますが、過去の記録としてそのまま保存しておいても閲覧するのにはちょっと不便なので、日時とイベント名を一行にしたテキストファイルにしておきたいと思った。
　ネットで探すと、Python用の icalendar パッケージが見つかった。

## Python 用の icalendar ライブラリーパッケージ
 Python で ical 形式を扱うパッケージは、以下のサイトからダウンロードする。

https://pypi.python.org/pypi/icalendar

私がダウンロードした時点では icalendar 3.10 で、Python 2.6, 2.7 and 3.3+ に対応している。

## パッケージのインストール
　上記からダウンロードした .zip ファイルを解凍し、ターミナルでそのフォルダーに移動してから、次のコマンドでインストールする。

```$ python setup.py install```

## ical データからイベントを取り出すプログラム
　ical 形式のファイルを読み込んで、標準出力に出力する Python プログラムは以下のとおり。

使用方法は以下のとおり

```$ python iCal2txt.py file | sort > output file```

使用例：```$ python iCal2txt.py yotei2016.ical | sort > calendar2016.txt ```
これで、「yotei2016.ical」のデータから日時とイベント名を取り出して日時順に並び替えたテキストデータとして「calendar2016.txt」が出力される。

Python プログラムソースは以下のとおり

```Python:iCal2txt.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import codecs
import sys
from icalendar import Calendar, Event
from datetime import datetime

argvs = sys.argv
fin = codecs.open(argvs[1])
cal = Calendar.from_ical(fin.read())
body = ""
for ev in cal.walk():
    if ev.name == 'VEVENT':
        start_dt = ev.decoded("dtstart")
        end_dt = ev.decoded("dtend")
        summary = ev['summary'].encode('utf-8')
        print "{start} - {end} : {summary}".format(start=start_dt.strftime("%Y/%m/%d %H:%M"), end=end_dt.strftime("%Y/%m/%d %H:%M"), summary=summary)
        
```

このファイルがあると、あのイベントは何時だったかな？　などと調べるのが簡単にできる。

以前、AppleScript で iCalアプリから同様のファイルを取り出すスクリプトを書いたけど、Python で書くと結構簡単にできて Python が好きになりました。（パッケージが有ったからですが）

## （追記）入力ファイル名の拡張子を .txt にしたファイルに出力する
　ソートが不要なら、出力ファイルを指定するのが面倒なので、入力ファイル名に拡張子を .txt にして出力するようにした。

```python:ical2txt2.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import codecs
import os
import sys
from icalendar import Calendar, Event
from datetime import datetime

argvs = sys.argv
fin = codecs.open(argvs[1])
cal = Calendar.from_ical(fin.read())
fin.close()
ldata = ""
for ev in cal.walk():
    if ev.name == 'VEVENT':
        start_dt = ev.decoded("dtstart")
        end_dt = ev.decoded("dtend")
        summary = ev['summary'].encode('utf-8')
        ldata += "{start} - {end} : {summary}".format(start=start_dt.strftime("%Y/%m/%d %H:%M"), end=end_dt.strftime("%Y/%m/%d %H:%M"), summary=summary) + os.linesep
fname,ext = (sys.argv[1]).split(".",1)
fout = fname + ".txt"
f = codecs.open(fout, "w")
f.write(ldata)
f.close()
```

## （追記2）ソートした結果を .txt ファイルに出力する
　プログラム内でソートすると文字化けしていたので、上記のようにソート前で出力するようにしていたが、文字化けを解消することができた。
 ソースは以下のとおり。
　出力の改行コードは環境に合わせて変更してください。
（```os.linesep``` の挙動が変だったので、改行コードを直接指定しています）

使用例：```$ python ical2txt.py yotei2016.ics ```

```python:ical2txt3.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import codecs
import os
import sys
from icalendar import Calendar, Event
from datetime import datetime

argvs = sys.argv
fin = codecs.open(argvs[1])
cal = Calendar.from_ical(fin.read())
fin.close()
li = []
for ev in cal.walk():
    if ev.name == 'VEVENT':
        start_dt = ev.decoded("dtstart")
        end_dt = ev.decoded("dtend")
        summary = ev['summary'].encode('utf-8')
        li.append("{start} - {end} : {summary}".format(start=start_dt.strftime("%Y/%m/%d %H:%M"), end=end_dt.strftime("%Y/%m/%d %H:%M"), summary=summary).decode('utf-8'))
li.sort()
fname,ext = (sys.argv[1]).split(".",1)
fout = fname + ".txt"
f = codecs.open(fout, "w")
for ld in li:
    f.write(ld.encode('utf-8') + "\n")
f.close()
```