class Channel: """A channel of communications.""" id: s.str() backend: s.dataclass(Backend) = field(default_factory=Backend) head: s.str() = "From {from}: " users: s.list(s.dataclass(User)) = field(default_factory=list) phones: s.list(s.dataclass(Phone)) = field(default_factory=list) aliases: s.dataclass(Aliases) = field(default_factory=Aliases) rcpt: vs.nick() = "ops"
def deop(self, nick: vs.nick()): """Demote channel operator to user.""" try: user = self.users[nick] except KeyError: raise Error(f"No such user: {nick}.") if not user.op: raise Error(f"User {user.nick} is not channel operator.") self.notify(f"demoted {user.nick} to channel user") user.op = False
def op(self, nick: vs.nick() = None): """List operators or promote user to channel operator.""" if nick is None: result = [] for nick in self.users: if self.users[nick].op: result.append(nick) return f"Operators: {_str_list(result)}." try: user = self.users[nick] except KeyError: raise Error(f"No such user: {nick}.") if user.op: raise Error(f"User {user.nick} is already channel operator.") user.op = True self.notify(f"promoted {user.nick} to channel operator")
def add(self, number: vs.e164(), nick: vs.nick()): """Add member to channel.""" if number in self.phones: raise Error( f"{number} is already registered to {self.phones[number].nick}." ) for alias in _dict_dataclass(self.channel.aliases).values(): if alias.lower() == nick.lower(): raise Error(f"Nick unavailable: {nick}.") try: user = self.users[nick] except KeyError: user = vokiz.resource.User(nick) self.users.add(user) self.phones.add(vokiz.resource.Phone(number, user.nick)) self.notify(f"added {number} ({user.nick})")
def rcpt(self, nick: vs.nick() = None): """Get or set recipient of unaddressed messages.""" if not nick: return f"Default recipient: {self.channel.rcpt}."
class Aliases: """Aliases for group distributions.""" ops: vs.nick() = "ops" all: vs.nick() = "all"
class User: """A user associated with a channel.""" nick: vs.nick() voice: s.bool() = True op: s.bool() = False
class Phone: """A phone number associated with a channel.""" number: vs.e164() nick: vs.nick() mute: s.bool() = False