From 986f7ced193f36c523c7ce1af401342e93cff92a Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 12 Apr 2019 20:50:50 +0000 Subject: [PATCH] Port to yaboli rewrite 5 --- .gitignore | 13 +- LICENSE | 2 +- bot.conf.default | 5 + infobot.conf.default | 9 -- infobot.py | 324 +++++++++++++++++++++---------------------- requirements.txt | 1 + 6 files changed, 175 insertions(+), 179 deletions(-) create mode 100644 bot.conf.default delete mode 100644 infobot.conf.default create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 99a4c59..54b9415 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ -**/__pycache__ +# python stuff +__pycache__/ + +# venv stuff +bin/ +include/ +lib/ +lib64 +pyvenv.cfg + +# config files *.conf -*.cookie diff --git a/LICENSE b/LICENSE index 8c068df..f2fd14f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Garmelon +Copyright (c) 2018 - 2019 Garmelon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/bot.conf.default b/bot.conf.default new file mode 100644 index 0000000..c2e2492 --- /dev/null +++ b/bot.conf.default @@ -0,0 +1,5 @@ +[general] +nick = () + +[rooms] +test diff --git a/infobot.conf.default b/infobot.conf.default deleted file mode 100644 index 8f57e4d..0000000 --- a/infobot.conf.default +++ /dev/null @@ -1,9 +0,0 @@ -[general] -nick = () -cookiefile = infobot.cookie - -[rooms] -# Format: -# room -# room=password -test diff --git a/infobot.py b/infobot.py index 89fbcb9..8fe1eb5 100644 --- a/infobot.py +++ b/infobot.py @@ -1,201 +1,191 @@ -import asyncio -import configparser import logging -import re import yaboli -from yaboli.utils import * class InfoBot(yaboli.Bot): - """ - Display information about the clients connected to a room in its nick. - """ + """ + Displays information about the clients connected to a room in its nick. + """ - async def on_command_specific(self, room, message, command, nick, argstr): - is_mentioned = similar(nick, room.session.nick) or similar(nick, "infobot") - is_mentioned = is_mentioned or re.fullmatch("p?bl?n?|\(p?bl?n?\)", normalize(nick)) - if is_mentioned: - if not argstr: - await self.botrulez_ping(room, message, command) - await self.botrulez_uptime(room, message, command) - await self.botrulez_kill(room, message, command) - await self.botrulez_restart(room, message, command) + ALIASES = ["InfoBot", "PBL", "(PBL)", "PBLN", "(PBLN)"] + HELP_GENERAL = "/me counts the types of clients in its nick" - await self.command_recount(room, message, command) + HELP_SPECIFIC = [ + "Displays information about the clients in a room in its nick:" + " (P\u00A0B\u00A0L\u00A0N)", + "You can also use @InfoBot, @PBL or @(PBL) for bot commands.", + "", + "!recount {atmention} - Recount people in the room", + #"!detail {atmention} - Detailed list of clients in this room", + #"!detail {atmention} @person - Detailed info regarding @person", + #"!hosts {atmention} [--mention] - Lists all hosts currently in this room", + "", + "Created by @Garmy using https://github.com/Garmelon/yaboli.", + "For additional info, try \"!help {atmention} \". Topics:", + "\tcount, lurkers, changelog", + ] - await self.command_help(room, message, command, argstr) - await self.command_detail(room, message, command, argstr) + HELP_COUNT = [ + "This bot counts the number of clients connected to a room. If you" + " open a room in two different tabs, the bot counts you twice.", + "The euphoria client, on the other hand, usually displays all" + " connections of an account with the same nick as one in the nick" + " list. Because of that, this bot's count is always at least as high" + " as the number of nicks on the nick list, similar to the number on" + " the button to toggle the nick list.", + "", + #"If the bot's count is off, try a !recount or a !restart {atmention}.", + "If the bot's count is off, try a !recount.", + ] - async def on_command_general(self, room, message, command, argstr): - if not argstr: - await self.botrulez_ping(room, message, command) - await self.botrulez_help(room, message, command, text="I count the types of clients in my nick") + HELP_LURKERS = [ + "People or bots who are connected to the room but haven't chosen a" + " nick are lurkers. The euphoria client doesn't display them in the" + " nick list.", + "This bot differentiates between people (L) and bots (N) who are" + " lurking.", + ] - await self.command_hosts(room, message, command, argstr) + HELP_CHANGELOG = [ + "(2019-04-12) update to yaboli rewrite 5", + ] - @yaboli.command("help") - async def command_help(self, room, message, argstr): - nick = mention(room.session.nick) - args = self.parse_args(argstr) - if not args: - text = ( - "Displays information about the clients in a room in its nick:" - " (P\u00A0B\u00A0L\u00A0N)\n" - "You can also use @InfoBot, @PBL or @(PBL) for bot commands.\n" - "\n" - "!recount {nick} - Recount people in the room\n" - "!detail {nick} - Detailed list of clients in this room\n" - "!detail {nick} @person - Detailed info regarding @person\n" - "!hosts {nick} [--mention] - Lists all hosts currently in this room\n" - "\n" - "Created by @Garmy using https://github.com/Garmelon/yaboli.\n" - "For additional info, try \"!help {nick} \". Topics:\n" - " count, lurkers, changelog" - ).format(nick=nick) - await room.send(text, message.mid) - else: - for topic in args: - if topic == "count": - text = ( - "This bot counts the number of clients connected to a room. If you" - " open a room in two different tabs, the bot counts you twice.\n" - "The euphoria client, on the other hand, usually displays all" - " connections of an account with the same nick as one in the nick list." - " Because of that, this bot's count is always as high as, or higher than," - " the number of nicks on the nick list, similar to the number on the" - " button to toggle the nick list.\n" - "\n" - "If the bot's count is off, try a !recount or a !restart {nick}." - ).format(nick=nick) - elif topic == "lurkers": - text = ( - "People or bots who are connected to the room but haven't chosen a" - " nick are lurkers. The euphoria client doesn't display them in the" - " nick list.\n" - "This bot differentiates between people (L) and bots (N) who are" - " lurking." - ) - elif topic == "changelog": - text = ( - "- add !recount command\n" - "- fix bot counting incorrectly\n" - "- port to rewrite-4 of yaboli\n" - "- add !detail and !manager commands\n" - ) - else: - text = f"Topic {topic!r} does not exist." + HELP_TOPICS = { + "count": HELP_COUNT, + "lurkers": HELP_LURKERS, + "changelog": HELP_CHANGELOG, + } - await room.send(text, message.mid) + def __init__(self, config_file): + super().__init__(config_file) + self.register_botrulez(help_=False, kill=True) # using our own help functions + self.register_general("help", self.cmd_help_general, args=False) + self.register_specific("help", self.cmd_help_specific) + self.register_specific("recount", self.cmd_recount, args=False) - async def update_nick(self, room): - p = len(room.listing.get(types=["account", "agent"], lurker=False)) - b = len(room.listing.get(types=["bot"], lurker=False)) - l = len(room.listing.get(types=["account", "agent"], lurker=True)) - n = len(room.listing.get(types=["bot"], lurker=True)) + async def cmd_help_specific(self, room, message, args): + if not args.has_args(): + await message.reply(self.format_help(room, self.HELP_SPECIFIC)) + return - name = [] - if p > 0: name.append(f"{p}P") - if b > 0: name.append(f"{b}B") - if l > 0: name.append(f"{l}L") - if n > 0: name.append(f"{n}N") - name = "\u0001(" + " ".join(name) + ")" + if len(args.basic()) > 5: + await message.reply("A maximum of 5 help topics is allowed.") + return - if room.session.nick != name: - await room.nick(name) + for topic in args.basic(): + help_lines = self.HELP_TOPICS.get(topic.lower()) + if help_lines is None: + await message.reply(f"Module {topic!r} not found.") + else: + await message.reply(self.format_help(room, help_lines)) - async def on_connected(self, room, log): - await self.update_nick(room) + async def cmd_recount(self, room, message, args): + await self.update_nick(room) + await message.reply("Recalibrated.") - async def on_join(self, room, session): - await self.update_nick(room) - await room.who() - await self.update_nick(room) + # Updating the nick - async def on_part(self, room, session): - await self.update_nick(room) - await room.who() - await self.update_nick(room) + def format_nick(self, users): + people = 0 + bots = 1 # room.who() doesn't include the bot itself. + lurkers = 0 + nurkers = 0 - async def on_nick(self, room, sid, uid, from_nick, to_nick): - await self.update_nick(room) - await room.who() - await self.update_nick(room) + for user in users: + if user.is_bot: + if user.nick: + bots += 1 + else: + nurkers += 1 + else: # user is person or something else + if user.nick: + people += 1 + else: + lurkers += 1 - @yaboli.command("recount") - async def command_recount(self, room, message): - await room.who() - await self.update_nick(room) - await room.send("Recalibrated.", message.mid) + info = [] - @yaboli.command("detail") - async def command_detail(self, room, message, argstr): - sessions = room.listing.get() - args = self.parse_args(argstr) + if people > 0: + info.append(f"{people}P") - if args: - lines = [] - for arg in args: - if arg.startswith("@") and arg[1:]: - nick = arg[1:] - else: - nick = arg + info.append(f"{bots}B") - for ses in sessions: - if similar(ses.nick, nick): - lines.append(self.format_session(ses)) + if lurkers > 0: + info.append(f"{lurkers}L") - if lines: - text = "\n".join(lines) - else: - text = "No sessions found that match any of the nicks." - await room.send(text, message.mid) + if nurkers > 0: + info.append(f"{nurkers}N") - else: - sessions = sorted(sessions, key=lambda s: s.uid) - lines = [self.format_session(s) for s in sessions] - text = "\n".join(lines) - await room.send(text, message.mid) + return "\u0001(" + " ".join(info) + ")" - @staticmethod - def format_session(s): - is_staff = "yes" if s.is_staff else "no" - is_manager = "yes" if s.is_manager else "no" - return f"UID: {s.uid}\t| SID: {s.sid}\t| staff: {is_staff}\t| host: {is_manager}\t| nick: {s.nick!r}" + async def update_nick(self, room): + users = await room.who() + new_nick = self.format_nick(users) + await room.nick(new_nick) - @yaboli.command("hosts") - async def command_hosts(self, room, message, argstr): - flags, args, kwargs = self.parse_flags(self.parse_args(argstr)) - sessions = room.listing.get() - sessions = sorted(set(s.nick for s in sessions if s.is_manager)) + async def on_connected(self, room): + await self.update_nick(room) - if "ping" in kwargs: - sessions = [mention(s) for s in sessions] - else: - sessions = [s for s in sessions] + async def on_join(self, room, user): + await self.update_nick(room) - if sessions: - text = "Hosts that are currently in this room:\n" + "\n".join(sessions) - else: - text = "No hosts currently in this room." - await room.send(text, message.mid) + async def on_part(self, room, user): + await self.update_nick(room) -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 = InfoBot(nick, cookiefile=cookiefile) - - for room, password in config.items("rooms"): - if not password: - password = None - bot.join_room(room, password=password) - - asyncio.get_event_loop().run_forever() +# @yaboli.command("detail") +# async def command_detail(self, room, message, argstr): +# sessions = room.listing.get() +# args = self.parse_args(argstr) +# +# if args: +# lines = [] +# for arg in args: +# if arg.startswith("@") and arg[1:]: +# nick = arg[1:] +# else: +# nick = arg +# +# for ses in sessions: +# if similar(ses.nick, nick): +# lines.append(self.format_session(ses)) +# +# if lines: +# text = "\n".join(lines) +# else: +# text = "No sessions found that match any of the nicks." +# await room.send(text, message.mid) +# +# else: +# sessions = sorted(sessions, key=lambda s: s.uid) +# lines = [self.format_session(s) for s in sessions] +# text = "\n".join(lines) +# await room.send(text, message.mid) +# +# @staticmethod +# def format_session(s): +# is_staff = "yes" if s.is_staff else "no" +# is_manager = "yes" if s.is_manager else "no" +# return f"UID: {s.uid}\t| SID: {s.sid}\t| staff: {is_staff}\t| host: {is_manager}\t| nick: {s.nick!r}" +# +# @yaboli.command("hosts") +# async def command_hosts(self, room, message, argstr): +# flags, args, kwargs = self.parse_flags(self.parse_args(argstr)) +# sessions = room.listing.get() +# sessions = sorted(set(s.nick for s in sessions if s.is_manager)) +# +# if "ping" in kwargs: +# sessions = [mention(s) for s in sessions] +# else: +# sessions = [s for s in sessions] +# +# if sessions: +# text = "Hosts that are currently in this room:\n" + "\n".join(sessions) +# else: +# text = "No hosts currently in this room." +# await room.send(text, message.mid) if __name__ == "__main__": - main("infobot.conf") + yaboli.enable_logging(level=logging.DEBUG) + yaboli.run(InfoBot) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9835705 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +yaboli >=0.2.0, <0.3.0