スキップしてメイン コンテンツに移動

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

PyPiでicalendarというのを見つけてちょっといじってみたんだけれど、icalendarは今ひとつドキュメントが足りてないのと、「テストコードがあるから使用方法はそっちを見てね」的な感じだけどカバーしきれていない感じなのとで、やっぱりicsをもうちょっといじってみることにしました。

さて、GoogleカレンダーのエクスポートをCSVにする。では浅瀬でパシャパシャやってただけなので、もうちょっと深いところまでいってみましょう。


まずデータを読み込みます。前回と同じデータですが、文字化けしている部分(どうもカレンダーを作成したアプリの不具合らしく、DESCRIPTIONのところのエンコードが壊れてた)はあらかじめ削除してあります。

>>> import ics
>>> with open('chiyo.ics', encoding='utf-8') as f:
...   cals = ics.Calendar(f.read())
>>> cals
<Calendar with 1663 events>
>>> cals.events[5]
<Event '岡山出張' begin:2008-12-10T00:00:00+00:00 end:2008-12-12T00:00:00+00:00>

with文を使うと、ブロックを抜けたときに自動的にファイルをclose()してくれるので便利です。
次に、それぞれのデータの値を見てみます。

>>> cals.events[5].name
'岡山出張'
>>> cals.events[5].begin
<Arrow [2008-12-10T00:00:00+00:00]>
>>> cals.events[5].end
<Arrow [2008-12-12T00:00:00+00:00]>
>>> cals.events[5].location
''
設定されていない空の項目は '' と空の値を返してくるようなので、同じメソッドで扱えそうです。
ところでここで、Arrow というキーワードが出てきました。前回は「日時が出てきたね、よしよし」と気にもとめなかったのですが、Arrow: better dates and times for Pythonという、Pythonのdatetimeモジュールをさらに改良したようなものらしいです。PyPiはこちら
Arrow を継承したオブジェクトは to() とか humanize() とかのファンクションが使えるようです。

>>> local=cals.events[5].begin.to('Asia/Tokyo')
>>> local
<Arrow [2008-12-10T09:00:00+09:00]>
>>> local.humanize()
'9 years ago'
>>> local.humanize(locale='ja_jp')
'9年前'
なかなかに多芸です。

ちなみに to() のパラメータはtimezone形式で、IANAのTime Zone Databaseで定義されています。

#code coordinates TZ comments
JP +353916+1394441 Asia/Tokyo


coordinatesというのは緯度経度のことです。日本標準時は東経135度の子午線がちょうど兵庫県を通っているため、協定世界時 (UTC) に135度分のオフセット (+0900) を加えたものになります。

それはさておき。
もうちょっと見てみましょう。日時のフォーマットは format() で変更できるようです。

>>> cals.events[5].begin.format('YYYY/MM/DD HH:mm:ss')
'2008/12/10 00:00:00'
>>> local.format('YYYY/MM/DD HH:mm:ss')
'2008/12/10 09:00:00'
>>> cals.events[5].begin.to('Asia/Tokyo').format('YYYY/MM/DD HH:mm:ss')
'2008/12/10 09:00:00'

これなら読みやすくなりそうです。
ということで試しに書いてみました。
for i in range(0, len(cals.events)):
    with cals.events[i] as ev:
        print('{0}, {1}, {2}, {3}, {4}'.format(
            ev.begin.to('Asia/Tokyo').format('YYYY/MM/DD HH:mm:ss'), 
            ev.end.to('Asia/Tokyo').format('YYYY/MM/DD HH:mm:ss'), 
            ev.summary, 
            ev.location, 
            ev.description, 
        ))
実行してみると、AttributeError: __enter__ というエラーが返ってきました。
>>> import ics
>>> dir(ics.Calendar.events)
['__class__', '__delattr__', '__delete__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__isabstractmethod__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__set__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'deleter', 'fdel', 'fget', 'fset', 'getter', 'setter']
with文で使用するには __enter____exit__ が必要なので、events ではwith文は使えないようです。

結局、試行錯誤しながら以下のようにしてみました。

import ics
import re

with open('diary.ics', encoding = 'utf-8') as fin:
    cals = ics.Calendar(fin.read())

with open('output.csv', 'w', encoding = 'utf-8') as fout:
    fout.write('開始, 終了, 件名, 場所, 説明\n')
    for i in range(0, len(cals.events)):
        s = u'{0}, {1}, "{2}", "{3}", "{4}"'.format(
            cals.events[i].begin.to('Asia/Tokyo').format('YYYY/MM/DD HH:mm:ss'), 
            cals.events[i].end.to('Asia/Tokyo').format('YYYY/MM/DD HH:mm:ss'), 
            cals.events[i].name, 
            cals.events[i].location, 
            cals.events[i].description, 
        )
        if re.search('(東京)|(岡山)|(藤沢)', s):
            if not re.search('移動', s):
                fout.write(s + '\n')

これで「東京」「岡山」「藤沢」を含み、かつ「移動」を含まないものをファイルに書き出します。ファイルは with 文で扱っているので、ブロック終了時に自動的に close() されますから fout.close() はありません。

コメント

このブログの人気の投稿

MPC-BEでmadVRの設定。

ノートPCでMP4動画を再生するのに、VLCメディアプレーヤーは使いやすいし何も設定しなくてもインストールしただけで使えるので便利ですが、画質・再生品質的には今一つの印象があります。印象なので、ここから先は単なる自己満足の世界で、定量的な評価などはありません。動画を見ていて、再生時に「ん?」と思うような引っかかりがなくなればOKというレベルでの自己満足追求です。 ちょっと否定的な出だしになりましたが、そんな感じで MPC-BE + madVR です。 MPC-BEは、もともとはWindows Media PlayerとそっくりなUIのMPC(Media Player Classic)からの派生です。WMP6.4が結構人気があったのにWindows MEのときにWMP7で外観が大きく変わってしまったため、前のほうが好きだった人たちがオープンソースで開発していました。その後、MPC-HC(Home Cinema)が派生し、さらにそこからMPC-BE(Black Edition)へと派生しています。一方で MPC-HCのほうもGitHubで開発が再開 しているようです。 MPC-BEはChromeCast(以下CC)へのキャストはできないので、大画面で見たい向きにはそこのところはちょっとカユイのですが、そもそもVLCなどでのCCへのキャストはMP4などのメディアファイルをCCへ流し込んでいるだけで、デコード処理自体はCC側で行うため、コーデック自体はCCで使っているSoCのライブラリによるはずです。なので、 PCのディスプレイで高画質動画を観たい 、もしくは PCからHDMIやDPなどで大画面テレビで再生したい 、という場合の方法になります。 ただし、PCの構成、特にCPUやGPUの処理能力が不足するとけっこう悲惨なことになりますので要注意。 参考にしたのは こちら 。"LOL, I has a web server"というサーバなんでしょうか。けっこういろいろと興味深いページがあるんですが、こちらから 3.1 DXVA2 Focused をベースにしています。 MPC-BEのインストールは他のサイトなどを参照していただいて、madVRの設定から始めます。 まずMPC-BEからレンダラとしてmadVRを設定します。 ここ

defaultuser100000。

Windows 10 May 2019 update (1903)をしたノートPCで、ふと c:\Users を見ると、 defaultuser100000 というユーザができていました。これまで通り Default というユーザは別にあります。 調べてみると、 Windows 10 Update created a default user account になにやら書いてあります。 ユーザアカウントをリネームしたときにバックアップを消すことができなかったとかそんな感じです。 そのまま削除しても問題はないようですが、ユーザアカウントがダブっていないか確認したほうがいいようなことが書いてあります。 まず、 netplwiz で自分が使用しているユーザアカウント名を確認します。また同時に他のユーザアカウントがログオンしていないかどうかも確認します。 管理者モードでコマンドプロンプトを開いて、 whoami /user を実行して SID を確認します。 regedit を起動して、 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList からユーザリストに先程の SID があるかどうかを確認します。それが自分の SID であれば問題ありません。 ProfileImagePath を確認して、ユーザプロファイルディレクトリがちゃんと設定されていること、また State の Value data が 0 であることを確認して、問題なければ特にすることはありません。 もし同じSIDのキーが2つあった場合には以下のようにします。 SID に ".bak" がついていた場合には、リネームして末尾の ".bak" を削除します。 ProfileImagePath を開いて、ユーザプロファイルディレクトリが正しいことを確認し、また State の Value data が 0 であることを確認して、問題なければ終了します。 もし ".bak" なしとありの同じSIDのキーが合った場合には以下のようにします。 ".bak" がないほうの S

.aiファイルをInkscapeで開くときの覚書。

Inkscapeで.aiファイルを開こうとしたら、開けるファイルとだめなファイルがあったので検索しました。 Inkscape edits to an SVG file, which was originally created in Adobe Illustrator, are lost when importing back into AI That's because Adobe cheats. It creates a valid SVG, but apart from the SVG code it also writes to the file, in encoded binary form, the entire AI-format source file of the image. Inkscape, of course, edits the SVG part of the image and leaves the encoded binary untouched. But when you import the SVG file back to AI, it completely disregards the SVG code with its edits and reads directly from the encoded AI binary. Therefore, any SVG changes are lost. To work around it, in Inkscape open the XML Editor and remove the non-SVG elements (everything not with the svg: prefix in its name, usually towards the end of the tree). If you need to do this job repeatedly you may consider using some XSLT-based automation. Alternatively, when exporting SVG from Illustrator, uncheck the options "Preserve Adobe Illustrato