# :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. time [admin] reset [nick] to let the bot forget about the tzinfo about someone"
+ 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 )
}
-
+
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 getTime( m, zone )
- rescue TZInfo::InvalidTimezoneIdentifier
- if @registry.has_key?( zone ) then
- zone = @registry[ zone ]
- m.reply 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}: #{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
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
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} timezone"
+ 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 timezone"
+ 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