· 8 years ago · Jun 12, 2018, 12:28 AM
1
2import yaboli
3from yaboli.utils import *
4import asyncio
5import random
6import re
7import sys
8
9
10
11class PointDB(yaboli.Database):
12 @yaboli.Database.operation
13 def initialize(conn):
14 cur = conn.cursor()
15 cur.execute((
16 "CREATE TABLE IF NOT EXISTS Points ("
17 "nick TEXT UNIQUE NOT NULL,"
18 "points INTEGER"
19 ")"
20 ))
21 conn.commit()
22
23 @yaboli.Database.operation
24 def add_point(conn, nick):
25 nick = mention_reduced(nick)
26 cur = conn.cursor()
27
28 cur.execute("INSERT OR IGNORE INTO Points (nick, points) VALUES (?, 0)", (nick,))
29 cur.execute("UPDATE Points SET points=points+2 WHERE nick=?", (nick,))
30 conn.commit()
31
32 @yaboli.Database.operation
33 def points_of(conn, nick):
34 nick = mention_reduced(nick)
35 cur = conn.cursor()
36
37 cur.execute("SELECT points FROM Points WHERE nick=?", (nick,))
38 res = cur.fetchone()
39 if res is not None:
40 return res[0]
41 else:
42 return 0
43
44class PlusOne(yaboli.Bot):
45 """
46 Count +1s awarded to users by other users.
47 """
48
49 PLUSONE_RE = r"(\+2)\s*(.*)"
50 MENTION_RE = r"((for|to)\s+)?@(\S+)"
51
52 def __init__(self, db):
53 super().__init__("PlusTwo")
54
55 self.db = db
56
57 self.help_general = "/me counts +2s."
58 self.help_specific = (
59 "Counts +2s: Simply reply \"+2\" to someone's message to award them a point.\n"
60 "Alternatively, specify a person with: \"+2 [to|for] @person\"\n"
61 "!points - show your own points\n"
62 "!points <person1> [<person2> ...] - list other people's points\n\n"
63 "Created by @ASCII-art as a ripoff of @PlusOne\n"
64 )
65 self.help_specific += self.list_help_topics()
66 self.ping_message = ":bronze!?:"
67
68 self.register_command("points", self.command_points, specific=False)
69 self.register_trigger(self.PLUSONE_RE, self.trigger_plusone)
70
71 async def trigger_plusone(self, message, match):
72 nick = None
73 specific = re.match(self.MENTION_RE, match.group(3))
74
75 if specific:
76 nick = specific.group(3)
77 elif message.parent:
78 parent_message = await self.room.get_message(message.parent)
79 nick = parent_message.sender.nick
80
81 if nick is None:
82 await self.room.send("You can't +2 nothing...", message.mid)
83 elif similar(nick, message.sender.nick):
84 newtext = random.choice([
85 "Don't +2 yourself, that's... nasty.",
86 "Don't +2 yourself, that's... It just doesn't work that way, alright?",
87 "No points for " + nick + "!",
88 "No", # Attempt to trigger @Elements
89 "Would you kindly stop that?",
90 "Where'd you get that idea from? It would never work."
91 ])
92 await self.room.send(newtext, message.mid)
93 else:
94 await self.db.add_point(nick)
95 await self.room.send(f"2 points for user {mention(nick)} registered.", message.mid)
96
97 async def command_points(self, message, argstr):
98 args = self.parse_args(argstr)
99 if not args:
100 points = await self.db.points_of(message.sender.nick)
101 await self.room.send(
102 f"You have {points} point{'s' if points != 1 else ''}.",
103 message.mid
104 )
105 else:
106 response = []
107 for arg in args:
108 if arg[:1] == "@":
109 nick = arg[1:]
110 points = await self.db.points_of(nick)
111 response.append(f"@{mention(nick)} has {points} point{'' if points == 1 else 's'}.")
112 else:
113 response.append(f"{arg!r} is not a mention.")
114 await self.room.send("\n".join(response), message.mid)
115
116def main():
117 if len(sys.argv) == 3:
118 db = PointDB(sys.argv[2])
119 asyncio.get_event_loop().run_until_complete(db.initialize())
120 run_bot(PlusOne, sys.argv[1], db)
121 else:
122 print("USAGE:")
123 print(f" {sys.argv[0]} <room> <pointsdb>")
124 return
125
126if __name__ == "__main__":
127 main()