Improve handling of fake contexts

This commit is contained in:
Vgr E. Barry 2016-11-06 17:27:09 -05:00
parent 61bca595c5
commit a39ded6053
3 changed files with 37 additions and 12 deletions

View File

@ -3,7 +3,6 @@ import time
from enum import Enum from enum import Enum
from src.context import IRCContext, Features from src.context import IRCContext, Features
from src.logger import debuglog
from src import users from src import users
Main = None # main channel Main = None # main channel
@ -248,9 +247,6 @@ class FakeChannel(Channel):
def part(self, message=""): def part(self, message=""):
self.state = _States.Left 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): def mode(self, *changes):
if not changes: if not changes:
return return

View File

@ -1,3 +1,7 @@
from operator import attrgetter
from src.logger import debuglog
Features = {"CASEMAPPING": "rfc1459", "CHARSET": "utf-8", "STATUSMSG": {"@", "+"}, "CHANTYPES": {"#"}} Features = {"CASEMAPPING": "rfc1459", "CHARSET": "utf-8", "STATUSMSG": {"@", "+"}, "CHANTYPES": {"#"}}
def lower(nick): def lower(nick):
@ -20,13 +24,21 @@ def lower(nick):
return nick.lower().translate(str.maketrans(mapping)) 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: class IRCContext:
"""Base class for channels and users.""" """Base class for channels and users."""
is_channel = False
is_user = False
is_fake = False
def __init__(self, name, client, *, ref=None): def __init__(self, name, client, *, ref=None):
self.name = name self.name = name
self.client = client self.client = client
@ -40,6 +52,22 @@ class IRCContext:
return "NOTICE" return "NOTICE"
return "PRIVMSG" 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 @staticmethod
def _who(cli, target, data=b""): def _who(cli, target, data=b""):
"""Handle WHO requests.""" """Handle WHO requests."""
@ -102,6 +130,11 @@ class IRCContext:
client.send("{0} {1} :{2}".format(send_type, name, extra)) client.send("{0} {1} :{2}".format(send_type, name, extra))
def send(self, data, *, notice=False, privmsg=False, prefix=None): 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) send_type = self.get_send_type(is_notice=notice, is_privmsg=privmsg)
name = self.name name = self.name
if prefix is not None: if prefix is not None:

View File

@ -4,7 +4,6 @@ import fnmatch
import re import re
from src.context import IRCContext, Features, lower from src.context import IRCContext, Features, lower
from src.logger import debuglog
from src import settings as var from src import settings as var
from src import db from src import db
@ -433,9 +432,6 @@ class FakeUser(User):
def queue_message(self, message): def queue_message(self, message):
self.send(message) # don't actually queue it 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 @property
def rawnick(self): def rawnick(self):
return self.nick # we don't have a raw nick return self.nick # we don't have a raw nick