from collections import defaultdict
|
|
from dataclasses import dataclass, field
|
|
from typing import Dict, Set
|
|
|
|
from paircd.client import Client
|
|
from paircd.message import Message
|
|
|
|
|
|
@dataclass
|
|
class Channel:
|
|
name: str
|
|
topic: str = ""
|
|
modes: Set[str] = field(default_factory=lambda: {"t"})
|
|
clients_by_nick: Dict[str, Client] = field(default_factory=dict)
|
|
modes_by_nick: Dict[str, Set[str]] = field(default_factory=lambda: defaultdict(set))
|
|
|
|
def add_client(self, client: Client) -> None:
|
|
self.clients_by_nick[client.nickname] = client
|
|
if len(self.clients_by_nick) == 1:
|
|
self.modes_by_nick[client.nickname].add("o")
|
|
|
|
def remove_client_by_nick(self, nick: str) -> None:
|
|
del self.clients_by_nick[nick]
|
|
del self.modes_by_nick[nick]
|
|
|
|
def write_message(self, msg: Message) -> None:
|
|
for client in self.clients_by_nick.values():
|
|
# Don't broadcast client's messages back to themselves
|
|
if msg.cmd == "PRIVMSG" and msg.prefix == client.id():
|
|
continue
|
|
client.write_message(msg)
|
|
|
|
def get_modes(self) -> Set[str]:
|
|
return self.modes
|
|
|
|
def get_mode_settings(self) -> str:
|
|
return f"+{''.join(sorted(self.modes))}"
|
|
|
|
def get_user_modes_by_nick(self, nick: str) -> Set[str]:
|
|
return self.modes_by_nick[nick]
|
|
|
|
def get_channel_name(self, nick: str) -> str:
|
|
modes = self.get_user_modes_by_nick(nick)
|
|
if "o" in modes:
|
|
return f"@{nick}"
|
|
if "v" in modes:
|
|
return f"+{nick}"
|
|
return nick
|
|
|
|
def get_channel_size(self) -> int:
|
|
return len(self.clients_by_nick)
|
|
|
|
def rename_client(self, name: str, new_name: str) -> None:
|
|
if name not in self.clients_by_nick:
|
|
raise KeyError(f"No client on channel with nick {name}")
|
|
if new_name in self.clients_by_nick:
|
|
raise KeyError(f"Client already exists with nick {new_name}")
|
|
self.clients_by_nick[new_name] = self.clients_by_nick[name]
|
|
del self.clients_by_nick[name]
|
|
self.modes_by_nick[new_name] = self.modes_by_nick[name]
|
|
del self.modes_by_nick[name]
|