From bf984bacd0b74996b9917bcb3e8abe1b9a1f7e9a Mon Sep 17 00:00:00 2001 From: Russell Date: Sat, 16 Feb 2019 13:40:10 -0500 Subject: [PATCH] Create ops only commands (#50) * Add support for ops commands. Fixes #48 * Update readme. remove prints --- README.md | 11 +++++++++++ pinhook/bot.py | 36 ++++++++++++++++++++---------------- pinhook/plugin.py | 23 +++++++++++++++++++++-- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index ea46a9c..6dabd6d 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,17 @@ It also contains the following IRC functions: * `action`: same as privmsg, but does a CTCP action. (i.e., `/me does a thing`) * `notice`: send a notice +You can optionally use the `@pinhook.plugin.ops` decorator to denote that a command should only be executable by a bot op. +* If you specify the optional second argument, it will be displayed when a non-op attempts to execute the command + +The function will need to be structured as such: +```python +@pinhook.plugin.register('!test') +@pinhook.plugin.ops('!test', 'Only ops can run this command!') +def test_plugin(msg): + return pinhook.plugin.message('This was run by an op!') +``` + **OR** The plugin function can return one of the following in order to give a response to the command: diff --git a/pinhook/bot.py b/pinhook/bot.py index 4d2eacf..3c45ffa 100644 --- a/pinhook/bot.py +++ b/pinhook/bot.py @@ -134,8 +134,8 @@ class Bot(irc.bot.SingleServerIRCBot): def on_action(self, c, e): self.process_event(c, e) - def call_help(self): - helplist = sorted([i for i in pinhook.plugin.cmds]) + def call_help(self, op): + helplist = sorted([i for i in pinhook.plugin.cmds if op or not ('ops' in pinhook.plugin.cmds[i] and pinhook.plugin.cmds[i]['ops'])]) msg = ', '.join(helplist) return self.output_message('Available commands: {}'.format(msg)) @@ -154,7 +154,7 @@ class Bot(irc.bot.SingleServerIRCBot): c.quit("See y'all later!") quit() elif cmd == '!help': - output = self.call_help() + output = self.call_help(op) elif cmd == '!reload' and op: self.logger.info('reloading plugins per request of {}'.format(nick)) self.load_plugins() @@ -165,19 +165,23 @@ class Bot(irc.bot.SingleServerIRCBot): output = None if cmd in pinhook.plugin.cmds: try: - output = pinhook.plugin.cmds[cmd]['run'](self.Message( - channel=chan, - cmd=cmd, - nick_list=nick_list, - nick=nick, - arg=arg, - privmsg=privmsg, - action=action, - notice=notice, - botnick=self.bot_nick, - ops=self.ops, - logger=self.logger - )) + if 'ops' in pinhook.plugin.cmds[cmd] and nick not in self.ops: + if pinhook.plugin.cmds[cmd]['ops_msg']: + output = self.output_message(pinhook.plugin.cmds[cmd]['ops_msg']) + else: + output = pinhook.plugin.cmds[cmd]['run'](self.Message( + channel=chan, + cmd=cmd, + nick_list=nick_list, + nick=nick, + arg=arg, + privmsg=privmsg, + action=action, + notice=notice, + botnick=self.bot_nick, + ops=self.ops, + logger=self.logger + )) except Exception as e: self.logger.exception('issue with command {}'.format(cmd)) else: diff --git a/pinhook/plugin.py b/pinhook/plugin.py index f94313e..3f39028 100644 --- a/pinhook/plugin.py +++ b/pinhook/plugin.py @@ -1,4 +1,5 @@ from enum import Enum +from functools import wraps cmds = {} @@ -31,10 +32,20 @@ def message(msg): def _add_plugin(command, help_text, func): - cmds[command] = { + if command not in cmds: + cmds[command] = {} + cmds[command].update({ 'run': func, 'help': help_text - } + }) + +def _ops_plugin(command, ops_msg, func): + if command not in cmds: + cmds[command] = {} + cmds[command].update({ + 'ops': True, + 'ops_msg': ops_msg, + }) def _add_listener(name, func): @@ -47,6 +58,7 @@ def clear_plugins(): def register(command, help_text=None): + @wraps(command) def register_for_command(func): _add_plugin(command, help_text, func) return func @@ -58,3 +70,10 @@ def listener(name): _add_listener(name, func) return func return register_as_listener + +def ops(command, msg=None): + @wraps(command) + def register_ops_command(func): + _ops_plugin(command, msg, func) + return func + return register_ops_command