patch 524dd6f7c12b54f938923345e56a313df81213f4 Author: E. Bosch Date: Wed Mar 31 03:21:58 CEST 2021 * irc: Add PART command diff -rN -u old-irgramd/irc.py new-irgramd/irc.py --- old-irgramd/irc.py 2024-10-23 04:28:39.519740992 +0200 +++ new-irgramd/irc.py 2024-10-23 04:28:39.519740992 +0200 @@ -30,6 +30,7 @@ IRC_MOTD_RX = re.compile(PREFIX + r'MOTD( +:| +|\n)(?P[^\n ]+|)') IRC_NAMES_RX = re.compile(PREFIX + r'NAMES( +:| +|\n)(?P[^\n ]+|)') IRC_NICK_RX = re.compile(PREFIX + r'NICK( +:| +|\n)(?P[^\n ]+|)') +IRC_PART_RX = re.compile(PREFIX + r'PART( +|\n)(?P[^ ]+|)( +:| +|\n|)(?P[^\n]+|)') IRC_PASS_RX = re.compile(PREFIX + r'PASS( +:| +|\n)(?P[^\n ]+|)') IRC_PING_RX = re.compile(PREFIX + r'PING( +:| +|\n)(?P[^\n]+|)') IRC_PRIVMSG_RX = re.compile(PREFIX + r'PRIVMSG( +|\n)(?P[^ ]+)( +:| +|\n)(?P[^\n]+|)') @@ -108,6 +109,7 @@ (IRC_MOTD_RX, self.handle_irc_motd, True, 0), (IRC_NAMES_RX, self.handle_irc_names, True, ALL_PARAMS), (IRC_NICK_RX, self.handle_irc_nick, False, ALL_PARAMS), + (IRC_PART_RX, self.handle_irc_part, True, 1), (IRC_PASS_RX, self.handle_irc_pass, False, ALL_PARAMS), (IRC_PING_RX, self.handle_irc_ping, True, ALL_PARAMS), (IRC_PRIVMSG_RX, self.handle_irc_privmsg, True, ALL_PARAMS), @@ -179,8 +181,9 @@ self.logger.debug('Handling JOIN: %s', channels) if channels == '0': - #part all - pass + for channel in self.irc_channels.keys(): + if user.irc_nick in self.irc_channels[channel]: + await self.part_irc_channel(user, channel, '') else: for channel in channels.split(','): if channel.lower() in self.irc_channels.keys(): @@ -188,6 +191,19 @@ else: await self.reply_code(user, 'ERR_NOSUCHCHANNEL', (channel,)) + async def handle_irc_part(self, user, channels, reason): + self.logger.debug('Handling PART: %s, %s', channels, reason) + + for channel in channels.split(','): + chan = channel.lower() + if chan in self.irc_channels.keys(): + if user.irc_nick in self.irc_channels[chan]: + await self.part_irc_channel(user, channel, reason) + else: + await self.reply_code(user, 'ERR_NOTONCHANNEL', (channel,)) + else: + await self.reply_code(user, 'ERR_NOSUCHCHANNEL', (channel,)) + async def handle_irc_names(self, user, channels): self.logger.debug('Handling NAMES: %s', channels) @@ -400,6 +416,18 @@ await self.irc_channel_topic(user, real_chan, entity_cache) await self.irc_namelist(user, real_chan) + async def part_irc_channel(self, user, channel, reason): + chan = channel.lower() + real_chan = self.get_realcaps_name(chan) + + # Notify IRC users in this channel + for usr in [self.users[x.lower()] for x in self.irc_channels[chan] if self.users[x.lower()].stream]: + await self.reply_command(usr, user, 'PART', (real_chan, reason)) + + self.irc_channels[chan].remove(user.irc_nick) + self.irc_channels_ops[chan].discard(user.irc_nick) + self.irc_channels_founder[chan].discard(user.irc_nick) + async def irc_channel_topic(self, user, channel, entity_cache=[None]): chan = channel.lower() topic = await self.tg.get_channel_topic(chan, entity_cache) @@ -415,12 +443,6 @@ await self.reply_code(user, 'RPL_NAMREPLY', (status, channel, ' '.join(chunk))) await self.reply_code(user, 'RPL_ENDOFNAMES', (channel,)) - async def part_irc_channel(self, user, channel): - self.irc_channels[channel].remove(user.irc_nick) - await self.send_irc_command(user, ':{} PART {} :'.format( - user.get_irc_mask(), channel - )) - def get_irc_op(self, nick, channel): chan = channel.lower() if chan in self.irc_channels.keys(): diff -rN -u old-irgramd/irc_replies.py new-irgramd/irc_replies.py --- old-irgramd/irc_replies.py 2024-10-23 04:28:39.519740992 +0200 +++ new-irgramd/irc_replies.py 2024-10-23 04:28:39.519740992 +0200 @@ -48,7 +48,7 @@ 'ERR_NICKNAMEINUSE': ('433', '{} :Nickname in use'), 'ERR_NICKCOLLISION': ('436', 'Nickname collision'), 'ERR_USERNOTINCHANNEL': ('441', 'User not in channel'), - 'ERR_NOTONCHANNEL': ('442', 'Not on channel'), + 'ERR_NOTONCHANNEL': ('442', '{} :Not on channel'), 'ERR_USERONCHANNEL': ('443', 'User on channel'), 'ERR_NOLOGIN': ('444', 'No login'), 'ERR_SUMMONDISABLED': ('445', 'Summon disabled'),