Add metadata interchange to pubsub mode

This commit is contained in:
dave 2018-01-16 17:18:15 -08:00
parent facfcbe3bc
commit 98433abe76
4 changed files with 90 additions and 21 deletions

View File

@ -14,17 +14,13 @@ from pyircbot.common import TouchReload
from json import dumps
# IRCEvent = namedtuple("IRCEvent", "command args prefix trailing")
# UserPrefix = namedtuple("UserPrefix", "nick username hostname")
# ServerPrefix = namedtuple("ServerPrefix", "hostname")
class PyIRCBotSub(PrimitiveBot):
def __init__(self, name, host, port, config):
super().__init__(config)
self.name = name
self.host = host
self.port = port
self.meta = {}
self.client = None # PubSub socket
def run(self):
@ -37,6 +33,8 @@ class PyIRCBotSub(PrimitiveBot):
self.client.sub("pyircbot_part")
self.client.sub("pyircbot_mode")
self.client.sub("pyircbot_quit")
self.client.sub("pyircbot_meta_update")
self.client.pub("pyircbot_meta_req", "x")
while True:
try:
channel, body = self.client.recv()
@ -49,11 +47,17 @@ class PyIRCBotSub(PrimitiveBot):
if name != self.name:
return
command = channel.split("_", 1)[1].upper()
command = channel.split("_", 1)[1]
if command == "meta_update":
self.meta.update(loads(rest))
print(self.meta)
return
args, sender, trailing, extras = loads(rest)
nick, username, hostname = extras["prefix"]
msg = IRCEvent(command,
msg = IRCEvent(command.upper(),
args,
UserPrefix(nick,
username,
@ -89,7 +93,6 @@ class PyIRCBotSub(PrimitiveBot):
os.mkdir(module_dir)
return module_dir
" IRC methods "
def act_PRIVMSG(self, towho, message):
"""Use the `/msg` command
@ -100,6 +103,14 @@ class PyIRCBotSub(PrimitiveBot):
# self.sendRaw("PRIVMSG %s :%s" % (towho, message))
self.client.pub("pyircbot_send", "{} {} {}".format(self.name, "privmsg", dumps([towho, message])))
def getBestModuleForService(self, service):
if service == "services":
return self
return super().getBestModuleForService(service)
def nick(self):
return self.meta.get("nick", None)
if __name__ == "__main__":
logging.basicConfig(level=logging.WARNING,

View File

@ -134,7 +134,7 @@ def load(filepath):
raise Exception("Unknown config format")
def parse_irc_line(data, client=True):
def parse_irc_line(data):
"""
Process one line of text irc sent us.

View File

@ -22,6 +22,7 @@ class PubSubClient(ModuleBase):
ModuleBase.__init__(self, bot, moduleName)
self.host, self.port = self.config.get("servers")[0].split(":")
self.bus = None
self.services = (self.bot.getmodulesbyservice("services") or [None]).pop(0)
self.bus_listener_thread = Thread(target=self.bus_listener)
self.bus_listener_thread.daemon = True
self.bus_listener_thread.start()
@ -40,16 +41,21 @@ class PubSubClient(ModuleBase):
except Again:
sleep(0.01)
continue
try:
print(channel, "--", message)
name, subcommand, message = message.split(" ", 2)
if name != self.config.get("name", "default") and name != "default":
continue
if subcommand == "privmsg":
dest, message = loads(message)
self.bot.act_PRIVMSG(dest, message)
except:
print_exc()
if channel == self.config.get("publish", "pyircbot_{}").format("meta_req"):
if self.services:
self.bus.pub(self.config.get("publish", "pyircbot_{}").format("meta_update"),
"{} {}".format(self.config.get("name", "default"),
dumps({"nick": self.services.nick()})))
else:
try:
name, subcommand, message = message.split(" ", 2)
if name != self.config.get("name", "default") and name != "default":
continue
if subcommand == "privmsg":
dest, message = loads(message)
self.bot.act_PRIVMSG(dest, message)
except:
print_exc()
def publish(self, subchannel, message):
"""
@ -59,9 +65,10 @@ class PubSubClient(ModuleBase):
:param message: message body
:type message: str
"""
self.bus.pub(self.config.get("publish").format(subchannel), "{} {}".format("default", message))
self.bus.pub(self.config.get("publish", "pyircbot_{}").format(subchannel),
"{} {}".format(self.config.get("name", "default"), message))
@hook("PRIVMSG", "JOIN", "PART", "KICK", "MODE", "QUIT", "NICK", "PING")
@hook("PRIVMSG", "JOIN", "PART", "KICK", "MODE", "QUIT", "NICK")
def busdriver(self, msg, cmd):
"""
Relay a privmsg to the event bus
@ -92,6 +99,7 @@ class PubSubClient(ModuleBase):
Connect to the message bus when the module is enabled
"""
self.bus = MsgbusSubClient(self.host, int(self.port))
self.bus.sub(self.config.get("publish", "pyircbot_{}").format("meta_req"))
for channel in self.config.get("subscriptions"):
self.bus.sub(channel)
self.publish("sys", "online")

50
tools/pubsubasciisend.py Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
from contextlib import closing
from msgbus.client import MsgbusSubClient
import argparse
from time import sleep
from json import dumps
def main():
parser = argparse.ArgumentParser(description="send irc art")
parser.add_argument("-i", "--host", default="127.0.0.1", help="host to connect to")
parser.add_argument("-p", "--port", default=7003, help="port to connect to")
parser.add_argument("-c", "--channel", required=True, help="irc channel")
parser.add_argument("-f", "--file", required=True, help="file containing irc lines to send")
parser.add_argument("--delay", type=float, default=1.0, help="delay between lines (s)")
parser.add_argument("--names", default=["default"], nargs="+", help="bot pubsub names to send via")
parser.add_argument("--name-burst", default=1, type=int, help="num lines to send before choosing next name")
parser.add_argument("--name-burst-delay", default=0.0, type=float, help="delay between single name bursts")
parser.add_argument("--name-change-delay", type=float, default=0.0)
args = parser.parse_args()
with open(args.file) as f:
with closing(MsgbusSubClient(args.host, args.port)) as client:
name = 0
per_name = 0
for line in f:
line = line.rstrip()
print(line)
client.pub("pyircbot_send", "{} privmsg {}".format(args.names[name], dumps([args.channel, line])))
per_name += 1
# if the current name has reached its quota
if per_name >= args.name_burst:
# Do the main sleep
sleep(args.delay)
per_name = 0
# Advance to the next name
name += 1
if name >= len(args.names):
name = 0
if args.name_change_delay:
sleep(args.name_change_delay)
else:
# Same name, do the burst delay
if args.name_burst_delay:
sleep(args.name_burst_delay)
if __name__ == '__main__':
main()