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 件のコメント:
コメントを投稿