Use database properly
This commit is contained in:
parent
bc7105d616
commit
94b0ce78ed
3 changed files with 141 additions and 101 deletions
|
|
@ -1,2 +0,0 @@
|
|||
- mention (without @) or otherwise make clear who which point goes to
|
||||
- add command to display people with most points (top 10 or so)
|
||||
30
import_points.py
Normal file
30
import_points.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import asyncio
|
||||
import sqlite3
|
||||
import sys
|
||||
|
||||
import yaboli
|
||||
from yaboli.utils import *
|
||||
|
||||
from plusone import PointsDB
|
||||
|
||||
|
||||
async def add_points(db, room, points):
|
||||
for (nick, amount) in points:
|
||||
print(f"&{room}: {mention(nick, ping=False)} + {amount}")
|
||||
await db.add_points(room, nick, amount)
|
||||
|
||||
def main(to_dbfile, from_dbfile, room):
|
||||
from_db = sqlite3.connect(from_dbfile)
|
||||
res = from_db.execute("SELECT nick, points FROM Points")
|
||||
points = res.fetchall()
|
||||
|
||||
to_db = PointsDB(to_dbfile)
|
||||
asyncio.get_event_loop().run_until_complete(add_points(to_db, room, points))
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) == 4:
|
||||
main(sys.argv[1], sys.argv[2], sys.argv[3])
|
||||
else:
|
||||
print(" USAGE:")
|
||||
print(f"{sys.argv[0]} <pointsdb> <old_pointsdb> <room>")
|
||||
exit(1)
|
||||
210
plusone.py
210
plusone.py
|
|
@ -7,132 +7,144 @@ import yaboli
|
|||
from yaboli.utils import *
|
||||
|
||||
|
||||
# Turn all debugging on
|
||||
asyncio.get_event_loop().set_debug(True)
|
||||
#logging.getLogger("asyncio").setLevel(logging.INFO)
|
||||
#logging.getLogger("yaboli").setLevel(logging.DEBUG)
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logger = logging.getLogger("plusone")
|
||||
|
||||
|
||||
class PointDB(yaboli.Database):
|
||||
def initialize(self, db): # called automatically
|
||||
class PointsDB(yaboli.Database):
|
||||
def initialize(self, db):
|
||||
with db:
|
||||
db.execute((
|
||||
"CREATE TABLE IF NOT EXISTS Points ( "
|
||||
"nick TEXT UNIQUE NOT NULL, "
|
||||
"points INTEGER "
|
||||
"CREATE TABLE IF NOT EXISTS points ("
|
||||
"normalized_nick TEXT PRIMARY KEY, "
|
||||
"nick TEXT NOT NULL, "
|
||||
"room TEXT NOT NULL, "
|
||||
"points INTEGER NOT NULL"
|
||||
")"
|
||||
))
|
||||
db.commit()
|
||||
|
||||
@yaboli.operation
|
||||
def add_point(self, db, nick):
|
||||
nick = normalize(nick)
|
||||
|
||||
cur = db.cursor()
|
||||
cur.execute("INSERT OR IGNORE INTO Points (nick, points) VALUES (?, 0)", (nick,))
|
||||
cur.execute("UPDATE Points SET points=points+1 WHERE nick=?", (nick,))
|
||||
db.commit()
|
||||
|
||||
@yaboli.operation
|
||||
def points_of(self, db, nick):
|
||||
nick = normalize(nick)
|
||||
|
||||
cur = db.execute("SELECT points FROM Points WHERE nick=?", (nick,))
|
||||
res = cur.fetchone()
|
||||
return res[0] if res is not None else 0
|
||||
|
||||
|
||||
PLUSONE_RE = r"(\+1|:\+1:|:bronze(!\?|\?!)?:)\s*(.*)"
|
||||
MENTION_RE = r"((to)\s+@?|@)(\S+)"
|
||||
|
||||
class PlusOne(yaboli.Bot):
|
||||
"""
|
||||
Count +1s awarded to users by other users.
|
||||
"""
|
||||
|
||||
PING_TEXT = ":bronze!?:"
|
||||
SHORT_HELP = "/me counts :+1:s"
|
||||
LONG_HELP = (
|
||||
"Counts +1/:+1:/:bronze:s: Simply reply \"+1\" to someone's message to award them a point.\n"
|
||||
"Alternatively, specify a person with: \"+1 [to] @person\"\n"
|
||||
"\n"
|
||||
"!points - show your own points\n"
|
||||
"!points <person1> [<person2> ...] - list other people's points\n"
|
||||
"\n"
|
||||
"Created by @Garmy using https://github.com/Garmelon/yaboli.\n"
|
||||
def add_points(self, db, room, nick, points):
|
||||
normalized_nick = normalize(nick)
|
||||
with db:
|
||||
db.execute(
|
||||
"INSERT OR IGNORE INTO points VALUES (?,?,?,0)",
|
||||
(normalized_nick, nick, room)
|
||||
)
|
||||
db.execute((
|
||||
"UPDATE points "
|
||||
"SET points=points+?, nick=? "
|
||||
"WHERE normalized_nick=? AND room=?"
|
||||
), (points, nick, normalized_nick, room))
|
||||
|
||||
async def on_created(self, room):
|
||||
room.pointdb = PointDB(f"points-{room.roomname}.db")
|
||||
@yaboli.operation
|
||||
def points_of(self, db, room, nick):
|
||||
normalized_nick = normalize(nick)
|
||||
print(nick, normalized_nick, room)
|
||||
res = db.execute((
|
||||
"SELECT points FROM points "
|
||||
"WHERE normalized_nick=? AND room=?"
|
||||
), (normalized_nick, room))
|
||||
points = res.fetchone()
|
||||
return points[0] if points else 0
|
||||
|
||||
class PlusOne:
|
||||
SHORT_DESCRIPTION = "counts :+1:s"
|
||||
DESCRIPTION = (
|
||||
"'plusone' counts +1/:+1:/:bronze:s:"
|
||||
" Simply reply '+1' to someone's message to give them a point.\n"
|
||||
" Alternatively, specify a person with: '+1 [to] @person'.\n"
|
||||
)
|
||||
COMMANDS = (
|
||||
"!points - show your own points\n"
|
||||
"!points <nick> [<nick> ...] - list other people's points\n"
|
||||
)
|
||||
AUTHOR = "Created by @Garmy using github.com/Garmelon/yaboli\n"
|
||||
|
||||
PLUSONE_RE = r"\s*(\+1|:\+1:|:bronze(!\?|\?!)?:)\s*(.*)"
|
||||
MENTION_RE = r"(to\s+@?|@)(\S+)"
|
||||
|
||||
def __init__(self, dbfile):
|
||||
self.db = PointsDB(dbfile)
|
||||
|
||||
@yaboli.command("points")
|
||||
async def command_points(self, room, message, argstr):
|
||||
args = yaboli.Bot.parse_args(argstr)
|
||||
if args:
|
||||
lines = []
|
||||
for nick in args:
|
||||
if nick[0] == "@": # a bit hacky, requires you to mention nicks starting with '@'
|
||||
nick = nick[1:]
|
||||
|
||||
points = await self.db.points_of(room.roomname, nick)
|
||||
line = f"{mention(nick, ping=False)} has {points} point{'' if points == 1 else 's'}."
|
||||
lines.append(line)
|
||||
|
||||
text = "\n".join(lines)
|
||||
await room.send(text, message.mid)
|
||||
|
||||
else: # your own points
|
||||
points = await self.db.points_of(room.roomname, message.sender.nick)
|
||||
text = f"You have {points} point{'' if points == 1 else 's'}."
|
||||
await room.send(text, message.mid)
|
||||
|
||||
@yaboli.trigger(PLUSONE_RE, flags=re.IGNORECASE)
|
||||
async def trigger_plusone(self, room, message, match):
|
||||
specific = re.match(self.MENTION_RE, match.group(3))
|
||||
|
||||
nick = None
|
||||
if specific:
|
||||
nick = specific.group(2)
|
||||
elif message.parent:
|
||||
parent_message = await room.get_message(message.parent)
|
||||
nick = parent_message.sender.nick
|
||||
|
||||
if nick is None:
|
||||
text = "You can't +1 nothing..."
|
||||
elif similar(nick, message.sender.nick):
|
||||
text = "There's no such thing as free points on the internet."
|
||||
else:
|
||||
await self.db.add_points(room.roomname, nick, 1)
|
||||
text = f"Point for user {mention(nick, ping=False)} registered."
|
||||
await room.send(text, message.mid)
|
||||
|
||||
class PlusOneBot(yaboli.Bot):
|
||||
PING_TEXT = ":bronze?!:"
|
||||
SHORT_HELP = PlusOne.SHORT_DESCRIPTION
|
||||
LONG_HELP = PlusOne.DESCRIPTION + PlusOne.COMMANDS + PlusOne.AUTHOR
|
||||
|
||||
def __init__(self, nick, dbfile, cookiefile=None):
|
||||
super().__init__(nick, cookiefile=cookiefile)
|
||||
self.plusone = PlusOne(dbfile)
|
||||
|
||||
async def on_send(self, room, message):
|
||||
await super().on_send(room, message)
|
||||
|
||||
await self.plusone.trigger_plusone(room, message)
|
||||
|
||||
async def on_command_specific(self, room, message, command, nick, argstr):
|
||||
if similar(nick, room.session.nick) and not argstr:
|
||||
await self.botrulez_ping(room, message, command, text=self.PING_TEXT)
|
||||
await self.botrulez_help(room, message, command, text=self.LONG_HELP)
|
||||
await self.botrulez_uptime(room, message, command)
|
||||
await self.botrulez_kill(room, message, command)
|
||||
await self.botrulez_restart(room, message, command)
|
||||
|
||||
await self.botrulez_kill(room, message, command, text="-1")
|
||||
await self.botrulez_restart(room, message, command, text="∓1")
|
||||
|
||||
async def on_command_general(self, room, message, command, argstr):
|
||||
if not argstr:
|
||||
await self.botrulez_ping(room, message, command, text=self.PING_TEXT)
|
||||
await self.botrulez_help(room, message, command, text=self.SHORT_HELP)
|
||||
|
||||
await self.command_points(room, message, command, argstr)
|
||||
|
||||
async def on_send(self, room, message):
|
||||
await super().on_send(room, message)
|
||||
await self.trigger_plusone(room, message)
|
||||
|
||||
@yaboli.command("points")
|
||||
async def command_points(self, room, message, argstr):
|
||||
args = self.parse_args(argstr)
|
||||
if not args:
|
||||
points = await room.pointdb.points_of(message.sender.nick)
|
||||
await room.send(
|
||||
f"You have {points} point{'s' if points != 1 else ''}.",
|
||||
message.mid
|
||||
)
|
||||
else:
|
||||
response = []
|
||||
for arg in args:
|
||||
if arg[:1] == "@":
|
||||
nick = arg[1:]
|
||||
else:
|
||||
nick = arg
|
||||
points = await room.pointdb.points_of(nick)
|
||||
response.append(f"{mention(nick)} has {points} point{'' if points == 1 else 's'}.")
|
||||
await room.send("\n".join(response), message.mid)
|
||||
|
||||
@yaboli.trigger(PLUSONE_RE)
|
||||
async def trigger_plusone(self, room, message, match):
|
||||
nick = None
|
||||
specific = re.match(MENTION_RE, match.group(3))
|
||||
|
||||
if specific:
|
||||
nick = specific.group(3)
|
||||
if nick[0] == "@":
|
||||
nick = nick[1:]
|
||||
elif message.parent:
|
||||
parent_message = await room.get_message(message.parent)
|
||||
nick = parent_message.sender.nick
|
||||
|
||||
if nick is None:
|
||||
await room.send("You can't +1 nothing...", message.mid)
|
||||
elif similar(nick, message.sender.nick):
|
||||
await room.send("Don't +1 yourself, that's not how things work.", message.mid)
|
||||
else:
|
||||
await room.pointdb.add_point(nick)
|
||||
await room.send(f"Point for user {mention(nick, ping=False)} registered.", message.mid)
|
||||
await self.plusone.command_points(room, message, command, argstr)
|
||||
|
||||
def main(configfile):
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
config = configparser.ConfigParser(allow_no_value=True)
|
||||
config.read(configfile)
|
||||
|
||||
nick = config.get("general", "nick")
|
||||
cookiefile = config.get("general", "cookiefile", fallback=None)
|
||||
bot = PlusOne(nick, cookiefile=cookiefile)
|
||||
dbfile = config.get("general", "dbfile", fallback=None)
|
||||
bot = PlusOneBot(nick, dbfile, cookiefile=cookiefile)
|
||||
|
||||
for room, password in config.items("rooms"):
|
||||
if not password:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue