LoginSignup
20
13

More than 1 year has passed since last update.

iCalendarデータの仕様とPythonにおける利用方法

Last updated at Posted at 2021-10-05

概要

この記事ではiCalendarデータの基本的な仕様およびPythonでiCalendarデータを扱えるicalendarパッケージについてまとめます。

iCalendarとは

iCalendarとはインターネットを通してPCやスマートフォンなど異なるデバイス間でカレンダー情報をやりとりするためのデータ形式です。

現在、カレンダー情報を扱うためのもっとも標準的な形式であり、iCalendar形式で作成されたファイルの拡張子は通常.ics.ical.icalendarのいずれかになります。

なおiCalendarではTODO情報やジャーナル情報も取り扱うことが可能ですが、それらについての説明は割愛します。

iCalendarの歴史

iCalendarは、1998年にIETF(Internet Engineering Task Forceの略。インターネット技術の標準化推進団体)によってRFC2445が作成され、以来、標準仕様とされてきました。

その後、インターネット技術の発展に合わせて、2009年には大きな改訂を加えたRFC5545が策定され、RFC5545の拡張的役割で2016年にRFC7986が定義されました。

より詳しい歴史を知りたい場合はこちらの記事(英語)が参考になります。
https://devguide.calconnect.org/iCalendar-Topics/History/

iCalendarデータ形式の構造

iCalendarデータの例

Googleカレンダーをエクスポートすると入手できるicsファイルのデータを例として、iCalendarデータの形式について説明します。

まず画像のような設定で予定を作成しました。

スクリーンショット 2021-09-17 15.42.55.png

BEGIN:VCALENDAR 
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:iCalendarテスト
X-WR-TIMEZONE:UTC
BEGIN:VEVENT
DTSTART:20210918T000000Z
DTEND:20210918T010000Z
DTSTAMP:20210917T064347Z
ORGANIZER:mailto:test-organizar@example.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=:test@example.com
 il.com;X-NUM-GUESTS=0:mailto:test@example.com
 il.com
CREATED:20210917T064324Z
DESCRIPTION:Googleカレンダーのicsファイルを見る
LAST-MODIFIED:20210917T064324Z
LOCATION:自宅
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:テスト用の予定
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

データ構造と各セクション

上記のデータを見るとわかる通り、iCalendarは全体をBEGIN:VCALENDAREND:VCALENDARで囲み、その中に各プロパティを記述します。

VCALENDARセクション内にはBEGIN:VEVENTEND:VEVENTに囲まれたセクションがあり、ここにはカレンダーの各予定(イベント)ごとの情報が定義されます。

VCALENDARは一度だけしか登場しませんが、VEVENTはカレンダーに登録されたイベントの数だけ設定されます。

次にiCalendarの具体的なプロパティについて説明します。

VCALENDARのプロパティ

プロパティ名 役割
PRODID カレンダーの識別子
VERSION iCalendarデータを生成したアプリケーションの識別情報。サービス名や利用言語情報を組み合わせるケースが多い
CALSCALE カレンダーの暦法。一般的にGREGORIANを指定する
METHOD PUBLISH・REQUEST・CANCELなどの値が入る

VEVENTのプロパティ

プロパティ名 内容
DTSTART イベント開始日時
DTEND イベント終了日時
DTSTAMP iCalendarオブジェクトのインスタンスが作成された日時
ORGANIZER イベント主催者情報。詳しくはこちら
ATTENDEE イベント参加者情報。詳しくはこちら
CREATED イベントが作成された日時
DESCRIPTION イベントの説明文
LOCATION イベント開催地
SEQUENCE イベント情報を変更する度に更新されていくシーケンス番号
STATUS イベントの状態。一般的にイベント作成時はCONFIRMED、キャンセル時はCANCELLEDが指定される
SUMMARY イベントタイトル
TRANSP イベントを設定した時間の状態。OPAQUEまたはTRANSPARENTという値が入る。TRANSPARENTは空き時間を表すため、会議などの予定の場合OPAQUEを設定する

ORGANIZER・ATTENDEEの詳細

ORGANIZER(主催者情報)とATTENDEE(参加者情報)ではカレンダー上での表示名や出欠の返事を求めるかなど細かな設定ができます。

設定例
ORGANIZER;CN=テスト太郎:mailto:test_organizer@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=テスト花子:mailto:test@example.com

例えば上記のような設定の場合、イベントの主催者はtest_organizer@example.comでカレンダー上ではテスト太郎と表示されます。
参加者はtest@example.comで表示名はテスト花子、イベントには必須参加であり、参加状況についてアクションを求めるということになります。

プロパティ名 内容
CN カレンダーにおける表示名
ROLE 役割。CHAIR(議長)・REQ-PARTICIPANT(必須参加)・OPT-PARTICIPANT(任意参加)などが設定される
PARTSTAT 参加状況について。NEEDS-ACTION・ACCEPTED・DECLINED・TENTATIVE・DELEGATEDなどが設定される

PythonでiCalendarデータを扱うには

PythonにはRFC5545互換のiCalendarファイル用パーサジェネレータであるicalendarパッケージがあります。
https://pypi.org/project/icalendar

公式サイトにインストール方法や詳細な使い方が載っているためぜひご覧になってください。
https://icalendar.readthedocs.io/en/latest/

ここではicalendarパッケージの基本的な使い方を紹介します。

icalendarパッケージの使い方

ジェネレータとして

例として「2021年10月1日12時から一時間〇〇会議あり」という予定をicalendarパッケージを利用して作成してみます。

# coding: utf-8

from datetime import datetime
from icalendar import Calendar, Event, vCalAddress, vText

cal = Calendar()
cal.add('prodid', '-//Test//test-product//ja//')
cal.add('version', '2.0')
cal.add('calscale', 'GREGORIAN')
cal.add('method', 'REQUEST')

# イベント作成
event = Event()
event.add('summary', u'〇〇会議')
event.add('dtstart', datetime(2021, 10, 1, 12))
event.add('dtend', datetime(2021, 10, 1, 13))
event.add('description', u'〇〇についての会議です')

# 開催者設定
organizer = vCalAddress('MAILTO:test_organizer@example.com')
organizer.params['cn'] = vText(u'テスト 太郎')
organizer.params['role'] = vText('CHAIR')
event['organizer'] = organizer

# 参加者設定
attendee = vCalAddress('MAILTO:test@example.com')
attendee.params['cn'] = vText('テスト 花子')
attendee.params['ROLE'] = vText('REQ-PARTICIPANT')
event.add('attendee', attendee)

cal.add_component(event)

# icsファイル作成
f = open('test.ics', 'wb')
f.write(cal.to_ical())
f.close()

各プロパティを定義するためにはadd()メソッドを利用します。
このコードを実行すると以下のようなicsファイルが作成されます。

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Test//test-product//ja//
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
SUMMARY:〇〇会議
DTSTART;VALUE=DATE-TIME:20211001T120000
DTEND;VALUE=DATE-TIME:20211001T130000
ATTENDEE;CN="テスト 花子";ROLE=REQ-PARTICIPANT:MAILTO:test@example.com
DESCRIPTION:〇〇についての会議です
ORGANIZER;CN="テスト 太郎";ROLE=CHAIR:MAILTO:test_organizer@example.com
END:VEVENT
END:VCALENDAR

パーサとして

先ほど作成したicsファイルをicalendarパッケージでパースしてみます。
まず、from_ical()メソッドを使い、iCalendarデータをプリミティブなPythonの型にデコードします。

# coding: utf-8

from datetime import datetime
from icalendar import Calendar

file = open('test.ics')
calendar = Calendar.from_ical(file.read())
print(calendar)
> VCALENDAR({u'CALSCALE': vText('GREGORIAN'), u'VERSION': vText('2.0'), u'METHOD': vText('REQUEST'), u'PRODID': vText('-//Test//test-product//ja//')}, VEVENT({u'ATTENDEE': vCalAddress('MAILTO:test@example.com'), u'DESCRIPTION': vText('〇〇についての会議です'), u'DTEND': <icalendar.prop.vDDDTypes object at 0x10b52a2d0>, u'DTSTART': <icalendar.prop.vDDDTypes object at 0x10b694390>, u'ORGANIZER': vCalAddress('MAILTO:test_organizer@example.com'), u'SUMMARY': vText('〇〇会議')}))

walk()メソッドを使うと、各プロパティの値を取り出せます。

print(calendar.walk('VCALENDAR')[0]['VERSION'])
> 2.0
print(calendar.walk('VEVENT')[0]['ORGANIZER'])
> MAILTO:test_organizer@example.com

終わりに

広く普及しているiCalendarですが、なかなかデータの中身をじっくり見る機会はなく、まとめてみると構造はシンプルながらも意外と多様な情報を持っていることに気付かされました。

冒頭で書いた通り、イベント予定の管理以外にTODO情報やジャーナル情報も扱えます。今回は紹介していませんが、それらのためのプロパティも存在するので興味があれば調べてみると面白いかもしれません。

参考サイト

iCalendar関連
https://datatracker.ietf.org/doc/html/rfc2445
https://datatracker.ietf.org/doc/html/rfc5545
https://datatracker.ietf.org/doc/html/rfc7986
https://icalendar.org/
https://devguide.calconnect.org/iCalendar-Topics

icalendarパッケージ関連
https://icalendar.readthedocs.io/en/latest/
https://github.com/collective/icalendar

20
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
13