def __init__(self, bot: BaseBot, name: str, database: MaskDatabase, log_chan: str, watch_chan: str): super().__init__(bot, name) self._database = database self._log_chan = log_chan self._watch_chan = watch_chan self._new_users: Set[str] = set() self._watch_masks: Dict[int, Glob] = {} for mask_id, mask in self._database.get_all(): self._watch_masks[mask_id] = gcompile(mask)
async def line_read(self, line: Line): if line.command == "001": await self.send( build("JOIN", [f"{self._log_chan},{self._watch_chan}"])) elif (line.command == "JOIN" and line.source is not None and self.casefold(line.params[0]) == self._watch_chan): folded = self.casefold(line.hostmask.nickname) if not folded == self.nickname_lower: self._new_users.add(folded) await self.send(self.prepare_whox(line.hostmask.nickname)) elif line.command == RPL_WHOSPCRPL: folded = self.casefold(line.params[6]) if folded in self._new_users: self._new_users.remove(folded) if folded in self.users: user = self.users[folded] await self._check_user(user, "JOINX") elif line.command in ["ACCOUNT", "CHGHOST", "NICK"]: folded = self.casefold(line.hostmask.nickname) if (not folded == self.nickname_lower and folded in self.users): user = self.users[folded] if self._watch_chan in user.channels: await self._check_user(user, line.command) elif (line.command == "PRIVMSG" and line.source is not None): folded = self.casefold(line.params[0]) message = line.params[1] if (folded in [self._log_chan, self.nickname_lower] and message.startswith(TRIGGER) and _is_admin(line.source)): reply_target = self._log_chan reply_method = "PRIVMSG" if self.is_me(folded): reply_target = line.hostmask.nickname reply_method = "NOTICE" argv = message.split(" ") command = argv.pop(0).replace(TRIGGER, "", 1) argc = len(argv) if command == "mask" and len(argv) > 1: subcommand = argv[0] raw_mask = gcollapse(argv[1]) mask = raw_mask if not mask.startswith("$"): mask = f"$m:{mask}" ext, sep, mask = mask.partition(":") mask = ext + sep + self.casefold(mask) comment: Optional[str] = None if argc > 2: comment = " ".join(argv[2:]) existing = self._database.find(mask) if subcommand == "add": if existing is None: mask_id = self._database.add(mask, comment) self._watch_masks[mask_id] = gcompile(mask) out = f"now watching {mask} ({mask_id})" await self.send( build(reply_method, [reply_target, out])) else: print("it exists!!!") # error message pass elif subcommand == "remove": if existing is not None: self._database.remove(existing) del self._watch_masks[existing] out = f"no longer watching {mask}" await self.send( build(reply_method, [reply_target, out])) else: # error message print("it does not exist!!") elif subcommand == "comment": if existing is not None: existing_mask = self._database.get(existing) self._database.set_comment(existing, comment) if comment is not None: out = f"set comment for {existing_mask}" else: out = f"removed comment for {existing_mask}" await self.send( build(reply_method, [reply_target, out])) else: print("it does not exist!!")
from ircstates import User from ircstates.names import Name from ircrobots import Bot as BaseBot from ircrobots import Server as BaseServer from ircrobots import ConnectionParams, SASLUserPass from ircstates.numerics import * from ircrobots.matching import Response, Responses, Folded, Nick, SELF from ircrobots.glob import Glob, collapse as gcollapse, compile as gcompile from .database import MaskDatabase TRIGGER = "!" ADMINS_S = ["*!*@bitbot/jess"] ADMINS = [gcompile(m) for m in ADMINS_S] def _masks(user: User) -> List[str]: masks: List[str] = [] if (user.username is not None and user.hostname is not None and user.realname is not None): nickuser = f"{user.nickname}!{user.username}" hostmask = f"{nickuser}@{user.hostname}" masks.append(f"$m:{hostmask}") masks.append(f"$x:{hostmask}#{user.realname}") masks.append(f"$r:{user.realname}") if user.ip is not None and not user.ip == user.hostname: ipmask = f"{nickuser}@{user.ip}"