Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
Mal Hancock | 004632537b | |
mallory | d528213c5f | |
mallory | c3613f196a | |
mallory | fdca6da624 | |
Mal Hancock | 5c9278bc63 | |
Lars Kellogg-Stedman | 35f5bb684b | |
mallory | 7c62e59c3a | |
mallory | b995b866ec | |
Mal Hancock | 9f62c6c67e | |
Mal Hancock | 855413a093 | |
Mal Hancock | cea5e6f855 | |
Mal Hancock | e7b7a5b832 | |
Mal Hancock | 0417dddf2f | |
Mal Hancock | a0378e09c9 | |
Mal Hancock | 5b241eee13 | |
Mal Hancock | 0e510cc8b6 | |
Mallory Hancock | 1c4fdb8d9e |
|
@ -0,0 +1,4 @@
|
|||
github: archangelic
|
||||
ko_fi: archangelic
|
||||
liberapay: archangelic
|
||||
custom: ["https://paypal.me/archangelic", "https://cash.app/$archangelic"]
|
|
@ -0,0 +1,30 @@
|
|||
# This workflows will upload a Python Package using Twine when a release is created
|
||||
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
||||
|
||||
name: Upload Python Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel twine
|
||||
- name: Build and publish
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
python setup.py upload
|
11
README.md
11
README.md
|
@ -127,14 +127,14 @@ These options are the same for both IRC and Twitch
|
|||
|
||||
There are two types of plugins, commands and listeners. Commands only activate if a message starts with the command word, while listeners receive all messages and are parsed by the plugin for maximum flexibility.
|
||||
|
||||
In your chosen plugins directory ("plugins" by default) make a python file with a function. You use the `@pinhook.plugin.register` decorator to create command plugins, or `@pinhook.plugin.listener` to create listeners.
|
||||
In your chosen plugins directory ("plugins" by default) make a python file with a function. You use the `@pinhook.plugin.command` decorator to create command plugins, or `@pinhook.plugin.listener` to create listeners.
|
||||
|
||||
The function will need to be structured as such:
|
||||
|
||||
```python
|
||||
import pinhook.plugin
|
||||
|
||||
@pinhook.plugin.register('!test')
|
||||
@pinhook.plugin.command('!test')
|
||||
def test_plugin(msg):
|
||||
message = '{}: this is a test!'.format(msg.nick)
|
||||
return pinhook.plugin.message(message)
|
||||
|
@ -162,15 +162,12 @@ 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
|
||||
You can optionally set a command to be used only by ops
|
||||
|
||||
The function will need to be structured as such:
|
||||
|
||||
```python
|
||||
@pinhook.plugin.register('!test')
|
||||
@pinhook.plugin.ops('!test', 'Only ops can run this command!')
|
||||
@pinhook.plugin.command('!test', ops=True, ops_msg='This command can only be run by an op')
|
||||
def test_plugin(msg):
|
||||
return pinhook.plugin.message('This was run by an op!')
|
||||
```
|
||||
|
|
|
@ -1 +1 @@
|
|||
theme: jekyll-theme-midnight
|
||||
theme: jekyll-theme-minimal
|
|
@ -17,7 +17,7 @@ def build_output(rolls, modifier):
|
|||
output = start
|
||||
return output
|
||||
|
||||
@pinhook.plugin.register('!roll')
|
||||
@pinhook.plugin.command('!roll')
|
||||
def roll(msg):
|
||||
matches = dicepattern.match(msg.arg)
|
||||
if matches:
|
||||
|
|
|
@ -17,7 +17,7 @@ def build_output(rolls, modifier):
|
|||
output = start
|
||||
return output
|
||||
|
||||
@pinhook.plugin.register('!roll')
|
||||
@pinhook.plugin.command('!roll')
|
||||
def roll(msg):
|
||||
matches = dicepattern.match(msg.arg)
|
||||
if matches:
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__ = '1.9.2'
|
||||
__version__ = '1.9.7'
|
||||
|
|
|
@ -14,6 +14,20 @@ irc.client.ServerConnection.buffer_class.errors = 'replace'
|
|||
|
||||
|
||||
class Bot(irc.bot.SingleServerIRCBot):
|
||||
internal_commands = {
|
||||
'join': 'join a channel',
|
||||
'quit': 'force the bot to quit',
|
||||
'reload': 'force bot to reload all plugins',
|
||||
'enable': 'enable a plugin',
|
||||
'disable': 'disable a plugin',
|
||||
'op': 'add a user as bot operator',
|
||||
'deop': 'remove a user as bot operator',
|
||||
'ops': 'list all ops',
|
||||
'ban': 'ban a user from using the bot',
|
||||
'unban': 'remove bot ban for user',
|
||||
'banlist': 'currently banned nicks'
|
||||
}
|
||||
|
||||
def __init__(self, channels, nickname, server, **kwargs):
|
||||
self.port = kwargs.get('port', 6667)
|
||||
self.ops = kwargs.get('ops', [])
|
||||
|
@ -36,21 +50,6 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
self.chanlist = channels
|
||||
self.bot_nick = nickname
|
||||
self.start_logging()
|
||||
self.output_message = plugin.message
|
||||
self.output_action = plugin.action
|
||||
self.internal_commands = {
|
||||
'join': 'join a channel',
|
||||
'quit': 'force the bot to quit',
|
||||
'reload': 'force bot to reload all plugins',
|
||||
'enable': 'enable a plugin',
|
||||
'disable': 'disable a plugin',
|
||||
'op': 'add a user as bot operator',
|
||||
'deop': 'remove a user as bot operator',
|
||||
'ops': 'list all ops',
|
||||
'ban': 'ban a user from using the bot',
|
||||
'unban': 'remove bot ban for user',
|
||||
'banlist': 'currently banned nicks'
|
||||
}
|
||||
self.internal_commands = {self.cmd_prefix + k: v for k,v in self.internal_commands.items()}
|
||||
plugin.load_plugins(self.plugin_dir, use_prefix=self.use_prefix_for_plugins, cmd_prefix=self.cmd_prefix)
|
||||
|
||||
|
@ -72,9 +71,9 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
if cmd:
|
||||
self.cmd = cmd
|
||||
self.arg = arg
|
||||
if text:
|
||||
if text != None:
|
||||
self.text = text
|
||||
if not (cmd or text):
|
||||
if not (cmd==None or text==None):
|
||||
raise TypeError('missing cmd or text parameter')
|
||||
|
||||
def start_logging(self):
|
||||
|
@ -140,7 +139,7 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
try:
|
||||
c.join(*arg.split())
|
||||
self.logger.info('joining {} per request of {}'.format(arg, nick))
|
||||
output = self.output_message('{}: joined {}'.format(nick, arg.split()[0]))
|
||||
output = plugin.message('{}: joined {}'.format(nick, arg.split()[0]))
|
||||
except:
|
||||
self.logger.exception('issue with join command: {}join #channel <channel key>'.format(self.cmd_prefix))
|
||||
elif cmd == 'quit' and op:
|
||||
|
@ -154,43 +153,43 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
elif cmd == 'reload' and op:
|
||||
self.logger.info('reloading plugins per request of {}'.format(nick))
|
||||
plugin.load_plugins(self.plugin_dir, use_prefix=self.use_prefix_for_plugins, cmd_prefix=self.cmd_prefix)
|
||||
output = self.output_message('Plugins reloaded')
|
||||
output = plugin.message('Plugins reloaded')
|
||||
elif cmd == 'enable' and op:
|
||||
if arg in plugin.plugins:
|
||||
if plugin.plugins[arg].enabled:
|
||||
output = self.output_message("{}: '{}' already enabled".format(nick, arg))
|
||||
output = plugin.message("{}: '{}' already enabled".format(nick, arg))
|
||||
else:
|
||||
plugin.plugins[arg].enable()
|
||||
output = self.output_message("{}: '{}' enabled!".format(nick, arg))
|
||||
output = plugin.message("{}: '{}' enabled!".format(nick, arg))
|
||||
else:
|
||||
output = self.output_message("{}: '{}' not found".format(nick, arg))
|
||||
output = plugin.message("{}: '{}' not found".format(nick, arg))
|
||||
elif cmd == 'disable' and op:
|
||||
if arg in plugin.plugins:
|
||||
if not plugin.plugins[arg].enabled:
|
||||
output = self.output_message("{}: '{}' already disabled".format(nick, arg))
|
||||
output = plugin.message("{}: '{}' already disabled".format(nick, arg))
|
||||
else:
|
||||
plugin.plugins[arg].disable()
|
||||
output = self.output_message("{}: '{}' disabled!".format(nick, arg))
|
||||
output = plugin.message("{}: '{}' disabled!".format(nick, arg))
|
||||
elif cmd == 'op' and op:
|
||||
for o in arg.split(' '):
|
||||
self.ops.append(o)
|
||||
output = self.output_message('{}: {} added as op'.format(nick, arg))
|
||||
output = plugin.message('{}: {} added as op'.format(nick, arg))
|
||||
elif cmd == 'deop' and op:
|
||||
for o in arg.split(' '):
|
||||
self.ops = [i for i in self.ops if i != o]
|
||||
output = self.output_message('{}: {} removed as op'.format(nick, arg))
|
||||
output = plugin.message('{}: {} removed as op'.format(nick, arg))
|
||||
elif cmd == 'ops' and op:
|
||||
output = self.output_message('current ops: {}'.format(', '.join(self.ops)))
|
||||
output = plugin.message('current ops: {}'.format(', '.join(self.ops)))
|
||||
elif cmd == 'ban' and op:
|
||||
for o in arg.split(' '):
|
||||
self.banned_users.append(o)
|
||||
output = self.output_message('{}: banned {}'.format(nick, arg))
|
||||
output = plugin.message('{}: banned {}'.format(nick, arg))
|
||||
elif cmd == 'unban' and op:
|
||||
for o in arg.split(' '):
|
||||
self.banned_users = [i for i in self.banned_users if i != o]
|
||||
output = self.output_message('{}: removed ban for {}'.format(nick, arg))
|
||||
output = plugin.message('{}: removed ban for {}'.format(nick, arg))
|
||||
elif cmd == 'banlist':
|
||||
output = self.output_message('currently banned: {}'.format(', '.join(self.banned_users)))
|
||||
output = plugin.message('currently banned: {}'.format(', '.join(self.banned_users)))
|
||||
return output
|
||||
|
||||
def call_plugins(self, privmsg, action, notice, chan, cmd, text, nick_list, nick, arg, msg_type):
|
||||
|
@ -199,7 +198,7 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
try:
|
||||
if plugin.cmds[cmd].ops and nick not in self.ops:
|
||||
if plugin.cmds[cmd].ops_msg:
|
||||
output = self.output_message(plugin.cmds[cmd].ops_msg)
|
||||
output = plugin.message(plugin.cmds[cmd].ops_msg)
|
||||
elif plugin.cmds[cmd].enabled:
|
||||
self.logger.debug('executing {}'.format(cmd))
|
||||
output = plugin.cmds[cmd].run(self.Message(
|
||||
|
@ -248,7 +247,12 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
|
||||
def process_event(self, c, e):
|
||||
nick = e.source.nick
|
||||
if nick == self.bot_nick:
|
||||
pass
|
||||
if e.arguments:
|
||||
text = e.arguments[0]
|
||||
else:
|
||||
text = ''
|
||||
if e.type == 'privmsg' or e.type == 'pubmsg':
|
||||
msg_type = 'message'
|
||||
else:
|
||||
|
@ -313,18 +317,24 @@ class Bot(irc.bot.SingleServerIRCBot):
|
|||
|
||||
|
||||
class TwitchBot(Bot):
|
||||
def __init__(self, nickname, channel, token, plugin_dir='plugins', log_level='info', ops=[]):
|
||||
def __init__(self, nickname, channel, token, **kwargs):
|
||||
self.port = kwargs.get('port', 6667)
|
||||
self.ops = kwargs.get('ops', [])
|
||||
self.plugin_dir = kwargs.get('plugin_dir', 'plugins')
|
||||
self.log_level = kwargs.get('log_level', 'info')
|
||||
self.log_file = kwargs.get('log_file', None)
|
||||
self.server_pass = kwargs.get('server_pass', None)
|
||||
self.cmd_prefix = kwargs.get('cmd_prefix', '!')
|
||||
self.use_prefix_for_plugins = kwargs.get('use_prefix_for_plugins', False)
|
||||
self.disable_help = kwargs.get('disable_help', False)
|
||||
self.banned_users = kwargs.get('banned_users', [])
|
||||
self.bot_nick = nickname
|
||||
self.log_level = log_level
|
||||
self.start_logging()
|
||||
self.channel = channel
|
||||
self.plugin_dir = plugin_dir
|
||||
self.ops = ops
|
||||
server = 'irc.twitch.tv'
|
||||
port = 6667
|
||||
self.logger.info('Joining Twitch Server')
|
||||
irc.bot.SingleServerIRCBot.__init__(self, [(server, port, 'oauth:'+token)], nickname, nickname)
|
||||
plugin.load_plugins(self.plugin_dir)
|
||||
irc.bot.SingleServerIRCBot.__init__(self, [('irc.twitch.tv', 6667, 'oauth:'+token)], nickname, nickname)
|
||||
self.internal_commands = {self.cmd_prefix + k: v for k,v in self.internal_commands.items()}
|
||||
plugin.load_plugins(self.plugin_dir, use_prefix=self.use_prefix_for_plugins, cmd_prefix=self.cmd_prefix)
|
||||
|
||||
def on_welcome(self, c, e):
|
||||
self.logger.info('requesting permissions')
|
||||
|
@ -333,4 +343,3 @@ class TwitchBot(Bot):
|
|||
c.cap('REQ', ':twitch.tv/commands')
|
||||
self.logger.info('Joining channel ' + self.channel)
|
||||
c.join(self.channel)
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ def read_conf(config, conf_format):
|
|||
elif config.name.endswith(('.toml', '.tml')):
|
||||
conf_format = 'toml'
|
||||
else:
|
||||
click.echo('Could not detect file format, please supply using --format option', err=True)
|
||||
raise click.ClickException('Could not detect file format, please supply using --format option')
|
||||
if conf_format == 'json':
|
||||
import json
|
||||
to_json = json.loads(config.read())
|
||||
|
@ -36,7 +36,7 @@ def read_conf(config, conf_format):
|
|||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
click.echo('yaml not installed, please use `pip3 install pinhook[yaml]` to install', err=True)
|
||||
raise click.ClickException('yaml not installed, please use `pip3 install pinhook[yaml]` to install')
|
||||
else:
|
||||
to_yaml = yaml.load(config.read(), Loader=yaml.FullLoader)
|
||||
output = schema.load(to_yaml)
|
||||
|
@ -44,7 +44,7 @@ def read_conf(config, conf_format):
|
|||
try:
|
||||
import toml
|
||||
except ImportError:
|
||||
click.echo('toml not installed, please use `pip3 install pinhook[toml]` to install', err=True)
|
||||
raise click.ClicKException('toml not installed, please use `pip3 install pinhook[toml]` to install')
|
||||
else:
|
||||
to_toml = toml.load(config.name)
|
||||
output = schema.load(to_toml)
|
||||
|
|
Loading…
Reference in New Issue