]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/contrib/plugins/stats.rb
remove whitespace
[user/henk/code/ruby/rbot.git] / data / rbot / contrib / plugins / stats.rb
1 #  Author:    Michael Brailsford  <brailsmt@yahoo.com>
2 #             aka brailsmt
3 #  Purpose:   Provides the ability to track various tokens that are spoken in a
4 #             channel.
5 #  Copyright: 2002 Michael Brailsford.  All rights reserved.
6 #  License:   This plugin is licensed under the BSD license.  The terms of
7 #             which follow.
8 #
9 #  Redistribution and use in source and binary forms, with or without
10 #  modification, are permitted provided that the following conditions
11 #  are met:
12 #
13 #  1. Redistributions of source code must retain the above copyright notice,
14 #     this list of conditions and the following disclaimer.
15 #
16 #  2. Redistributions in binary form must reproduce the above copyright
17 #     notice, this list of conditions and the following disclaimer in the
18 #     documentation and/or other materials provided with the distribution.
19
20 class StatsPlugin < Plugin
21
22         @@commands = {
23                 "stats" => "handle_stats",
24                 "track" => "handle_track",
25                 "untrack" => "handle_untrack",
26                 "listtokens" => "handle_listtokens",
27                 "rmabuser" => "handle_rmabuser"
28         }
29
30         #{{{
31         def initialize
32                 super
33                 @listen = true
34                 @channels = Hash.new
35                 #check to see if a stats token file already exists for this channel...
36                 Dir["#{@bot.botclass}/stats/*"].each { |fname|
37                         channel = File.basename fname
38                         tokens = Hash.new
39                         IO.foreach(fname) { |line|
40                                 if line =~ /^(\S+)\s*<=>(.*)/
41                                         tokens[$1] = parse_token_stats $2
42                                 end
43                         }
44                         @channels[channel] = tokens
45                 }
46         end
47         #}}}
48         #{{{
49         def cleanup
50                 @channels = nil
51         end
52         #}}}
53         #{{{
54         def help(plugin, topic="")
55                 "Stats:  The stats plugin tracks various tokens from users in the channel.  The tokens are only tracked if it is the only thing on a line.\nUsage:  stats <token>  --  lists the stats for <token>\n        [un]track <token>  --  Adds or deletes <token> from the list of tokens\n        listtokens  --  lists the tokens that are currently being tracked"
56         end
57         #}}}
58         #{{{
59         def privmsg(m)
60                 if not m.params and not m.plugin =~ /listtokens/
61                         m.reply "What a crazy fool!  Did you mean |help stats?"
62                         return
63                 end
64
65                 meth = self.method(@@commands[m.plugin])
66                 meth.call(m)
67         end
68         #}}}
69         #{{{
70         def save
71                 Dir.mkdir("#{@bot.botclass}/stats") if not FileTest.directory?("#{@bot.botclass}/stats")
72                 #save the tokens to a file...
73                 @channels.each_pair { |channel, tokens|
74                         if not tokens.empty?
75                                 File.open("#{@bot.botclass}/stats/#{channel}", "w") { |f|
76                                         tokens.each { |token, datahash|
77                                                 f.puts "#{token} <=> #{datahash_to_s(datahash)}"
78                                         }
79                                 }
80                         else
81                                 File.delete "#{@bot.botclass}/stats/#{channel}"
82                         end
83                 }
84         end
85         #}}}
86         #{{{
87         def listen(m)
88                 if not m.private?
89                         tokens = @channels[m.target]
90                         if not @@commands[m.plugin]
91                                 tokens.each_pair { |key, hsh|
92                                         if not m.message.scan(/#{Regexp.escape(key)}/).empty?
93                                                 if hsh[m.sourcenick]
94                                                         hsh[m.sourcenick] += 1
95                                                 else
96                                                         hsh[m.sourcenick] = 1
97                                                 end
98                                         end
99                                 }
100                         end
101                 end
102 #This is the old code   {{{
103 #               if not m.private?
104 #                       tokens = @channels[m.target]
105 #                       hsh = tokens[m.message]
106 #                       if hsh
107 #                               if hsh[m.sourcenick]
108 #                                       hsh[m.sourcenick] += 1
109 #                               else
110 #                                       hsh[m.sourcenick] = 1
111 #                               end
112 #                       end
113 #               end     }}}
114         end
115         #}}}
116         #The following are helper functions for the plugin      {{{
117                 def datahash_to_s(dhash)
118                         rv = ""
119                         dhash.each { |key, val|
120                                 rv << "#{key}:#{val} "
121                         }
122                         rv.chomp
123                 end
124
125                 def parse_token_stats(stats)
126                         rv = Hash.new
127                         stats.split(" ").each { |nickstat|
128                                 nick, stat = nickstat.split ":"
129                                 rv[nick] = stat.to_i
130                         }
131                         rv
132                 end
133                 #}}}
134         #The following are handler methods for dealing with each command from IRC       {{{
135         #{{{
136         def handle_stats(m)
137                 if not m.private?
138                         total = 0
139                         tokens = @channels[m.target]
140                         hsh = tokens[m.params]
141                         msg1 = ""
142                         if not hsh.empty?
143                                 sorted = hsh.sort { |i, j| j[1] <=> i[1] }
144                                 sorted.each { |a|
145                                         total += a[1]
146                                 }
147
148                                 msg = "Stats for #{m.params}.  Said #{total} times.  The top sayers are "
149                                 if sorted[0..2]
150                                         msg << "#{sorted[0].join ':'}" if sorted[0]
151                                         msg << ", #{sorted[1].join ':'}" if sorted[1]
152                                         msg << ", and #{sorted[2].join ':'}" if sorted[2]
153                                         msg << "."
154
155                                         msg1 << "#{m.sourcenick} has said it "
156                                         if hsh[m.sourcenick]
157                                                 msg1 << "#{hsh[m.sourcenick]} times."
158                                         else
159                                                 msg1 << "0 times."
160                                         end
161                                 else
162                                         msg << "#{m.params} has not been said yet!"
163                                 end
164                                 @bot.action m.replyto, msg
165                                 @bot.action m.replyto, msg1 if msg1
166                         else
167                                 m.reply "#{m.params} is not currently being tracked."
168                         end
169                 end
170         end
171         #}}}
172         #{{{
173         def handle_track(m)
174                 if not m.private?
175                         if @channels[m.target]
176                                 tokens = @channels[m.target]
177                         else
178                                 tokens = Hash.new
179                                 @channels[m.target] = tokens
180                         end
181                         tokens[m.params] = Hash.new
182                         m.reply "now tracking #{m.params}"
183                 end
184         end
185         #}}}
186         #{{{
187         def handle_untrack(m)
188                 if not m.private?
189                         toks = @channels[m.target]
190                         if toks.has_key? m.params
191                                 toks.delete m.params
192                                 m.reply "no longer tracking #{m.params}"
193                         else
194                                 m.reply "Are your signals crossed?  Since when have I tracked that?"
195                         end
196                 end
197
198                 toks = nil
199         end
200         #}}}
201         #{{{
202         def handle_listtokens(m)
203                 if not m.private? and not @channels.empty?
204                         tokens = @channels[m.target]
205                         unless tokens.empty?
206                                 toks = ""
207                                 tokens.each_key { |k|
208                                         toks << "#{k} "
209                                 }
210                                 @bot.action m.replyto, "is currently keeping stats for:  #{toks}"
211                         else
212                                 @bot.action m.replyto, "is not currently keeping stats for anything"
213                         end
214                 elsif not m.private?
215                         @bot.action m.replyto, "is not currently keeping stats for anything"
216                 end
217         end
218         #}}}
219         #{{{
220         def handle_rmabuser(m)
221                 m.reply "This feature has not yet been implemented"
222         end
223         #}}}
224         #}}}
225
226 end
227 plugin = StatsPlugin.new
228 plugin.register("stats")
229 plugin.register("track")
230 plugin.register("untrack")
231 plugin.register("listtokens")
232 #plugin.register("rmabuser")