mirror of https://github.com/jesopo/ircstates
add MODE parsing
This commit is contained in:
parent
8d7da30d8e
commit
15030a8306
|
@ -10,8 +10,31 @@ class Channel(Named):
|
|||
self.topic_setter: Optional[str] = None
|
||||
self.topic_time: Optional[datetime] = None
|
||||
|
||||
self.list_modes: Dict[str, List[str]] = {}
|
||||
self.modes: Dict[str, str] = {}
|
||||
self.list_modes: Dict[str, List[str]] = {}
|
||||
self.modes: Dict[str, Optional[str]] = {}
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Channel(name={self.name!r})"
|
||||
|
||||
def add_mode(self,
|
||||
char: str,
|
||||
param: Optional[str],
|
||||
list_mode: bool):
|
||||
if list_mode:
|
||||
if not char in self.list_modes:
|
||||
self.list_modes[char] = []
|
||||
if not param in self.list_modes[char]:
|
||||
self.list_modes[char].append(param or "")
|
||||
else:
|
||||
self.modes[char] = param
|
||||
|
||||
def remove_mode(self,
|
||||
char: str,
|
||||
param: Optional[str]):
|
||||
if char in self.list_modes:
|
||||
if param in self.list_modes[char]:
|
||||
self.list_modes[char].remove(param)
|
||||
if not self.list_modes[char]:
|
||||
del self.list_modes[char]
|
||||
elif char in self.modes:
|
||||
del self.modes[char]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Callable, Dict, List, Optional, Set
|
||||
from typing import Callable, Dict, List, Optional, Set, Tuple
|
||||
from datetime import datetime
|
||||
from irctokens import build, Line, StatefulDecoder, StatefulEncoder
|
||||
|
||||
|
@ -21,7 +21,8 @@ class Server(Named):
|
|||
def __init__(self, name: str):
|
||||
self.name = name
|
||||
|
||||
self.nickname = ""
|
||||
self.nickname = ""
|
||||
self.modes: List[str] = []
|
||||
|
||||
self._encoder = StatefulEncoder()
|
||||
self._decoder = StatefulDecoder()
|
||||
|
@ -206,3 +207,45 @@ class Server(Named):
|
|||
channel = self.channels[channel_lower]
|
||||
channel.topic_setter = line.params[2]
|
||||
channel.topic_time = datetime.fromtimestamp(int(line.params[3]))
|
||||
|
||||
@line_handler("MODE")
|
||||
def handle_MODE(self, line: Line):
|
||||
target = line.params[0]
|
||||
modes = line.params[1]
|
||||
params = line.params[2:].copy()
|
||||
|
||||
modifier = True
|
||||
parts: List[Tuple[bool, str]] = []
|
||||
|
||||
for c in list(modes):
|
||||
if c == "+":
|
||||
modifier = True
|
||||
elif c == "-":
|
||||
modifier = False
|
||||
else:
|
||||
parts.append((modifier, c))
|
||||
|
||||
if target == self.nickname:
|
||||
for add, char in parts:
|
||||
if add:
|
||||
if not char in self.modes:
|
||||
self.modes.append(char)
|
||||
elif char in self.modes:
|
||||
self.modes.remove(char)
|
||||
elif self.has_channel(target):
|
||||
channel = self.channels[self.casemap_lower(target)]
|
||||
for add, char in parts:
|
||||
list_mode = char in self.isupport.chanmodes.list_modes
|
||||
if add and (
|
||||
list_mode or
|
||||
char in self.isupport.chanmodes.setting_b_modes or
|
||||
char in self.isupport.chanmodes.setting_c_modes):
|
||||
channel.add_mode(char, params.pop(0), list_mode)
|
||||
elif not add and (
|
||||
list_mode or
|
||||
char in self.isupport.chanmodes.setting_b_modes):
|
||||
channel.remove_mode(char, params.pop(0))
|
||||
elif add:
|
||||
channel.add_mode(char, None, False)
|
||||
else:
|
||||
channel.remove_mode(char, None)
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
from .channel import *
|
||||
from .nickname import *
|
||||
from .mode import *
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
import unittest
|
||||
import ircstates, irctokens
|
||||
|
||||
|
||||
class ModeTestUMode(unittest.TestCase):
|
||||
def test_add(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE nickname +i"))
|
||||
self.assertEqual(server.modes, ["i"])
|
||||
|
||||
def test_remove(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE nickname +i"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE nickname -i"))
|
||||
self.assertEqual(server.modes, [])
|
||||
|
||||
class ModeTestChannelList(unittest.TestCase):
|
||||
def test_add(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +b asd!*@*"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.list_modes, {"b": ["asd!*@*"]})
|
||||
|
||||
def test_remove(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +b asd!*@*"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan -b asd!*@*"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.list_modes, {})
|
||||
|
||||
class ModeTestChannelTypeB(unittest.TestCase):
|
||||
def test_add(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +k password"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.modes, {"k": "password"})
|
||||
|
||||
def test_remove(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +k password"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan -k *"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.list_modes, {})
|
||||
|
||||
class ModeTestChannelTypeC(unittest.TestCase):
|
||||
def test_add(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +l 100"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.modes, {"l": "100"})
|
||||
|
||||
def test_remove(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +l 100"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan -l"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.list_modes, {})
|
||||
|
||||
class ModeTestChannelTypeD(unittest.TestCase):
|
||||
def test_add(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +i"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.modes, {"i": None})
|
||||
|
||||
def test_remove(self):
|
||||
server = ircstates.Server("test")
|
||||
server.parse_tokens(irctokens.tokenise("001 nickname"))
|
||||
server.parse_tokens(irctokens.tokenise(":nickname JOIN #chan"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan +i"))
|
||||
server.parse_tokens(irctokens.tokenise("MODE #chan -i"))
|
||||
channel = server.channels["#chan"]
|
||||
self.assertEqual(channel.list_modes, {})
|
||||
|
Loading…
Reference in New Issue