例えば、ターミナルでruby weather.rb
を実行すると、こんな感じで表示してくれます。
やっていること
- Livedoorが提供しているお天気WebサービスのAPIに6桁からなるCity IDを渡し、
- 返ってきたJSONをパースし、
- その結果をTerminal-notifierに渡す
通知センターで何かしたい時に、Rubyで気軽にさくさくっと書けるあたりが面白いね。
ソースコード
weather.rb
#
# 天気予報をOSXの通知センターで表示するサンプルプログラム
#
require 'json'
require 'open-uri'
require 'terminal-notifier'
def notify_weather
# location_idについては、以下を参照のこと
# http://weather.livedoor.com/forecast/rss/primary_area.xml
location_id = '012010'
idx = 0
json_url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=#{location_id}"
weather_url = "http://weather.livedoor.com/area/forecast/#{location_id}"
begin
received_body = open(json_url).read
json = JSON.parse(received_body)
rescue => e
p e.message
return false
end
json_title = json['title']
json_expected_condition = json['forecasts'][idx]['telop']
json_celsius_max = json['forecasts'][idx]['temperature']['max'] ? json['forecasts'][idx]['temperature']['max']['celsius'] : "不明"
json_celsius_min = json['forecasts'][idx]['temperature']['min'] ? json['forecasts'][idx]['temperature']['min']['celsius'] : "不明"
title_message = json_title
body_message = "#{json_expected_condition} (#{json_celsius_max} / #{json_celsius_min})"
TerminalNotifier.notify(body_message, {
:title => title_message,
:open => weather_url
}
)
end
notify_weather
例えば、これをlaunchd(8)の使い方を参考にしながら登録してやれば、1時間に1回とか天気が自動で通知されるっていう仕組みを作ることができる。
但し、あんまり実行しすぎないようにね。
追記(2014/7/10)
はてブにて、
kjw_junichi
これ、Mavericksだと、アイコン表示を天気の奴用意すれば、さらに面白そうだなぁ
こんな感じですよね。
- お天気Webサービスで取得できるJSONには、お天気アイコンのURLが埋め込まれていた
- terminal-notifier.notifyの実装では、TerminalNotifier.executeにまんまオプション引き渡しているっぽい
terminal-notifier.rb
def notify(message, options = {}, verbose = false)
TerminalNotifier.execute(verbose, options.merge(:message => message))
$?.success?
end
- 実体のソースを見てみれば、それっぽい記述もあった
terminal-notifier/AppDelgate.m
// Mavericks options
if(options[@"appIcon"]){
// replacement app icon
[userNotification setValue:[self getImageFromURL:options[@"appIcon"]] forKey:@"_identityImage"];
[userNotification setValue:@(true) forKey:@"_identityImageHasBorder"];
}
こりゃ行けそうだと、早速実装してみました。(実行にはOSX Mavericks以上の環境が必要)
weather_2.rb
#
# 天気予報をOSXの通知センターで表示するサンプルプログラム
# アイコンも表示できるぜ!版
#
require 'json'
require 'open-uri'
require 'terminal-notifier'
def notify_weather
# location_idについては、以下を参照のこと
# http://weather.livedoor.com/forecast/rss/primary_area.xml
location_id = '012010'
idx = 1 # 0: 今日の天気、1: 明日の天気、2: あさっての天気
json_url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=#{location_id}"
weather_url = "http://weather.livedoor.com/area/forecast/#{location_id}"
weather_icon_path = "/tmp/weather_icon.gif"
begin
received_body = open(json_url).read
json = JSON.parse(received_body)
rescue => e
p e.message
return false
end
json_title = json['title']
json_expected_condition = json['forecasts'][idx]['telop']
json_celsius_max = json['forecasts'][idx]['temperature']['max'] ? json['forecasts'][idx]['temperature']['max']['celsius'] : "不明"
json_celsius_min = json['forecasts'][idx]['temperature']['min'] ? json['forecasts'][idx]['temperature']['min']['celsius'] : "不明"
json_imageurl = json['forecasts'][idx]['image']['url']
title_message = json_title
body_message = "#{json_expected_condition} (#{json_celsius_max} / #{json_celsius_min})"
# 天気画像のダウンロード
begin
open(weather_icon_path, 'wb') do |weather_icon|
open(json_imageurl) do |data|
weather_icon.write(data.read)
end
end
rescue => e
p e.message
return false
end
TerminalNotifier.notify(body_message, {
:title => title_message,
:open => weather_url,
:appIcon => weather_icon_path,
}
)
end
notify_weather
コメントありがとうございました。おかげさまでまた一つ勉強になりました!