# and edited (zunda.freeshell.org does not have fileutils.rb T_T
dirstack = []
until FileTest.directory?( ddir ) do
dirstack.push( ddir )
ddir = File.dirname( ddir )
end
dirstack.reverse_each do |dir|
Dir.mkdir dir
end
# finally we can write a file
File::open( Weather::file_path( path, date ), 'a' ) do |fh|
fh.puts( to_s )
end
end
class << self
def parse( string )
new.parse( string )
end
def date_to_s( date )
date.strftime( '%Y%m%d' )
end
def file_path( path, date )
date.strftime( "#{path}/%Y/%Y%m.weather" ).gsub( /\/\/+/, '/' )
end
def restore( path, date )
r = nil
datestring = Weather::date_to_s( date )
begin
File::open( file_path( path, date ), 'r' ) do |fh|
fh.each( "\n" ) do |l|
if /^#{datestring}\t/ =~ l then
r = l # will use the last/newest data found in the file
end
end
end
rescue Errno::ENOENT
end
r ? Weather::parse( r ) : nil
end
end
end
=begin
=== Methods as a plugin
weather method also can be used as a usual plug-in in your diary body.
Please note that the argument is not a String but a Time object.
--- weather( date = nil )
Returns an HTML flagment of the weather for the date. This will be
provoked as a body_enter_proc. @date is used when ((|date|)) is
nil.
--- get_weather
Access the URL to get the current weather information when:
* @mode is append or replace,
* @date is today, and
* There is no cached data without an error for today
This will be provoked as an update_proc.
=end
Weather_default_path = "#{@cache_path}/weather"
Weather_default_items = {
# UNIX time
'conditions at' => 'timestamp',
# English phrases
'sky conditions' => 'condition',
'weather' => 'weather',
# Direction (e.g. SE)
'winddir' => 'winddir',
# English phrases when unit conversion failed, otherwise, key with (unit)
'wind(m/s)' => 'wind(m/s)',
'wind(deg)' => 'wind(deg)',
'visibility(km)' => 'visibility(km)',
'temperature(C)' => 'temperature(C)',
'windchill(C)' => 'windchill(C)',
'dewpoint(C)' => 'dewpoint(C)',
'relative humidity(%)' => 'humidity(%)',
'pressure (altimeter)(mb)' => 'pressure(hPa)',
}
# shows weather
def weather( date = nil, wrap = true )
return '' if bot? and not @options['weather.show_robot']
path = @options['weather.dir'] || Weather_default_path
w = Weather::restore( path, date || @date )
if w then
%Q|#{wrap ? '' : ' '}#{w.to_html( @options['weather.show_error'] )}#{wrap ? "
\n" : ''}|
else
''
end
end
# gets weather when the diary is updated
def get_weather
return unless @options['weather.url']
return unless @mode == 'append' or @mode == 'replace'
return unless @date.strftime( '%Y%m%d' ) == Time::now.strftime( '%Y%m%d' )
path = @options['weather.dir'] || Weather_default_path
w = Weather::restore( path, @date )
if not w or w.error then
items = @options['weather.items'] || Weather_default_items
update_weather_url( @options )
w = Weather.new( @date, @options['weather.tz'], @conf )
w.get( @options['weather.url'], @options['weather.header'] || {}, items )
if @options.has_key?( 'weather.oldest' ) then
oldest = @options['weather.oldest']
else
oldest = 21600
end
w.check_age( oldest )
w.store( path, @date )
end
end
# Update URL of weather information
#
# Around April, 2012, NOAA chnaged the URL of the current weather from
# http://weather.noaa.gov/weather/current/#{station_id}.html
# to
# http://www.aviationweather.gov/adds/metars/?station_ids=#{station_id}&std_trans=translated&chk_metars=on&hoursStr=most+recent+only
def update_weather_url( hash )
if hash['weather.url'] and match = hash['weather.url'].scan(%r[\Ahttp://weather.noaa.gov/weather/current/(\w{4,4}).html\z])[0]
hash['weather.url'] = Weather::STATION_URL_TEMPLATE % match[0]
end
end
# www configuration interface
def configure_weather
if( @mode == 'saveconf' ) then
# weather.url
station = Weather::extract_station_id( @cgi.params['weather.url'][0] )
if station
@conf['weather.url'] = Weather::STATION_URL_TEMPLATE % station
else
@conf['weather.url'] = @cgi.params['weather.url'][0]
end
# weather.tz
tz = @cgi.params['weather.tz'][0]
unless tz.empty? then # need more checks
@conf['weather.tz'] = tz
else
@conf['weather.tz'] = ''
end
%w(in_title show_mobile show_robot).each do |item|
case @cgi.params["weather.#{item}"][0]
when 'true'
@conf["weather.#{item}"] = true
when 'false'
@conf["weather.#{item}"] = false
end
end
end
update_weather_url( @conf )
weather_configure_html( @conf )
end
add_header_proc do
<<"_END"
\t
_END
end
if not feed? and not @options['weather.in_title'] then
add_body_enter_proc do |date|
weather( date )
end
end
if not feed? and @options['weather.in_title'] then
add_title_proc do |date, title|
title + weather( date, false )
end
end
add_update_proc do get_weather end
add_conf_proc( 'weather', @weather_plugin_name ) do configure_weather end
# Local Variables:
# mode: ruby
# indent-tabs-mode: t
# tab-width: 3
# ruby-indent-level: 3
# End: