Compare commits

..

No commits in common. "master" and "v1.9.2" have entirely different histories.

9 changed files with 55 additions and 95 deletions

4
.github/FUNDING.yml vendored
View File

@ -1,4 +0,0 @@
github: archangelic
ko_fi: archangelic
liberapay: archangelic
custom: ["https://paypal.me/archangelic", "https://cash.app/$archangelic"]

View File

@ -1,30 +0,0 @@
# 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

View File

@ -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.command` 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.register` 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.command('!test')
@pinhook.plugin.register('!test')
def test_plugin(msg):
message = '{}: this is a test!'.format(msg.nick)
return pinhook.plugin.message(message)
@ -162,12 +162,15 @@ 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 set a command to be used only by ops
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.command('!test', ops=True, ops_msg='This command can only be run by an op')
@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!')
```

View File

@ -1 +1 @@
theme: jekyll-theme-minimal
theme: jekyll-theme-midnight

View File

@ -17,7 +17,7 @@ def build_output(rolls, modifier):
output = start
return output
@pinhook.plugin.command('!roll')
@pinhook.plugin.register('!roll')
def roll(msg):
matches = dicepattern.match(msg.arg)
if matches:

View File

@ -17,7 +17,7 @@ def build_output(rolls, modifier):
output = start
return output
@pinhook.plugin.command('!roll')
@pinhook.plugin.register('!roll')
def roll(msg):
matches = dicepattern.match(msg.arg)
if matches:

View File

@ -1 +1 @@
__version__ = '1.9.7'
__version__ = '1.9.2'

View File

@ -14,20 +14,6 @@ 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', [])
@ -50,6 +36,21 @@ 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)
@ -71,9 +72,9 @@ class Bot(irc.bot.SingleServerIRCBot):
if cmd:
self.cmd = cmd
self.arg = arg
if text != None:
if text:
self.text = text
if not (cmd==None or text==None):
if not (cmd or text):
raise TypeError('missing cmd or text parameter')
def start_logging(self):
@ -139,7 +140,7 @@ class Bot(irc.bot.SingleServerIRCBot):
try:
c.join(*arg.split())
self.logger.info('joining {} per request of {}'.format(arg, nick))
output = plugin.message('{}: joined {}'.format(nick, arg.split()[0]))
output = self.output_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:
@ -153,43 +154,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 = plugin.message('Plugins reloaded')
output = self.output_message('Plugins reloaded')
elif cmd == 'enable' and op:
if arg in plugin.plugins:
if plugin.plugins[arg].enabled:
output = plugin.message("{}: '{}' already enabled".format(nick, arg))
output = self.output_message("{}: '{}' already enabled".format(nick, arg))
else:
plugin.plugins[arg].enable()
output = plugin.message("{}: '{}' enabled!".format(nick, arg))
output = self.output_message("{}: '{}' enabled!".format(nick, arg))
else:
output = plugin.message("{}: '{}' not found".format(nick, arg))
output = self.output_message("{}: '{}' not found".format(nick, arg))
elif cmd == 'disable' and op:
if arg in plugin.plugins:
if not plugin.plugins[arg].enabled:
output = plugin.message("{}: '{}' already disabled".format(nick, arg))
output = self.output_message("{}: '{}' already disabled".format(nick, arg))
else:
plugin.plugins[arg].disable()
output = plugin.message("{}: '{}' disabled!".format(nick, arg))
output = self.output_message("{}: '{}' disabled!".format(nick, arg))
elif cmd == 'op' and op:
for o in arg.split(' '):
self.ops.append(o)
output = plugin.message('{}: {} added as op'.format(nick, arg))
output = self.output_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 = plugin.message('{}: {} removed as op'.format(nick, arg))
output = self.output_message('{}: {} removed as op'.format(nick, arg))
elif cmd == 'ops' and op:
output = plugin.message('current ops: {}'.format(', '.join(self.ops)))
output = self.output_message('current ops: {}'.format(', '.join(self.ops)))
elif cmd == 'ban' and op:
for o in arg.split(' '):
self.banned_users.append(o)
output = plugin.message('{}: banned {}'.format(nick, arg))
output = self.output_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 = plugin.message('{}: removed ban for {}'.format(nick, arg))
output = self.output_message('{}: removed ban for {}'.format(nick, arg))
elif cmd == 'banlist':
output = plugin.message('currently banned: {}'.format(', '.join(self.banned_users)))
output = self.output_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):
@ -198,7 +199,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 = plugin.message(plugin.cmds[cmd].ops_msg)
output = self.output_message(plugin.cmds[cmd].ops_msg)
elif plugin.cmds[cmd].enabled:
self.logger.debug('executing {}'.format(cmd))
output = plugin.cmds[cmd].run(self.Message(
@ -247,12 +248,7 @@ 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 = ''
text = e.arguments[0]
if e.type == 'privmsg' or e.type == 'pubmsg':
msg_type = 'message'
else:
@ -317,24 +313,18 @@ class Bot(irc.bot.SingleServerIRCBot):
class TwitchBot(Bot):
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', [])
def __init__(self, nickname, channel, token, plugin_dir='plugins', log_level='info', ops=[]):
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, [('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)
irc.bot.SingleServerIRCBot.__init__(self, [(server, port, 'oauth:'+token)], nickname, nickname)
plugin.load_plugins(self.plugin_dir)
def on_welcome(self, c, e):
self.logger.info('requesting permissions')
@ -343,3 +333,4 @@ class TwitchBot(Bot):
c.cap('REQ', ':twitch.tv/commands')
self.logger.info('Joining channel ' + self.channel)
c.join(self.channel)

View File

@ -27,7 +27,7 @@ def read_conf(config, conf_format):
elif config.name.endswith(('.toml', '.tml')):
conf_format = 'toml'
else:
raise click.ClickException('Could not detect file format, please supply using --format option')
click.echo('Could not detect file format, please supply using --format option', err=True)
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:
raise click.ClickException('yaml not installed, please use `pip3 install pinhook[yaml]` to install')
click.echo('yaml not installed, please use `pip3 install pinhook[yaml]` to install', err=True)
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:
raise click.ClicKException('toml not installed, please use `pip3 install pinhook[toml]` to install')
click.echo('toml not installed, please use `pip3 install pinhook[toml]` to install', err=True)
else:
to_toml = toml.load(config.name)
output = schema.load(to_toml)