4 # :title: Time Zone Plugin for rbot
6 # Author:: Ian Monroe <ian@monroe.nu>
7 # Author:: Raine Virta <raine.virta@gmail.com>
8 # Copyright:: (C) 2006 Ian Monroe
9 # Copyright:: (C) 2010 Raine Virta
10 # License:: MIT license
14 class TimePlugin < Plugin
15 def help(plugin, topic="")
18 _("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")
20 _("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") % {
22 :prefix => @bot.config['core.address_prefix'].first
29 # this plugin only wants to store strings
41 if zone.length == 2 then #country code
43 zone = 'GB' if zone == 'UK' #country doesn't know its own name
45 nationZones = TZInfo::Country.get(zone).zone_identifiers
46 if nationZones.size == 1 then
49 m.reply "#{zone} has the cities of #{nationZones.join( ', ' )}."
51 rescue TZInfo::InvalidCountryCode
52 m.reply "#{zone} is not a valid country code."
55 ['/', '_'].each { |sp|
57 zone.split(sp).each{ |s|
59 s[1, s.length] = s[1, s.length].downcase if sp == '/'
64 tz = TZInfo::Timezone.get( zone )
65 "#{tz.friendly_identifier} - #{tz.now.strftime( '%a %b %d %H:%M' )} #{tz.current_period.abbreviation}"
68 def showTime(m, params)
72 case params[:where].size
77 zone = params[:where].first
78 nick = m.channel.get_user(zone)
79 speaker = (nick == m.sourcenick)
81 zone = params[:where].join('_')
84 # now we have a non-nil nick iff we want user information
86 if @registry.has_key? nick
87 zone = @registry[nick]
90 msg = _("I don't know where you are, use %{pfx}time set <Continent>/<City> to let me know")
92 msg = _("I don't know where %{nick} is, (s)he should use %{pfx}time set <Continent>/<City> to let me know")
94 m.reply(msg % { :pfx => @bot.config['core.address_prefix'].first, :nick => nick })
100 m.reply getTime( m, zone )
101 rescue TZInfo::InvalidTimezoneIdentifier
106 def setUserZone( m, params )
107 if params[:where].size > 0 then
108 s = setZone( m, m.sourcenick, params[:where].join('_') )
110 m.reply "Requires <Continent>/<City> or country code"
114 def resetUserZone( m, params )
115 s = resetZone( m, m.sourcenick)
118 def setAdminZone( m, params )
119 if params[:who] and params[:where].size > 0 then
120 s = setZone( m, params[:who], params[:where].join('_') )
122 m.reply "Requires a nick and the <Continent>/<City> or country code"
126 def resetAdminZone( m, params )
128 s = resetZone( m, params[:who])
130 m.reply "Requires a nick"
134 def setZone( m, user, zone )
137 rescue TZInfo::InvalidTimezoneIdentifier
138 m.reply "#{zone} is an invalid time zone. Format is <Continent>/<City> or a two character country code."
141 @registry[ user ] = zone
142 m.reply "Ok, I'll remember that #{user} is on the #{zone} time zone"
145 def resetZone( m, user )
146 @registry.delete(user)
147 m.reply "Ok, I've forgotten #{user}'s time zone"
152 str = params[:where].to_s
157 if zone = @registry[m.sourcenick]
164 rescue ArgumentError => e
165 # Handle 28/9/1978, which is a valid date representation at least in Italy
166 if e.message == 'argument out of range'
174 offset = (time - now).abs
175 raise if offset < 0.1
177 if str.match(/^\d+$/)
178 time = Time.at(str.to_i)
180 m.reply _("unintelligible time")
185 if zone = @registry[m.sourcenick]
186 time = time.convert_zone(zone)
189 m.reply _("%{time} %{w} %{str}") % {
190 :time => time.strftime(_("%a, %d %b %Y %H:%M:%S %Z %z")),
191 :str => Utils.timeago(time),
192 :w => time >= now ? _("is") : _("was")
196 def on_timezone(to_zone)
197 original_zone = ENV["TZ"]
200 ENV["TZ"] = original_zone
206 def convert_zone(to_zone)
207 original_zone = ENV["TZ"]
208 utc_time = dup.gmtime
210 to_zone_time = utc_time.localtime
211 ENV["TZ"] = original_zone
216 plugin = TimePlugin.new
218 plugin.default_auth('admin', false)
220 plugin.map 'time set [time][zone] [to] *where', :action=> 'setUserZone', :defaults => {:where => false}
221 plugin.map 'time reset [time][zone]', :action=> 'resetUserZone'
222 plugin.map 'time admin set [time][zone] [for] :who [to] *where', :action=> 'setAdminZone', :defaults => {:who => false, :where => false}
223 plugin.map 'time admin reset [time][zone] [for] :who', :action=> 'resetAdminZone', :defaults => {:who => false}
224 plugin.map 'time *where', :action => 'showTime', :defaults => {:where => false}