Browse Source

Add !partwhen command

main
Ben Kurtovic 3 years ago
parent
commit
a4fe1f9722
2 changed files with 132 additions and 0 deletions
  1. +131
    -0
      commands/partwhen.py
  2. +1
    -0
      commands/rc_monitor.py

+ 131
- 0
commands/partwhen.py View File

@@ -0,0 +1,131 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2021 Ben Kurtovic <ben.kurtovic@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import base64
import cPickle as pickle
import re

from earwigbot.commands import Command
from earwigbot.config.permissions import User

class PartWhen(Command):
"""Ask the bot to part the channel when a condition is met."""
name = "partwhen"
commands = ["partwhen", "unpartwhen"]
hooks = ["join", "msg"]

def setup(self):
self._conds = self._load_conditions()

def check(self, data):
if data.is_command and data.command in self.commands:
return True
try:
if data.line[1] == "JOIN":
if data.chan in self._conds and "join" in self._conds[data.chan]:
return True
except IndexError:
pass
return False

def process(self, data):
if data.line[1] == "JOIN":
self._handle_join(data)
return

if not self.config.irc["permissions"].is_admin(data):
self.reply(data, "You must be a bot admin to use this command.")
return

channel = data.chan
args = data.args
if args and args[0].startswith("#"):
# "!partwhen #channel <event> <args>..."
channel = args[0]
args = args[1:]

if data.command == "unpartwhen":
if self._conds.get(channel):
del self._conds[channel]
self._save_conditions()
self.reply(data, "Cleared part conditions for {0}.".format(
"this channel" if channel == data.chan else channel))
else:
self.reply(data, "No part conditions set.")
return

if not args:
conds = self._conds.get(channel, {})
existing = "; ".join("{0} {1}".format(cond, ", ".join(str(user) for user in users))
for cond, users in conds.iteritems())
if existing:
status = "Current part conditions: {0}.".format(existing)
else:
status = "No part conditions set for {0}.".format(
"this channel" if channel == data.chan else channel)
self.reply(data, "{0} Usage: !{1} [<channel>] <event> <args>...".format(
status, data.command))
return

event = args[0]
args = args[1:]
if event == "join":
if not args:
self.reply(data, "Join event requires an argument for the user joining, "
"in nick!ident@host syntax.")
return
cond = args[0]
match = re.match(r"(.*?)!(.*?)@(.*?)$", cond)
if not match:
self.reply(data, "User join pattern is invalid; should use "
"nick!ident@host syntax.")
return
conds = self._conds.setdefault(channel, {}).setdefault("join", [])
conds.append(User(match.group(1), match.group(2), match.group(3)))
self._save_conditions()
self.reply(data, "Okay, I will leave {0} when {1} joins.".format(
"the channel" if channel == data.chan else channel, cond))
else:
self.reply(data, "Unknown event: {0} (valid events: join).".format(event))

def _handle_join(self, data):
user = User(data.nick, data.ident, data.host)
conds = self._conds.get(data.chan, {}).get("join", {})
for cond in conds:
if user in cond:
self.logger.info("Parting {0} because {1} met join condition {2}".format(
data.chan, str(user), str(cond)))
self.part(data.chan, "Requested to leave when {0} joined".format(data.nick))
break

def _load_conditions(self):
permdb = self.config.irc["permissions"]
try:
raw = permdb.get_attr("command:partwhen", "data")
except KeyError:
return {}
return pickle.loads(base64.b64decode(raw))

def _save_conditions(self):
permdb = self.config.irc["permissions"]
raw = base64.b64encode(pickle.dumps(self._conds, pickle.HIGHEST_PROTOCOL))
permdb.set_attr("command:partwhen", "data", raw)

+ 1
- 0
commands/rc_monitor.py View File

@@ -49,6 +49,7 @@ class RCMonitor(Command):
log = ('Cannot use without a report channel set as '
'config.commands["{0}"]["channel"]')
self.logger.warn(log.format(self.name))
return

self._stats = {
"start": datetime.utcnow(),


Loading…
Cancel
Save