Karma: ported to irc bot v2. deleted
This commit is contained in:
		
							parent
							
								
									6205be109b
								
							
						
					
					
						commit
						c9542c1617
					
				| @ -1,254 +0,0 @@ | ||||
| """ | ||||
| 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/>. | ||||
| """ | ||||
| 
 | ||||
| from math import floor | ||||
| import re | ||||
| 
 | ||||
| import MySQLdb as mdb | ||||
| 
 | ||||
| from Module import Module | ||||
| 
 | ||||
| __author__ = "Mike Bloy <mike@bloy.org>" | ||||
| __date__ = "$Oct 23, 2010 11:12:33 AM$" | ||||
| 
 | ||||
| class Karma(Module): | ||||
| 
 | ||||
|     def __init__(self, irc, config): | ||||
|         """ | ||||
|         Upon creation, determine the save file location | ||||
|         """ | ||||
| 
 | ||||
|         Module.__init__(self, irc, config) | ||||
| 
 | ||||
|         pattern = "(?:\((.+?)\)|(\S+))" | ||||
|         karmapattern = pattern + '(\+\+|--|\+-|-\+)' + '(\s+|$)' | ||||
|         querypattern = '^!rank\s+(.*)' | ||||
|         reportpattern = '^!karma\s+report\s+(highest|lowest|positive|negative|top)' | ||||
|         statpattern = '^!karma\s+stat\s+(.*)' | ||||
| 
 | ||||
|         self.karmare = re.compile(karmapattern) | ||||
|         self.queryre = re.compile(querypattern) | ||||
|         self.reportre = re.compile(reportpattern) | ||||
|         self.statre = re.compile(statpattern) | ||||
| 
 | ||||
|     def db_init(self): | ||||
|         # 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 | ||||
|             db = self.get_db() | ||||
|             try: | ||||
|                 version = 1 | ||||
|                 cur = db.cursor(mdb.cursors.DictCursor) | ||||
|                 cur.execute(''' | ||||
|                    CREATE TABLE karma_log ( | ||||
|                         id SERIAL, | ||||
|                         karma_key VARCHAR(128) NOT NULL, | ||||
|                         delta INTEGER NOT NULL, | ||||
|                         who VARCHAR(64) NOT NULL, | ||||
|                         userhost VARCHAR(256) NOT NULL, | ||||
|                         karmatime TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||||
|                     ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin | ||||
|                     ''') | ||||
|                 cur.execute('CREATE INDEX karma_log_key_ix ON karma_log (karma_key)') | ||||
|                 cur.execute('CREATE INDEX karma_log_who_ix ON karma_log (who)') | ||||
|                 cur.execute(''' | ||||
|                     CREATE VIEW karma_values AS | ||||
|                     SELECT karma_key, SUM(delta) AS value | ||||
|                     FROM karma_log | ||||
|                     GROUP BY karma_key''') | ||||
|                 cur.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''') | ||||
|                 db.commit() | ||||
|                 self.db_register_module_version(self.__class__.__name__, version) | ||||
|             except mdb.Error as e: | ||||
|                 db.rollback() | ||||
|                 self.log.error("database error trying to create tables") | ||||
|                 self.log.exception(e) | ||||
|                 raise | ||||
|             finally: cur.close() | ||||
| 
 | ||||
|     def do(self, connection, event, nick, userhost, what, admin_unlocked): | ||||
|         """look for karma strings at the start of messages""" | ||||
| 
 | ||||
|         # don't return anything, do this attempt regardless | ||||
|         if (self.karmare.search(what)): | ||||
|             self.handle_karma_change(connection, nick, userhost, what) | ||||
| 
 | ||||
|         if (self.queryre.search(what)): | ||||
|             return self.irc.reply(event, self.handle_karma_query(connection, nick, userhost, what)) | ||||
|         elif (self.statre.search(what)): | ||||
|             return self.irc.reply(event, self.handle_stat_query(connection, nick, userhost, what)) | ||||
|         elif (self.reportre.search(what)): | ||||
|             return self.irc.reply(event, self.handle_report_query(connection, nick, userhost, what)) | ||||
| 
 | ||||
|     def handle_karma_change(self, connection, nick, userhost, what): | ||||
|         """ | ||||
|         handle the karma change and storage. | ||||
|         """ | ||||
| 
 | ||||
|         if self.karmare.search(what): | ||||
|             matches = self.karmare.findall(what) | ||||
|             for match in matches: | ||||
|                 key = match[0] if match[0] else match[1] | ||||
|                 value = match[2] | ||||
| 
 | ||||
|                 if (value == '++'): | ||||
|                     self.karma_modify(key, 1, nick, userhost) | ||||
|                 elif (value == '--'): | ||||
|                     self.karma_modify(key, -1, nick, userhost) | ||||
|                 elif (value == '+-'): | ||||
|                     self.karma_modify(key, 1, nick, userhost) | ||||
|                     self.karma_modify(key, -1, nick, userhost) | ||||
|                 elif (value == '-+'): | ||||
|                     self.karma_modify(key, -1, nick, userhost) | ||||
|                     self.karma_modify(key, 1, nick, userhost) | ||||
| 
 | ||||
|     def karma_modify(self, key, value, nick, userhost): | ||||
|         """ | ||||
|         Go out to the database and update the karma value. | ||||
|         """ | ||||
| 
 | ||||
|         db = self.get_db() | ||||
|         try: | ||||
|             cur = db.cursor(mdb.cursors.DictCursor) | ||||
|             sql = ''' | ||||
|             INSERT INTO karma_log (karma_key, delta, who, userhost) | ||||
|             VALUES (%s, %s, %s, %s) | ||||
|             ''' | ||||
|             cur.execute(sql, (key.lower(), value, nick, userhost)) | ||||
|             db.commit() | ||||
|         except mdb.Error as e: | ||||
|             db.rollback() | ||||
|             self.log.error("database error modifying karma") | ||||
|             self.log.exception(e) | ||||
|             raise | ||||
|         finally: cur.close() | ||||
| 
 | ||||
|     def handle_report_query(self, connection, nick, userhost, what): | ||||
|         match = self.reportre.search(what) | ||||
|         report = match.group(1) | ||||
| 
 | ||||
|         message = '{nick}: the desired report is not yet implemented'.format(nick=nick) | ||||
|         query = None | ||||
|         header = None | ||||
|         if (report == 'highest'): | ||||
|             query = 'SELECT karma_key AS who, value FROM karma_values ORDER BY value DESC LIMIT 5' | ||||
|             header = 'Top 5 karma recipients:' | ||||
|         elif (report == 'lowest'): | ||||
|             query = 'SELECT karma_key AS who, value FROM karma_values ORDER BY value ASC LIMIT 5' | ||||
|             header = 'Bottom 5 karma recipients:' | ||||
|         elif (report == 'positive'): | ||||
|             query = 'SELECT who, pos AS value FROM karma_users ORDER BY pos DESC LIMIT 5' | ||||
|             header = 'Top 5 Optimists:' | ||||
|         elif (report == 'negative'): | ||||
|             query = 'SELECT who, neg AS value FROM karma_users ORDER BY neg DESC LIMIT 5' | ||||
|             header = 'Top 5 Pessimists:' | ||||
|         elif (report == 'top'): | ||||
|             query = 'SELECT who, pos+neg AS value FROM karma_users ORDER BY value DESC LIMIT 5' | ||||
|             header = 'Top 5 Total Karma Givers:' | ||||
| 
 | ||||
|         if (query != None): | ||||
|             db = self.get_db() | ||||
|             list = [] | ||||
|             try: | ||||
|                 cur = db.cursor(mdb.cursors.DictCursor) | ||||
|                 cur.execute(query) | ||||
|                 result = cur.fetchone() | ||||
|                 while (result != None): | ||||
|                     list.append("{key} ({value})".format(key=result['who'], value=result['value'])) | ||||
|                     result = cur.fetchone() | ||||
|                 list = ', '.join(list) | ||||
|                 message = '{header} {list}'.format(header=header, list=list) | ||||
|             except mdb.Error as e: | ||||
|                 self.log.error("database error during report query") | ||||
|                 self.log.exception(e) | ||||
|                 raise | ||||
|             finally: cur.close() | ||||
| 
 | ||||
|         return message | ||||
| 
 | ||||
|     def handle_stat_query(self, connection, nick, userhost, what): | ||||
|         match = self.statre.search(what) | ||||
|         statnick = match.group(1) | ||||
| 
 | ||||
|         db = self.get_db() | ||||
|         reply = '{nick}: {statnick} has never given karma'.format(nick=nick, statnick=statnick) | ||||
|         try: | ||||
|             cur = db.cursor(mdb.cursors.DictCursor) | ||||
|             query = ''' | ||||
|             SELECT pos, neg | ||||
|             FROM karma_users | ||||
|             WHERE who = :who | ||||
|             ''' | ||||
|             cur.execute(query, {'who': statnick}) | ||||
|             value = cur.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 mdb.Error as e: | ||||
|             self.log.error("database error during handle stat query") | ||||
|             self.log.exception(e) | ||||
|             raise | ||||
|         finally: cur.close() | ||||
| 
 | ||||
|         return reply | ||||
| 
 | ||||
|     def handle_karma_query(self, connection, nick, userhost, what): | ||||
|         match = self.queryre.search(what) | ||||
|         key = match.group(1) | ||||
| 
 | ||||
|         db = self.get_db() | ||||
|         reply = '{nick}: {key} has no karma'.format(nick=nick, key=key) | ||||
|         try: | ||||
|             cur = db.cursor(mdb.cursors.DictCursor) | ||||
|             query = ''' | ||||
|             SELECT value | ||||
|             FROM karma_values | ||||
|             WHERE karma_key = %s | ||||
|             ''' | ||||
|             cur.execute(query, (key.lower(),)) | ||||
|             value = cur.fetchone() | ||||
| 
 | ||||
|             if (value != None): | ||||
|                 query = ''' | ||||
|                 SELECT count(*) FROM karma_values WHERE value > %s | ||||
|                 ''' | ||||
|                 cur.execute(query, (value['value'],)) | ||||
|                 rank = cur.fetchone() | ||||
|                 rank = rank['count(*)'] + 1; | ||||
| 
 | ||||
|                 reply = '{0:s}: {1:s} has {2:d} points of karma (rank {3:d})'.format( | ||||
|                     nick, key, int(floor(value['value'])), rank) | ||||
|         except mdb.Error as e: | ||||
|             self.log.error("database error during handle karma query") | ||||
|             self.log.exception(e) | ||||
|             raise | ||||
|         finally: cur.close() | ||||
| 
 | ||||
|         return reply | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     print "Hello World" | ||||
| 
 | ||||
| # vi:tabstop=4:expandtab:autoindent | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user