1+ from cloudbot import hook
2+ from cloudbot .util import timeformat , formatting , database
3+
4+ import time
5+ import re
6+
7+ CAN_DOWNVOTE = False
8+
9+ from sqlalchemy import Table , Column , Integer , String , PrimaryKeyConstraint
10+ from sqlalchemy import select
11+
12+ karma_table = Table (
13+ 'karma' ,
14+ database .metadata ,
15+ Column ('nick_vote' , String (25 )),
16+ Column ('up_karma' , Integer , default = 0 ),
17+ Column ('down_karma' , Integer , default = 0 ),
18+ PrimaryKeyConstraint ('nick_vote' )
19+ )
20+
21+ voters = {}
22+
23+
24+ def up (db , nick_vote ):
25+ """ gives one karma to a user """
26+ db .execute ("""INSERT or IGNORE INTO karma(
27+ nick_vote,
28+ up_karma,
29+ down_karma,
30+ total_karma) values(:nick,0,0,0)""" , {'nick' : nick_vote .lower ()})
31+ query = karma_table .update ().values (
32+ up_karma = karma_table .c .up_karma + 1
33+ ).where (karma_table .c .nick_vote == nick_vote .lower ())
34+ db .execute (query )
35+ db .commit ()
36+
37+
38+ def down (db , nick_vote ):
39+ """ takes one karma away from a user """
40+ db .execute ("""INSERT or IGNORE INTO karma(
41+ nick_vote,
42+ up_karma,
43+ down_karma,
44+ total_karma) values(:nick,0,0,0)""" , {'nick' : nick_vote .lower ()})
45+ query = karma_table .update ().values (
46+ down_karma = karma_table .c .down_karma + 1
47+ ).where (karma_table .c .nick_vote == nick_vote .lower ())
48+ db .execute (query )
49+ db .commit ()
50+
51+
52+ def allowed (uid ):
53+ """ checks if a user is allowed to vote, and keeps track of voters """
54+ global voters
55+ time_restriction = 300.0
56+
57+ # clear expired voters
58+ for _uid , _timestamp in voters .items ():
59+ if (time .time () - _timestamp ) >= time_restriction :
60+ del voters [_uid ]
61+
62+ if uid in voters :
63+ last_voted = voters [uid ]
64+ return False , timeformat .time_until (last_voted , now = time .time () - time_restriction )
65+ else :
66+ voters [uid ] = time .time ()
67+ return True , 0
68+
69+ karma_re = re .compile ('^([a-z0-9_\-\[\]\\ ^{}|`]{3,})(\+\+|\-\-)$' , re .I )
70+
71+
72+ @hook .regex (karma_re )
73+ def karma_add (match , nick , conn , db , notice ):
74+ nick_vote = match .group (1 ).strip ()
75+ if nick .lower () == nick_vote .lower ():
76+ notice ("You can't vote on yourself!" )
77+ return
78+
79+ uid = ":" .join ([conn .name , nick , nick_vote ]).lower ()
80+ vote_allowed , when = allowed (uid )
81+
82+ if vote_allowed :
83+ if match .group (2 ) == '++' :
84+ up (db , nick_vote )
85+ notice ("Gave {} 1 karma!" .format (nick_vote ))
86+ if match .group (2 ) == '--' and CAN_DOWNVOTE :
87+ down (db , nick_vote )
88+ notice ("Took away 1 karma from {}." .format (nick_vote ))
89+ else :
90+ return
91+ else :
92+ notice ("You are trying to vote too often. You can vote on this user again in {}!" .format (when ))
93+
94+
95+ @hook .command ('karma' , 'k' )
96+ def karma (text , chan , db ):
97+ """k/karma <nick> -- returns karma stats for <nick>"""
98+
99+ if not chan .startswith ('#' ):
100+ return
101+
102+ nick_vote = text
103+
104+ query = db .execute (
105+ select ([karma_table ])
106+ .where (karma_table .c .nick_vote == nick_vote .lower ())
107+ ).fetchall ()
108+
109+ if not query :
110+ return "That user has no karma."
111+ else :
112+ query = query [0 ]
113+ karma_text = formatting .pluralize (query ['up_karma' ] - query ['down_karma' ], 'karma point' )
114+ return "{} has {}." .format (nick_vote , karma_text )
0 commit comments