以前、ruby-garoon2icalを利用させて頂き、会社のサイボウズガルーンとgoogleカレンダー経由でiphoneのカレンダーに表示させていたが、ruby1.9.2にアップデートしてからプログラムがエラーを吐くようになった。
エラー箇所は「csv = CSV.parse(result3.body.toutf8)」の部分で、調べると改行コードがCR+LFだとエラーになるっぽい。
仕事のスケジュールが見えないと、何かとめんどくさいのでruby1.9で動くように改修。
たぶん上手い書き方があると思うけど、とりあえず動けば良いので、一旦改行コードがCR+LF形式のCSVを出力してから改行コードを置換すると言った幼稚な書き方をしています。
icalはちゃんと作成されたっぽいので、後はgoogleカレンダーの設定をやり直して待つだけ。
ちゃんと読み込むといいなぁ。
【追記】
cronで回したら以下のようなエラーが発生。
/usr/local/lib/ruby/1.9.1/csv.rb:2027:in `=~': invalid byte sequence in US-ASCII (ArgumentError)
from /usr/local/lib/ruby/1.9.1/csv.rb:2027:in `init_separators'
from /usr/local/lib/ruby/1.9.1/csv.rb:1570:in `initialize'
from /usr/local/lib/ruby/1.9.1/csv.rb:1335:in `new'
from /usr/local/lib/ruby/1.9.1/csv.rb:1335:in `open'
from /usr/local/apache2/htdocs/garoon2-sync/garoon2ical.rb:65:in `<main>'
ruby1.9から文字コードの取り扱いが厳格になった(ruby1.8を知らんが)らしいので、実行時に文字コードを指定する。
ruby -Ku garoon2ical.rb
【追記2】
同期したら文字化けしてた。
どうやらicsを直接見に行かせると、charsetを送っていないらしい。
icsを吐くディレクトリに.htaccessを作成して
AddType “text/calendar; charset=utf-8” ics
を記載。
以下、ソース
calnameは「cybozu」
#!/bin/env ruby
require ‘rubygems’
require ‘mechanize’
require ‘csv’
require ‘icalendar’
require ‘kconv’
require ‘yaml’
require ‘nkf’
#$KCODE = ‘u’
#設定の読み込み
conf = YAML.load_file(“config.yaml”)
agent = Mechanize.new
page = agent.get conf[“cybozu_url”]
form = page.forms.first
form.field_with(:name => “_account”).value = conf[“username”]
form.field_with(:name => “_password”).value = conf[“password”]
result = form.submit
#ここまでで、ログインできてる
form =result.forms.first
#現在日付から 90日とってみよう
today = Date.today
endday = today + conf[“date_range”]
form.field_with(:name => “start_year”).value = today.year
form.field_with(:name => “start_month”).value = today.month
form.field_with(:name => “start_day”).value = “1”
form.field_with(:name => “end_year”).value = endday.year
form.field_with(:name => “end_month”).value = endday.month
form.field_with(:name => “end_day”).value = endday.day
form.field_with(:name => “charset”).value = “UTF8”
form.radiobutton_with(:name => “item_name”,:value => “0”).check
result2 = form.submit
open(conf[“calname”]+”.csv”,”w”) do |f|
f.print result2.body
end
# 改行コード変換(ruby1.9)
result3 = “”
File.open(conf[“calname”]+”.csv”, “r”) do |f|
f.each do |line|
result3 << NKF.nkf(“-w -Lu -m0”, line)
end
end
File.open(conf[“calname”]+”2.csv”, ‘w’) do |f|
f.puts result3
end
#csv = CSV.parse(result3.body.toutf8)
#CSV.foreach(conf[“calname”]+”2.csv”){|row|
# puts row.join(‘,’)
# }
csv = CSV.open(‘cybozu2.csv’, ‘r’)
# iCalオブジェクトの生成
cal = Icalendar::Calendar.new
csv.each do |sc|
cal.event do
dtstart DateTime.parse(sc[0]+” “+sc[1]), {‘TZID’ => ‘Asia/Tokyo’}
dtend DateTime.parse(sc[2]+” “+sc[3]), {‘TZID’ => ‘Asia/Tokyo’}
summary sc[5]+”(“+sc[4]+”)”
description sc[6].sub(/\n/,””)
end
end
# STANDARD コンポーネントを生成
standard_component = Icalendar::Component.new(‘STANDARD’)
standard_component.custom_property(‘dtstart’, ‘19700101T000000’)
standard_component.custom_property(‘tzoffsetfrom’, ‘+0900’)
standard_component.custom_property(‘tzoffsetto’, ‘+0900’)
standard_component.custom_property(‘tzname’, ‘JST’)
# VTIMEZONE コンポーネントを生成
vtimezone_component = Icalendar::Component.new(‘VTIMEZONE’)
vtimezone_component.custom_property(‘tzid’, ‘Asia/Tokyo’)
vtimezone_component.add(standard_component)
cal.add(vtimezone_component)
# iCalファイル生成
File.open(conf[“calname”]+”.ics”, “w+b”) { |f|
f.write(cal.to_ical.toutf8)
}