-# Time Zone Plugin for rbot
-# (c) 2006 Ian Monroe <ian@monroe.nu>
-# Licensed under MIT License.
+#-- vim:sw=2:et
+#++
+#
+# :title: Time Zone Plugin for rbot
+#
+# Author:: Ian Monroe <ian@monroe.nu>
+# Author:: Raine Virta <raine.virta@gmail.com>
+# Copyright:: (C) 2006 Ian Monroe
+# Copyright:: (C) 2010 Raine Virta
+# License:: MIT license
require 'tzinfo'
class TimePlugin < Plugin
-
def help(plugin, topic="")
- "time <time zone> to get the local time of a certain location. <time zone> can be <Continent/City> or <two character country code>. time <nick> to see the local time of that person if their time zone is set. time admin set <nick> <time zone> to set the time zone for another user."
+ case topic
+ when "set"
+ _("usage: time set <Continent>/<City> -- setting your location allows the bot to calibrate time replies into your time zone, and other people to figure out what time it is for you")
+ else
+ _("usage: time <timestamp|time zone|nick> -- %{b}timestamp%{b}: get info about a specific time, relative to your own time zone | %{b}time zone%{b}: get local time of a certain location, <time zone> can be '<Continent>/<City>' or a two character country code | %{b}nick%{b}: get local time of another person, given they have set their location | see `%{prefix}help time set` on how to set your location") % {
+ :b => Bold,
+ :prefix => @bot.config['core.address_prefix'].first
+ }
+ end
end
def initialize
end
['/', '_'].each { |sp|
arr = Array.new
- zone.split(sp).each{ |s|
+ zone.split(sp).each{ |s|
s[0] = s[0,1].upcase
s[1, s.length] = s[1, s.length].downcase if sp == '/'
arr.push(s) }
zone = arr.join( sp )
}
-
- TZInfo::Timezone.get( zone ).now
+
+ tz = TZInfo::Timezone.get( zone )
+ "#{tz.friendly_identifier} - #{tz.now.strftime( '%a %b %d %H:%M' )} #{tz.current_period.abbreviation}"
end
def showTime(m, params)
- zone = params[:where].join('_')
- if params[:where].size > 0 then
- begin
- m.reply "#{zone} - #{getTime( m, zone )}"
- rescue TZInfo::InvalidTimezoneIdentifier
- if @registry.has_key?( zone ) then
- zone = @registry[ zone ]
- m.reply "#{zone} - #{getTime( m, zone )}"
- else
- m.reply "#{zone} is an unknown time."
- end
- end
+ nick = nil
+ zone = nil
+ speaker = false
+ case params[:where].size
+ when 0
+ nick = m.sourcenick
+ speaker = true
+ when 1
+ zone = params[:where].first
+ nick = m.channel.get_user(zone)
+ speaker = (nick == m.sourcenick)
else
- if @registry.has_key?( m.sourcenick) then
- zone = @registry[ m.sourcenick ]
- m.reply "#{m.sourcenick}: #{zone} - #{getTime( m, zone )}"
+ zone = params[:where].join('_')
+ end
+
+ # now we have a non-nil nick iff we want user information
+ if nick
+ if @registry.has_key? nick
+ zone = @registry[nick]
else
- m.reply "#{m.sourcenick}: use time set <Continent/City> to set your timezone."
+ if speaker
+ msg = _("I don't know where you are, use %{pfx}time set <Continent>/<City> to let me know")
+ else
+ msg = _("I don't know where %{nick} is, (s)he should use %{pfx}time set <Continent>/<City> to let me know")
+ end
+ m.reply(msg % { :pfx => @bot.config['core.address_prefix'].first, :nick => nick })
+ return false
end
end
+
+ begin
+ m.reply getTime( m, zone )
+ rescue TZInfo::InvalidTimezoneIdentifier
+ parse(m, params)
+ end
end
def setUserZone( m, params )
if params[:where].size > 0 then
s = setZone( m, m.sourcenick, params[:where].join('_') )
else
- m.reply "Requires Continent/City or country code"
+ m.reply "Requires <Continent>/<City> or country code"
end
end
+ def resetUserZone( m, params )
+ s = resetZone( m, m.sourcenick)
+ end
+
def setAdminZone( m, params )
if params[:who] and params[:where].size > 0 then
s = setZone( m, params[:who], params[:where].join('_') )
else
- m.reply 'Requires a nick and the Continent/City or country code.'
+ m.reply "Requires a nick and the <Continent>/<City> or country code"
+ end
+ end
+
+ def resetAdminZone( m, params )
+ if params[:who]
+ s = resetZone( m, params[:who])
+ else
+ m.reply "Requires a nick"
end
end
begin
getTime( m, zone )
rescue TZInfo::InvalidTimezoneIdentifier
- m.reply "#{zone} is an invalid timezone. Format is Continent/City or a two character country code."
+ m.reply "#{zone} is an invalid time zone. Format is <Continent>/<City> or a two character country code."
return
end
@registry[ user ] = zone
+ m.reply "Ok, I'll remember that #{user} is on the #{zone} time zone"
+ end
+
+ def resetZone( m, user )
+ @registry.delete(user)
+ m.reply "Ok, I've forgotten #{user}'s time zone"
+ end
+
+ def parse(m, params)
+ require 'time'
+ str = params[:where].to_s
+ now = Time.now
+
+ begin
+ time = begin
+ if zone = @registry[m.sourcenick]
+ on_timezone(zone) {
+ Time.parse str
+ }
+ else
+ Time.parse str
+ end
+ rescue ArgumentError => e
+ # Handle 28/9/1978, which is a valid date representation at least in Italy
+ if e.message == 'argument out of range'
+ str.tr!('/', '-')
+ Time.parse str
+ else
+ raise
+ end
+ end
+
+ offset = (time - now).abs
+ raise if offset < 0.1
+ rescue => e
+ if str.match(/^\d+$/)
+ time = Time.at(str.to_i)
+ else
+ m.reply _("unintelligible time")
+ return
+ end
+ end
+
+ if zone = @registry[m.sourcenick]
+ time = time.convert_zone(zone)
+ end
+
+ m.reply _("%{time} %{w} %{str}") % {
+ :time => time.strftime(_("%a, %d %b %Y %H:%M:%S %Z %z")),
+ :str => Utils.timeago(time),
+ :w => time >= now ? _("is") : _("was")
+ }
+ end
+
+ def on_timezone(to_zone)
+ original_zone = ENV["TZ"]
+ ENV["TZ"] = to_zone
+ ret = yield
+ ENV["TZ"] = original_zone
+ return ret
+ end
+end
+
+class ::Time
+ def convert_zone(to_zone)
+ original_zone = ENV["TZ"]
+ utc_time = dup.gmtime
+ ENV["TZ"] = to_zone
+ to_zone_time = utc_time.localtime
+ ENV["TZ"] = original_zone
+ return to_zone_time
end
end
plugin = TimePlugin.new
-plugin.map 'time set *where', :action=> 'setUserZone', :defaults => {:where => false}
-plugin.map 'time admin set :who *where', :action=> 'setAdminZone', :defaults => {:where => false, :who=>false}, :auth=> 'timeadmin'
+
+plugin.default_auth('admin', false)
+
+plugin.map 'time set [time][zone] [to] *where', :action=> 'setUserZone', :defaults => {:where => false}
+plugin.map 'time reset [time][zone]', :action=> 'resetUserZone'
+plugin.map 'time admin set [time][zone] [for] :who [to] *where', :action=> 'setAdminZone', :defaults => {:who => false, :where => false}
+plugin.map 'time admin reset [time][zone] [for] :who', :action=> 'resetAdminZone', :defaults => {:who => false}
plugin.map 'time *where', :action => 'showTime', :defaults => {:where => false}