summaryrefslogtreecommitdiff
path: root/contrib/plugins/stats.rb
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/plugins/stats.rb')
-rw-r--r--contrib/plugins/stats.rb232
1 files changed, 232 insertions, 0 deletions
diff --git a/contrib/plugins/stats.rb b/contrib/plugins/stats.rb
new file mode 100644
index 00000000..4cafbbe9
--- /dev/null
+++ b/contrib/plugins/stats.rb
@@ -0,0 +1,232 @@
+# Author: Michael Brailsford <brailsmt@yahoo.com>
+# aka brailsmt
+# Purpose: Provides the ability to track various tokens that are spoken in a
+# channel.
+# Copyright: 2002 Michael Brailsford. All rights reserved.
+# License: This plugin is licensed under the BSD license. The terms of
+# which follow.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+
+class StatsPlugin < Plugin
+
+ @@commands = {
+ "stats" => "handle_stats",
+ "track" => "handle_track",
+ "untrack" => "handle_untrack",
+ "listtokens" => "handle_listtokens",
+ "rmabuser" => "handle_rmabuser"
+ }
+
+ #{{{
+ def initialize
+ super
+ @listen = true
+ @channels = Hash.new
+ #check to see if a stats token file already exists for this channel...
+ Dir["#{@bot.botclass}/stats/*"].each { |fname|
+ channel = File.basename fname
+ tokens = Hash.new
+ IO.foreach(fname) { |line|
+ if line =~ /^(\S+)\s*<=>(.*)/
+ tokens[$1] = parse_token_stats $2
+ end
+ }
+ @channels[channel] = tokens
+ }
+ end
+ #}}}
+ #{{{
+ def cleanup
+ @channels = nil
+ end
+ #}}}
+ #{{{
+ def help(plugin, topic="")
+ "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"
+ end
+ #}}}
+ #{{{
+ def privmsg(m)
+ if not m.params and not m.plugin =~ /listtokens/
+ m.reply "What a crazy fool! Did you mean |help stats?"
+ return
+ end
+
+ meth = self.method(@@commands[m.plugin])
+ meth.call(m)
+ end
+ #}}}
+ #{{{
+ def save
+ Dir.mkdir("#{@bot.botclass}/stats") if not FileTest.directory?("#{@bot.botclass}/stats")
+ #save the tokens to a file...
+ @channels.each_pair { |channel, tokens|
+ if not tokens.empty?
+ File.open("#{@bot.botclass}/stats/#{channel}", "w") { |f|
+ tokens.each { |token, datahash|
+ f.puts "#{token} <=> #{datahash_to_s(datahash)}"
+ }
+ }
+ else
+ File.delete "#{@bot.botclass}/stats/#{channel}"
+ end
+ }
+ end
+ #}}}
+ #{{{
+ def listen(m)
+ if not m.private?
+ tokens = @channels[m.target]
+ if not @@commands[m.plugin]
+ tokens.each_pair { |key, hsh|
+ if not m.message.scan(/#{Regexp.escape(key)}/).empty?
+ if hsh[m.sourcenick]
+ hsh[m.sourcenick] += 1
+ else
+ hsh[m.sourcenick] = 1
+ end
+ end
+ }
+ end
+ end
+#This is the old code {{{
+# if not m.private?
+# tokens = @channels[m.target]
+# hsh = tokens[m.message]
+# if hsh
+# if hsh[m.sourcenick]
+# hsh[m.sourcenick] += 1
+# else
+# hsh[m.sourcenick] = 1
+# end
+# end
+# end }}}
+ end
+ #}}}
+ #The following are helper functions for the plugin {{{
+ def datahash_to_s(dhash)
+ rv = ""
+ dhash.each { |key, val|
+ rv << "#{key}:#{val} "
+ }
+ rv.chomp
+ end
+
+ def parse_token_stats(stats)
+ rv = Hash.new
+ stats.split(" ").each { |nickstat|
+ nick, stat = nickstat.split ":"
+ rv[nick] = stat.to_i
+ }
+ rv
+ end
+ #}}}
+ #The following are handler methods for dealing with each command from IRC {{{
+ #{{{
+ def handle_stats(m)
+ if not m.private?
+ total = 0
+ tokens = @channels[m.target]
+ hsh = tokens[m.params]
+ msg1 = ""
+ if not hsh.empty?
+ sorted = hsh.sort { |i, j| j[1] <=> i[1] }
+ sorted.each { |a|
+ total += a[1]
+ }
+
+ msg = "Stats for #{m.params}. Said #{total} times. The top sayers are "
+ if sorted[0..2]
+ msg << "#{sorted[0].join ':'}" if sorted[0]
+ msg << ", #{sorted[1].join ':'}" if sorted[1]
+ msg << ", and #{sorted[2].join ':'}" if sorted[2]
+ msg << "."
+
+ msg1 << "#{m.sourcenick} has said it "
+ if hsh[m.sourcenick]
+ msg1 << "#{hsh[m.sourcenick]} times."
+ else
+ msg1 << "0 times."
+ end
+ else
+ msg << "#{m.params} has not been said yet!"
+ end
+ @bot.action m.replyto, msg
+ @bot.action m.replyto, msg1 if msg1
+ else
+ m.reply "#{m.params} is not currently being tracked."
+ end
+ end
+ end
+ #}}}
+ #{{{
+ def handle_track(m)
+ if not m.private?
+ if @channels[m.target]
+ tokens = @channels[m.target]
+ else
+ tokens = Hash.new
+ @channels[m.target] = tokens
+ end
+ tokens[m.params] = Hash.new
+ m.reply "now tracking #{m.params}"
+ end
+ end
+ #}}}
+ #{{{
+ def handle_untrack(m)
+ if not m.private?
+ toks = @channels[m.target]
+ if toks.has_key? m.params
+ toks.delete m.params
+ m.reply "no longer tracking #{m.params}"
+ else
+ m.reply "Are your signals crossed? Since when have I tracked that?"
+ end
+ end
+
+ toks = nil
+ end
+ #}}}
+ #{{{
+ def handle_listtokens(m)
+ if not m.private? and not @channels.empty?
+ tokens = @channels[m.target]
+ unless tokens.empty?
+ toks = ""
+ tokens.each_key { |k|
+ toks << "#{k} "
+ }
+ @bot.action m.replyto, "is currently keeping stats for: #{toks}"
+ else
+ @bot.action m.replyto, "is not currently keeping stats for anything"
+ end
+ elsif not m.private?
+ @bot.action m.replyto, "is not currently keeping stats for anything"
+ end
+ end
+ #}}}
+ #{{{
+ def handle_rmabuser(m)
+ m.reply "This feature has not yet been implemented"
+ end
+ #}}}
+ #}}}
+
+end
+plugin = StatsPlugin.new
+plugin.register("stats")
+plugin.register("track")
+plugin.register("untrack")
+plugin.register("listtokens")
+#plugin.register("rmabuser")