2010-10-25 18:44:28 -05:00
"""
Karma - handle karma ( + + and - - ) tracking
Copyright ( C ) 2010 Brian S . Stephan
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : / / www . gnu . org / licenses / > .
"""
2010-10-23 22:52:15 -05:00
import re
2010-10-27 17:59:01 -05:00
import sqlite3
2010-10-23 22:52:15 -05:00
from Module import Module
2010-10-24 09:37:43 -05:00
__author__ = " Mike Bloy <mike@bloy.org> "
__date__ = " $Oct 23, 2010 11:12:33 AM$ "
2010-10-23 22:52:15 -05:00
class Karma ( Module ) :
def __init__ ( self , config , server , modlist ) :
"""
Upon creation , determine the save file location
"""
Module . __init__ ( self , config , server , modlist )
2010-11-17 10:21:30 -06:00
pattern = " (?:( \ S+)| \ ((.+) \ )) "
2010-11-23 21:45:47 -06:00
karmapattern = pattern + ' ( \ + \ +|--| \ +-|- \ +) ' + ' ( \ s+|$) '
2010-10-28 20:15:48 -05:00
querypattern = ' ^rank \ s+(.*) '
2010-11-25 11:41:12 -06:00
reportpattern = ' ^karma \ s+report \ s+(highest|lowest|positive|negative) '
2010-11-23 22:05:03 -06:00
statpattern = ' ^karma \ s+stat \ s+(.*) '
2010-10-23 22:52:15 -05:00
self . karmare = re . compile ( karmapattern )
self . queryre = re . compile ( querypattern )
2010-11-23 22:05:03 -06:00
self . reportre = re . compile ( reportpattern )
self . statre = re . compile ( statpattern )
2010-10-23 22:52:15 -05:00
2010-10-27 17:59:01 -05:00
def db_init ( self ) :
2010-10-24 13:05:16 -05:00
# need to init the database if karma tables don't already exist
version = self . db_module_registered ( self . __class__ . __name__ )
if ( version == None ) :
# have to create the database tables
conn = self . get_db ( )
try :
conn . execute ( '''
CREATE TABLE karma_log (
id INTEGER PRIMARY KEY AUTOINCREMENT ,
key TEXT NOT NULL ,
delta INTEGER NOT NULL ,
who TEXT NOT NULL ,
userhost TEXT NOT NULL ,
karmatime TEXT DEFAULT CURRENT_TIMESTAMP
) ''' )
conn . execute ( ' CREATE INDEX karma_log_key_ix ON karma_log (key) ' )
conn . execute ( ' CREATE INDEX karma_log_who_ix ON karma_log (who) ' )
conn . execute ( '''
CREATE VIEW karma_values AS
SELECT key , SUM ( delta ) AS value
FROM karma_log
GROUP BY key ''' )
2010-10-25 21:14:35 -05:00
2010-10-24 13:05:16 -05:00
sql = ' INSERT INTO drbotzo_modules VALUES (?,?) '
conn . execute ( sql , ( self . __class__ . __name__ , 1 ) )
conn . commit ( )
2010-11-23 22:05:03 -06:00
version = 1
2010-10-27 17:59:01 -05:00
except sqlite3 . Error as e :
conn . rollback ( )
print ( " sqlite error: " + str ( e ) )
raise
2010-11-23 22:05:03 -06:00
if ( version < 2 ) :
conn = self . get_db ( )
try :
conn . execute ( '''
CREATE VIEW karma_users AS
SELECT who , COUNT ( NULLIF ( delta , - 1 ) ) AS pos ,
COUNT ( NULLIF ( delta , 1 ) ) AS neg
FROM karma_log GROUP BY who ''' )
sql = ' UPDATE drbotzo_modules SET version = ? WHERE module = ? '
conn . execute ( sql , ( 2 , self . __class__ . __name__ ) )
conn . commit ( )
version = 2
except sqlite3 . Error as e :
conn . rollback ( )
print ( " sqlite error: " + str ( e ) )
raise
2010-10-23 22:52:15 -05:00
def do ( self , connection , event , nick , userhost , replypath , what , admin_unlocked ) :
2010-10-24 09:36:15 -05:00
""" look for karma strings at the start of messages """
2010-10-25 18:37:30 -05:00
2010-10-29 13:08:48 -05:00
if ( self . karmare . search ( what ) ) :
2010-10-28 20:46:09 -05:00
return self . handle_karma_change ( connection , nick , userhost , replypath , what )
2010-10-29 13:08:48 -05:00
elif ( self . queryre . search ( what ) ) :
2010-10-28 20:46:09 -05:00
return self . handle_karma_query ( connection , nick , userhost , replypath , what )
2010-11-25 11:41:12 -06:00
elif ( self . statre . search ( what ) ) :
return self . handle_stat_query ( connection , nick , userhost , replypath , what )
2010-11-23 22:05:03 -06:00
2010-10-24 09:36:15 -05:00
def handle_karma_change ( self , connection , nick , userhost , replypath , what ) :
"""
handle the karma change and storage .
"""
2010-10-29 13:08:48 -05:00
match = self . karmare . search ( what )
2010-10-25 19:11:17 -05:00
key = match . group ( 1 ) if match . group ( 1 ) else match . group ( 2 )
value = match . group ( 3 )
2010-10-24 09:36:15 -05:00
if ( value == ' ++ ' ) :
2010-11-25 11:15:37 -06:00
return self . karma_modify ( key , 1 , connection , nick , userhost , replypath )
2010-11-19 09:33:37 -06:00
elif ( value == ' -- ' ) :
2010-11-25 11:15:37 -06:00
return self . karma_modify ( key , - 1 , connection , nick , userhost , replypath )
2010-11-19 09:33:37 -06:00
elif ( value == ' +- ' ) :
2010-11-25 11:15:37 -06:00
self . karma_modify ( key , 1 , connection , nick , userhost , replypath )
return self . karma_modify ( key , - 1 , connection , nick , userhost , replypath )
2010-11-23 21:45:47 -06:00
elif ( value == ' -+ ' ) :
2010-11-25 11:15:37 -06:00
self . karma_modify ( key , - 1 , connection , nick , userhost , replypath )
return self . karma_modify ( key , 1 , connection , nick , userhost , replypath )
2010-11-19 09:26:49 -06:00
2010-11-25 11:15:37 -06:00
def karma_modify ( self , key , value , connection , nick , userhost , replypath ) :
2010-11-19 09:26:49 -06:00
"""
Go out to the database and update the karma value .
"""
2010-10-24 09:36:15 -05:00
2010-10-24 13:05:16 -05:00
conn = self . get_db ( )
2010-10-24 09:36:15 -05:00
try :
2010-10-24 13:05:16 -05:00
sql = '''
INSERT INTO karma_log ( key , delta , who , userhost )
VALUES ( ? , ? , ? , ? )
'''
conn . execute ( sql , ( key , value , nick , userhost ) )
conn . commit ( )
2010-10-27 17:59:01 -05:00
except sqlite3 . Error as e :
conn . rollback ( )
return self . reply ( connection , replypath , " sqlite error: " + str ( e ) )
2010-11-25 11:41:12 -06:00
def handle_stat_query ( self , connection , nick , userhost , replypath , what ) :
match = self . statre . search ( what )
statnick = match . group ( 1 )
conn = self . get_db ( )
reply = ' {nick} : {statnick} has never given karma ' . format ( nick = nick , statnick = statnick )
try :
query = '''
SELECT pos , neg
FROM karma_users
WHERE who = : who
'''
value = conn . execute ( query , { ' who ' : statnick } ) . fetchone ( )
if ( value != None ) :
pos = value [ 0 ]
neg = value [ 1 ]
total = pos + neg ;
reply = ' {nick} : {statnick} has given {pos} postive karma and {neg} negative karma, for a total of {total} karma ' . format ( nick = nick , statnick = statnick , pos = pos , neg = neg , total = total )
except sqlite3 . Error as e :
return self . reply ( connection , replypath , " sqlite error: " + str ( e ) )
return self . reply ( connection , replypath , reply )
2010-10-24 09:36:15 -05:00
def handle_karma_query ( self , connection , nick , userhost , replypath , what ) :
2010-10-29 13:08:48 -05:00
match = self . queryre . search ( what )
2010-10-24 09:36:15 -05:00
key = match . group ( 1 )
2010-10-24 13:05:16 -05:00
conn = self . get_db ( )
reply = ' {nick} : {key} has no karma ' . format ( nick = nick , key = key )
2010-10-24 09:36:15 -05:00
try :
2010-10-24 13:05:16 -05:00
query = '''
SELECT value
FROM karma_values
WHERE key = : key
'''
value = conn . execute ( query , { ' key ' : key } ) . fetchone ( )
2010-10-24 14:48:26 -05:00
2010-10-24 13:05:16 -05:00
if ( value != None ) :
2010-10-24 14:48:26 -05:00
query = '''
SELECT count ( * ) FROM karma_values WHERE value > : value
'''
rank = conn . execute ( query , { ' value ' : value [ 0 ] } ) . fetchone ( )
rank = rank [ 0 ] + 1 ;
2010-10-25 21:14:35 -05:00
2010-10-24 14:48:26 -05:00
reply = ' {nick} : {key} has {value[0]!s} points of karma (rank {rank} ) ' . format (
nick = nick , key = key , value = value , rank = rank )
2010-10-27 17:59:01 -05:00
except sqlite3 . Error as e :
return self . reply ( connection , replypath , " sqlite error: " + str ( e ) )
2010-10-24 09:36:15 -05:00
2010-10-28 20:46:09 -05:00
return self . reply ( connection , replypath , reply )
2010-10-23 22:52:15 -05:00
if __name__ == " __main__ " :
print " Hello World "
2010-11-19 09:20:48 -06:00
# vi:tabstop=4:expandtab:autoindent