]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/quotes.rb
Fix a problem introduced with the new quote saving procedure
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / quotes.rb
1 # GB: Ok, we *really* need to switch to db for this plugin too
2
3 Quote = Struct.new("Quote", "num", "date", "source", "quote")
4
5 class QuotePlugin < Plugin
6   def initialize
7     super
8     @lists = Hash.new
9     Dir["#{@bot.botclass}/quotes/*"].each {|f|
10       next if File.directory?(f)
11       channel = File.basename(f)
12       @lists[channel] = Array.new if(!@lists.has_key?(channel))
13       IO.foreach(f) {|line|
14         if(line =~ /^(\d+) \| ([^|]+) \| (\S+) \| (.*)$/)
15           num = $1.to_i
16           @lists[channel][num] = Quote.new(num, $2, $3, $4)
17         end
18       }
19     }
20   end
21   def save
22     Dir.mkdir("#{@bot.botclass}/quotes") if(!FileTest.directory?("#{@bot.botclass}/quotes"))
23     Dir.mkdir("#{@bot.botclass}/quotes/new") if(!FileTest.directory?("#{@bot.botclass}/quotes/new"))
24     @lists.each {|channel, quotes|
25       begin
26         debug "Writing new quotefile for channel #{channel} ..."
27         File.open("#{@bot.botclass}/quotes/new/#{channel}", "w") {|file|
28           quotes.compact.each {|q| 
29             file.puts "#{q.num} | #{q.date} | #{q.source} | #{q.quote}"
30           }
31         }
32         debug "Officializing quotefile for channel #{channel} ..."
33         File.rename("#{@bot.botclass}/quotes/new/#{channel}",
34                     "#{@bot.botclass}/quotes/#{channel}")
35       rescue => e
36         $stderr.puts "failed to write quotefile for channel #{channel}!\n#{$!}"
37         debug "#{e.class}: #{e}"
38         debug e.backtrace.join("\n")
39       end
40     }
41   end
42   def addquote(source, channel, quote)
43     @lists[channel] = Array.new if(!@lists.has_key?(channel))
44     num = @lists[channel].length 
45     @lists[channel][num] = Quote.new(num, Time.new, source, quote)
46     return num
47   end
48   def getquote(source, channel, num=nil)
49     return nil unless(@lists.has_key?(channel))
50     return nil unless(@lists[channel].length > 0)
51     if(num)
52       if(@lists[channel][num])
53         return @lists[channel][num], @lists[channel].length - 1
54       end
55     else
56       # random quote
57       return @lists[channel].compact[rand(@lists[channel].nitems)],
58       @lists[channel].length - 1
59     end
60   end
61   def delquote(channel, num)
62     return false unless(@lists.has_key?(channel))
63     return false unless(@lists[channel].length > 0)
64     if(@lists[channel][num])
65       @lists[channel][num] = nil
66       @lists[channel].pop if num == @lists[channel].length - 1
67       return true
68     end
69     return false
70   end
71   def countquote(source, channel=nil, regexp=nil)
72     unless(channel)
73       total=0
74       @lists.each_value {|l|
75         total += l.compact.length
76       }
77       return total
78     end
79     return 0 unless(@lists.has_key?(channel))
80     return 0 unless(@lists[channel].length > 0)
81     if(regexp)
82       matches = @lists[channel].compact.find_all {|a| a.quote =~ /#{regexp}/i }
83     else
84       matches = @lists[channel].compact
85     end
86     return matches.length
87   end
88   def searchquote(source, channel, regexp)
89     return nil unless(@lists.has_key?(channel))
90     return nil unless(@lists[channel].length > 0)
91     matches = @lists[channel].compact.find_all {|a| a.quote =~ /#{regexp}/i }
92     if(matches.length > 0)
93       return matches[rand(matches.length)], @lists[channel].length - 1
94     else
95       return nil
96     end
97   end
98   def help(plugin, topic="")
99     case topic
100     when "addquote"
101       return "addquote [<channel>] <quote> => Add quote <quote> for channel <channel>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !addquote without addressing if so configured"
102     when "delquote"
103       return "delquote [<channel>] <num> => delete quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !delquote without addressing if so configured"
104     when "getquote"
105       return "getquote [<channel>] [<num>] => get quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Without <num>, a random quote will be returned. Responds to !getquote without addressing if so configured"
106     when "searchquote"
107       return "searchquote [<channel>] <regexp> => search for quote from <channel> that matches <regexp>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !searchquote without addressing if so configured"
108     when "topicquote"
109       return "topicquote [<channel>] [<num>] => set topic to quote from <channel> with number <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Without <num>, a random quote will be set. Responds to !topicquote without addressing if so configured"
110     when "countquote"
111       return "countquote [<channel>] <regexp> => count quotes from <channel> that match <regexp>. You only need to supply <channel> if you are addressing #{@bot.nick} privately. Responds to !countquote without addressing if so configured"
112     when "whoquote"
113       return "whoquote [<channel>] <num> => show who added quote <num>. You only need to supply <channel> if you are addressing #{@bot.nick} privately"
114     when "whenquote"
115       return "whenquote [<channel>] <num> => show when quote <num> was added. You only need to supply <channel> if you are addressing #{@bot.nick} privately"
116     else
117       return "Quote module (Quote storage and retrieval) topics: addquote, delquote, getquote, searchquote, topicquote, countquote, whoquote, whenquote"
118     end
119   end
120   def listen(m)
121     return unless(m.kind_of? PrivMessage)
122
123     command = m.message.dup
124     if(m.address? && m.private?)
125       case command
126         when (/^addquote\s+(#\S+)\s+(.*)/)
127           channel = $1
128           quote = $2
129           if(@bot.auth.allow?("addquote", m.source, m.replyto))
130             if(channel =~ /^#/)
131               num = addquote(m.source, channel, quote)
132               m.reply "added the quote (##{num})"
133             end
134           end
135         when (/^getquote\s+(#\S+)$/)
136           channel = $1
137           if(@bot.auth.allow?("getquote", m.source, m.replyto))
138             quote, total = getquote(m.source, channel)
139             if(quote)
140               m.reply "[#{quote.num}] #{quote.quote}"
141             else
142               m.reply "quote not found!"
143             end
144           end
145         when (/^getquote\s+(#\S+)\s+(\d+)$/)
146           channel = $1
147           num = $2.to_i
148           if(@bot.auth.allow?("getquote", m.source, m.replyto))
149             quote, total = getquote(m.source, channel, num)
150             if(quote)
151               m.reply "[#{quote.num}] #{quote.quote}"
152             else
153               m.reply "quote not found!"
154             end
155           end
156         when (/^whoquote\s+(#\S+)\s+(\d+)$/)
157           channel = $1
158           num = $2.to_i
159           if(@bot.auth.allow?("getquote", m.source, m.replyto))
160             quote, total = getquote(m.source, channel, num)
161             if(quote)
162               m.reply "quote #{quote.num} added by #{quote.source}"
163             else
164               m.reply "quote not found!"
165             end
166           end
167         when (/^whenquote\s+(#\S+)\s+(\d+)$/)
168           channel = $1
169           num = $2.to_i
170           if(@bot.auth.allow?("getquote", m.source, m.replyto))
171             quote, total = getquote(m.source, channel, num)
172             if(quote)
173               m.reply "quote #{quote.num} added on #{quote.date}"
174             else
175               m.reply "quote not found!"
176             end
177           end
178         when (/^topicquote\s+(#\S+)$/)
179           channel = $1
180           if(@bot.auth.allow?("topicquote", m.source, m.replyto))
181             quote, total = getquote(m.source, channel)
182             if(quote)
183               @bot.topic channel, "[#{quote.num}] #{quote.quote}"
184             else
185               m.reply "quote not found!"
186             end
187           end
188         when (/^topicquote\s+(#\S+)\s+(\d+)$/)
189           channel = $1
190           num = $2.to_i
191           if(@bot.auth.allow?("topicquote", m.source, m.replyto))
192             quote, total = getquote(m.source, channel, num)
193             if(quote)
194               @bot.topic channel, "[#{quote.num}] #{quote.quote}"
195             else
196               m.reply "quote not found!"
197             end
198           end
199         when (/^delquote\s+(#\S+)\s+(\d+)$/)
200           channel = $1
201           num = $2.to_i
202           if(@bot.auth.allow?("delquote", m.source, m.replyto))
203             if(delquote(channel, num))
204               m.okay
205             else
206               m.reply "quote not found!"
207             end
208           end
209         when (/^searchquote\s+(#\S+)\s+(.*)$/)
210           channel = $1
211           reg = $2
212           if(@bot.auth.allow?("getquote", m.source, m.replyto))
213             quote, total = searchquote(m.source, channel, reg)
214             if(quote)
215               m.reply "[#{quote.num}] #{quote.quote}"
216             else
217               m.reply "quote not found!"
218             end
219           end
220         when (/^countquote$/)
221           if(@bot.auth.allow?("getquote", m.source, m.replyto))
222             total = countquote(m.source)
223             m.reply "#{total} quotes"
224           end
225         when (/^countquote\s+(#\S+)\s*(.*)$/)
226           channel = $1
227           reg = $2
228           if(@bot.auth.allow?("getquote", m.source, m.replyto))
229             total = countquote(m.source, channel, reg)
230             if(reg.length > 0)
231               m.reply "#{total} quotes match: #{reg}"
232             else
233               m.reply "#{total} quotes"
234             end
235           end
236       end
237     elsif (m.address? || (@bot.config["QUOTE_LISTEN"] && command.gsub!(/^!/, "")))
238       case command
239         when (/^addquote\s+(.+)/)
240           if(@bot.auth.allow?("addquote", m.source, m.replyto))
241             num = addquote(m.source, m.target, $1)
242             m.reply "added the quote (##{num})"
243           end
244         when (/^getquote$/)
245           if(@bot.auth.allow?("getquote", m.source, m.replyto))
246             quote, total = getquote(m.source, m.target)
247             if(quote)
248               m.reply "[#{quote.num}] #{quote.quote}"
249             else
250               m.reply "no quotes found!"
251             end
252           end
253         when (/^getquote\s+(\d+)$/)
254           num = $1.to_i
255           if(@bot.auth.allow?("getquote", m.source, m.replyto))
256             quote, total = getquote(m.source, m.target, num)
257             if(quote)
258               m.reply "[#{quote.num}] #{quote.quote}"
259             else
260               m.reply "quote not found!"
261             end
262           end
263         when (/^whenquote\s+(\d+)$/)
264           num = $1.to_i
265           if(@bot.auth.allow?("getquote", m.source, m.replyto))
266             quote, total = getquote(m.source, m.target, num)
267             if(quote)
268               m.reply "quote #{quote.num} added on #{quote.date}"
269             else
270               m.reply "quote not found!"
271             end
272           end
273         when (/^whoquote\s+(\d+)$/)
274           num = $1.to_i
275           if(@bot.auth.allow?("getquote", m.source, m.replyto))
276             quote, total = getquote(m.source, m.target, num)
277             if(quote)
278               m.reply "quote #{quote.num} added by #{quote.source}"
279             else
280               m.reply "quote not found!"
281             end
282           end
283         when (/^topicquote$/)
284           if(@bot.auth.allow?("topicquote", m.source, m.replyto))
285             quote, total = getquote(m.source, m.target)
286             if(quote)
287               @bot.topic m.target, "[#{quote.num}] #{quote.quote}"
288             else
289               m.reply "no quotes found!"
290             end
291           end
292         when (/^topicquote\s+(\d+)$/)
293           num = $1.to_i
294           if(@bot.auth.allow?("topicquote", m.source, m.replyto))
295             quote, total = getquote(m.source, m.target, num)
296             if(quote)
297               @bot.topic m.target, "[#{quote.num}] #{quote.quote}"
298             else
299               m.reply "quote not found!"
300             end
301           end
302         when (/^delquote\s+(\d+)$/)
303           num = $1.to_i
304           if(@bot.auth.allow?("delquote", m.source, m.replyto))
305             if(delquote(m.target, num))
306               m.okay
307             else
308               m.reply "quote not found!"
309             end
310           end
311         when (/^searchquote\s+(.*)$/)
312           reg = $1
313           if(@bot.auth.allow?("getquote", m.source, m.replyto))
314             quote, total = searchquote(m.source, m.target, reg)
315             if(quote)
316               m.reply "[#{quote.num}] #{quote.quote}"
317             else
318               m.reply "quote not found!"
319             end
320           end
321         when (/^countquote(?:\s+(.*))?$/)
322           reg = $1
323           if(@bot.auth.allow?("getquote", m.source, m.replyto))
324             total = countquote(m.source, m.target, reg)
325             if(reg && reg.length > 0)
326               m.reply "#{total} quotes match: #{reg}"
327             else
328               m.reply "#{total} quotes"
329             end
330           end
331       end
332     end
333   end
334 end
335 plugin = QuotePlugin.new
336 plugin.register("quotes")