From a39ded6053f9c279e512cc6c829101db51e91290 Mon Sep 17 00:00:00 2001 From: "Vgr E. Barry" Date: Sun, 6 Nov 2016 17:27:09 -0500 Subject: [PATCH] Improve handling of fake contexts --- src/channels.py | 4 ---- src/context.py | 41 +++++++++++++++++++++++++++++++++++++---- src/users.py | 4 ---- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/channels.py b/src/channels.py index dda4bbd..076bc00 100644 --- a/src/channels.py +++ b/src/channels.py @@ -3,7 +3,6 @@ import time from enum import Enum from src.context import IRCContext, Features -from src.logger import debuglog from src import users Main = None # main channel @@ -248,9 +247,6 @@ class FakeChannel(Channel): def part(self, message=""): self.state = _States.Left - def send(self, data, **kw): - debuglog("Would message fake channel {0}: {1!r}".format(self.name, data)) - def mode(self, *changes): if not changes: return diff --git a/src/context.py b/src/context.py index d7a8315..75430e4 100644 --- a/src/context.py +++ b/src/context.py @@ -1,3 +1,7 @@ +from operator import attrgetter + +from src.logger import debuglog + Features = {"CASEMAPPING": "rfc1459", "CHARSET": "utf-8", "STATUSMSG": {"@", "+"}, "CHANTYPES": {"#"}} def lower(nick): @@ -20,13 +24,21 @@ def lower(nick): return nick.lower().translate(str.maketrans(mapping)) +def context_types(*types): + def wrapper(cls): + cls._getters = l = [] + cls.is_fake = False + for context_type in types: + name = "is_" + context_type + setattr(cls, name, False) + l.append((context_type, attrgetter(name))) + return cls + return wrapper + +@context_types("channel", "user") class IRCContext: """Base class for channels and users.""" - is_channel = False - is_user = False - is_fake = False - def __init__(self, name, client, *, ref=None): self.name = name self.client = client @@ -40,6 +52,22 @@ class IRCContext: return "NOTICE" return "PRIVMSG" + @classmethod + def get_context_type(cls, *, max_types=1): + context_type = [] + if cls.is_fake: + context_type.append("fake") + for name, getter in cls._getters: + if getter(cls): + context_type.append(name) + + final = " ".join(context_type) + + if len(context_type) > (cls.is_fake + max_types): + raise RuntimeError("Invalid context type for {0}: {1!r}".format(cls.__name__, final)) + + return final + @staticmethod def _who(cli, target, data=b""): """Handle WHO requests.""" @@ -102,6 +130,11 @@ class IRCContext: client.send("{0} {1} :{2}".format(send_type, name, extra)) def send(self, data, *, notice=False, privmsg=False, prefix=None): + if self.is_fake: + # Leave out 'fake' from the message; get_context_type() takes care of that + debuglog("Would message {0} {1}: {2!r}".format(self.get_context_type(), self.name, data)) + return + send_type = self.get_send_type(is_notice=notice, is_privmsg=privmsg) name = self.name if prefix is not None: diff --git a/src/users.py b/src/users.py index ed58b9f..60d07ec 100644 --- a/src/users.py +++ b/src/users.py @@ -4,7 +4,6 @@ import fnmatch import re from src.context import IRCContext, Features, lower -from src.logger import debuglog from src import settings as var from src import db @@ -433,9 +432,6 @@ class FakeUser(User): def queue_message(self, message): self.send(message) # don't actually queue it - def send(self, data, **kw): - debuglog("Would message fake user {0}: {1!r}".format(self.nick, data)) - @property def rawnick(self): return self.nick # we don't have a raw nick