diff options
| author | 2018-09-26 18:27:17 +0100 | |
|---|---|---|
| committer | 2018-09-26 18:27:17 +0100 | |
| commit | 51a52e2b0e54031cce5876f54d1d48c268b5441c (patch) | |
| tree | a4c0e8e86c55aa701b06297d5b5a2ceebeaab60d /modules | |
| parent | Also use docstrings to check if a command has help available, allow one-string (diff) | |
| signature | ||
Switch to using @Utils.hook and docstrings for event hooks
Diffstat (limited to 'modules')
67 files changed, 743 insertions, 638 deletions
diff --git a/modules/8ball.py b/modules/8ball.py index 37d38743..ebfb1b0c 100644 --- a/modules/8ball.py +++ b/modules/8ball.py @@ -1,5 +1,5 @@ import random -from src import Utils +from src import ModuleManager, Utils CHOICES = [ "Definitely", @@ -28,15 +28,11 @@ CHOICES = [ "Sources say maybe" ] -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command.8ball").hook( - self.decide, - min_args=1, - help="Ask the mystic 8ball a question!", - usage="<question>" - ) - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.8ball", min_args=1, usage="<question>") def decide(selfs, event): + """ + Ask the mystic 8ball a question! + """ event["stdout"].write("You shake the magic ball... it " "says " + Utils.bold(random.choice(CHOICES))) diff --git a/modules/accept_invite.py b/modules/accept_invite.py index 40888f8a..e9b2add9 100644 --- a/modules/accept_invite.py +++ b/modules/accept_invite.py @@ -2,11 +2,11 @@ from src import Utils class Module(object): def __init__(self, bot, events, exports): - events.on("received.invite").hook(self.on_invite) exports.add("serverset", {"setting": "accept-invites", "help": "Set whether I accept invites on this server", "validate": Utils.bool_or_none}) + @Utils.hook("received.invite") def on_invite(self, event): if event["server"].is_own_nickname(event["target_user"].nickname): if event["server"].get_setting("accept-invites", True): diff --git a/modules/admin.py b/modules/admin.py index 392a44ff..1742758e 100644 --- a/modules/admin.py +++ b/modules/admin.py @@ -1,29 +1,39 @@ +from src import ModuleManager, Utils - -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command.changenickname").hook( - self.change_nickname, permission="changenickname", - min_args=1, help="Change my nickname", usage="<nickname>") - events.on("received.command.raw").hook(self.raw, - permission="raw", min_args=1, usage="<raw line>", - help="Send a raw IRC line through the bot") - events.on("received.command.part").hook(self.part, - permission="part", min_args=1, help="Part from a channel", - usage="<#channel>") - events.on("received.command.reconnect").hook(self.reconnect, - permission="reconnect", help="Reconnect from this network") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.changenickname", + permission="changenickname", min_args=1, usage="<nickname>") def change_nickname(self, event): + """ + Change my nickname + """ nickname = event["args_split"][0] event["server"].send_nick(nickname) + @Utils.hook("received.command.raw", permission="raw", min_args=1, + usage="<raw line>") def raw(self, event): + """ + Send a line of raw IRC data + """ event["server"].send(event["args"]) + @Utils.hook("received.command.part", permission="part", usage="[#channel]") def part(self, event): - event["server"].send_part(event["args_split"][0]) + """ + Part from the current or given channel + """ + if event["args"]: + target = event["args_split"][0] + elif event["is_channel"]: + target = event["target"].name + else: + event["stderr"].write("No channel provided") + event["server"].send_part(target) + @Utils.hook("received.command.reconnect", permission="reconnect") def reconnect(self, event): + """ + Reconnect to the current network + """ event["server"].send_quit("Reconnecting") diff --git a/modules/auto_mode.py b/modules/auto_mode.py index af6dc606..08648ca3 100644 --- a/modules/auto_mode.py +++ b/modules/auto_mode.py @@ -3,26 +3,6 @@ from src import Utils class Module(object): _name = "AutoMode" def __init__(self, bot, events, exports): - self.bot = bot - - events.on("received.join").hook(self.on_join) - - events.on("received.command.addop").hook(self.add_op, - require_mode="o", min_args=1, channel_only=True, - usage="<nickname>", help="Add a user to the automode op list") - events.on("received.command.removeop").hook(self.remove_op, - require_mode="o", min_args=1, channel_only=True, - usage="<nickname>", help="Remove a user from the automode " - "op list") - - events.on("received.command.addvoice").hook(self.add_voice, - require_mode="o", min_args=1, channel_only=True, - usage="<nickname>", help="Add a user to the automode voice list") - events.on("received.command.removevoice").hook(self.remove_voice, - require_mode="o", min_args=1, channel_only=True, - usage="<nickname>", help="Remove a user from the automode " - "voice list") - exports.add("channelset", {"setting": "automode", "help": "Disable/Enable automode", "validate": Utils.bool_or_none}) @@ -34,8 +14,11 @@ class Module(object): if modes: channel.send_mode("+%s" % "".join(modes), " ".join([user.nickname for mode in modes])) + + @Utils.hook("received.join") def on_join(self, event): self._check_modes(event["channel"], event["user"]) + @Utils.hook("received.account") def on_account(self, event): for channel in event["user"].channels: self._check_modes(channel, event["user"]) @@ -70,12 +53,32 @@ class Module(object): event["stdout"].write("Removed automode %s from '%s'" % ( mode_name, target_user.nickname)) + @Utils.hook("received.command.addop", require_mode="o", min_args=1, + channel_only=True, usage="<nickname>") def add_op(self, event): + """ + Add a user to the auto-mode list as an op + """ self._add_mode(event, "o", "op") + @Utils.hook("received.command.removeop", require_mode="o", min_args=1, + channel_only=True, usage="<nickname>") def remove_op(self, event): + """ + Remove a user from the auto-mode list as an op + """ self._remove_mode(event, "o", "op") + @Utils.hook("received.command.addvoice", require_mode="o", min_args=1, + channel_only=True, usage="<nickname>") def add_voice(self, event): + """ + Add a user to the auto-mode list as a voice + """ self._add_mode(event, "v", "voice") + @Utils.hook("received.command.removevoice", require_mode="o", min_args=1, + channel_only=True, usage="<nickname>") def remove_voice(self, event): + """ + Remove a user from the auto-mode list as anvoice + """ self._remove_mode(event, "v", "voice") diff --git a/modules/bitcoin.py b/modules/bitcoin.py index c85e6bf1..1c88c0bb 100644 --- a/modules/bitcoin.py +++ b/modules/bitcoin.py @@ -1,13 +1,13 @@ -from src import Utils +from src import ModuleManager, Utils -class Module(object): +class Module(ModuleManager.BaseModule): _name = "BTC" - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command.btc").hook(self.btc, - help="Get the exchange rate of bitcoins", usage="[currency]") + @Utils.hook("received.command.btc", usage="[currency]") def btc(self, event): + """ + Get the exchange rate of bitcoins + """ currency = (event["args"] or "USD").upper() page = Utils.get_url("https://blockchain.info/ticker", json=True) diff --git a/modules/books.py b/modules/books.py index e0569a76..7a0204a6 100644 --- a/modules/books.py +++ b/modules/books.py @@ -1,20 +1,12 @@ import json, re -from src import Utils +from src import ModuleManager, Utils URL_GOOGLEBOOKS = "https://www.googleapis.com/books/v1/volumes" URL_BOOKINFO = "https://books.google.co.uk/books?id=%s" REGEX_BOOKID = re.compile("id=([\w\-]+)") -class Module(object): +class Module(ModuleManager.BaseModule): _name = "ISBN" - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command.isbn").hook(self.isbn, - help="Get book information from a provided ISBN", - min_args=1, usage="<isbn>") - events.on("received.command.book").hook(self.book, - help="Get book information from a provided title", - min_args=1, usage="<book title>") def get_book(self, query, event): page = Utils.get_url(URL_GOOGLEBOOKS, get_params={ @@ -44,12 +36,20 @@ class Module(object): else: event["stderr"].write("Failed to load results") + @Utils.hook("received.command.isbn", min_args=1, usage="<isbn>") def isbn(self, event): + """ + Get book information from a provided ISBN + """ isbn = event["args_split"][0] if len(isbn) == 10: isbn = "978%s" % isbn isbn = isbn.replace("-", "") self.get_book("isbn:%s" % isbn, event) + @Utils.hook("received.command.book", min_args=1, usage="<book title>") def book(self, event): + """ + Get book information from a provided title + """ self.get_book(event["args"], event) diff --git a/modules/bot_channel.py b/modules/bot_channel.py index cbe50119..2e2ff6fb 100644 --- a/modules/bot_channel.py +++ b/modules/bot_channel.py @@ -1,12 +1,11 @@ - +from src import Utils class Module(object): def __init__(self, bot, events, exports): - events.on("received.numeric.001").hook(self.do_join) - exports.add("serverset", {"setting": "bot-channel", "help": "Set main channel"}) + @Utils.hook("received.numeric.001") def do_join(self, event): event["server"].send_join(event["server"].get_setting("bot-channel", "#bitbot")) diff --git a/modules/channel_op.py b/modules/channel_op.py index ad2233d9..13f9df5a 100644 --- a/modules/channel_op.py +++ b/modules/channel_op.py @@ -3,46 +3,6 @@ from src import Utils class Module(object): _name = "Channel Op" def __init__(self, bot, events, exports): - self.bot = bot - - events.on("received.command").on("kick", "k").hook(self.kick, - channel_only=True, require_mode="o", usage="<nickname> [reason]", - min_args=1, help="Kick a user from the channel") - events.on("received.command.ban").hook(self.ban, channel_only=True, - require_mode="o", min_args=1, usage="<nickname/hostmask>", - help="Ban a user/hostmask from the channel") - events.on("received.command.unban").hook(self.unban, - channel_only=True, require_mode="o", usage="<nickname/hostmask>", - min_args=1, help="Unban a user/hostmask from the channel") - - events.on("received.command").on("kickban", "kb" - ).hook(self.kickban, channel_only=True, require_mode="o", - min_args=1, help="Kickban a user from the channel", - usage="<nickanme> [reason]") - - events.on("received.command.op" - ).hook(self.op, channel_only=True, require_mode="o", - help="Give +o to a user", usage="[nickname]") - events.on("received.command.deop" - ).hook(self.deop, channel_only=True, require_mode="o", - help="Take +o from a user", usage="[nickname]") - - events.on("received.command.voice").hook(self.voice, - channel_only=True, require_mode="o", usage="[nickname]", - help="Give +v to a user") - events.on("received.command.devoice").hook(self.devoice, - channel_only=True, require_mode="o", usage="[nickname]", - help="Take +v from a user") - - events.on("received.command.topic").hook(self.topic, min_args=1, - require_mode="o", channel_only=True, usage="<topic>", - help="Set the topic of the current channel") - events.on("received.command").on("topicappend", "tappend").hook( - self.tappend, min_args=1, require_mode="o", channel_only=True, - usage="<topic>", help="Set the topic of the current channel") - - events.on("received.message.channel").hook(self.highlight_spam) - exports.add("channelset", {"setting": "highlight-spam-threshold", "help": "Set the number of nicknames in a message that " "qualifies as spam", "validate": Utils.int_or_none}) @@ -56,7 +16,12 @@ class Module(object): "help": "Set ban format ($n = nick, $u = username, " "$h = hostname)"}) + @Utils.hook("received.command.kick|k", channel_only=True, + require_mode="o", usage="<nickname> [reason]", min_args=1) def kick(self, event): + """ + Kick a user from the current channel + """ target = event["args_split"][0] target_user = event["server"].get_user(target) if event["args_split"][1:]: @@ -84,48 +49,96 @@ class Module(object): channel.send_ban(hostmask) else: channel.send_unban(hostmask) + + @Utils.hook("received.command.ban", channel_only=True, min_args=1, + require_mode="o", usage="<nickname/hostmask>") def ban(self, event): + """ + Ban a user/hostmask from the current channel + """ target_user = event["server"].get_user(event["args_split"][0]) if event["target"].has_user(target_user): self._ban(event["target"], True, target_user) else: event["target"].send_ban(event["args_split"][0]) + @Utils.hook("received.command.unban", channel_only=True, min_args=1, + require_mode="o", usage="<nickname/hostmask>") def unban(self, event): + """ + Unban a user/hostmask from the current channel + """ target_user = event["server"].get_user(event["args_split"][0]) if event["target"].has_user(target_user): self._ban(event["target"], False, target_user) else: event["target"].send_unban(event["args_split"][0]) + @Utils.hook("received.command.kickban|kb", channel_only=True, + require_mode="o", usage="<nickname> [reason]", min_args=1) def kickban(self, event): + """ + Kick and ban a user from the current channel + """ if event["server"].has_user(event["args_split"][0]): self.ban(event) self.kick(event) else: event["stderr"].write("That user is not in this channel") + @Utils.hook("received.command.op", channel_only=True, + require_mode="o", usage="[nickname]") def op(self, event): + """ + Op a user in the current channel + """ target = event["user"].nickname if not event["args_split"] else event[ "args_split"][0] event["target"].send_mode("+o", target) + @Utils.hook("received.command.deop", channel_only=True, + require_mode="o", usage="[nickname]") def deop(self, event): + """ + Remove op from a user in the current channel + """ target = event["user"].nickname if not event["args_split"] else event[ "args_split"][0] event["target"].send_mode("-o", target) + + @Utils.hook("received.command.voice", channel_only=True, + require_mode="o", usage="[nickname]") def voice(self, event): + """ + Voice a user in the current channel + """ target = event["user"].nickname if not event["args_split"] else event[ "args_split"][0] event["target"].send_mode("+v", target) + @Utils.hook("received.command.devoice", channel_only=True, + require_mode="o", usage="[nickname]") def devoice(self, event): + """ + Remove voice from a user in the current channel + """ target = event["user"].nickname if not event["args_split"] else event[ "args_split"][0] event["target"].send_mode("-v", target) + @Utils.hook("received.command.topic", min_args=1, require_mode="o", + channel_only=True, usage="<topic>") def topic(self, event): + """ + Set the topic in the current channel + """ event["target"].send_topic(event["args"]) + @Utils.hook("received.command.tappend", min_args=1, require_mode="o", + channel_only=True, usage="<topic>") def tappend(self, event): + """ + Append to the topic in the current channel + """ event["target"].send_topic(event["target"].topic + event["args"]) + @Utils.hook("received.message.channel") def highlight_spam(self, event): if event["channel"].get_setting("highlight-spam-protection", False): nicknames = list(map(lambda user: user.nickname, diff --git a/modules/channel_save.py b/modules/channel_save.py index 41a68481..b352d0a6 100644 --- a/modules/channel_save.py +++ b/modules/channel_save.py @@ -1,12 +1,7 @@ +from src import ModuleManager, Utils - -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.numeric.001").hook(self.on_connect) - events.on("self.join").hook(self.on_join) - events.on("self.part").hook(self.on_part) - events.on("self.kick").hook(self.on_kick) - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.numeric.001") def on_connect(self, event): channels = event["server"].get_setting("autojoin", []) chan_keys = event["server"].get_setting("channel_keys", {}) @@ -25,6 +20,7 @@ class Module(object): event["server"].send_join( ",".join(channels_sorted), ",".join(keys_sorted)) + @Utils.hook("self.join") def on_join(self, event): channels = event["server"].get_setting("autojoin", []) if not event["channel"].name in channels: @@ -37,8 +33,10 @@ class Module(object): channels.remove(channel_name) server.set_setting("autojoin", channels) + @Utils.hook("self.part") def on_part(self, event): self._remove_channel(event["server"], event["channel"].name) + @Utils.hook("self.kick") def on_kick(self, event): self._remove_channel(event["server"], event["channel"].name) diff --git a/modules/check_mode.py b/modules/check_mode.py index 788f573c..2d0298b6 100644 --- a/modules/check_mode.py +++ b/modules/check_mode.py @@ -1,10 +1,7 @@ +from src import ModuleManager, Utils - -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("preprocess.command").hook(self.preprocess_command) - +class Module(ModuleManager.BaseModule): + @Utils.hook("preprocess.command") def preprocess_command(self, event): if event["is_channel"] and event["hook"].kwargs.get( "require_mode"): diff --git a/modules/check_urls.py b/modules/check_urls.py index fa05695e..b0438ec8 100644 --- a/modules/check_urls.py +++ b/modules/check_urls.py @@ -10,8 +10,6 @@ class Module(object): def __init__(self, bot, events, exports): self.bot = bot self.events = events - events.on("received.message.channel").hook(self.message) - exports.add("channelset", {"setting": "check-urls", "help": "Enable/Disable automatically checking for " "malicious URLs", "validate": Utils.bool_or_none}) @@ -22,6 +20,7 @@ class Module(object): "help": "Enable/Disable automatically kicking users that " "send malicious URLs", "validate": Utils.bool_or_none}) + @Utils.hook("received.message.channel") def message(self, event): match = RE_URL.search(event["message"]) if match and event["channel"].get_setting("check-urls", diff --git a/modules/coins.py b/modules/coins.py index e66aff6c..47b51cf1 100644 --- a/modules/coins.py +++ b/modules/coins.py @@ -28,34 +28,6 @@ REGEX_STREET = re.compile("street([1-9]|1[0-2])$") class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command.coins").hook(self.coins, - help="Show how many coins you have") - - events.on("received.command.richest").hook( - self.richest, help="Show the top 10 richest users") - events.on("received.command.redeemcoins").hook( - self.redeem_coins, help="Redeem free coins") - - events.on("received.command.resetcoins").hook( - self.reset_coins, permission="resetcoins", - min_args=1, help= - "Reset a specified user's coins to %s" % str(DECIMAL_ZERO), - usage="<target>") - events.on("received.command.givecoins").hook(self.give_coins, - min_args=1, help="Give coins to a user", - usage="<nickname> <coins>", permission="givecoins") - - - events.on("received.command.flip").hook(self.flip, - help="Bet coins on a coin flip", usage= - "heads|tails <coin amount>", min_args=2, authenticated=True) - events.on("received.command.roulette").hook( - self.roulette, min_args=2, help="Spin the roulette wheel", - usage="<type> <amount>", authenticated=True) - - events.on("received.command.sendcoins").hook( - self.send, min_args=2, help="Send coins to a user", - usage="<nickname> <amount>", authenticated=True) now = datetime.datetime.now() until_next_hour = 60-now.second @@ -65,7 +37,11 @@ class Module(object): bot.add_timer("coin-interest", INTEREST_INTERVAL, persist=False, next_due=time.time()+until_next_hour) + @Utils.hook("received.command.coins") def coins(self, event): + """ + Show how many coins you have + """ if event["args_split"]: target = event["server"].get_user(event["args_split"][0]) else: @@ -74,7 +50,12 @@ class Module(object): event["stdout"].write("%s has %s coin%s" % (target.nickname, "{0:.2f}".format(coins), "" if coins == 1 else "s")) + @Utils.hook("received.command.resetcoins", permission="resetcoins", + min_args=1, usage="<target>") def reset_coins(self, event): + """ + Reset a user's coins to 0 + """ target = event["server"].get_user(event["args_split"][0]) coins = decimal.Decimal(target.get_setting("coins", "0.0")) if coins == DECIMAL_ZERO: @@ -84,7 +65,12 @@ class Module(object): target.del_setting("coins") event["stdout"].write("Reset coins for %s" % target.nickname) + @Utils.hook("received.command.givecoins", min_args=1, + usage="<nickname> <coins>", permission="givecoins") def give_coins(self, event): + """ + Give coins to a user + """ target = event["server"].get_user(event["args_split"][0]) coins = event["args_split"][1] match = REGEX_FLOAT.match(coins) @@ -98,7 +84,11 @@ class Module(object): event["stdout"].write("Gave '%s' %s coins" % (target.nickname, str(coins))) + @Utils.hook("received.command.richest") def richest(self, event): + """ + Show the top 10 richest users + """ all_coins = event["server"].get_all_user_settings("coins", []) all_coins = list(filter(lambda coin: decimal.Decimal(coin[1]), all_coins)) @@ -112,7 +102,11 @@ class Module(object): all_coins[nickname])) for nickname in top_10) event["stdout"].write("Richest users: %s" % top_10) + @Utils.hook("received.command.redeemcoins") def redeem_coins(self, event): + """ + Redeem your free coins + """ user_coins = decimal.Decimal(event["user"].get_setting( "coins", "0.0")) if user_coins == DECIMAL_ZERO: @@ -137,7 +131,12 @@ class Module(object): event["stderr"].write( "You can only redeem coins when you have none") + @Utils.hook("received.command.flip", usage="heads|tails <coin amount>", + min_args=2, authenticated=True) def flip(self, event): + """ + Bet on a coin flip + """ side_name = event["args_split"][0].lower() coin_bet = event["args_split"][1].lower() if coin_bet == "all": @@ -176,7 +175,12 @@ class Module(object): event["user"].nickname, side_name, coin_bet_str, "" if coin_bet == 1 else "s")) + @Utils.hook("received.command.sendcoins", min_args=2, + usage="<nickname> <amount>", authenticated=True) def send(self, event): + """ + Send coins to another user + """ if event["user"].get_id() == event["server"].get_user(event[ "args_split"][0]).get_id(): event["stderr"].write("You can't send coins to yourself") @@ -239,7 +243,12 @@ class Module(object): str(coins)) event["timer"].redo() + @Utils.hook("received.command.roulette", min_args=2, + usage="<type> <amount>", authenticated=True) def roulette(self, event): + """ + Spin a roulette wheel + """ bets = event["args_split"][0].lower().split(",") if "0" in bets: event["stderr"].write("You can't bet on 0") diff --git a/modules/commands.py b/modules/commands.py index a58d0748..3bc2604f 100644 --- a/modules/commands.py +++ b/modules/commands.py @@ -45,29 +45,7 @@ class StdErr(Out): class Module(object): def __init__(self, bot, events, exports): - self.bot = bot self.events = events - events.on("received.message.channel").hook(self.channel_message, - priority=EventManager.PRIORITY_LOW) - events.on("received.message.private").hook(self.private_message, - priority=EventManager.PRIORITY_LOW) - - events.on("received.command.help").hook(self.help, - help="Show help for commands", usage="<command>") - events.on("received.command.usage").hook(self.usage, min_args=1, - help="Show usage help for commands", usage="<command>") - events.on("received.command.more").hook(self.more, skip_out=True, - help="Get more output from the last command") - events.on("received.command.ignore").hook(self.ignore, min_args=1, - help="Ignore commands from a given user", usage="<nickname>", - permission="ignore") - events.on("received.command.unignore").hook(self.unignore, min_args=1, - help="Unignore commands from a given user", usage="<nickname>", - permission="unignore") - - events.on("new").on("user", "channel").hook(self.new) - events.on("send.stdout").hook(self.send_stdout) - events.on("send.stderr").hook(self.send_stderr) exports.add("channelset", {"setting": "command-prefix", "help": "Set the command prefix used in this channel"}) @@ -76,6 +54,7 @@ class Module(object): exports.add("serverset", {"setting": "identity-mechanism", "help": "Set the identity mechanism for this server"}) + @Utils.hook("new.user|channel") def new(self, event): if "user" in event: target = event["user"] @@ -156,6 +135,7 @@ class Module(object): buffer.skip_next() event.eat() + @Utils.hook("received.message.channel", priority=EventManager.PRIORITY_LOW) def channel_message(self, event): command_prefix = event["channel"].get_setting("command-prefix", event["server"].get_setting("command-prefix", "!")) @@ -168,6 +148,7 @@ class Module(object): command = event["message_split"][1].lower() self.message(event, command, 2) + @Utils.hook("received.message.private", priority=EventManager.PRIORITY_LOW) def private_message(self, event): if event["message_split"]: command = event["message_split"][0].lower() @@ -176,7 +157,11 @@ class Module(object): def _get_help(self, hook): return hook.kwargs.get("help", None) or hook.function.__doc__ + @Utils.hook("received.command.help", usage="<command>") def help(self, event): + """ + Show help for a given command + """ if event["args"]: command = event["args_split"][0].lower() if command in self.events.on("received").on( @@ -185,7 +170,8 @@ class Module(object): help = self._get_help(hooks[0]) if help: - event["stdout"].write("%s: %s" % (command, help.strip())) + event["stdout"].write("%s: %s" % (command, " ".join( + [line.strip() for line in help.split("\n")]))) else: event["stderr"].write("No help available for %s" % command) else: @@ -200,7 +186,11 @@ class Module(object): help_available = sorted(help_available) event["stdout"].write("Commands: %s" % ", ".join(help_available)) + @Utils.hook("received.command.usage", min_args=1, usage="<command>") def usage(self, event): + """ + Show the usage for a given command + """ command_prefix = "" if event["is_channel"]: command_prefix = event["target"].get_setting("command-prefix", @@ -218,11 +208,20 @@ class Module(object): else: event["stderr"].write("Unknown command '%s'" % command) + @Utils.hook("received.command.more", skip_out=True) def more(self, event): + """ + Show more output from the last command + """ if event["target"].last_stdout and event["target"].last_stdout.has_text(): event["target"].last_stdout.send() + @Utils.hook("received.command.ignore", min_args=1, usage="<nickname>", + permission="ignore") def ignore(self, event): + """ + Ignore commands from a given user + """ user = event["server"].get_user(event["args_split"][0]) if user.get_setting("ignore", False): event["stderr"].write("I'm already ignoring '%s'" % @@ -231,7 +230,12 @@ class Module(object): user.set_setting("ignore", True) event["stdout"].write("Now ignoring '%s'" % user.nickname) + @Utils.hook("received.command.unignore", min_args=1, usage="<nickname>", + permission="unignore") def unignore(self, event): + """ + Unignore commands from a given user + """ user = event["server"].get_user(event["args_split"][0]) if not user.get_setting("ignore", False): event["stderr"].write("I'm not ignoring '%s'" % user.nickname) @@ -239,11 +243,13 @@ class Module(object): user.set_setting("ignore", False) event["stdout"].write("Removed ignore for '%s'" % user.nickname) + @Utils.hook("send.stdout") def send_stdout(self, event): stdout = StdOut(event["module_name"], event["target"]) stdout.write(event["message"]).send() if stdout.has_text(): event["target"].last_stdout = stdout + @Utils.hook("send.stderr") def send_stderr(self, event): stderr = StdErr(event["module_name"], event["target"]) stderr.write(event["message"]).send() diff --git a/modules/ctcp.py b/modules/ctcp.py index a9144974..efb855fb 100644 --- a/modules/ctcp.py +++ b/modules/ctcp.py @@ -4,11 +4,11 @@ from src import Utils class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.message.private").hook(self.private_message) exports.add("serverset", {"setting": "ctcp-responses", "help": "Set whether I respond to CTCPs on this server", "validate": Utils.bool_or_none}) + @Utils.hook("received.message.private") def private_message(self, event): if event["message"][0] == "\x01" and event["message"][-1] == "\x01": if event["server"].get_setting("ctcp-responses", True): diff --git a/modules/database_backup.py b/modules/database_backup.py index 27a366a3..45bc730f 100644 --- a/modules/database_backup.py +++ b/modules/database_backup.py @@ -1,4 +1,5 @@ import datetime, glob, os, shutil, time +from src import Utils BACKUP_INTERVAL = 60*60 # 1 hour BACKUP_COUNT = 5 @@ -10,10 +11,10 @@ class Module(object): until_next_hour = 60-now.second until_next_hour += ((60-(now.minute+1))*60) - events.on("timer.database-backup").hook(self.backup) bot.add_timer("database-backup", BACKUP_INTERVAL, persist=False, next_due=time.time()+until_next_hour) + @Utils.hook("timer.database-backup") def backup(self, event): full_location = self.bot.database.full_location files = glob.glob("%s.*" % full_location) diff --git a/modules/define.py b/modules/define.py index 1b88e83b..178a9c5a 100644 --- a/modules/define.py +++ b/modules/define.py @@ -12,13 +12,6 @@ class Module(object): def __init__(self, bot, events, exports): self.bot = bot self._last_called = 0 - self.events = events - - events.on("received.command.define").hook(self.define, - help="Define a provided term", usage="<phrase>") - - events.on("received.command.randomword").hook(self.random_word, - help="Generate a random word!") def _get_definition(self, word): word = event["args"] if "args" in event else event @@ -30,7 +23,11 @@ class Module(object): return page + @Utils.hook("received.command.define", usage="<phrase>") def define(self, event): + """ + Define a provided term + """ if event["args"]: word = event["args"] else: @@ -46,7 +43,11 @@ class Module(object): else: event["stderr"].write("Failed to load results") + @Utils.hook("received.command.randomword") def random_word(self, event): + """ + Define a random word + """ if not self._last_called or (time.time()-self._last_called >= RANDOM_DELAY_SECONDS): self._last_called = time.time() diff --git a/modules/dice.py b/modules/dice.py index 30e4f319..cb48efae 100644 --- a/modules/dice.py +++ b/modules/dice.py @@ -1,28 +1,24 @@ import random -from src import Utils +from src import ModuleManager, Utils -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command.roll").hook( - self.roll_dice, - min_args=1, - help="Roll some dice, DND style!", - usage="[1-5]d[1-20]" - ) - - self.err_msg = "Incorrectly formatted dice! Format must be [number]d[number], for example, 1d20" +ERROR_FORMAT = "Incorrect format! Format must be [number]d[number], e.g. 1d20" +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.roll", min_args=1, usage="[1-5]d[1-20]") def roll_dice(self, event): + """ + Roll some dice, DND style! + """ raw_input = event["args_split"][0] roll = raw_input.split("d") results = [] if len(roll) is not 2: - event["stderr"].write(self.err_msg) + event["stderr"].write(ERROR_FORMAT) return if roll[0].isdigit() is False or roll[1].isdigit() is False: - event["stderr"].write(self.err_msg) + event["stderr"].write(ERROR_FORMAT) return roll = [int(roll[0]), int(roll[1])] diff --git a/modules/dns.py b/modules/dns.py index e5552aa8..19ef7ea0 100644 --- a/modules/dns.py +++ b/modules/dns.py @@ -1,13 +1,14 @@ import socket +from src import ModuleManager, Utils -class Module(object): +class Module(ModuleManager.BaseModule): _name = "DNS" - def __init__(self, bot, events, exports): - events.on("received.command.dns").hook(self.dns, min_args=1, - help="Get all addresses for a given hostname (IPv4/IPv6)", - usage="<hostname>") + @Utils.hook("received.command.dns", min_args=1, usage="<hostname>") def dns(self, event): + """ + Get all addresses for a given hostname (IPv4/IPv6) + """ hostname = event["args_split"][0] try: address_info = socket.getaddrinfo(hostname, 1, 0, diff --git a/modules/ducks.py b/modules/ducks.py index a9c4f6b5..56f495c8 100644 --- a/modules/ducks.py +++ b/modules/ducks.py @@ -15,30 +15,8 @@ DUCK_MINIMUM_UNIQUE = 3 class Module(object): - def __init__(self, bot, events, exports): self.bot = bot - self.events = events - - events.on("received.command.bef").hook(self.befriend, - priority=EventManager.PRIORITY_HIGH, - help="Befriend a duck!") - events.on("received.command.bang").hook(self.shoot, - priority=EventManager.PRIORITY_HIGH, - help="Shoot a duck! Meanie.") - events.on("received.command.decoy").hook( - self.duck_decoy, - priority=EventManager.PRIORITY_HIGH, - help="Lay out a sneaky decoy!") - - - events.on("received.command.friends").hook(self.duck_friends, - help="See who the friendliest people to ducks are!") - events.on("received.command.killers").hook(self.duck_enemies, - help="See who shoots the most smount of ducks!") - events.on("received.command.duckstats").hook(self.duck_stats, - help="Shows your duck stats!") - exports.add("channelset", {"setting": "ducks-enabled", "help": "Toggle ducks!", "validate": Utils.bool_or_none}) @@ -47,24 +25,18 @@ class Module(object): "validate": Utils.bool_or_none}) exports.add("channelset", {"setting": "ducks-min-unique", - "help": "Minimum unique users required to " - "talk before a duck spawns.", - "validate": Utils.int_or_none}) + "help": "Minimum unique users required to talk before a " + "duck spawns.", "validate": Utils.int_or_none}) exports.add("channelset", {"setting": "ducks-min-messages", - "help": "Minimum messages between ducks " - "spawning.", - "validate": Utils.int_or_none}) - - events.on("new.channel").hook(self.new_channel) - - events.on("received.message.channel").hook( - self.channel_message, EventManager.PRIORITY_LOW) + "help": "Minimum messages between ducks spawning.", + "validate": Utils.int_or_none}) for server in self.bot.servers.values(): for channel in server.channels.values(): self.bootstrap(channel) + @Utils.hook("new.channel") def new_channel(self, event): self.bootstrap(event["channel"]) @@ -148,7 +120,11 @@ class Module(object): channel.send_kick(target, "You tried shooting a non-existent duck. Creepy!") + @Utils.hook("received.command.decoy") def duck_decoy(self, event): + """ + Prepare a decoy duck + """ channel = event["target"] if self.is_duck_channel(channel) == False: return @@ -219,6 +195,8 @@ class Module(object): else: game["duck_spawned"] = 1 + @Utils.hook("received.message.channel", + priority=EventManager.PRIORITY_MONITOR) def channel_message(self, event): if not event["channel"].get_setting("ducks-enabled", False): return @@ -248,7 +226,11 @@ class Module(object): if self.should_generate_duck(event) == True: self.show_duck(event) + @Utils.hook("received.command.bef") def befriend(self, event): + """ + Befriend a duck + """ channel = event["target"] user = event["user"] nick = user.nickname @@ -282,7 +264,11 @@ class Module(object): self.clear_ducks(channel) event.eat() + @Utils.hook("received.command.bang") def shoot(self, event): + """ + Shoot a duck + """ channel = event["target"] user = event["user"] nick = user.nickname @@ -317,7 +303,11 @@ class Module(object): self.clear_ducks(channel) event.eat() + @Utils.hook("received.command.duckstats") def duck_stats(self, event): + """ + Show your duck stats + """ user = event["user"] channel = event["target"].name nick = user.nickname @@ -358,7 +348,11 @@ class Module(object): event["stdout"].write(Utils.bold(nick) + ": " + msg) event.eat() + @Utils.hook("received.command.killers") def duck_enemies(self, event): + """ + Show the top duck shooters + """ the_enemy = event["server"].find_all_user_channel_settings("ducks-shot") notorious = {} @@ -392,7 +386,11 @@ class Module(object): event["stdout"].write(sentence) event.eat() + @Utils.hook("received.command.friends") def duck_friends(self, event): + """ + Show the top duck friends + """ friends = event["server"].find_all_user_channel_settings( "ducks-befriended") diff --git a/modules/eval.py b/modules/eval.py index ab68a368..3db6bd3e 100644 --- a/modules/eval.py +++ b/modules/eval.py @@ -1,14 +1,14 @@ import socket -from src import Utils +from src import ModuleManager, Utils EVAL_URL = "https://eval.appspot.com/eval" -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command.eval").hook(self.eval, min_args=1, - help="Evaluate a python statement", usage="<statement>") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.eval", min_args=1, usage="<statement>") def eval(self, event): + """ + Evaluate a python statement + """ try: code, page = Utils.get_url(EVAL_URL, get_params={ "statement": event["args"]}, code=True) diff --git a/modules/geoip.py b/modules/geoip.py index 5bc464b1..f20df6aa 100644 --- a/modules/geoip.py +++ b/modules/geoip.py @@ -1,14 +1,15 @@ -from src import Utils +from src import ModuleManager, Utils URL_GEOIP = "http://ip-api.com/json/%s" -class Module(object): +class Module(ModuleManager.BaseModule): _name = "GeoIP" - def __init__(self, bot, events, exports): - events.on("received.command.geoip").hook(self.geoip, min_args=1, - help="Get geoip data on a given IPv4/IPv6 address", usage="<IP>") + @Utils.hook("received.command.geoip", min_args=1, usage="<IP>") def geoip(self, event): + """ + Get geoip data on a given IPv4/IPv6 address + """ page = Utils.get_url(URL_GEOIP % event["args_split"][0], json=True) if page: diff --git a/modules/google.py b/modules/google.py index 1d7b6e8c..f98ed2ad 100644 --- a/modules/google.py +++ b/modules/google.py @@ -10,12 +10,12 @@ URL_GOOGLESUGGEST = "http://google.com/complete/search" class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command").on("google", "g").hook(self.google, - help="Google feeling lucky", usage="[search term]") - events.on("received.command.suggest").hook(self.suggest, - help="Get suggested phrases from Google", usage="[phrase]") + @Utils.hook("received.command.google|g", usage="[search term]") def google(self, event): + """ + Get first Google result for a given search term + """ phrase = event["args"] or event["buffer"].get() if phrase: page = Utils.get_url(URL_GOOGLESEARCH, get_params={ @@ -34,7 +34,11 @@ class Module(object): else: event["stderr"].write("No phrase provided") + @Utils.hook("received.command.suggest", usage="[phrase]") def suggest(self, event): + """ + Get suggested phrases from Google + """ phrase = event["args"] or event["buffer"].get() if phrase: page = Utils.get_url(URL_GOOGLESUGGEST, get_params={ diff --git a/modules/greeting.py b/modules/greeting.py index 45ba0b7b..9d0eb838 100644 --- a/modules/greeting.py +++ b/modules/greeting.py @@ -1,11 +1,11 @@ - +from src import Utils class Module(object): def __init__(self, bot, events, exports): - events.on("received.join").hook(self.join) exports.add("channelset", {"setting": "greeting", "help": "Set a greeting to send to users when they join"}) + @Utils.hook("recevied.join") def join(self, event): greeting = event["channel"].get_setting("greeting", None) if greeting: diff --git a/modules/hash.py b/modules/hash.py index e123da9a..4508d613 100644 --- a/modules/hash.py +++ b/modules/hash.py @@ -1,12 +1,12 @@ import hashlib +from src import ModuleManager, Utils -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command.hash").hook(self.hash, min_args=2, - help="Hash a string", usage="<algo> <string>") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.hash", min_args=2, usage="<algo> <string>") def hash(self, event): + """ + Hash a given string with a given algorithm + """ algorithm = event["args_split"][0].lower() if algorithm in hashlib.algorithms_available: phrase = " ".join(event["args_split"][1:]) diff --git a/modules/haveibeenpwned.py b/modules/haveibeenpwned.py index 79662913..0a328c3e 100644 --- a/modules/haveibeenpwned.py +++ b/modules/haveibeenpwned.py @@ -1,15 +1,16 @@ -from src import Utils +from src import ModuleManager, Utils URL_HAVEIBEENPWNEDAPI = "https://haveibeenpwned.com/api/v2/breachedaccount/%s" URL_HAVEIBEENPWNED = "https://haveibeenpwned.com/" -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command.beenpwned").hook(self.beenpwned, - help="Find out if a username, email or similar has appeared " - "in any hacked databases", usage="<username/email>", min_args=1) - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.beenpwned", usage="<username/email>", + min_args=1) def beenpwned(self, event): + """ + Find out if a username, email or similar has appeared in any + hacked databases + """ page = Utils.get_url(URL_HAVEIBEENPWNEDAPI % event["args"], json=True, code=True) if page: diff --git a/modules/ids.py b/modules/ids.py index 17b20a6e..fb81f492 100644 --- a/modules/ids.py +++ b/modules/ids.py @@ -1,18 +1,20 @@ +from src import ModuleManager, Utils - -class Module(object): +class Module(ModuleManager.BaseModule): _name = "IDs" - def __init__(self, bot, events, exports): - events.on("received.command.myid").hook(self.my_id, - help="Show your user ID") - events.on("received.command.channelid").hook( - self.channel_id, channel_only=True, - help="Show the current channel's ID") + @Utils.hook("received.command.myid") def my_id(self, event): + """ + Show your user ID + """ event["stdout"].write("%s: %d" % (event["user"].nickname, event["user"].get_id())) + @Utils.hook("received.command.channelid", channel_only=True) def channel_id(self, event): + """ + Show the current channel's ID + """ event["stdout"].write("%s: %d" % (event["target"].name, event["target"].id)) diff --git a/modules/imdb.py b/modules/imdb.py index 741b2955..d735910f 100644 --- a/modules/imdb.py +++ b/modules/imdb.py @@ -10,10 +10,12 @@ class Module(object): _name = "IMDb" def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command.imdb").hook(self.imdb, min_args=1, - help="Search for a given title on IMDb", usage="<movie/tv title>") + @Utils.hook("received.command.imdb", min_args=1, usage="<movie/tv title>") def imdb(self, event): + """ + Search for a given title on IMDb + """ page = Utils.get_url(URL_OMDB, get_params={ "t": event["args"], "apikey": self.bot.config["omdbapi-api-key"]}, diff --git a/modules/in.py b/modules/in.py index 2351fb11..52363fec 100644 --- a/modules/in.py +++ b/modules/in.py @@ -7,11 +7,12 @@ SECONDS_MAX_DESCRIPTION = "8 weeks" class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command.in").hook(self.in_command, min_args=2, - help="Set a reminder", usage="<time> <message>") - events.on("timer.in").hook(self.timer_due) + @Utils.hook("received.command.in", min_args=2, usage="<time> <message>") def in_command(self, event): + """ + Set a reminder + """ seconds = Utils.from_pretty_time(event["args_split"][0]) message = " ".join(event["args_split"][1:]) if seconds: @@ -31,6 +32,7 @@ class Module(object): event["stderr"].write( "Please provided a valid time above 0 seconds") + @Utils.hook("timer.in") def timer_due(self, event): for server in self.bot.servers.values(): if event["server_id"] == server.id: diff --git a/modules/isgd.py b/modules/isgd.py index 3ceacaff..6128ceb0 100644 --- a/modules/isgd.py +++ b/modules/isgd.py @@ -6,12 +6,9 @@ REGEX_URL = re.compile("https?://", re.I) class Module(object): def __init__(self, bot, events, exports): - self.bot = bot self.events = events - events.on("get.shortlink").hook(self.shortlink) - events.on("received.command.shorten").hook(self.shorten, min_args=1, - help="Shorten a URL using the is.gd service.", usage="<url>") + @Utils.hook("get.shortlink") def shortlink(self, event): url = event["url"] if not re.match(REGEX_URL, url): @@ -24,7 +21,11 @@ class Module(object): if data and data["shorturl"]: return data["shorturl"] + @Utils.hook("received.command.shorten", min_args=1, usage="<url>") def shorten(self, event): + """ + Shorten a given URL using the is.gd service + """ link = self.events.on("get.shortlink").call_for_result( url=event["args"]) if link: diff --git a/modules/karma.py b/modules/karma.py index 897f0ea2..350e32fa 100644 --- a/modules/karma.py +++ b/modules/karma.py @@ -6,26 +6,17 @@ KARMA_DELAY_SECONDS = 3 class Module(object): def __init__(self, bot, events, exports): - self.bot = bot self.events = events - events.on("new.user").hook(self.new_user) - events.on("received.message.channel").hook( - self.channel_message, priority=EventManager.PRIORITY_MONITOR) - events.on("received.command.karma").hook( - self.karma, help="Get your or someone else's karma", - usage="[target]") - events.on("received.command.resetkarma").hook( - self.reset_karma, permission="resetkarma", - min_args=1, help="Reset a specified karma to 0", - usage="<target>") - exports.add("channelset", {"setting": "karma-verbose", "help": "Disable/Enable automatically responding to " "karma changes", "validate": Utils.bool_or_none}) + @Utils.hook("new.user") def new_user(self, event): event["user"].last_karma = None + @Utils.hook("received.message.channel", + priority=EventManager.PRIORITY_MONITOR) def channel_message(self, event): match = re.match(REGEX_KARMA, event["message"].strip()) if match and not event["action"]: @@ -60,7 +51,11 @@ class Module(object): target=event["channel"], message="Try again in a couple of seconds") + @Utils.hook("received.command.karma", usage="[target]") def karma(self, event): + """ + Get your or someone else's karma + """ if event["args"]: target = event["args"] else: @@ -68,7 +63,12 @@ class Module(object): karma = event["server"].get_setting("karma-%s" % target, 0) event["stdout"].write("%s has %s karma" % (target, karma)) + @Utils.hook("received.command.resetkarma", permission="resetkarma", + min_args=1, usage="<target>") def reset_karma(self, event): + """ + Reset a specified karma to 0 + """ setting = "karma-%s" % event["args_split"][0] karma = event["server"].get_setting(setting, 0) if karma == 0: diff --git a/modules/lastfm.py b/modules/lastfm.py index d46bc50b..ddeefc6b 100644 --- a/modules/lastfm.py +++ b/modules/lastfm.py @@ -14,11 +14,11 @@ class Module(object): exports.add("set", {"setting": "lastfm", "help": "Set username on last.fm"}) - events.on("received.command").on("np", "listening", "nowplaying" - ).hook(self.np, help="Get the last listened to track from a user", - usage="[username]") - + @Utils.hook("received.command.np|listening|nowplaying", usage="[username]") def np(self, event): + """ + Get the last listened to track from a user + """ if event["args_split"]: lastfm_username = event["args_split"][0] shown_username = lastfm_username diff --git a/modules/modules.py b/modules/modules.py index eebeea7c..533091aa 100644 --- a/modules/modules.py +++ b/modules/modules.py @@ -1,31 +1,15 @@ -from src import ModuleManager +from src import ModuleManager, Utils class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command.loadmodule").hook(self.load, - min_args=1, permission="load-module", help="Load a module", - usage="<module-name>") - events.on("received.command.unloadmodule").hook(self.unload, - min_args=1, permission="unload-module", help="Unload a module", - usage="<module-name>") - - events.on("received.command.reloadmodule").hook(self.reload, - min_args=1, permission="reload-module", help="Reoad a module", - usage="<module-name>") - - events.on("received.command.reloadallmodules").hook(self.reload_all, - permission="reload-module", help="Reload all modules") - - events.on("received.command.enablemodule").hook(self.enable, - min_args=1, permission="enable-module", help="Enable a module", - usage="<module-name>") - events.on("received.command.disablemodule").hook(self.disable, - min_args=1, permission="disable-module", help="Disable a module", - usage="<module-name>") - + @Utils.hook("received.command.loadmodule", min_args=1, + permission="load-module", usage="<module-name>") def load(self, event): + """ + Load a module + """ name = event["args_split"][0].lower() if name in self.bot.modules.modules: event["stderr"].write("Module '%s' is already loaded" % name) @@ -33,7 +17,12 @@ class Module(object): self.bot.modules.load_module(name) event["stdout"].write("Loaded '%s'" % name) + @Utils.hook("received.command.unloadmodule", min_args=1, + permission="unload-module", usage="<module-name>") def unload(self, event): + """ + Unload a module + """ name = event["args_split"][0].lower() if not name in self.bot.modules.modules: event["stderr"].write("Module '%s' isn't loaded" % name) @@ -45,7 +34,12 @@ class Module(object): self.bot.modules.unload_module(name) self.bot.modules.load_module(name) + @Utils.hook("received.command.reloadmodule", min_args=1, + permission="reload-module", usage="<module-name>") def reload(self, event): + """ + Reload a module + """ name = event["args_split"][0].lower() try: self._reload(name) @@ -62,7 +56,11 @@ class Module(object): return event["stdout"].write("Reloaded '%s'" % name) + @Utils.hook("received.command.reloadallmodules", permission="reload-module") def reload_all(self, event): + """ + Reload all modules + """ reloaded = [] failed = [] for name in list(self.bot.modules.modules.keys()): @@ -83,7 +81,12 @@ class Module(object): else: event["stdout"].write("Reloaded %d modules" % len(reloaded)) + @Utils.hook("received.command.enablemodule", min_args=1, + permission="enable-module", usage="<module-name>") def enable(self, event): + """ + Remove a module from the module blacklist + """ name = event["args_split"][0].lower() blacklist = self.bot.get_setting("module-blacklist", []) if not name in blacklist: @@ -94,7 +97,12 @@ class Module(object): event["stdout"].write("Module '%s' has been enabled and can now " "be loaded" % name) + @Utils.hook("received.command.disablemodule", min_args=1, + permission="disable-module", usage="<module-name>") def disable(self, event): + """ + Add a module to the module blacklist + """ name = event["args_split"][0].lower() and_unloaded = "" if name in self.bot.modules.modules: diff --git a/modules/nickname_aliases.py b/modules/nickname_aliases.py index cac6d91b..29545a75 100644 --- a/modules/nickname_aliases.py +++ b/modules/nickname_aliases.py @@ -1,5 +1,6 @@ #--ignore import types, json +from src import Utils def get_target(user): return user.alias or user.nickname @@ -24,11 +25,8 @@ class Module(object): _name = "Aliases" def __init__(self, bot, events, exports): self.bot = bot - events.on("new.user").hook(self.new_user) - events.on("received.nick").hook(self.nickname_change) - events.on("received.command.alias").hook(self.alias) - #events.on("received.command.mainalias").hook(self.main_alias) + @Utils.hook("new.user") def new_user(self, event): method_type = types.MethodType user = event["user"] @@ -40,6 +38,7 @@ class Module(object): event["user"].find_settings = method_type(find_settings, user) event["user"].del_setting = method_type(del_setting, user) + @Utils.hook("received.nick") def nickname_change(self, event): old_nickname = event["old_nickname"] new_nickname = event["new_nickname"] @@ -63,6 +62,7 @@ class Module(object): SET nickname=? WHERE nickname=?""", [new_nickname.lower(), old_nickname.lower()]) + @Utils.hook("received.command.alias") def alias(self, event): if event["args"]: target = event["args_split"][0] diff --git a/modules/nickserv.py b/modules/nickserv.py index 5ba2a992..8816a26a 100644 --- a/modules/nickserv.py +++ b/modules/nickserv.py @@ -1,14 +1,12 @@ import base64 -from src import EventManager +from src import EventManager, Utils class Module(object): def __init__(self, bot, events, exports): - events.on("received.numeric.001").hook(self.on_connect, - priority=EventManager.PRIORITY_URGENT) - exports.add("serverset", {"setting": "nickserv-password", "help": "Set the nickserv password for this server"}) + @Utils.hook("received.numeric.001", priority=EventManager.PRIORITY_URGENT) def on_connect(self, event): nickserv_password = event["server"].get_setting( "nickserv-password") diff --git a/modules/nr.py b/modules/nr.py index e1b605cd..4d953d82 100644 --- a/modules/nr.py +++ b/modules/nr.py @@ -23,26 +23,6 @@ class Module(object): def __init__(self, bot, events, exports): self.bot = bot self._client = None - events.on("received.command.nrtrains" - ).hook(self.trains, min_args=1, - help="Get train/bus services for a station (Powered by NRE)", - usage="<crs_id>") - events.on("received.command.nrservice" - ).hook(self.service, min_args=1, - help="Get train service information for a UID, headcode or RID (Powered by NRE)", - usage="<service_id>") - events.on("received.command.nrhead" - ).hook(self.head, min_args=1, - help="Get information for a given headcode/UID/RID (Powered by NRE)", - usage="<headcode>") - events.on("received.command.nrcode" - ).hook(self.service_code, min_args=1, - help="Get the text for a given delay/cancellation code (Powered by NRE)", - usage="<code>") - events.on("telegram.command.nrtrains").hook(self.trains) - events.on("telegram.command.nrcode").hook(self.service_code) - events.on("telegram.command.nrhead").hook(self.head) - events.on("telegram.command.nrservice").hook(self.service) @property def client(self): @@ -134,7 +114,13 @@ class Module(object): def reduced_activities(self, string): return [a for a in self.activities(string) if a in self.PASSENGER_ACTIVITIES] + @Utils.hook("telegram.command.nrtrains") + @Utils.hook("received.command.nrtrains", min_args=1, usage="<crs_id>") def trains(self, event): + """ + Get train/bus services for a station (Powered by NRE) + """ + client = self.client colours = self.COLOURS @@ -308,7 +294,13 @@ class Module(object): else: event["stdout"].write("%s%s: %s" % (station_summary, " departures calling at %s" % filter["inter"] if filter["inter"] else '', trains_string)) + @Utils.hook("telegram.command.nrservice") + @Utils.hook("received.command.nrservice", min_args=1, usage="<service_id>") def service(self, event): + """ + Get train service information for a UID, headcode or RID + (Powered by NRE) + """ client = self.client colours = self.COLOURS external = event.get("external", False) @@ -497,7 +489,12 @@ class Module(object): len(stations_filtered), total_count, ", ".join([s["summary"] for s in stations_filtered]))) + @Utils.hook("telegram.command.nrhead") + @Utils.hook("received.command.nrhead", min_args=1, usage="<headcode>") def head(self, event): + """ + Get information for a given headcode/UID/RID (Powered by NRE) + """ client = self.client service_id = event["args_split"][0] @@ -513,7 +510,13 @@ class Module(object): else: event["stdout"].write(", ".join(["h/%s r/%s u/%s rs/%s %s (%s) -> %s (%s)" % (a["trainid"], a["rid"], a["uid"], a["rsid"], a["originName"], a["originCrs"], a["destinationName"], a["destinationCrs"]) for a in services])) + @Utils.hook("telegram.command.nrcode") + @Utils.hook("received.command.nrcode", min_args=1, usage="<code>") def service_code(self, event): + """ + Get the text for a given delay/cancellation code (Powered by NRE) + """ + client = self.client if not event["args"].isnumeric(): diff --git a/modules/perform.py b/modules/perform.py index f5572fdc..889e8092 100644 --- a/modules/perform.py +++ b/modules/perform.py @@ -1,10 +1,7 @@ -from src import EventManager - -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.numeric.001").hook(self.on_connect, - priority=EventManager.PRIORITY_URGENT) +from src import EventManager, ModuleManager, Utils +class Module(ModuleManager.BaseModule): + @Utils.hook("received.numeric.001", priority=EventManager.PRIORITY_URGENT) def on_connect(self, event): commands = event["server"].get_setting("perform", []) for i, command in enumerate(commands): diff --git a/modules/permissions.py b/modules/permissions.py index 27c40485..bc8a6eca 100644 --- a/modules/permissions.py +++ b/modules/permissions.py @@ -1,40 +1,16 @@ import base64, os import scrypt +from src import ModuleManager, Utils REQUIRES_IDENTIFY = ("You need to be identified to use that command " "(/msg %s register | /msg %s identify)") -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("new.user").hook(self.new_user) - events.on("preprocess.command").hook( - self.preprocess_command) - events.on("received.part").hook(self.on_part) - - events.on("received.command.identify").hook(self.identify, - private_only=True, min_args=2, - usage="<account> <password>", help="Identify yourself") - events.on("received.command.register").hook(self.register, - private_only=True, min_args=1, - usage="<password>", help="Register your nickname") - events.on("received.command.logout").hook(self.logout, - private_only=True, help="Sign out from the bot") - events.on("received.command.resetpassword").hook( - self.reset_password, private_only=True, - help="Reset a user's password", min_args=2, - usage="<nickname> <password>", permission="resetpassword") - - events.on("received.command.mypermissions").hook( - self.my_permissions, authenticated=True) - events.on("received.command.givepermission").hook( - self.give_permission, min_args=2, permission="givepermission") - events.on("received.command.removepermission").hook( - self.remove_permission, min_args=2, permission="removepermission") - +class Module(ModuleManager.BaseModule): + @Utils.hook("new.user") def new_user(self, event): self._logout(event["user"]) + @Utils.hook("received.part") def on_part(self, event): if len(event["user"].channels) == 1 and event["user" ].identified_account_override: @@ -62,7 +38,12 @@ class Module(object): user.identified_account_override = None user.identified_account_id_override = None + @Utils.hook("received.command.identify", private_only=True, min_args=2, + usage="<account> <password>") def identify(self, event): + """ + Identify yourself + """ identity_mechanism = event["server"].get_setting("identity-mechanism", "internal") if not identity_mechanism == "internal": @@ -94,7 +75,12 @@ class Module(object): else: event["stderr"].write("You are already identified") + @Utils.hook("received.command.register", private_only=True, min_args=1, + usage="<password>") def register(self, event): + """ + Register yourself + """ identity_mechanism = event["server"].get_setting("identity-mechanism", "internal") if not identity_mechanism == "internal": @@ -113,14 +99,23 @@ class Module(object): else: event["stderr"].write("This nickname is already registered") + @Utils.hook("received.command.logout", private_only=True) def logout(self, event): + """ + Logout from your identified account + """ if event["user"].identified_account_override: self._logout(event["user"]) event["stdout"].write("You have been logged out") else: event["stderr"].write("You are not logged in") + @Utils.hook("received.command.resetpassword", private_only=True, + min_args=2, usage="<nickname> <password>", permission="resetpassword") def reset_password(self, event): + """ + Reset a given user's password + """ target = event["server"].get_user(event["args_split"][0]) password = " ".join(event["args_split"][1:]) registered = target.get_setting("authentication", None) @@ -133,6 +128,7 @@ class Module(object): event["stdout"].write("Reset password for '%s'" % target.nickname) + @Utils.hook("preprocess.command") def preprocess_command(self, event): permission = event["hook"].kwargs.get("permission", None) authenticated = event["hook"].kwargs.get("authenticated", False) @@ -162,7 +158,11 @@ class Module(object): return REQUIRES_IDENTIFY % (event["server"].nickname, event["server"].nickname) + @Utils.hook("received.command.mypermissions", authenticated=True) def my_permissions(self, event): + """ + Show your permissions + """ permissions = event["user"].get_setting("permissions", []) event["stdout"].write("Your permissions: %s" % ", ".join(permissions)) @@ -172,7 +172,12 @@ class Module(object): permissions = target.get_setting("permissions", []) return [target, registered, permissions] + @Utils.hook("received.command.givepermission", min_args=2, + permission="givepermission") def give_permission(self, event): + """ + Give a given permission to a given user + """ permission = event["args_split"][1].lower() target, registered, permissions = self._get_user_details( event["server"], event["args_split"][0]) @@ -189,7 +194,12 @@ class Module(object): target.set_setting("permissions", permissions) event["stdout"].write("Gave permission '%s' to %s" % ( permission, target.nickname)) + @Utils.hook("received.command.removepermission", min_args=2, + permission="removepermission") def remove_permission(self, event): + """ + Remove a given permission from a given user + """ permission = event["args_split"][1].lower() target, registered, permissions = self._get_user_details( event["server"], event["args_split"][0]) diff --git a/modules/print_activity.py b/modules/print_activity.py index 69c8d1b3..12e43a8b 100644 --- a/modules/print_activity.py +++ b/modules/print_activity.py @@ -1,41 +1,10 @@ import datetime -from src import EventManager +from src import EventManager, Utils class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.message.channel").hook( - self.channel_message, priority=EventManager.PRIORITY_HIGH) - events.on("self.message.channel").hook( - self.self_channel_message) - - events.on("received.notice.channel").hook( - self.channel_notice, priority=EventManager.PRIORITY_HIGH) - events.on("received.notice.private").hook( - self.private_notice, priority=EventManager.PRIORITY_HIGH) - events.on("received.server-notice").hook( - self.server_notice, priority=EventManager.PRIORITY_HIGH) - - events.on("received.join").hook(self.join) - events.on("self.join").hook(self.self_join) - - events.on("received.part").hook(self.part) - events.on("self.part").hook(self.self_part) - - events.on("received.nick").hook(self.on_nick) - events.on("self.nick").hook(self.on_nick) - - events.on("received.quit").hook(self.on_quit) - - events.on("received.kick").hook(self.kick) - events.on("self.kick").hook(self.self_kick) - - events.on("received.topic").hook(self.on_topic) - events.on("received.numeric.333").hook(self.on_333) - - events.on("received.mode.channel").hook(self.mode) - def print_line(self, event, line, channel=None): timestamp = datetime.datetime.now().isoformat() target = str(event["server"]) @@ -53,18 +22,25 @@ class Module(object): self.print_line(event, "<%s> %s" % ( nickname, event["message"]), channel=event["channel"].name) + @Utils.hook("received.message.channel", + priority=EventManager.PRIORITY_HIGH) def channel_message(self, event): self._on_message(event, event["user"].nickname) + @Utils.hook("self.message.channel") def self_channel_message(self, event): self._on_message(event, event["server"].nickname) def _on_notice(self, event, target): self.print_line(event, "(notice->%s) <%s> %s" % ( target, event["user"].nickname, event["message"])) + @Utils.hook("received.notice.channel", + priority=EventManager.PRIORITY_HIGH) def channel_notice(self, event): self._on_notice(event, event["channel"].name) + @Utils.hook("received.notice.private", priority=EventManager.PRIORITY_HIGH) def private_notice(self, event): self._on_notice(event, event["server"].nickname) + @Utils.hook("received.server-notice", priority=EventManager.PRIORITY_HIGH) def server_notice(self, event): self.print_line(event, "(server notice) %s" % event["message"]) @@ -72,8 +48,10 @@ class Module(object): if not self.bot.args.verbose: self.print_line(event, "%s joined %s" % (nickname, event["channel"].name)) + @Utils.hook("received.join") def join(self, event): self._on_join(event, event["user"].nickname) + @Utils.hook("self.join") def self_join(self, event): self._on_join(event, event["server"].nickname) @@ -82,16 +60,21 @@ class Module(object): self.print_line(event, "%s left %s%s" % (nickname, event["channel"].name, "" if not event[ "reason"] else " (%s)" % event["reason"])) + @Utils.hook("received.part") def part(self, event): self._on_part(event, event["user"].nickname) + @Utils.hook("self.part") def self_part(self, event): self._on_part(event, event["server"].nickname) + @Utils.hook("received.nick") + @Utils.hook("self.nick") def on_nick(self, event): if not self.bot.args.verbose: self.print_line(event, "%s changed nickname to %s" % ( event["old_nickname"], event["new_nickname"])) + @Utils.hook("received.quit") def on_quit(self, event): if not self.bot.args.verbose: self.print_line(event, "%s quit%s" % (event["user"].nickname, @@ -102,21 +85,26 @@ class Module(object): self.print_line(event, "%s kicked %s from %s%s" % ( event["user"].nickname, nickname, event["channel"].name, "" if not event["reason"] else " (%s)" % event["reason"])) + @Utils.hook("received.kick") def kick(self, event): self._on_kick(event, event["target_user"].nickname) + @Utils.hook("self.kick") def self_kick(self, event): self._on_kick(event, event["server"].nickname) def _on_topic(self, event, setter, action, topic, channel): self.print_line(event, "topic %s by %s: %s" % (action, setter, topic), channel=channel.name) + @Utils.hook("received.topic") def on_topic(self, event): self._on_topic(event, event["user"].nickname, "changed", event["topic"], event["channel"]) + @Utils.hook("received.numeric.333") def on_333(self, event): self._on_topic(event, event["setter"], "set", event["channel"].topic, event["channel"]) + @Utils.hook("received.mode.channel") def mode(self, event): args = " ".join(event["mode_args"]) if args: diff --git a/modules/quit.py b/modules/quit.py index 5d40a718..817bb041 100644 --- a/modules/quit.py +++ b/modules/quit.py @@ -1,4 +1,5 @@ import random +from src import ModuleManager, Utils QUOTES = { "You can build a throne with bayonets, but it's difficult to sit on it." : "Boris Yeltsin", @@ -54,10 +55,8 @@ QUOTES = { "I don’t need to understand how encryption works" : "Amber Rudd", } -class Module(object): - def __init__(self, bot, events, exports): - events.on("get.quit-quote").hook(self.quote) - +class Module(ModuleManager.BaseModule): + @Utils.hook("get.quit-quote") def quote(self, event): quote = random.choice(list(QUOTES.items())) return (" - " if quote[1] else "").join(quote) diff --git a/modules/quotes.py b/modules/quotes.py index f8cf83c0..6cb1637a 100644 --- a/modules/quotes.py +++ b/modules/quotes.py @@ -1,27 +1,18 @@ import random, time +from src import ModuleManager, Utils -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command").on("quoteadd", "qadd").hook( - self.quote_add, min_args=1, help="Added a quote to a category", - usage="<category> = <quote>") - events.on("received.command").on("quoteget", "qget").hook( - self.quote_get, min_args=1, help="Find a quote within a category", - usage="<category> = <search>") - events.on("received.command").on("quotedel", "qdel").hook( - self.quote_del, min_args=1, help="Delete a quote from a category", - usage="<category> = <quote>") - events.on("received.command").on("quote", "q").hook(self.quote, - help="Get a random quote from a category", - usage="<category>", min_args=1) - +class Module(ModuleManager.BaseModule): def category_and_quote(self, s): if "=" in s: return [part.strip() for part in s.split("=", 1)] return None, None + @Utils.hook("received.command.quoteadd|qadd", min_args=1, + usage="<category> = <quote>") def quote_add(self, event): + """ + Add a quote to a category + """ category, quote = self.category_and_quote(event["args"]) if category and quote: setting = "quotes-%s" % category @@ -32,7 +23,12 @@ class Module(object): else: event["stderr"].write("Please provide a category AND quote") + @Utils.hook("received.command.quoteget|qget", min_args=1, + usage="<category> = <search>") def quote_get(self, event): + """ + Get a quote from a ccategory + """ category, to_find = self.category_and_quote(event["args"]) if category and to_find: to_find = to_find.lower() @@ -50,7 +46,12 @@ class Module(object): event["stderr"].write("Please provide a category and a " "part of a quote to find") + @Utils.hook("received.command.quotedel|qdel", min_args=1, + usage="<category> = <quote>") def quote_del(self, event): + """ + Delete a quote from a category + """ category, remove_quote = self.category_and_quote(event["args"]) remove_quote_lower = remove_quote.lower() if category and remove_quote: @@ -70,7 +71,11 @@ class Module(object): event["stderr"].write("Please provide a category and a quote " "to remove") + @Utils.hook("received.command.quote|q", usage="<category>", min_args=1) def quote(self, event): + """ + Get a random quote from a category + """ category = event["args"].strip().lower() quotes = event["server"].get_setting("quotes-%s" % category, []) if quotes: diff --git a/modules/random_number.py b/modules/random_number.py index 1bfbeeca..a8451d88 100644 --- a/modules/random_number.py +++ b/modules/random_number.py @@ -1,14 +1,14 @@ import random, uuid +from src import ModuleManager, Utils -class Module(object): +class Module(ModuleManager.BaseModule): _name = "Random" - def __init__(self, bot, events, exports): - events.on("received.command").on("random", "rand").hook(self.random, - help="Get a random number", usage="[start] [end]") - events.on("received.command.guid").hook(self.guid, - help="Get a random guid") + @Utils.hook("received.command.random|rand", usage="[start] [end]") def random(self, event): + """ + Get a random number + """ start, end = "1", "100" if len(event["args_split"]) > 1: start, end = event["args_split"][:2] @@ -27,5 +27,9 @@ class Module(object): event["stderr"].write( "Both start and end must be valid integers") + @Utils.hook("received.command.guid") def guid(self, event): + """ + Get a random guid + """ event["stdout"].write(str(uuid.uuid4())) diff --git a/modules/sasl.py b/modules/sasl.py index 360bb644..cbebb31e 100644 --- a/modules/sasl.py +++ b/modules/sasl.py @@ -1,14 +1,8 @@ import base64 +from src import Utils class Module(object): def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.cap.ls").hook(self.on_cap) - events.on("received.cap.ack").hook(self.on_cap_ack) - events.on("received.authenticate").hook(self.on_authenticate) - events.on("received.numeric.903").hook(self.sasl_success) - events.on("received.numeric.904").hook(self.sasl_failure) - exports.add("serverset", {"setting": "sasl", "help": "Set the sasl username/password for this server", "validate": self._validate}) @@ -19,6 +13,7 @@ class Module(object): mechanism, arguments = s.split(" ", 1) return {"mechanism": mechanism, "args": arguments} + @Utils.hook("received.cap.ls") def on_cap(self, event): has_sasl = "sasl" in event["capabilities"] our_sasl = event["server"].get_setting("sasl", None) @@ -35,12 +30,14 @@ class Module(object): if do_sasl: event["server"].queue_capability("sasl") + @Utils.hook("received.cap.ack") def on_cap_ack(self, event): if "sasl" in event["capabilities"]: sasl = event["server"].get_setting("sasl") event["server"].send_authenticate(sasl["mechanism"].upper()) event["server"].wait_for_capability("sasl") + @Utils.hook("received.authenticate") def on_authenticate(self, event): if event["message"] != "+": event["server"].send_authenticate("*") @@ -63,7 +60,9 @@ class Module(object): def _end_sasl(self, server): server.capability_done("sasl") + @Utils.hook("received.numeric.903") def sasl_success(self, event): self._end_sasl(event["server"]) + @Utils.hook("received.numeric.904") def sasl_failure(self, event): self._end_sasl(event["server"]) diff --git a/modules/sed.py b/modules/sed.py index c9ef778d..bae45656 100644 --- a/modules/sed.py +++ b/modules/sed.py @@ -6,9 +6,7 @@ REGEX_SED = re.compile("^s/") class Module(object): def __init__(self, bot, events, exports): - self.bot = bot self.events = events - events.on("received.message.channel").hook(self.channel_message) exports.add("channelset", {"setting": "sed", "help": "Disable/Enable sed in a channel", @@ -17,6 +15,7 @@ class Module(object): "help": "Disable/Enable sed only looking at the messages " "sent by the user", "validate": Utils.bool_or_none}) + @Utils.hook("received.message.channel") def channel_message(self, event): sed_split = re.split(REGEX_SPLIT, event["message"], 3) if event["message"].startswith("s/") and len(sed_split) > 2: diff --git a/modules/seen.py b/modules/seen.py index 89e59e18..8a5c80fc 100644 --- a/modules/seen.py +++ b/modules/seen.py @@ -1,17 +1,17 @@ import time -from src import Utils - -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.message.channel").hook(self.channel_message) - events.on("received.command.seen").hook(self.seen, min_args=1, - help="Find out when a user was last seen", usage="<username>") +from src import ModuleManager, Utils +class Module(ModuleManager.BaseModule): + @Utils.hook("received.message.channel") def channel_message(self, event): seen_seconds = time.time() event["user"].set_setting("seen", seen_seconds) + @Utils.hook("received.command.seen", min_args=1, usage="<username>") def seen(self, event): + """ + Find out when a user was last seen + """ seen_seconds = event["server"].get_user(event["args_split"][0] ).get_setting("seen") if seen_seconds: diff --git a/modules/set.py b/modules/set.py index 86cbe6bf..78001209 100644 --- a/modules/set.py +++ b/modules/set.py @@ -1,34 +1,9 @@ - +from src import Utils class Module(object): def __init__(self, bot, events, exports): - self.bot = bot self.exports = exports - events.on("received.command.set").hook(self.set, - usage="<setting> <value>", help="Set a specified user setting") - events.on("received.command.get").hook(self.get, min_args=1, - usage="<setting>", help="Get a specified user setting") - - events.on("received.command.channelset").hook(self.channel_set, - channel_only=True, usage="<setting> <value>", require_mode="o", - help="Set a specified setting for the current channel") - events.on("received.command.channelsetoverride").hook( - self.channel_set, channel_only=True, usage="<setting> <value>", - permission="channelsetoverride", - help="Set a specified setting for the current channel") - events.on("received.command.channelget").hook(self.channel_get, - channel_only=True, usage="<setting>", min_args=1, - require_mode="o", help="Get a specified setting for the current " - "channel") - - events.on("received.command.serverset").hook(self.server_set, - usage="<setting> <value>", permission="serverset", - help="Set a specified setting for the current server") - events.on("received.command.serverget").hook(self.server_get, - usage="<setting>", min_args=1, permission="serverget", - help="Get a specified setting for the current server") - def _set(self, settings, event, target): settings_dict = dict([(setting["setting"], setting ) for setting in settings]) @@ -50,13 +25,29 @@ class Module(object): else: event["stdout"].write("Available settings: %s" % ( ", ".join(settings_dict.keys()))) + @Utils.hook("received.command.set", usage="<setting> <value>") def set(self, event): + """ + Set a specified user setting + """ self._set(self.exports.get_all("set"), event, event["user"]) + @Utils.hook("received.command.channelset", channel_only=True, + usage="<setting> <value>", require_mode="o") + @Utils.hook("received.command.channelsetoverride", channel_only=True, + usage="<setting> <value>", permission="channelsetoverride") def channel_set(self, event): + """ + Get a specified channel setting for the current channel + """ self._set(self.exports.get_all("channelset"), event, event["target"]) + @Utils.hook("received.command.serverset", usage="<setting> <value>", + permission="serverset") def server_set(self, event): + """ + Set a specified server setting for the current server + """ self._set(self.exports.get_all("serverset"), event, event["server"]) def _get(self, event, setting, qualifier, value): @@ -66,17 +57,31 @@ class Module(object): else: event["stdout"].write("'%s' has no value set" % setting) + @Utils.hook("received.command.get", min_args=1, usage="<setting>") def get(self, event): + """ + Get a specified user setting + """ setting = event["args_split"][0] self._get(event, setting, "", event["user"].get_setting( setting, None)) + @Utils.hook("received.command.channelget", channel_only=True, + usage="<setting>", min_args=1, require_mode="o") def channel_get(self, event): + """ + Get a specified channel setting for the current channel + """ setting = event["args_split"][0] self._get(event, setting, " for %s" % event["target"].name, event["target"].get_setting(setting, None)) + @Utils.hook("received.command.serverget", usage="<setting>", min_args=1, + permission="serverget") def server_get(self, event): + """ + Get a specified server setting for the current server + """ setting = event["args_split"][0] self._get(event, setting, "", event["server"].get_setting( setting, None)) diff --git a/modules/shakespeare.py b/modules/shakespeare.py index bc4a9900..99d4ba2d 100644 --- a/modules/shakespeare.py +++ b/modules/shakespeare.py @@ -1,5 +1,5 @@ import random -from src import Utils +from src import ModuleManager, Utils INSULT_INTRO = ["Thou art a", "Ye", "Thou", "Thy", "Thee"] @@ -51,14 +51,8 @@ INSULT_PART_3 = ["apple-john", "baggage", "barnacle", "bladder", "boar-pig", "vassal", "whey-face", "wagtail"] -class Module(object): - - def __init__(self, bot, events, exports): - self.bot = bot - self.events = events - - events.on("received.command.insult").hook(self.dispense_insult) - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.insult") def dispense_insult(self, event): insult = [random.choice(INSULT_INTRO), random.choice(INSULT_PART_1), random.choice(INSULT_PART_2), random.choice(INSULT_PART_3)] diff --git a/modules/soundcloud.py b/modules/soundcloud.py index 70e75423..8ecde75a 100644 --- a/modules/soundcloud.py +++ b/modules/soundcloud.py @@ -11,10 +11,12 @@ class Module(object): _name = "SoundCloud" def __init__(self, bot, events, exports): self.bot = bot - events.on("received").on("command").on("soundcloud", "sc" - ).hook(self.soundcloud, help="Search SoundCloud") + @Utils.hook("received.command.soundcloud|sc") def soundcloud(self, event): + """ + Search SoundCloud + """ query = None url = None diff --git a/modules/spotify.py b/modules/spotify.py index eef89b15..6816cd50 100644 --- a/modules/spotify.py +++ b/modules/spotify.py @@ -1,14 +1,14 @@ import json -from src import Utils +from src import ModuleManager, Utils URL_SPOTIFY = "https://api.spotify.com/v1/search" -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command.spotify").hook(self.spotify, min_args=1, - help="Search for a track on spotify") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.spotify", min_args=1) def spotify(self, event): + """ + Search for a track on spotify + """ page = Utils.get_url(URL_SPOTIFY, get_params={"type": "track", "limit": 1, "q": event["args"]}, json=True) if page: diff --git a/modules/stats.py b/modules/stats.py index 867d7577..927eedad 100644 --- a/modules/stats.py +++ b/modules/stats.py @@ -4,17 +4,21 @@ from src import Utils class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command.uptime").hook(self.uptime, - help="Show my uptime") - events.on("received.command.stats").hook(self.stats, - help="Show my network/channel/user stats") + @Utils.hook("received.command.uptime") def uptime(self, event): + """ + Show my uptime + """ seconds = int(time.time()-self.bot.start_time) event["stdout"].write("Uptime: %s" % Utils.to_pretty_time( seconds)) + @Utils.hook("received.command.stats") def stats(self, event): + """ + Show my network/channel/user stats + """ networks = len(self.bot.servers) channels = 0 users = 0 diff --git a/modules/strax.py b/modules/strax.py index 0a189b48..385c825b 100644 --- a/modules/strax.py +++ b/modules/strax.py @@ -1,12 +1,13 @@ import random +from src import ModuleManager, Utils - -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command.strax").hook( - self.strax, help="Suggests a glorious method of battle for the glory of the Sontaran Empire, through IRC!") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.strax") def strax(self, event): + """ + Suggests a glorious method of battle for the glory of the Sontaran + Empire, through IRC! + """ suggestion_greeting = ["Might I suggest", "Can I suggest", "Should we attack immediately with"] command_greeting = ["We should attack now with", "We must attack now with", "I suggest attacking with", "We should coordinate an attack with"] diff --git a/modules/telegram.py b/modules/telegram.py index d99c51cc..f60613b4 100644 --- a/modules/telegram.py +++ b/modules/telegram.py @@ -1,5 +1,5 @@ -import telegram -from telegram.ext import CommandHandler, MessageHandler, Updater, Filters +#--ignore +import telegram, telegram.ext import json from datetime import datetime @@ -15,16 +15,16 @@ class Module(Thread): self.bot = bot self.events = events - self.updater = Updater(key) + self.updater = telegram.ext.Updater(key) self.dispatcher = self.updater.dispatcher - start_handler = CommandHandler("start", self.start) - command_handler = MessageHandler(Filters.command, self.handle) + start_handler = telegram.ext.CommandHandler("start", self.start) + command_handler = telegram.ext.MessageHandler( + telegram.ext.Filters.command, self.handle) self.dispatcher.add_handler(start_handler) self.dispatcher.add_handler(command_handler) self.updater.start_polling() - events.on("signal.interrupt").hook(self.sigint) def start(self, bot, update): bot.send_message(chat_id=update.message.chat_id, text="`Dolphin, but Telegram`", parse_mode="Markdown") @@ -48,6 +48,7 @@ class Module(Thread): } self.events.on("telegram.command").on(command).call(**data) + @Utils.hook("signal.interrupt") def sigint(self, event): self.updater.stop() diff --git a/modules/tfl.py b/modules/tfl.py index 3efb85b9..ef7d2b08 100644 --- a/modules/tfl.py +++ b/modules/tfl.py @@ -23,30 +23,6 @@ class Module(object): def __init__(self, bot, events, exports): self.bot = bot self.result_map = {} - events.on("received.command.tflbus" - ).hook(self.bus, min_args=1, - help="Get bus due times for a TfL bus stop", - usage="<stop_id>") - events.on("received.command.tflline" - ).hook(self.line, - help="Get line status for TfL underground lines", - usage="<line_name>") - events.on("received.command.tflsearch" - ).hook(self.search, min_args=1, - help="Get a list of TfL stop IDs for a given name", - usage="<name>") - events.on("received.command.tflvehicle" - ).hook(self.vehicle, min_args=1, - help="Get information for a given vehicle", - usage="<ID>") - events.on("received.command.tflstop" - ).hook(self.stop, min_args=1, - help="Get information for a given stop", - usage="<stop_id>") - events.on("received.command.tflservice" - ).hook(self.service, min_args=1, - help="Get service information and arrival estimates", - usage="<service index>") def vehicle_span(self, arrival_time, human=True): vehicle_due_iso8601 = arrival_time @@ -72,7 +48,11 @@ class Module(object): platform = m.group(2) return platform + @Utils.hook("received.command.tflbus", min_args=1, usage="<stop_id>") def bus(self, event): + """ + Get bus due times for a TfL bus stop + """ app_id = self.bot.config["tfl-api-id"] app_key = self.bot.config["tfl-api-key"] stop_id = event["args_split"][0] @@ -144,7 +124,11 @@ class Module(object): else: event["stderr"].write("Bus ID '%s' unknown" % stop_id) + @Utils.hook("received.command.tflline", usage="<line_name>") def line(self, event): + """ + Get line status for TfL underground lines + """ app_id = self.bot.config["tfl-api-id"] app_key = self.bot.config["tfl-api-key"] @@ -183,7 +167,11 @@ class Module(object): else: event["stderr"].write("No results") + @Utils.hook("received.command.tflsearch", min_args=1, usage="<name>") def search(self, event): + """ + Get a list of TfL stop IDs for a given name + """ app_id = self.bot.config["tfl-api-id"] app_key = self.bot.config["tfl-api-key"] @@ -200,7 +188,11 @@ class Module(object): else: event["stderr"].write("No results") + @Utils.hook("received.command.tflvehicle", min_args=1, usage="<ID>") def vehicle(self, event): + """ + Get information for a given vehicle + """ app_id = self.bot.config["tfl-api-id"] app_key = self.bot.config["tfl-api-key"] @@ -208,7 +200,7 @@ class Module(object): vehicle = Utils.get_url(URL_VEHICLE % vehicle_id, get_params={ "app_id": app_id, "app_key": app_key}, json=True)[0] - + arrival_time = self.vehicle_span(vehicle["expectedArrival"], human=False) platform = self.platform(vehicle["platformName"]) @@ -216,7 +208,12 @@ class Module(object): vehicle["vehicleId"], vehicle["lineName"], vehicle["destinationName"], vehicle["currentLocation"], vehicle["stationName"], vehicle["naptanId"], arrival_time, platform)) + @Utils.hook("received.command.tflservice", min_args=1, + usage="<service index>") def service(self, event): + """ + Get service information and arrival estimates + """ app_id = self.bot.config["tfl-api-id"] app_key = self.bot.config["tfl-api-key"] @@ -244,7 +241,11 @@ class Module(object): a["expectedArrival"][11:16] ) for a in arrivals])) + @Utils.hook("received.command.tflstop", min_args=1, usage="<stop_id>") def stop(self, event): + """ + Get information for a given stop + """ app_id = self.bot.config["tfl-api-id"] app_key = self.bot.config["tfl-api-key"] diff --git a/modules/thesaurus.py b/modules/thesaurus.py index 9328a330..3791d609 100644 --- a/modules/thesaurus.py +++ b/modules/thesaurus.py @@ -7,11 +7,13 @@ URL_THESAURUS = "http://words.bighugelabs.com/api/2/%s/%s/json" class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command").on("synonym", "antonym").hook( - self.thesaurus, min_args=1, usage="<word> [type]", - help="Get synonyms/antonyms for a provided phrase") + @Utils.hook("received.command.synonym|antonym", min_args=1, + usage="<word> [type]") def thesaurus(self, event): + """ + Get synonyms/antonyms for a provided phrase + """ phrase = event["args_split"][0] page = Utils.get_url(URL_THESAURUS % (self.bot.config[ "bighugethesaurus-api-key"], phrase), json=True) diff --git a/modules/title.py b/modules/title.py index 6dc4cc4e..80b450f8 100644 --- a/modules/title.py +++ b/modules/title.py @@ -1,14 +1,14 @@ import re -from src import Utils +from src import ModuleManager, Utils REGEX_URL = re.compile("https?://\S+", re.I) -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command").on("title", "t").hook(self.title, - help="Get the title of a URL", usage="[URL]") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.title|t", usage="[URL]") def title(self, event): + """ + Get the title of a URL + """ url = None if len(event["args"]) > 0: url = event["args_split"][0] diff --git a/modules/to.py b/modules/to.py index 8ff51ffe..2bfe410d 100644 --- a/modules/to.py +++ b/modules/to.py @@ -1,14 +1,7 @@ -from src import EventManager - -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.message.channel").hook(self.channel_message, - priority=EventManager.PRIORITY_HIGH) - events.on("received.command.to").hook(self.to, min_args=2, - help=("Relay a message to a user the next time they talk " - "in this channel"), channel_only=True, - usage="<username> <message>") +from src import EventManager, ModuleManager, Utils +class Module(ModuleManager.BaseModule): + @Utils.hook("received.message.channel", priority=EventManager.PRIORITY_HIGH) def channel_message(self, event): messages = event["channel"].get_user_setting(event["user"].get_id(), "to", []) @@ -18,7 +11,12 @@ class Module(object): if messages: event["channel"].del_user_setting(event["user"].get_id(), "to") + @Utils.hook("received.command.to", min_args=2, channel_only=True, + usage="<username> <message>") def to(self, event): + """ + Relay a message to a user the next time they talk in this channel" + """ target_user = event["server"].get_user(event["args_split"][0]) messages = event["target"].get_user_setting(target_user.get_id(), "to", []) diff --git a/modules/todo.py b/modules/todo.py index ec1c6a01..957accee 100644 --- a/modules/todo.py +++ b/modules/todo.py @@ -1,16 +1,11 @@ +from src import ModuleManager, Utils - -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command.todo").hook(self.todo, - help="Find out what's in your todo list", usage="[item number]") - events.on("received.command.todoadd").hook(self.todo_add, min_args=1, - help="Add something to your todo list", usage="<description>") - events.on("received.command.tododel").hook(self.todo_del, min_args=1, - help="Remove something from your todo list", usage="<item number>") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.todo", usage="[item number]") def todo(self, event): + """ + Find out what's in your todo list + """ todo = event["user"].get_setting("todo", []) if event["args"]: if event["args_split"][0].isdigit() and int(event["args_split"][0]) > 0: @@ -25,7 +20,11 @@ class Module(object): todo_count = len(todo) event["stdout"].write("There are %d items in your todo" % todo_count) + @Utils.hook("received.command.todoadd", min_args=1, usage="<description>") def todo_add(self, event): + """ + Add something to your todo list + """ arg_lower = event["args"].lower() todo = event["user"].get_setting("todo", []) for item in todo: @@ -37,7 +36,11 @@ class Module(object): event["user"].set_setting("todo", todo) event["stdout"].write("Saved") + @Utils.hook("received.command.tododel", min_args=1, usage="<item number>") def todo_del(self, event): + """ + Remove something from your todo list + """ todo = event["user"].get_setting("todo", []) if event["args_split"][0].isdigit() and int(event["args_split"][0]) > 0: index = int(event["args_split"][0]) diff --git a/modules/torrent.py b/modules/torrent.py new file mode 100644 index 00000000..fdc3221d --- /dev/null +++ b/modules/torrent.py @@ -0,0 +1,49 @@ +#--ignore + +import tempfile, time +import libtorrent + +def magnet(magnet): + #log.info("Opening session for link %s", url) + + session = libtorrent.session() + session.add_extension('ut_metadata') + session.add_extension('ut_pex') + session.add_extension('metadata_transfer') + session.add_dht_router("router.utorrent.com", 6881) + session.add_dht_router("router.bittorrent.com", 6881) + session.add_dht_router("dht.transmissionbt.com", 6881) + session.add_dht_router("dht.aelitis.com", 6881) + session.start_dht() + session.start_lsd() + session.start_upnp() + session.start_natpmp() + + params = {'save_path': "/dev/null", 'duplicate_is_error': True, + 'storage_mode': libtorrent.storage_mode_t(2), 'paused': False, + 'auto_managed': True} + handle = libtorrent.add_magnet_uri(session, magnet, params) + + #log.info("Waiting metadata") + has_metadata = False + for i in range(10): + if handle.has_metadata(): + print("yes!") + has_metadata = True + break + else: + time.sleep(1) + if not has_metadata: + print("no!") + #event["stderr"].write("Timed out getting magnet info") + return + session.pause() + + #log.info("Metadata retrieved") + torrent_info = handle.get_torrent_info() + print(dir(torrent_info)) + + session.remove_torrent(handle) + #log.info("Torrent file saved to %s", file_path) + +magnet("magnet:?xt=urn:btih:ea5938cbb6176a675a3e71682faf9801b5b6116f") diff --git a/modules/trakt.py b/modules/trakt.py index 57f4bce1..81f9f00d 100644 --- a/modules/trakt.py +++ b/modules/trakt.py @@ -8,14 +8,14 @@ URL_TRAKTSLUG = "https://trakt.tv/%s/%s" class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command").on("nowwatching", "nw").hook( - self.now_watching, usage="[username]", - help="Get what you or another user is now watching on trakt.tv") - exports.add("set", {"setting": "trakt", "help": "Set username on trakt.tv"}) + @Utils.hook("received.command.nowwatching|nw", usage="[username]") def now_watching(self, event): + """ + Get what you or another user is now watching on trakt.tv + """ if event["args"]: username = event["args_split"][0] else: diff --git a/modules/translate.py b/modules/translate.py index fd2c2c07..297b3147 100644 --- a/modules/translate.py +++ b/modules/translate.py @@ -1,17 +1,16 @@ import json, re -from src import Utils +from src import ModuleManager, Utils URL_TRANSLATE = "http://translate.googleapis.com/translate_a/single" URL_LANGUAGES = "https://cloud.google.com/translate/docs/languages" REGEX_LANGUAGES = re.compile("(\w+)?:(\w+)? ") -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command").on("translate", "tr").hook( - self.translate, help="Translate the provided phrase or the " - "last line seen.", usage="[phrase]") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.translate|tr", usage="[phrase]") def translate(self, event): + """ + Translate the provided phrase or the last line in thie current channel + """ phrase = event["args"] if not phrase: phrase = event["buffer"].get() diff --git a/modules/tweets.py b/modules/tweets.py index 9995293a..8f8d2396 100644 --- a/modules/tweets.py +++ b/modules/tweets.py @@ -16,16 +16,17 @@ class Module(object): self.bot = bot self.events = events - events.on("received.command").on("tweet", "tw").hook(self.tweet, - help="Find a tweet", usage="[@username/URL/ID]") - def make_timestamp(self, s): seconds_since = time.time() - datetime.datetime.strptime(s, "%a %b %d %H:%M:%S %z %Y").timestamp() since, unit = Utils.time_unit(seconds_since) return "%s %s ago" % (since, unit) + @Utils.hook("received.command.tweet|tw", usage="[@username/URL/ID]") def tweet(self, event): + """ + Get/find a tweet + """ api_key = self.bot.config["twitter-api-key"] api_secret = self.bot.config["twitter-api-secret"] access_token = self.bot.config["twitter-access-token"] diff --git a/modules/upc.py b/modules/upc.py index 0e47801f..8da063f5 100644 --- a/modules/upc.py +++ b/modules/upc.py @@ -1,16 +1,15 @@ -from src import Utils +from src import ModuleManager, Utils UPCITEMDB_URL = "https://api.upcitemdb.com/prod/trial/lookup" -class Module(object): +class Module(ModuleManager.BaseModule): _name = "UPC" - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command").on("upc", "ean", "gtin").hook( - self.upc, min_args=1, usage="<UPC|EAN>", - help="Look up a product by UPC or EAN") + @Utils.hook("received.command.upc|ean|gtin", min_args=1, usage="<UPC|EAN>") def upc(self, event): + """ + Look up a product by UPC, EAN or GTIN + """ arg_len = len(event["args_split"][0]) if not arg_len == 12 and not arg_len == 13: event["stderr"].write("Invalid UPC/EAN provided") diff --git a/modules/urbandictionary.py b/modules/urbandictionary.py index bb0f7918..6151afb8 100644 --- a/modules/urbandictionary.py +++ b/modules/urbandictionary.py @@ -1,16 +1,16 @@ import json, re -from src import Utils +from src import ModuleManager, Utils URL_URBANDICTIONARY = "http://api.urbandictionary.com/v0/define" REGEX_DEFNUMBER = re.compile("-n(\d+) \S+") -class Module(object): - def __init__(self, bot, events, exports): - events.on("received.command").on("urbandictionary", "ud").hook( - self.ud, min_args=1, help="Get the definition of a provided term", - usage="<term>") - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.urbandictionary|ud", min_args=1, + usage="<term>") def ud(self, event): + """ + Get the definition of a provided term from Urban Dictionary + """ term = event["args"] number = 1 match = re.match(REGEX_DEFNUMBER, term) diff --git a/modules/weather.py b/modules/weather.py index e79d1ad8..f16b62b7 100644 --- a/modules/weather.py +++ b/modules/weather.py @@ -7,11 +7,12 @@ URL_WEATHER = "http://api.openweathermap.org/data/2.5/weather" class Module(object): def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command.weather").hook(self.weather, min_args=1, - help="Get current weather data for a provided location", - usage="<location>") + @Utils.hook("received.command.weather", min_args=1, usage="<location>") def weather(self, event): + """ + Get current weather data for a provided location + """ api_key = self.bot.config["openweathermap-api-key"] page = Utils.get_url(URL_WEATHER, get_params={ "q": event["args"], "units": "metric", diff --git a/modules/wikipedia.py b/modules/wikipedia.py index ffe9473d..f668b8ca 100644 --- a/modules/wikipedia.py +++ b/modules/wikipedia.py @@ -1,14 +1,13 @@ -from src import Utils +from src import ModuleManager, Utils URL_WIKIPEDIA = "https://en.wikipedia.org/w/api.php" -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.command").on("wiki", "wi" - ).hook(self.wikipedia, min_args=1) - +class Module(ModuleManager.BaseModule): + @Utils.hook("received.command.wiki|wi", min_args=1) def wikipedia(self, event): + """ + Get information from wikipedia + """ page = Utils.get_url(URL_WIKIPEDIA, get_params={ "action": "query", "prop": "extracts", "titles": event["args"], "exintro": "", diff --git a/modules/wolframalpha.py b/modules/wolframalpha.py index 90bff060..6415639c 100644 --- a/modules/wolframalpha.py +++ b/modules/wolframalpha.py @@ -8,12 +8,12 @@ class Module(object): _name = "Wolfram|Alpha" def __init__(self, bot, events, exports): self.bot = bot - events.on("received.command").on("wolframalpha", "wa" - ).hook(self.wa, min_args=1, help= - "Evauate a given string on Wolfram|Alpha", - usage="<query>") + @Utils.hook("received.command.wolframalpha|wa", min_args=1, usage="<query>") def wa(self, event): + """ + Evauate a given string on Wolfram|Alpha + """ code, result = Utils.get_url(URL_WA, get_params={"i": event["args"], "appid": self.bot.config["wolframalpha-api-key"], "reinterpret": "true", "units": "metric"}, code=True) diff --git a/modules/words.py b/modules/words.py index 55f2fd9d..689f5c73 100644 --- a/modules/words.py +++ b/modules/words.py @@ -1,26 +1,7 @@ import time -from src import Utils - -class Module(object): - def __init__(self, bot, events, exports): - self.bot = bot - events.on("received.message.channel" - ).hook(self.channel_message) - events.on("self.message.channel" - ).hook(self.self_channel_message) - events.on("received.command.words" - ).hook(self.words, channel_only=True, - usage="<nickname>", help= - "See how many words you or the given nickname have used") - events.on("received.command.trackword" - ).hook(self.track_word, min_args=1, - help="Start tracking a word", usage="<word>", - permission="track-word") - events.on("received.command.wordusers" - ).hook(self.word_users, min_args=1, - help="Show who has used a tracked word the most", - usage="<word>") +from src import ModuleManager, Utils +class Module(ModuleManager.BaseModule): def _channel_message(self, user, event): words = list(filter(None, event["message_split"])) word_count = len(words) @@ -42,13 +23,19 @@ class Module(object): word_count = user.get_setting(setting, 0) word_count += 1 user.set_setting(setting, word_count) + @Utils.hook("received.message.channel") def channel_message(self, event): self._channel_message(event["user"], event) + @Utils.hook("self.message.channel") def self_channel_message(self, event): self._channel_message(event["server"].get_user( event["server"].nickname), event) + @Utils.hook("received.command.words", channel_only=True, usage="<nickname>") def words(self, event): + """ + See how many words you or the given nickname have used + """ if event["args_split"]: target = event["server"].get_user(event["args_split" ][0]) @@ -64,7 +51,12 @@ class Module(object): event["stdout"].write("%s has used %d words (%d in %s)" % ( target.nickname, total, this_channel, event["target"].name)) + @Utils.hook("received.command.trackword", min_args=1, + permission="track-word") def track_word(self, event): + """ + Start tracking a word + """ word = event["args_split"][0].lower() tracked_words = event["server"].get_setting("tracked-words", []) if not word in tracked_words: @@ -74,7 +66,11 @@ class Module(object): else: event["stderr"].write("Already tracking '%s'" % word) + @Utils.hook("received.command.wordusers", min_args=1, usage="<word>") def word_users(self, event): + """ + Show who has used a tracked word the most + """ word = event["args_split"][0].lower() if word in event["server"].get_setting("tracked-words", []): word_users = event["server"].get_all_user_settings( diff --git a/modules/youtube.py b/modules/youtube.py index 1cd0f675..10766c9c 100644 --- a/modules/youtube.py +++ b/modules/youtube.py @@ -20,11 +20,6 @@ class Module(object): def __init__(self, bot, events, exports): self.bot = bot self.events = events - events.on("received.command").on("yt", "youtube").hook(self.yt, - help="Find a video on youtube", usage="[query]") - events.on("received.message.channel").hook(self.channel_message) - - events.on("get.searchyoutube").hook(self.search_video) exports.add("channelset", {"setting": "auto-youtube", "help": "Disable/Enable automatically getting info from " @@ -65,6 +60,7 @@ class Module(object): video_title, video_duration, video_uploader, "{:,}".format( int(video_views)), video_opinions, URL_YOUTUBESHORT % video_id) + @Utils.hook("get.searchyoutube") def search_video(self, event): search = event["query"] video_id = "" @@ -80,8 +76,11 @@ class Module(object): video_id = search_page["items"][0]["id"]["videoId"] return "https://youtu.be/%s" % video_id - + @Utils.hook("received.command.yt|youtube", usage="[query]") def yt(self, event): + """ + Find a video on youtube + """ video_id = None search = None if event["args"]: @@ -111,6 +110,7 @@ class Module(object): else: event["stderr"].write("No search phrase provided") + @Utils.hook("received.message.channel") def channel_message(self, event): match = re.search(REGEX_YOUTUBE, event["message"]) if match and event["channel"].get_setting("auto-youtube", False): |
