modules/logging.py -> IRCLogging.py; IRCLog.py -> IRCBuffer.py; change logging

to be an object on the server object instead of an event call
This commit is contained in:
jesopo 2018-08-28 12:23:57 +01:00
parent ea9b6f32dc
commit e5a5fa5c4b
18 changed files with 66 additions and 95 deletions

View file

@ -261,9 +261,8 @@ class Database(object):
def _execute_fetch(self, query, fetch_func, params=[]): def _execute_fetch(self, query, fetch_func, params=[]):
printable_query = " ".join(query.split()) printable_query = " ".join(query.split())
self.bot.events.on("log.debug").call( self.bot.log.debug("executing query: \"%s\" (params: %s)",
message="executing query: \"%s\" (params: %s)", [printable_query, params])
params=[printable_query, params])
start = time.monotonic() start = time.monotonic()
cursor = self.cursor() cursor = self.cursor()
@ -272,9 +271,8 @@ class Database(object):
end = time.monotonic() end = time.monotonic()
total_milliseconds = (end - start) * 1000 total_milliseconds = (end - start) * 1000
self.bot.events.on("log.debug").call( self.bot.log.debug("executed in %fms", [total_milliseconds])
message="executed in %fms",
params=[total_milliseconds])
return value return value
def execute_fetchall(self, query, params=[]): def execute_fetchall(self, query, params=[]):
return self._execute_fetch(query, return self._execute_fetch(query,

View file

@ -1,4 +1,4 @@
import traceback import time, traceback
PRIORITY_URGENT = 0 PRIORITY_URGENT = 0
PRIORITY_HIGH = 1 PRIORITY_HIGH = 1
@ -42,9 +42,10 @@ class MultipleEventHook(object):
event_hook.call(max, **kwargs) event_hook.call(max, **kwargs)
class EventHook(object): class EventHook(object):
def __init__(self, bot, name=None): def __init__(self, bot, name=None, parent=None):
self.bot = bot self.bot = bot
self.name = name self.name = name
self.parent = parent
self._children = {} self._children = {}
self._hooks = [] self._hooks = []
self._hook_notify = None self._hook_notify = None
@ -52,6 +53,14 @@ class EventHook(object):
self._call_notify = None self._call_notify = None
self._stored_events = [] self._stored_events = []
def _get_path(self):
path = [self.name]
parent = self.parent
while not parent == None and not parent.name == None:
path.append(parent.name)
parent = parent.parent
return ".".join(path[::-1])
def hook(self, function, priority=PRIORITY_LOW, replay=False, **kwargs): def hook(self, function, priority=PRIORITY_LOW, replay=False, **kwargs):
callback = EventCallback(function, self.bot, priority, **kwargs) callback = EventCallback(function, self.bot, priority, **kwargs)
if self._hook_notify: if self._hook_notify:
@ -87,6 +96,10 @@ class EventHook(object):
results = self.call(max=max, **kwargs) results = self.call(max=max, **kwargs)
return default if not len(results) else results[0] return default if not len(results) else results[0]
def call(self, max=None, **kwargs): def call(self, max=None, **kwargs):
self.bot.log.debug("calling event: \"%s\" (params: %s)",
[self._get_path(), kwargs])
start = time.monotonic()
event = Event(self.bot, self.name, **kwargs) event = Event(self.bot, self.name, **kwargs)
if self._call_notify: if self._call_notify:
self._call_notify(self, event) self._call_notify(self, event)
@ -109,13 +122,18 @@ class EventHook(object):
# message="Failed to call event callback", # message="Failed to call event callback",
# data=traceback.format_exc()) # data=traceback.format_exc())
called += 1 called += 1
end = time.monotonic()
total_milliseconds = (end - start) * 1000
self.bot.log.debug("event called in %fms", [total_milliseconds])
return returns return returns
def get_child(self, child_name): def get_child(self, child_name):
child_name_lower = child_name.lower() child_name_lower = child_name.lower()
if not child_name_lower in self._children: if not child_name_lower in self._children:
self._children[child_name_lower] = EventHook(self.bot, self._children[child_name_lower] = EventHook(self.bot,
child_name) child_name, self)
if self._child_notify: if self._child_notify:
self._child_notify(self, self._children[ self._child_notify(self, self._children[
child_name_lower]) child_name_lower])

View file

@ -1,5 +1,5 @@
import os, select, sys, threading, time, traceback import os, select, sys, threading, time, traceback
import EventManager, IRCServer, ModuleManager, Timer import EventManager, IRCLogging, IRCServer, ModuleManager, Timer
class Bot(object): class Bot(object):
def __init__(self): def __init__(self):
@ -13,6 +13,7 @@ class Bot(object):
self.poll = select.epoll() self.poll = select.epoll()
self.modules = ModuleManager.ModuleManager(self) self.modules = ModuleManager.ModuleManager(self)
self.events = EventManager.EventHook(self) self.events = EventManager.EventHook(self)
self.log = IRCLogging.Log(self)
self.timers = [] self.timers = []
self.events.on("timer").on("reconnect").hook(self.reconnect) self.events.on("timer").on("reconnect").hook(self.reconnect)
self.events.on("boot").on("done").hook(self.setup_timers) self.events.on("boot").on("done").hook(self.setup_timers)

View file

@ -1,5 +1,5 @@
import uuid import uuid
import IRCLog import IRCBuffer
class Channel(object): class Channel(object):
def __init__(self, name, id, server, bot): def __init__(self, name, id, server, bot):
@ -15,7 +15,10 @@ class Channel(object):
self.users = set([]) self.users = set([])
self.modes = {} self.modes = {}
self.created_timestamp = None self.created_timestamp = None
self.log = IRCLog.Log(bot) self.buffer = IRCBuffer.Buffer(bot)
def __repr__(self):
return "IRCChannel.Channel(%s|%s)" % (self.server.name, self.name)
def set_topic(self, topic): def set_topic(self, topic):
self.topic = topic self.topic = topic

View file

@ -302,12 +302,12 @@ def handle_PRIVMSG(data):
bot.events.on("received").on("message").on("channel").call( bot.events.on("received").on("message").on("channel").call(
user=user, message=message, message_split=message_split, user=user, message=message, message_split=message_split,
channel=channel, action=action, server=data.server) channel=channel, action=action, server=data.server)
channel.log.add_line(user.nickname, message, action) channel.buffer.add_line(user.nickname, message, action)
elif server.is_own_nickname(target): elif server.is_own_nickname(target):
bot.events.on("received").on("message").on("private").call( bot.events.on("received").on("message").on("private").call(
user=user, message=message, message_split=message_split, user=user, message=message, message_split=message_split,
action=action, server=data.server) action=action, server=data.server)
user.log.add_line(user.nickname, message, action) user.buffer.add_line(user.nickname, message, action)
@handler(description="we've received a notice") @handler(description="we've received a notice")
def handle_NOTICE(data): def handle_NOTICE(data):

View file

@ -1,43 +0,0 @@
import re
class Line(object):
def __init__(self, sender, message, action, from_self):
self.sender = sender
self.message = message
self.action = action
self.from_self = from_self
class Log(object):
def __init__(self, bot):
self.lines = []
self.max_lines = 64
self._skip_next = False
def add_line(self, sender, message, action, from_self=False):
if not self._skip_next:
line = Line(sender, message, action, from_self)
self.lines.insert(0, line)
if len(self.lines) > self.max_lines:
self.lines.pop()
self._skip_next = False
def get(self, index=0, **kwargs):
from_self = kwargs.get("from_self", True)
for line in self.lines:
if line.from_self and not from_self:
continue
return line
def find(self, pattern, **kwargs):
from_self = kwargs.get("from_self", True)
for_user = kwargs.get("for_user", "")
for_user = for_user.lower() if for_user else None
not_pattern = kwargs.get("not_pattern", None)
for line in self.lines:
if line.from_self and not from_self:
continue
elif re.search(pattern, line.message):
if not_pattern and re.search(not_pattern, line.message):
continue
if for_user and not line.sender.lower() == for_user:
continue
return line
def skip_next(self):
self._skip_next = True

View file

@ -13,7 +13,7 @@ class BitBotFormatter(logging.Formatter):
s = "%s.%03d" % (t, record.msecs) s = "%s.%03d" % (t, record.msecs)
return s return s
class Module(object): class Log(object):
def __init__(self, bot): def __init__(self, bot):
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
self.logger.setLevel(logging.DEBUG) self.logger.setLevel(logging.DEBUG)
@ -33,23 +33,15 @@ class Module(object):
file_handler.setFormatter(formatter) file_handler.setFormatter(formatter)
self.logger.addHandler(file_handler) self.logger.addHandler(file_handler)
bot.events.on("log.debug").hook(self.debug) def debug(self, message, params):
bot.events.on("log.info").hook(self.info) self._log(message, params, logging.DEBUG)
bot.events.on("log.warn").hook(self.warn) def info(self, message, params):
bot.events.on("log.error").hook(self.error) self._log(message, params, logging.INFO)
bot.events.on("log.critical").hook(self.critical) def warn(self, message, params):
self._log(message, params, logging.WARN)
def debug(self, event): def error(self, message, params):
self._log(event, logging.DEBUG) self._log(message, params, logging.ERROR)
def info(self, event): def critical(self, message, params):
self._log(event, logging.INFO) self._log(message, params, logging.CRITICAL)
def warn(self, event): def _log(self, message, params, level):
self._log(event, logging.WARN)
def error(self, event):
self._log(event, logging.ERROR)
def critical(self, event):
self._log(event, logging.CRITICAL)
def _log(self, event, level):
message = event["message"]
params = event.get("params", [])
self.logger.log(level, message, *params) self.logger.log(level, message, *params)

View file

@ -267,13 +267,13 @@ class Server(object):
full_message_split = full_message.split() full_message_split = full_message.split()
if self.has_channel(target): if self.has_channel(target):
channel = self.get_channel(target) channel = self.get_channel(target)
channel.log.add_line(None, message, action, True) channel.buffer.add_line(None, message, action, True)
self.bot.events.on("self").on("message").on("channel").call( self.bot.events.on("self").on("message").on("channel").call(
message=full_message, message_split=full_message_split, message=full_message, message_split=full_message_split,
channel=channel, action=action, server=self) channel=channel, action=action, server=self)
else: else:
user = self.get_user(target) user = self.get_user(target)
user.log.add_line(None, message, action, True) user.buffer.add_line(None, message, action, True)
self.bot.events.on("self").on("message").on("private").call( self.bot.events.on("self").on("message").on("private").call(
message=full_message, message_split=full_message_split, message=full_message, message_split=full_message_split,
user=user, action=action, server=self) user=user, action=action, server=self)

View file

@ -1,5 +1,5 @@
import uuid import uuid
import IRCLog import IRCBuffer
class User(object): class User(object):
def __init__(self, nickname, id, server, bot): def __init__(self, nickname, id, server, bot):
@ -11,7 +11,11 @@ class User(object):
self.server = server self.server = server
self.bot = bot self.bot = bot
self.channels = set([]) self.channels = set([])
self.log = IRCLog.Log(bot) self.buffer = IRCBuffer.Buffer(bot)
def __repr__(self):
return "IRCUser.User(%s|%s)" % (self.server.name, self.name)
def set_nickname(self, nickname): def set_nickname(self, nickname):
self.nickname = nickname self.nickname = nickname
self.nickname_lower = nickname.lower() self.nickname_lower = nickname.lower()

View file

@ -102,7 +102,7 @@ class Module(object):
if is_channel and hook.kwargs.get("private_only"): if is_channel and hook.kwargs.get("private_only"):
return return
log = target.log buffer = target.buffer
module_name = hook.function.__self__._name module_name = hook.function.__self__._name
stdout, stderr = StdOut(module_name, target), StdErr(module_name, stdout, stderr = StdOut(module_name, target), StdErr(module_name,
@ -114,7 +114,7 @@ class Module(object):
for returned in returns: for returned in returns:
if returned: if returned:
stderr.write(returned).send() stderr.write(returned).send()
log.skip_next() buffer.skip_next()
return return
args_split = list(filter(None, event["message_split"][args_index:])) args_split = list(filter(None, event["message_split"][args_index:]))
min_args = hook.kwargs.get("min_args") min_args = hook.kwargs.get("min_args")
@ -130,7 +130,7 @@ class Module(object):
server = event["server"] server = event["server"]
user = event["user"] user = event["user"]
self.bot.events.on("received").on("command").on(command).call( self.bot.events.on("received").on("command").on(command).call(
1, user=user, server=server, target=target, log=log, 1, user=user, server=server, target=target, buffer=buffer,
args=args, args_split=args_split, stdout=stdout, stderr=stderr, args=args, args_split=args_split, stdout=stdout, stderr=stderr,
command=command.lower(), is_channel=is_channel) command=command.lower(), is_channel=is_channel)
if not hook.kwargs.get("skip_out", False): if not hook.kwargs.get("skip_out", False):
@ -138,7 +138,7 @@ class Module(object):
stderr.send() stderr.send()
target.last_stdout = stdout target.last_stdout = stdout
target.last_stderr = stderr target.last_stderr = stderr
log.skip_next() buffer.skip_next()
def channel_message(self, event): def channel_message(self, event):

View file

@ -15,7 +15,7 @@ class Module(object):
if event["args"]: if event["args"]:
word = event["args"] word = event["args"]
else: else:
word = event["log"].get(from_self=False) word = event["buffer"].get(from_self=False)
page = Utils.get_url(URL_WORDNIK % event["args"], get_params={ page = Utils.get_url(URL_WORDNIK % event["args"], get_params={
"useCanonical": "true", "limit": 1, "useCanonical": "true", "limit": 1,
"sourceDictionaries": "wiktionary", "api_key": self.bot.config[ "sourceDictionaries": "wiktionary", "api_key": self.bot.config[

View file

@ -13,7 +13,7 @@ class Module(object):
usage="[search term]") usage="[search term]")
def google(self, event): def google(self, event):
phrase = event["args"] or event["log"].get() phrase = event["args"] or event["buffer"].get()
if phrase: if phrase:
page = Utils.get_url(URL_GOOGLESEARCH, get_params={ page = Utils.get_url(URL_GOOGLESEARCH, get_params={
"q": phrase, "key": self.bot.config[ "q": phrase, "key": self.bot.config[

View file

@ -36,9 +36,7 @@ class Module(object):
target = str(event["server"]) target = str(event["server"])
if not channel == None: if not channel == None:
target += channel target += channel
self.bot.events.on("log.info").call( self.bot.log.info("%s | %s", [target, line])
message="%s | %s",
params=[target, line])
def _on_message(self, event, nickname): def _on_message(self, event, nickname):
if not self.bot.args.verbose: if not self.bot.args.verbose:

View file

@ -25,7 +25,7 @@ class Module(object):
else: else:
query = event["args"] query = event["args"]
else: else:
last_soundcloud = event["log"].find(REGEX_SOUNDCLOUD) last_soundcloud = event["buffer"].find(REGEX_SOUNDCLOUD)
if last_soundcloud: if last_soundcloud:
url = re.match(REGEX_SOUNDCLOUD, url = re.match(REGEX_SOUNDCLOUD,
last_soundcloud.message).string last_soundcloud.message).string

View file

@ -14,7 +14,7 @@ class Module(object):
if len(event["args"]) > 0: if len(event["args"]) > 0:
url = event["args_split"][0] url = event["args_split"][0]
else: else:
url = event["log"].find(REGEX_URL) url = event["buffer"].find(REGEX_URL)
if url: if url:
url = re.search(REGEX_URL, url.message).group(0) url = re.search(REGEX_URL, url.message).group(0)
if not url: if not url:

View file

@ -14,7 +14,7 @@ class Module(object):
def translate(self, event): def translate(self, event):
phrase = event["args"] phrase = event["args"]
if not phrase: if not phrase:
phrase = event["log"].get() phrase = event["buffer"].get()
if phrase: if phrase:
phrase = phrase.message phrase = phrase.message
if not phrase: if not phrase:

View file

@ -32,7 +32,7 @@ class Module(object):
if event["args"]: if event["args"]:
target = event["args"] target = event["args"]
else: else:
target = event["log"].find(REGEX_TWITTERURL) target = event["buffer"].find(REGEX_TWITTERURL)
if target: if target:
target = target.message target = target.message
if target: if target:

View file

@ -72,7 +72,7 @@ class Module(object):
if event["args"]: if event["args"]:
search = event["args"] search = event["args"]
else: else:
last_youtube = event["log"].find(REGEX_YOUTUBE) last_youtube = event["buffer"].find(REGEX_YOUTUBE)
if last_youtube: if last_youtube:
video_id = re.search(REGEX_YOUTUBE, last_youtube.message).group(1) video_id = re.search(REGEX_YOUTUBE, last_youtube.message).group(1)
if search or video_id: if search or video_id: