GoogleカレンダーのエクスポートをCSVにする。

Android端末を使っている関係で、Googleカレンダーを使用してスケジュール管理しているわけですが、これをエクスポートするとiCalendar形式のファイルになります。
iCalendar形式はxmlでもCSVでもなくて、
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:<ちよすけのメールアドレス>
X-WR-TIMEZONE:Asia/Tokyo
BEGIN:VTIMEZONE
TZID:Asia/Tokyo
X-LIC-LOCATION:Asia/Tokyo
BEGIN:STANDARD
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
こんな感じにフィールド名:値という形式になっています。

これを容易に扱えるようにするには、「何かと都合のいい」CSV(カンマ区切り形式)が便利ですから、ぜひとも変換したい。

そしてこういうテキストを扱うのに適しているのは、昔ならsedやawk、perlなどでしたが、pythonでやればオブジェクト指向的にぱっぱと処理できるではないか、と思ったのでやってみました。

python2でもpython3でもどちらでもいいんですが、新しいことをやるのにはpython3のほうがいいです。

そして、iCalendar形式をpythonで扱うためのライブラリがすでにありました。
PyPi(ぱいぱい)よりicsです。

===
Ics.py is a pythonic and easy iCalendar library. It’s goals are to read and write ics data in a developer friendly way.
===

Windowsのpython3ではpipが標準で同梱されているので、コマンドプロンプトまたはPowerShellを開いて
pip install ics
でインストールできます。

そこでIdleを起動してちょっといじってみました。
まず、Googleカレンダーからエクスポートしたスケジュールデータはzipファイルに入っていますから、これを解凍し、さらに利用しやすいように名前を変更します。ここではchiyo.icsにしました。
まずはカレントディレクトリを移動します。chiyo.icsは/Users/chiyoに置いてあるとします。

>>> import os
>>> os.getcwd()
'C:\\Program Files\\Python36'
>>> os.chdir('/Users/chiyo')
>>> os.getcwd()
'C:\\Users\\chiyo'

pythonではパス区切りに '/' も使えるんですね。
では早速chiyo.icsを読み込んでみます。

>>> import ics
>>> f = open('chiyo.ics', 'r')
>>> c=ics.Calendar(f.read())
Traceback (most recent call last):
  File "", line 1, in 
    c=ics.Calendar(f.read())
UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 770: illegal multibyte sequence
>>> f
<_io.TextIOWrapper name='chiyo.ics' mode='r' encoding='cp932'>
>>> f.encoding
'cp932'

エンコードが違いますと怒られました。なんでデフォルトのファイルエンコーディングがcp932なんですかね。Windowsシステムの設定を参照してるんでしょうけど…。
そこで、標準ライブラリのcodecsを使用します。

>>> import codecs
>>> f=codecs.open('chiyo.ics', 'r', 'utf-8')
>>> c=ics.Calendar(f.read())
>>> c
<Calendar with 1588 events>

読み込めました。

cはiCalendarのBEGIN:VEVENTからEND:VEVENTに囲まれたそれぞれのスケジュールデータを保持していて、引数で指定できます。

>>> c.events[5]
<Event '岡山出張' begin:2008-12-10T00:00:00+00:00 end:2008-12-12T00:00:00+00:00>
>>> 

という感じ。

表示されているのはSUMMARY、DTSTART、DTENDの3つのフィールドだけですが、フィールドには他にもLOCATION、DESCRIPTIONなどがあります。
これらはそれぞれ、Calendar.name、Calendar.begin、Calendar.end、Calendar.location、Calendar.descriptionになります。

なので、プログラムとしてはc.events[]の添字を1から最大数まで増やしながら、上記のそれぞれのメンバを書き出すだけになります。

>>> for i in range(1, 100):
 print (c.events[i].begin, c.events[i].end, c.events[i].name, c.events[i].location, c.events[i].description, sep=',')

2008-12-10T00:00:00+00:00,2008-12-12T00:00:00+00:00,岡山出張,,

実際にはこんな風にどんどん出力されます。
日付形式とかちょっとアレな感じですが、これで出力できそうです。エンコーディングの問題があったので、出力用のファイルもcodecs.open()で開きます。

>>> fout=codecs.open('chiyo.out', 'w', encoding='utf-8')
>>> for i in range(1, 1588):
 print (c.events[i].begin, c.events[i].end, c.events[i].name, c.events[i].location, c.events[i].description, sep=',', file=fout)
 
>>> 

これでファイル 'chiyo.out' に出力できました。

実際には、どうもエンコーディングの違うフィールドがあるようで、データの一部が文字化けしてたりしましたが、一応目的は達成できました。
この文字化けはもしかしたらAndroidで使ってるカレンダーツールが悪さしているかもしれません。ちょっと注意してみましょう。

もうちょっとicsをいじってみる。 に続く。

0 件のコメント:

コメントを投稿

Vimの補完プラグインをインストール。その4

Vimの補完プラグインをインストール。その3 で、 ddc-tabnine が使えそうです、などと書いたのですが、早速やってみました。 まず、tabnineのバイナリを用意しないといけません。がどうにもTabNineのサイトがわかりにくいので、 tabnine-nvim にあるダ...