Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

090629-Windowsで今日の予定をGoogleカレンダーから取得し表示する

090629stopwatch

 

スクリプトを実行すると、その日の予定までの残り時間が示される。「あと15分で出なきゃ」「あと30分で休憩だ」などのように使うことができる。

 

ちなみに私は、タスクマネージャを使って、このスクリプトを自動的に10分おきに走らせている。「うっかり時間超過」の多い私にとってはありがたい。

 

ポイント1は、最初に「putsjis」というメソッドを定義している点。Windowsコマンドプロンプトは<SJIS>だが、さまざまなネットサービスは断然<UTF-8>の方が使いやすい。そこで、スクリプトそのものや外部とのやりとりはすべて<UTF-8>でやり、コマンドプロンプトに出力するときだけ、「kconv」ライブラリの「tosjis」メソッドを使って<SJIS>を使っている。

 

ポイント2は、Googleカレンダーの返してきたさまざまな種類の予定から時間指定の予定だけを正規表現で取り出している点。困ったことにGoogleカレンダーは、時間も詳細も公開設定も、すべてdescriptionに入れて返してくる。仕方ないので、このdescriptionをよく見て、時間指定の予定を選び出さなければならない。

 

 

 

 

require "kconv"

$KCODE="UTF-8"

 

def putsjis(string = "")

puts(string.tosjis)

end

 

##### 時刻表示 #####

 

now = Time.now

 

# 現在時刻を表示して1秒待つ

putsjis "現在時刻:"

putsjis now.strftime("%H 時 %M 分")

putsjis

sleep 1

 

# 現在からの残り時間を整形する

class TimeLength

def initialize(time)

@seconds = time - Time.now

end

def format

 

flag = "あと "

if @seconds < 0

@seconds = -@seconds

flag = "《超過》 "

end

 

minutes = (@seconds / 60).round

hours = (minutes / 60).round

minutes = minutes % 60

 

flag + hours.to_s + " 時間 " + minutes.to_s + " 分"

end

end

 

class Event

def initialize(label, notify_hour, notify_minute, hour, minute, day_option = :today)

@label = label

@now = Time.now

if day_option == :tomorrow

@day = @now.day + 1

else

@day = @now.day

end

@notify_starttime = Time.local(@now.year, @now.month, @now.day, notify_hour, notify_minute)

@event_starttime = Time.local(@now.year, @now.month, @day, hour, minute)

end

 

def println

if @notify_starttime <= @now && @now <= @event_starttime + 60*30 # 30分後まで

tl = TimeLength.new(@event_starttime)

putsjis @label + "まで:"

putsjis tl.format

putsjis

sleep 1

end

end

end

 

##### Googleカレンダー #####

 

# 今日と明日の予定をGoogleカレンダーから取得し、表示します

# はじめにメールアドレス、パスワード、カレンダーの非公開URLを設定して下さい

 

require 'gcalapi'

 

# アカウントメールアドレス

mail = "xxxxxxxx@gmail.com"

# パスワード

pass = "xxxxxxxx"

# Googleカレンダーの「カレンダー設定」画面から取得した非公開URL

feed = "http://www.google.com/calendar/feeds/xxxxxxxxx%40gmail.com/private-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/basic"

 

# Googleカレンダーから予定を取得し、eventsに格納する

srv = GoogleCalendar::Service.new(mail, pass)

cal = GoogleCalendar::Calendar::new(srv, feed)

events = cal.events

 

# 今日の日付の文字列を作っておく

TODAY = Time.now.strftime("%Y/%m/%d")

 

putsjis "今日の予定:"

putsjis

sleep 1

 

# 各予定について・・・

events.each do |event|

title = event.title

 

# 時刻指定されている場合

if /^(\w*): (\d{4}\/\d{2}\/\d{2}) (\d{2}):(\d{2})~(\d{2}:\d{2}).*/ =~ event.desc

event_type = :time_ok

type = Regexp.last_match(1).to_s

date = Regexp.last_match(2).to_s

hour = Regexp.last_match(3).to_s

minute = Regexp.last_match(4).to_s

endtime = Regexp.last_match(4).to_s

if date == TODAY

event_tmp = Event.new(title, 0, 0, hour, minute)

event_tmp.println

end

 

# 時刻指定されていない場合

elsif /^(\w*): (\d{4}\/\d{2}\/\d{2})~(\d{4}\/\d{2}\/\d{2}).*/ =~ event.desc

event_type = :time_ng

type = Regexp.last_match(1).to_s

starttime = Regexp.last_match(2).to_s

endtime = Regexp.last_match(3).to_s

 

# 開始日のみの場合

elsif /^(\w*): (\d{4}\/\d{2}\/\d{2}).*/ =~ event.desc

event_type = :only_startdate

type = Regexp.last_match(1).to_s

starttime = Regexp.last_match(2).to_s

else

raise "unexpected format: " + event.desc

end

end

putsjis "以上"

 

sleep 2