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