Created
August 18, 2010 04:57
-
-
Save shenqi/533487 to your computer and use it in GitHub Desktop.
fetch livedoor weather and growl it!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby -Ku | |
require 'net/http' | |
require 'rubygems' | |
require 'rmagick' | |
include Magick | |
class Kakumaru | |
def initialize(iconurl) | |
@image = Magick::Image.read(iconurl.to_s.sub(/(.*\..*)\?.*/) {$1}).first | |
@size = @image.columns < @image.rows ? @image.columns : @image.rows #短い方のピクセル数を代入 | |
@magsize = @size > 75 ? @size : @size * (75.div(@size) + 1) #75未満の場合拡大するサイズを指定 | |
@fill_in_color = 'white' | |
end | |
def resize(x = 0, y = 0) | |
#ToDo: crop時の設定をもっと詰める。わざわざcropを使っているので。 | |
image = @image.border(x, y, @fill_in_color).crop(CenterGravity,@size,@size) | |
image.resize!(@magsize,@magsize,filter=LanczosFilter) unless @size == @magsize | |
return image | |
end | |
def shori(image) | |
image.alpha = ActivateAlphaChannel | |
bg = Magick::Image.new(@magsize, @magsize) {self.background_color = 'none'} | |
tn = (@magsize * 0.07).round | |
Magick::Draw.new {self.fill = 'white'}.roundrectangle(0,0,@magsize,@magsize,tn,tn).draw(bg) | |
image.composite!(bg, 0, 0, CopyOpacityCompositeOp) | |
return image | |
end | |
def convert(iconsize = nil, x = 0, y = 0) | |
image = resize(x, y) | |
if iconsize then | |
return shori(image).resize(iconsize, iconsize, filter=LanczosFilter) | |
else | |
return shori(image) | |
end | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby -Ku | |
require 'net/http' | |
require 'open-uri' | |
require 'tempfile' | |
require File.dirname(__FILE__) + '/seikei.rb' | |
require 'rubygems' | |
require 'meow' | |
require 'nokogiri' | |
#notify forecast for livedoor | |
#notify current status for bbc | |
urls = ['http://weather.livedoor.com/area/34/90.html', 'http://news.bbc.co.uk/weather/forecast/2199'] | |
def growl(title, message, icon, url) | |
growl = Meow.new("天気予報") | |
opt = { :icon => icon , :sticky => 'true'} | |
growl.notify(title, message.chomp, opt) do | |
system("open '#{url}'") | |
end | |
end | |
def gicon(iconurl) | |
temp = Tempfile::new('growlicon', '/tmp') | |
image = Kakumaru.new(iconurl).convert | |
image.write('png:' + temp.path) | |
temp.close | |
icon = Meow.import_image(temp.path) | |
temp.close(true) #closeしてtempfileを消す | |
return icon | |
end | |
def fetch_livedoor(url) | |
page = Nokogiri::HTML(open(url)) | |
results = [] | |
probs = [] | |
for n in 1..4 | |
probs << [page.xpath('//table[@class="normal"][1]/tr[1]/td')[n].text, page.xpath('//table[@class="normal"][1]/tr[2]/td')[n-1].text] | |
end | |
for n in 1..4 | |
probs << [page.xpath('//table[@class="normal"][2]/tr[1]/td')[n].text, page.xpath('//table[@class="normal"][2]/tr[2]/td')[n-1].text] | |
end | |
prob = probs.delete_if{|prob| prob[1] == '---'}.collect{|prob| prob.join('時: ')} | |
gaiyo = page.xpath('//div[@class="telopbox-etc"]/p').text | |
for t in 1..2 | |
if t == 1 then | |
location = page.xpath('//li[@class="bdno on"]').text | |
location = page.xpath('//div[@class="title-outer"][1]/h2').text.sub(/.*\ (.*)の天気/) { $1 } if location.empty? | |
title = location + ': ' + page.xpath('//table[@class="normal"][1]//img/@alt').to_s | |
else | |
title = '明日の天気: ' + page.xpath('//table[@class="normal"][2]//img/@alt').to_s | |
end | |
kaze = page.xpath("//table[@class=\"normal\"][#{t}]/tr[3]/td").text | |
max = page.xpath("//table[@class=\"normal\"][#{t}]//span[@class=\"maxtemp\"]") | |
maxtemp = max[1].text + ' ' + max[3].text if max[3] | |
min = page.xpath("//table[@class=\"normal\"][#{t}]//span[@class=\"mintemp\"]") | |
mintemp = min[1].text + ' ' + min[3].text if min[3] | |
iconurl = page.xpath("//table[@class=\"normal\"][#{t}]//img/@src").to_s | |
if t == 1 then | |
message = "降水確率 - #{prob[0]}\n" | |
else | |
message = '' | |
end | |
message << "最高気温 - #{maxtemp}\n" if max[3] | |
message << "最低気温 - #{mintemp}\n" if min[3] | |
if t == 2 then | |
message << "\n降水確率\n" | |
n = prob.map{|item| item.split('').length}.sort.last | |
prob.length.times do |i| | |
message << (prob[i].ljust(n) + "\n") #rjustにしたいがなぜかgrowl時にずれる… | |
end | |
message << "\n" | |
end | |
message << "風 - #{kaze}\n" | |
message << "\n#{gaiyo}" if t == 1 | |
results << [title, message, gicon(iconurl)] | |
end | |
return results | |
end | |
def fetch_bbc(url) | |
page = Nokogiri::HTML(Net::HTTP.get(URI(url))) | |
location = page.xpath('//h2[@id="Forecast"]').text.split(',').first | |
current = page.xpath('//div[@id="ob_V_node"]') | |
iconurl = current.xpath('.//img/@src').to_s | |
weather = current.xpath('.//img/@alt').to_s | |
title = location + ': ' + weather | |
temp = 'Temperature: ' + current.xpath('.//li[@class="obstemp"]/span[3]/span[@class="cent"]').text + "\n" | |
kaze = 'Wind: ' + current.xpath('.//span[@title="SW"]/span[@class="blq-hide"]').text + ' ' + current.xpath('.//span[@title="SW"]/span[@class="kph hide"]').text + "\n" | |
extra = current.xpath('.//ul[@class="humpresvis"]').text.delete("\t") | |
message = temp + kaze + extra | |
icon = gicon(iconurl) | |
results = [] | |
results << [title, message, icon] | |
return results | |
end | |
def notify(urls) | |
urls.each do |url| | |
results = fetch_livedoor(url) if url =~ /weather\.livedoor\.com/ | |
results = fetch_bbc(url) if url =~ /bbc\.co\.uk/ | |
results.each do |result| | |
growl(result[0], result[1], result[2], url) | |
end | |
end | |
end | |
notify(urls) |
全体的に綺麗にした。
bbcのcurrent statusをfetchするようにした。天気予報は…お察しください
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
todo: 別ファイルにしただけなのでseikei.rbをもっと自動化する