Kirjoittaja: Blaze
Kirjoitettu: 28.04.2008 – 28.04.2008
Tagit: teksti, koodi näytille, vinkki
Tämä Ruby-skripti hakee paikallissään Ilmatieteen laitokselta osoitteesta fmi.fi. Haetusta HTML:stä napsitaan säännöllisillä lausekkeilla kiinnostavat osat.
Mallitulostus:
blaze@sakura ~ $ fmiweather.rb Kokkola Kokkola Hollihaka Kokkola Hollihaka, Tuorein havainto: 28.04.2008 00:00 lämpötila 8.3 °C, paine 1014.6 hPa, kosteus 90%, tunnin sadekertymä 0 mm Aurinko nousee 5:08 ja laskee 21:40. Päivän pituus on 16 h 33 min.
Vaatii htmlentities-kirjaston
Lisensoitu EVVKTVH-lisenssillä
#!/usr/bin/ruby
###############################################################################
#
# fmiweather.rb 2.0 - fetch weather data from fmi.fi (or an excercise in
# regular expressions >_>)
#
# Copyright © Karri "Blaze" Kahelin 2007, 2008
#
# Licenced under the ICCLEIYSIYUA (http://www.evvk.com/evvktvh.html)
# Requires the htmlentities library, available at
# http://htmlentities.rubyforge.org/
#
# Hakee paikallissään Ilmatieteen laitokselta osoitteesta fmi.fi
# Lisensoitu EVVKTVH-lisenssillä (http://www.evvk.com/evvktvh.html)
# Vaatii htmlentities-kirjaston, joka on saatavilla osoitteesta
# http://htmlentities.rubyforge.org/
#
###############################################################################
require 'net/http'
require 'htmlentities'
$debug = false
# gets page using HTTP
def get_page(municip, *station)
uri = "http://www.fmi.fi/saa/paikalli.html?kunta=#{municip}"
uri += "&station=#{station[0]}" if !station.empty?
puts("Getting URI #{uri}") if $debug
Net::HTTP.get(URI.parse(uri))
end
# parses & prints list of all available municipalities
def print_municipalities
puts("Listing all available municipalities") if $debug
page = get_page('')
page.scan(/\<OPTION\ VALUE="(.*?)".*?>\1<\/OPTION>/m).flatten.each {
|a| puts a
}
end
# parses & prints list of all available stations in an municipality
def print_stations(municip)
puts("Listing available stations in #{municip}") if $debug
page = get_page(municip)
arr = page.scan(/\<OPTION\ VALUE="\d*".*?>(.*?)<\/OPTION>/m).flatten
if arr.empty?
# this municipality only has one station, which is, of course,
# marked up differently -_-
arr = [page[/Havaintoasema.*<b>(.*?)<\/b>/, 1]]
end
arr.each { |a| puts a }
end
# parses & prints weather data
def print_weather(municip)
puts("Municipality #{municip}") if $debug
page = get_page(municip)
# did user give station?
if ARGV[1] != nil
# station names contain spaces. join rest of the args to one,
# so user doesn't have to enclose them to quotation marks
arg = ARGV[1..ARGV.length].join(' ')
puts("Station #{arg}") if $debug
# check there actually are multiple stations
if page =~ /SELECT\ NAME="station"/
# get numerical station ID
snum = page[/station.*VALUE="(.*?)"(.*?)>#{arg\
}<\/OPTION>/m, 1]
puts "Determined to have ID #{snum}" if $debug
# fetch new page using the specified station
# TODO: don't fetch the page again, if user asked for
# the default station
page = get_page(municip, snum)
end
end
# get the data from HTML
station = page[/station.*?SELECTED.>(.*?)<\/OPTION>.*?<\/SELECT>/m, 1]
if station == municip
# only one station exists for the municipality. this needs to
# be handled differently
station = page[/Havaintoasema.*<b>(.*?)<\/b>/, 1]
end
sundata = page[/Aurinko.*/]
wdata = page[/Tuorein.*/]
all = station + ', ' + wdata + "\n" + sundata
# sanitize data for console output
[['<br />', "\n"], [/<.*?>/, '']].each { |a| all.gsub! a[0], a[1] }
all = HTMLEntities.new(:html4).decode(all)
puts all
end
# prints usage instructions
def print_help()
puts 'Syntax:'
puts 'fmiweather.rb [-lm|-ls] [municipality [station]]'
puts "\t-lm\tlist municipalities"
puts "\t-ls\tlist stations in a municipality"
end
# end of function definitions
if ARGV[0] == '-lm'
print_municipalities
elsif ARGV[0] == '-ls'
ARGV[1] ? print_stations(ARGV[1]) : print_help
else
ARGV[0] ? print_weather(ARGV[0]) : print_help
end