]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/remind.rb
plugin(oxford): moved to lexico.com, closes #13
[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     Utils.parse_time_offset(timestr)
9   end
10
11   class UnparsedPeriodError < RuntimeError ; end
12   class NegativePeriodError < RuntimeError ; end
13   class ShortRepeatError < RuntimeError ; end
14
15   def initialize
16     super
17     @reminders = Hash.new
18   end
19   def cleanup
20     @reminders.each_value {|v|
21       v.each_value {|vv|
22         @bot.timer.remove(vv)
23       }
24     }
25     @reminders.clear
26     super
27   end
28   def help(plugin, topic="")
29     "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"
30   end
31   def add_reminder(m, who, subject, timestr, repeat=false)
32     begin
33       period = timestr_offset(timestr)
34     rescue RuntimeError
35       raise UnparsedPeriodError
36     end
37     raise NegativePeriodError if period <= 0
38     raise ShortRepeatError if period < 30 && repeat
39
40     if(period <= 0)
41       return "that time is in the past! (#{timestr})"
42     end
43     if(period < 30 && repeat)
44       return
45     end
46     if(!@reminders.has_key?(who))
47       @reminders[who] = Hash.new
48     elsif(@reminders[who].has_key?(subject))
49       del_reminder(who, subject)
50     end
51
52     if(repeat)
53       @reminders[who][subject] = @bot.timer.add(period) {
54         tstr = (Time.now + period).strftime("%H:%M:%S")
55         @bot.say who, "repeat reminder (next at #{tstr}): #{subject}"
56       }
57     else
58       @reminders[who][subject] = @bot.timer.add_once(period) {
59         tstr = Time.now.strftime("%H:%M:%S")
60         @bot.say who, "reminder (#{tstr}): #{subject}"
61       }
62     end
63
64     m.okay
65   end
66
67   def del_reminder(who, subject=nil)
68     if(subject)
69       if(@reminders.has_key?(who) && @reminders[who].has_key?(subject))
70         @bot.timer.remove(@reminders[who][subject])
71         @reminders[who].delete(subject)
72         return true
73       else
74         return false
75       end
76     else
77       if(@reminders.has_key?(who))
78         @reminders[who].each_value {|v|
79           @bot.timer.remove(v)
80         }
81         @reminders.delete(who)
82         return true
83       else
84         return false
85       end
86     end
87   end
88   def remind(m, params)
89     who = params.has_key?(:who) ? params[:who] : m.sourcenick
90     string = params[:string].to_s
91     debug "in remind, string is: #{string}"
92     tried = []
93
94     begin
95       if !tried.include?(:in) and string =~ /^(.*)\s+in\s+(.*)$/
96         subject = $1
97         period = $2
98         tried << :in
99         add_reminder(m, who, subject, period)
100         return true
101       end
102
103       if !tried.include?(:every) and string =~ /^(.*)\s+every\s+(.*)$/
104         subject = $1
105         period = $2
106         tried << :every
107         add_reminder(m, who, subject, period, true)
108         return true
109       end
110
111       if !tried.include?(:at) and string =~ /^(.*)\s+at\s+(.*)$/
112         subject = $1
113         time = $2
114         tried << :at
115         add_reminder(m, who, subject, time)
116         return true
117       end
118
119       usage(m)
120       return false
121     rescue NegativePeriodError
122       m.reply "that time is in the past! (#{timestr})"
123       return false
124     rescue ShortRepeatError
125       m.reply "repeats of less than 30 seconds are forbidden"
126       return false
127     rescue UnparsedPeriodError
128       retry
129     end
130
131   end
132
133   def no_more(m, params)
134     who = params.has_key?(:who) ? params[:who] : m.sourcenick
135     deleted = params.has_key?(:string) ?
136               del_reminder(who, params[:string].to_s) : del_reminder(who)
137     if deleted
138       m.okay
139     else
140       m.reply "but I wasn't going to :/"
141     end
142   end
143 end
144 plugin = RemindPlugin.new
145
146 plugin.default_auth('other', false)
147
148 plugin.map 'remind me no more', :action => 'no_more'
149 plugin.map 'remind me no more [about] *string', :action => 'no_more'
150 plugin.map 'remind me [about] *string'
151 plugin.map 'remind :who no more', :auth_path => 'other', :action => 'no_more'
152 plugin.map 'remind :who no more [about] *string', :auth_path => 'other', :action => 'no_more'
153 plugin.map 'remind :who [about] *string', :auth_path => 'other'
154