Kirjautuminen

Haku

Tehtävät

Koodit: Ruby: Sää Ilmatieteen laitokselta

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

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta