Untested, but close to functional

This commit is contained in:
Jeremy Fincher 2003-03-26 10:04:26 +00:00
parent e112e32d71
commit e7da39da77
1 changed files with 222 additions and 23 deletions

View File

@ -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):
"<nick>"
"[<channel>] (if not sent on the channel itself) <nick>"
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):
"[<channel>] (if not sent in the channel itself) <nick>"
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: