]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/remind.rb
Fri Jul 29 13:07:56 BST 2005 Tom Gilbert <tom@linuxbrit.co.uk>
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / remind.rb
1 require 'rbot/utils'
2
3 class RemindPlugin < Plugin
4   # read a time in string format, turn it into "seconds from now".
5   # example formats handled are "5 minutes", "2 days", "five hours",
6   # "11:30", "15:45:11", "one day", etc.
7   #
8   # Throws:: RunTimeError "invalid time string" on parse failure
9   def timestr_offset(timestr)
10     case timestr
11       when (/^(\S+)\s+(\S+)$/)
12         mult = $1
13         unit = $2
14         if(mult =~ /^([\d.]+)$/)
15           num = $1.to_f
16           raise "invalid time string" unless num
17         else
18           case mult
19             when(/^(one|an|a)$/)
20               num = 1
21             when(/^two$/)
22               num = 2
23             when(/^three$/)
24               num = 3
25             when(/^four$/)
26               num = 4
27             when(/^five$/)
28               num = 5
29             when(/^six$/)
30               num = 6
31             when(/^seven$/)
32               num = 7
33             when(/^eight$/)
34               num = 8
35             when(/^nine$/)
36               num = 9
37             when(/^ten$/)
38               num = 10
39             when(/^fifteen$/)
40               num = 15
41             when(/^twenty$/)
42               num = 20
43             when(/^thirty$/)
44               num = 30
45             when(/^sixty$/)
46               num = 60
47             else
48               raise "invalid time string"
49           end
50         end
51         case unit
52           when (/^(s|sec(ond)?s?)$/)
53             return num
54           when (/^(m|min(ute)?s?)$/)
55             return num * 60
56           when (/^(h|h(ou)?rs?)$/)
57             return num * 60 * 60
58           when (/^(d|days?)$/)
59             return num * 60 * 60 * 24
60           else
61             raise "invalid time string"
62         end
63       when (/^(\d+):(\d+):(\d+)$/)
64         hour = $1.to_i
65         min = $2.to_i
66         sec = $3.to_i
67         now = Time.now
68         later = Time.mktime(now.year, now.month, now.day, hour, min, sec)
69         return later - now
70       when (/^(\d+):(\d+)$/)
71         hour = $1.to_i
72         min = $2.to_i
73         now = Time.now
74         later = Time.mktime(now.year, now.month, now.day, hour, min, now.sec)
75         return later - now
76       when (/^(\d+):(\d+)(am|pm)$/)
77         hour = $1.to_i
78         min = $2.to_i
79         ampm = $3
80         if ampm == "pm"
81           hour += 12
82         end
83         now = Time.now
84         later = Time.mktime(now.year, now.month, now.day, hour, min, now.sec)
85         return later - now
86       when (/^(\S+)$/)
87         num = 1
88         unit = $1
89         case unit
90           when (/^(s|sec(ond)?s?)$/)
91             return num
92           when (/^(m|min(ute)?s?)$/)
93             return num * 60
94           when (/^(h|h(ou)?rs?)$/)
95             return num * 60 * 60
96           when (/^(d|days?)$/)
97             return num * 60 * 60 * 24
98           else
99             raise "invalid time string"
100         end
101       else
102         raise "invalid time string"
103     end
104   end
105
106   def initialize
107     super
108     @reminders = Hash.new
109   end
110   def cleanup
111     @reminders.each_value {|v|
112       v.each_value {|vv|
113         @bot.timer.remove(vv)
114       }
115     }
116     @reminders.clear
117   end
118   def help(plugin, topic="")
119     "reminder plugin: remind <who> [about] <message> in <time>, remind <who> [about] <message> every <time>, remind <who> [about] <message> at <time>, remind <who> no more [about] <message>, remind <who> no more. Generally <who> should be 'me', but you can remind others (nick or channel) if you have remind_others auth"
120   end
121   def add_reminder(who, subject, timestr, repeat=false)
122     begin
123       period = timestr_offset(timestr)
124     rescue RuntimeError
125       return "couldn't parse that time string (#{timestr}) :("
126     end
127     if(period <= 0)
128       return "that time is in the past! (#{timestr})"
129     end
130     if(period < 30 && repeat)
131       return "repeats of less than 30 seconds are forbidden"
132     end
133     if(!@reminders.has_key?(who))
134       @reminders[who] = Hash.new
135     elsif(@reminders[who].has_key?(subject))
136       del_reminder(who, subject)
137     end
138
139     if(repeat)
140       @reminders[who][subject] = @bot.timer.add(period) {
141         time = Time.now + period
142         tstr = time.strftime("%H:%M:%S")
143         @bot.say who, "repeat reminder (next at #{tstr}): #{subject}"
144       }
145     else
146       @reminders[who][subject] = @bot.timer.add_once(period) {
147         time = Time.now + period
148         tstr = time.strftime("%H:%M:%S")
149         @bot.say who, "reminder (#{tstr}): #{subject}"
150       }
151     end
152     return false
153   end
154   def del_reminder(who, subject=nil)
155     if(subject)
156       if(@reminders.has_key?(who) && @reminders[who].has_key?(subject))
157         @bot.timer.remove(@reminders[who][subject])
158         @reminders[who].delete(subject)
159         return true
160       else
161         return false
162       end
163     else
164       if(@reminders.has_key?(who))
165         @reminders[who].each_value {|v|
166           @bot.timer.remove(v)
167         }
168         @reminders.delete(who)
169         return true
170       else
171         return false
172       end
173     end
174   end
175   def remind(m, params)
176     who = params.has_key?(:who) ? params[:who] : m.sourcenick
177     string = params[:string].to_s
178     puts "in remind, string is: #{string}"
179     if(string =~ /^(.*)\s+in\s+(.*)$/)
180       subject = $1
181       period = $2
182       if(err = add_reminder(who, subject, period))
183         m.reply "incorrect usage: " + err
184         return
185       end
186     elsif(string =~ /^(.*)\s+every\s+(.*)$/)
187       subject = $1
188       period = $2
189       if(err = add_reminder(who, subject, period, true))
190         m.reply "incorrect usage: " + err
191         return
192       end
193     elsif(string =~ /^(.*)\s+at\s+(.*)$/)
194       subject = $1
195       time = $2
196       if(err = add_reminder(who, subject, time))
197         m.reply "incorrect usage: " + err
198         return
199       end
200     else
201       usage(m)
202       return
203     end
204     m.okay
205   end
206   def no_more(m, params)
207     who = params.has_key?(:who) ? params[:who] : m.sourcenick
208     deleted = params.has_key?(:string) ? 
209               del_reminder(who, params[:string].to_s) : del_reminder(who)
210     if deleted
211       m.okay
212     else 
213       m.reply "but I wasn't going to :/"
214     end
215   end
216 end
217 plugin = RemindPlugin.new
218 plugin.map 'remind me no more', :action => 'no_more'
219 plugin.map 'remind me no more about *string', :action => 'no_more'
220 plugin.map 'remind me no more *string', :action => 'no_more'
221 plugin.map 'remind me about *string'
222 plugin.map 'remind me *string'
223 plugin.map 'remind :who no more', :auth => 'remind_other', :action => 'no_more'
224 plugin.map 'remind :who no more about *string', :auth => 'remind_other', :action => 'no_more'
225 plugin.map 'remind :who no more *string', :auth => 'remind_other', :action => 'no_more'
226 plugin.map 'remind :who about *string', :auth => 'remind_other'
227 plugin.map 'remind :who *string', :auth => 'remind_other'
228