Mode mode (and mode arg) parsing to IRCChannel.py, add IRCChannel.mode_str
This commit is contained in:
parent
675c510223
commit
795f6afbeb
3 changed files with 47 additions and 19 deletions
|
@ -121,9 +121,8 @@ def handle_324(event):
|
||||||
if event["args"][1] in event["server"].channels:
|
if event["args"][1] in event["server"].channels:
|
||||||
channel = event["server"].channels.get(event["args"][1])
|
channel = event["server"].channels.get(event["args"][1])
|
||||||
modes = event["args"][2]
|
modes = event["args"][2]
|
||||||
for mode in modes[1:]:
|
args = event["args"][3:]
|
||||||
if mode in event["server"].channel_modes:
|
channel.parse_modes(modes, args[:])
|
||||||
channel.add_mode(mode)
|
|
||||||
|
|
||||||
def handle_329(event):
|
def handle_329(event):
|
||||||
channel = event["server"].channels.get(event["args"][1])
|
channel = event["server"].channels.get(event["args"][1])
|
||||||
|
|
|
@ -80,22 +80,12 @@ def mode(events, event):
|
||||||
is_channel = target[0] in event["server"].channel_types
|
is_channel = target[0] in event["server"].channel_types
|
||||||
if is_channel:
|
if is_channel:
|
||||||
channel = event["server"].channels.get(target)
|
channel = event["server"].channels.get(target)
|
||||||
|
modes = event["args"][1]
|
||||||
args = event["args"][2:]
|
args = event["args"][2:]
|
||||||
_args = args[:]
|
|
||||||
modes = RE_MODES.findall(event["args"][1])
|
channel.parse_modes(modes, args[:])
|
||||||
for chunk in modes:
|
|
||||||
remove = chunk[0] == "-"
|
events.on("received.mode.channel").call(modes=modes, mode_args=args,
|
||||||
for mode in chunk[1:]:
|
|
||||||
if mode in event["server"].channel_modes:
|
|
||||||
channel.change_mode(remove, mode)
|
|
||||||
elif mode in event["server"].prefix_modes and len(args):
|
|
||||||
channel.change_mode(remove, mode, args.pop(0))
|
|
||||||
elif (mode in event["server"].channel_list_modes or
|
|
||||||
mode in event["server"].channel_paramatered_modes):
|
|
||||||
args.pop(0)
|
|
||||||
elif not remove:
|
|
||||||
args.pop(0)
|
|
||||||
events.on("received.mode.channel").call(modes=modes, mode_args=_args,
|
|
||||||
channel=channel, server=event["server"], user=user)
|
channel=channel, server=event["server"], user=user)
|
||||||
elif event["server"].is_own_nickname(target):
|
elif event["server"].is_own_nickname(target):
|
||||||
modes = event["args"][1]
|
modes = event["args"][1]
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import typing, uuid
|
import re, typing, uuid
|
||||||
from src import EventManager, IRCBot, IRCBuffer, IRCObject, IRCServer, IRCUser
|
from src import EventManager, IRCBot, IRCBuffer, IRCObject, IRCServer, IRCUser
|
||||||
from src import utils
|
from src import utils
|
||||||
|
|
||||||
|
RE_MODES = re.compile(r"[-+]\w+")
|
||||||
|
|
||||||
class Channel(IRCObject.Object):
|
class Channel(IRCObject.Object):
|
||||||
name = ""
|
name = ""
|
||||||
def __init__(self, name: str, id, server: "IRCServer.Server",
|
def __init__(self, name: str, id, server: "IRCServer.Server",
|
||||||
|
@ -50,6 +52,26 @@ class Channel(IRCObject.Object):
|
||||||
def has_user(self, user: IRCUser.User) -> bool:
|
def has_user(self, user: IRCUser.User) -> bool:
|
||||||
return user in self.users
|
return user in self.users
|
||||||
|
|
||||||
|
def mode_str(self) -> str:
|
||||||
|
modes = [] # type: typing.List[typing.Tuple[str, typing.List[str]]]
|
||||||
|
# sorta alphanumerically by mode char
|
||||||
|
modes_iter = sorted(self.modes.items(), key=lambda mode: mode[0])
|
||||||
|
|
||||||
|
for mode, args in modes_iter:
|
||||||
|
# not list mode (e.g. +b) and not prefix mode (e.g. +o)
|
||||||
|
if (not mode in self.server.channel_list_modes and
|
||||||
|
not mode in self.server.prefix_modes):
|
||||||
|
args_list = typing.cast(typing.List[str], list(args))
|
||||||
|
modes.append((mode, args_list))
|
||||||
|
|
||||||
|
# move modes with args to the front
|
||||||
|
modes.sort(key=lambda mode: not bool(mode[1]))
|
||||||
|
|
||||||
|
out_modes = "".join(mode for mode, args in modes)
|
||||||
|
out_args = " ".join(args[0] for mode, args in modes if args)
|
||||||
|
|
||||||
|
return "+%s%s" % (out_modes, " %s" % out_args if out_args else "")
|
||||||
|
|
||||||
def add_mode(self, mode: str, arg: str=None):
|
def add_mode(self, mode: str, arg: str=None):
|
||||||
if not mode in self.modes:
|
if not mode in self.modes:
|
||||||
self.modes[mode] = set([])
|
self.modes[mode] = set([])
|
||||||
|
@ -87,6 +109,23 @@ class Channel(IRCObject.Object):
|
||||||
else:
|
else:
|
||||||
self.add_mode(mode, arg)
|
self.add_mode(mode, arg)
|
||||||
|
|
||||||
|
def parse_modes(self, modes: str, args: typing.List[str]):
|
||||||
|
for chunk in RE_MODES.findall(modes):
|
||||||
|
remove = chunk[0] == "-"
|
||||||
|
for mode in chunk[1:]:
|
||||||
|
if mode in self.server.channel_list_modes:
|
||||||
|
args.pop(0)
|
||||||
|
elif (mode in self.server.channel_paramatered_modes or
|
||||||
|
mode in self.server.prefix_modes):
|
||||||
|
self.change_mode(remove, mode, args.pop(0))
|
||||||
|
elif mode in self.server.channel_setting_modes:
|
||||||
|
if remove:
|
||||||
|
self.change_mode(remove, mode)
|
||||||
|
else:
|
||||||
|
self.change_mode(remove, mode, args.pop(0))
|
||||||
|
elif mode in self.server.channel_modes:
|
||||||
|
self.change_mode(remove, mode)
|
||||||
|
|
||||||
def set_setting(self, setting: str, value: typing.Any):
|
def set_setting(self, setting: str, value: typing.Any):
|
||||||
self.bot.database.channel_settings.set(self.id, setting, value)
|
self.bot.database.channel_settings.set(self.id, setting, value)
|
||||||
def get_setting(self, setting: str, default: typing.Any=None
|
def get_setting(self, setting: str, default: typing.Any=None
|
||||||
|
|
Loading…
Reference in a new issue