From 6be2d92bac5c18a99f11ec4c55a0a9d5ff210c26 Mon Sep 17 00:00:00 2001 From: dave Date: Mon, 4 Dec 2017 23:53:44 -0800 Subject: [PATCH] Make line parser reuseable (and make it work for client & server lines) --- pyircbot/common.py | 40 +++++++++++++++++++++++++++++++++++++++ pyircbot/irccore.py | 46 ++++++++------------------------------------- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/pyircbot/common.py b/pyircbot/common.py index 254ce9b..96a2a66 100644 --- a/pyircbot/common.py +++ b/pyircbot/common.py @@ -132,3 +132,43 @@ def load(filepath): return json_load(f) else: raise Exception("Unknown config format") + + +def parse_irc_line(data, client=True): + """ + Process one line of text irc sent us. + + Return tuple of (command, args, prefix, trailing) + + :param data: the data to process + :type data: str + :return tuple:""" + if data.strip() == "": + return + + prefix = None + command = None + args = [] + trailing = None + + if data[0] == ":": + prefix = data.split(" ")[0][1:] + data = data[data.find(" ") + 1:] + command = data.split(" ")[0] + data = data[data.find(" ") + 1:] + if(data[0] == ":"): + # no args + trailing = data[1:].strip() + else: + # find trailing + pos = data.find(" :") + if pos == -1: + trailing = None + else: + trailing = data[pos + 2:].strip() + data = data[:data.find(" :")] + args = data.split(" ") + for index, arg in enumerate(args): + args[index] = arg.strip() + + return (command, args, prefix, trailing) diff --git a/pyircbot/irccore.py b/pyircbot/irccore.py index 8faadbf..2f4eb04 100644 --- a/pyircbot/irccore.py +++ b/pyircbot/irccore.py @@ -12,7 +12,7 @@ import logging import traceback import sys from inspect import getargspec -from pyircbot.common import burstbucket +from pyircbot.common import burstbucket, parse_irc_line from collections import namedtuple from io import StringIO @@ -81,12 +81,17 @@ class IRCCore(object): self.server = (self.server + 1) % len(self.servers) await asyncio.sleep(1, loop=loop) continue - while self.alive: try: data = await self.reader.readuntil() self.log.debug("<<< {}".format(repr(data))) - self.process_line(data.decode("UTF-8")) + command, args, prefix, trailing = parse_irc_line(data.decode("UTF-8")) + self.fire_hook("_RECV", args=args, prefix=prefix, trailing=trailing) + if command not in self.hookcalls: + self.log.warning("Unknown command: cmd='{}' prefix='{}' args='{}' trailing='{}'" + .format(command, prefix, args, trailing)) + else: + self.fire_hook(command, args=args, prefix=prefix, trailing=trailing) except (ConnectionResetError, asyncio.streams.IncompleteReadError): traceback.print_exc() break @@ -132,41 +137,6 @@ class IRCCore(object): self.writer.close() self.log.info("Kill complete") - def process_line(self, data): - """Process one line of text irc sent us - - :param data: the data to process - :type data: str""" - if data.strip() == "": - return - - prefix = None - command = None - args = [] - trailing = None - - if data[0] == ":": - prefix = data.split(" ")[0][1:] - data = data[data.find(" ") + 1:] - command = data.split(" ")[0] - data = data[data.find(" ") + 1:] - if(data[0] == ":"): - # no args - trailing = data[1:].strip() - else: - trailing = data[data.find(" :") + 2:].strip() - data = data[:data.find(" :")] - args = data.split(" ") - for index, arg in enumerate(args): - args[index] = arg.strip() - - self.fire_hook("_RECV", args=args, prefix=prefix, trailing=trailing) - if command not in self.hookcalls: - self.log.warning("Unknown command: cmd='%s' prefix='%s' args='%s' trailing='%s'" % (command, prefix, args, - trailing)) - else: - self.fire_hook(command, args=args, prefix=prefix, trailing=trailing) - def sendRaw(self, data): asyncio.run_coroutine_threadsafe(self.outputq.put((5, data, )), self._loop)