From e7da39da772a0fc4423b352cbdaf371d29fe703d Mon Sep 17 00:00:00 2001 From: Jeremy Fincher Date: Wed, 26 Mar 2003 10:04:26 +0000 Subject: [PATCH] Untested, but close to functional --- plugins/ChannelStats.py | 245 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 222 insertions(+), 23 deletions(-) diff --git a/plugins/ChannelStats.py b/plugins/ChannelStats.py index b4177ff39..01f2043b9 100644 --- a/plugins/ChannelStats.py +++ b/plugins/ChannelStats.py @@ -43,6 +43,8 @@ from baseplugin import * import re import time +import sqlite + import privmsgs import ircutils import callbacks @@ -50,40 +52,237 @@ import callbacks smileys = (':)', ';)', ':]', ':-)', ':-D', ':D', ':P', ':p', '(=', '=)') frowns = (':|', ':-/', ':-\\', ':\\', ':/', ':(', ':-(', ':\'(') -smileyRegexp = re.compile('|'.join([re.escape(s) for s in smileys])) -frownRegexp = re.compile('|'.join([re.escape(s) for s in frowns])) +smileyre = re.compile('|'.join([re.escape(s) for s in smileys])) +frownre = re.compile('|'.join([re.escape(s) for s in frowns])) class ChannelStats(callbacks.Privmsg, DBHandler): def __init__(self): callbacks.Privmsg.__init__(self) - DBHandler.__init__(self, '.stats') + DBHandler.__init__(self) + def makeDb(self, filename): + if os.path.exists(filename): + return sqlite.connect(filename) + db = sqlite.connect(filename) + cursor = db.cursor() + cursor.execute("""CREATE TABLE stats ( + id INTEGER PRIMARY KEY, + username TEXT UNIQUE, + last_seen TIMESTAMP, + last_msg TEXT, + smileys INTEGER, + frowns INTEGER, + chars INTEGER, + words INTEGER, + msgs INTEGER, + actions INTEGER, + joins INTEGER, + parts INTEGER, + kicks INTEGER, + kicked INTEGER, + modes INTEGER, + topics INTEGER, + )""") + cursor.execute("""CREATE INDEX stats_username ON stats (username)""") + db.commit() + return db + def doPrivmsg(self, irc, msg): - recipient = msg.args[0] - if ircutils.isChannel(recipient): - db = self.getDb(recipient) - db[msg.nick] = (time.time(), msg.args[1]) - #callbacks.Privmsg.doPrivmsg(self, irc, msg) - super(self.__class__, self).doPrivmsg(irc, msg) - #self.__class__.__bases__[0].doPrivmsg(self, irc, msg) + if ircutils.isChannel(msg.args[0]): + (channel, s) = msg.args + db = self.getDb(channel) + try: + name = ircdb.users.getUserName(msg.prefix) + except KeyError: + return + cursor.execute("""SELECT * FROM stats WHERE username=%s""", name) + if cursor.rowcount == 0: # User isn't in database. + cursor.execute("""INSERT INTO stats VALUES ( + NULL, %s, %s, %s, %s, %s, + %s, %s, 1, %s, + 0, 0, 0, 0, 0 )""", + name, int(time.time()), msg.args[1], + len(smileyre.findall(s)), + len(frownre.findall(s)), len(s), len(s.split()), + int(ircmsgs.isAction(msg))) + else: + cursor.execute("""SELECT chars, words, msgs, + actions, smileys, frowns + FROM stats WHERE username=%s""", name) + values = cursor.fetchone() + cursor.execute("""UPDATE stats SET + last_seen=%s, last_msg=%s, chars=%s, + words=%s, msgs=%s, actions=%s, + smileys=%s, frowns=%s + WHERE username=%s""", + int(time.time()), + s, + values.chars + len(s), + values.words + len(s.split()), + values.msgs + 1, + values.actions + ircmsgs.isAction(msg), + values.smileys + len(smileyre.findall(s)), + values.frowns + len(frownre.findall(s)), + name) + db.commit() + + def doJoin(self, irc, msg): + try: + name = ircdb.users.getUserName(msg.prefix) + except KeyError: + return + channels = msg.args[0].split(',') + for channel in channels: + db = self.getDb(channel) + cursor = db.cursor() + cursor.execute("SELECT joins FROM stats WHERE username=%s", name) + if cursor.rowcount == 0: + return + joins = cursor.fetchone()[0] + cursor.execute("UPDATE stats SET joins=%s WHERE username=%s", + joins+1, name) + db.commit() + + def doPart(self, irc, msg): + try: + name = ircdb.users.getUserName(msg.prefix) + except KeyError: + return + channels = msg.args[0].split(',') + for channel in channels: + db = self.getDb(channel) + cursor = db.cursor() + cursor.execute("SELECT parts FROM stats WHERE username=%s", name) + if cursor.rowcount == 0: + return + parts = cursor.fetchone()[0] + cursor.execute("UPDATE stats SET parts=%s WHERE username=%s", + parts+1, name) + db.commit() + + def doTopic(self, irc, msg): + try: + name = ircdb.users.getUserName(msg.prefix) + except KeyError: + return + channel = msg.args[0] + db = self.getDb(channel) + cursor = db.cursor() + cursor.execute("SELECT topics FROM stats WHERE username=%s", name) + if cursor.rowcount == 0: + return + topics = cursor.fetchone()[0] + cursor.execute("UPDATE stats SET topics=%s WHERE username=%s", + topics+1, name) + db.commit() + + def doMode(self, irc, msg): + try: + name = ircdb.users.getUserName(msg.prefix) + except KeyError: + return + channel = msg.args[0] + db = self.getDb(channel) + cursor = db.cursor() + cursor.execute("SELECT modes FROM stats WHERE username=%s", name) + if cursor.rowcount == 0: + return + modes = cursor.fetchone()[0] + cursor.execute("UPDATE stats SET modes=%s WHERE username=%s", + modes+1, name) + db.commit() + + def doKick(self, irc, msg): + db = self.getDb(msg.args[0]) + cursor = db.cursor() + try: + name = ircdb.users.getUserName(msg.prefix) + cursor.execute("SELECT kicks FROM stats WHERE username=%s", name) + if cursor.rowcount != 0: + kicks = cursor.fetchone()[0] + cursor.execute("UPDATE stats SET kicks=%s WHERE username=%s", + kicks+1, name) + except KeyError: + pass + try: + kicked = msg.args[1] + name = ircdb.users.getUserName(irc.state.nickToHostmask(kicked)) + cursor.execute("SELECT kicked FROM stats WHERE username=%s", name) + if cursor.rowcount != 0: + kicked = cursor.fetchone()[0] + cursor.execute("UPDATE stats SET kicked=%s WHERE username=%s", + kicked+1, name) + except KeyError: + pass + db.commit() def seen(self, irc, msg, args): - "" + "[] (if not sent on the channel itself) " channel = privmsgs.getChannel(msg, args) - nick = ircutils.nick(privmsgs.getArgs(args)) + name = privmsgs.getArgs(args) + if not irc.users.hasUser(name): + hostmask = irc.state.nickToHostmask(name) + try: + name = irc.users.getUserName(hostmask) + except KeyError: + irc.error(msg, conf.replyNoUser) + return db = self.getDb(channel) - try: - (t, saying) = db[nick] - if t == 0.0: # Default record time. - raise KeyError - t = time.localtime(t) - ret = '%s was last seen on %s on %s at %s saying {%s}' %\ - (nick, channel, time.strftime('%d-%b-%Y', t), - time.strftime('%H:%M:%S'), saying) - irc.reply(msg, ret) - except KeyError: - irc.reply(msg, 'I haven\'t seen any user by that nick.') + cursor = db.cursor() + cursor.execute("""SELECT (last_seen, last_msg) FROM stats + WHERE username=%s""", name) + if cursor.rowcount == 0: + irc.reply(msg, 'I have no stats for that user.') + else: + (seen, m) = cursor.fetchone() + ago = int(time.time()) - seen + days = ago / 86400 + ago %= 86400 + hours = ago / 3600 + ago %= 3600 + minutes = ago / 60 + seconds = ago % 60 + s = '%s day%s %s hour%s %s minute%s %s second%s ago' % \ + (days, days == 1 and ',' or 's,', + hours, hours == 1 and ',' or 's,', + minutes, minutes == 1 and ',' or 's,', + seconds, seconds == 1 and ',' or 's,') + irc.reply(msg, '%s was last seen here at %s saying %s' % \ + (name, s, m)) + + def stats(self, irc, msg, args): + "[] (if not sent in the channel itself) " + channel = privmsgs.getChannel(msg, args) + name = privmsgs.getArgs(args) + if not irc.users.hasUser(name): + hostmask = irc.state.nickToHostmask(name) + try: + name = irc.users.getUserName(hostmask) + except KeyError: + irc.error(msg, conf.replyNoUser) + return + db = self.getDb(channel) + cursor = db.cursor() + cursor.execute("""SELECT smileys, frowns, chars, words, msgs, actions, + joins, parts, kicks, kicked, modes, topics + FROM stats WHERE username=%s""", name) + if cursor.rowcount == 0: + irc.reply(msg, 'I have no stats for that user.') + return + values = cursor.fetchone() + s = '%s has %s messages, with a total of %s chars, %s words, ' \ + '%s smileys, and %s frowns; %s of those messages were ACTIONs. ' \ + '%s has joined %s times, parted %s times, kicked someone %s times'\ + ' been kicked %s times, changed the topic %s times, ' \ + 'and changed the mode %s times.' % \ + (values.msgs, values.chars, values.words, + values.smileys, values.frowns, values.actions, + values.joins, values.parts, values.kicks, + values.kicked, values.topics, + values.modes) + irc.reply(msg, s) Class = ChannelStats + # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: