def quit(irc, source, args): """<target> [<reason>] Admin-only. Quits the PyLink client with nick <target>, if one exists.""" utils.checkAuthenticated(irc, source, allowOper=False) try: nick = args[0] except IndexError: irc.reply( "Error: Not enough arguments. Needs 1-2: nick, reason (optional).") return if irc.pseudoclient.uid == utils.nickToUid(irc, nick): irc.reply("Error: Cannot quit the main PyLink PseudoClient!") return u = utils.nickToUid(irc, nick) quitmsg = ' '.join(args[1:]) or 'Client Quit' if not utils.isManipulatableClient(irc, u): irc.reply( "Error: Cannot force quit a protected PyLink services client.") return irc.proto.quitClient(u, quitmsg) irc.callHooks( [u, 'PYLINK_BOTSPLUGIN_QUIT', { 'text': quitmsg, 'parse_as': 'QUIT' }])
def msg(irc, source, args): """<source> <target> <text> Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client.""" utils.checkAuthenticated(irc, source, allowOper=False) try: msgsource, target, text = args[0], args[1], ' '.join(args[2:]) except IndexError: irc.reply( 'Error: Not enough arguments. Needs 3: source nick, target, text.') return sourceuid = utils.nickToUid(irc, msgsource) if not sourceuid: irc.reply('Error: Unknown user %r.' % msgsource) return if not utils.isChannel(target): real_target = utils.nickToUid(irc, target) if real_target is None: irc.reply('Error: Unknown user %r.' % target) return else: real_target = target if not text: irc.reply('Error: No text given.') return irc.proto.messageClient(sourceuid, real_target, text) irc.callHooks([ sourceuid, 'PYLINK_BOTSPLUGIN_MSG', { 'target': real_target, 'text': text, 'parse_as': 'PRIVMSG' } ])
def kick(irc, source, args): """<source> <channel> <user> [<reason>] Admin-only. Kicks <user> from <channel> via <source>, where <source> is the nick of a PyLink client.""" utils.checkAuthenticated(irc, source, allowOper=False) try: nick = args[0] channel = args[1] target = args[2] reason = ' '.join(args[3:]) except IndexError: irc.reply( "Error: Not enough arguments. Needs 3-4: source nick, channel, target, reason (optional)." ) return u = utils.nickToUid(irc, nick) or nick targetu = utils.nickToUid(irc, target) if not utils.isChannel(channel): irc.reply("Error: Invalid channel name %r." % channel) return if utils.isInternalServer(irc, u): irc.proto.kickServer(u, channel, targetu, reason) else: irc.proto.kickClient(u, channel, targetu, reason) irc.callHooks([ u, 'PYLINK_BOTSPLUGIN_KICK', { 'channel': channel, 'target': targetu, 'text': reason, 'parse_as': 'KICK' } ])
def nick(irc, source, args): """<target> <newnick> Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>.""" utils.checkAuthenticated(irc, source, allowOper=False) try: nick = args[0] newnick = args[1] except IndexError: irc.reply("Error: Not enough arguments. Needs 2: nick, newnick.") return u = utils.nickToUid(irc, nick) if newnick in ('0', u): newnick = u elif not utils.isNick(newnick): irc.reply('Error: Invalid nickname %r.' % newnick) return elif not utils.isManipulatableClient(irc, u): irc.reply( "Error: Cannot force nick changes for a protected PyLink services client." ) return irc.proto.nickClient(u, newnick) irc.callHooks([ u, 'PYLINK_BOTSPLUGIN_NICK', { 'newnick': newnick, 'oldnick': nick, 'parse_as': 'NICK' } ])
def joinclient(irc, source, args): """<target> <channel1>,[<channel2>], etc. Admin-only. Joins <target>, the nick of a PyLink client, to a comma-separated list of channels.""" utils.checkAuthenticated(irc, source, allowOper=False) try: nick = args[0] clist = args[1].split(',') if not clist: raise IndexError except IndexError: irc.reply( "Error: Not enough arguments. Needs 2: nick, comma separated list of channels." ) return u = utils.nickToUid(irc, nick) if not utils.isManipulatableClient(irc, u): irc.reply( "Error: Cannot force join a protected PyLink services client.") return for channel in clist: if not utils.isChannel(channel): irc.reply("Error: Invalid channel name %r." % channel) return irc.proto.joinClient(u, channel) irc.callHooks([ u, 'PYLINK_BOTSPLUGIN_JOIN', { 'channel': channel, 'users': [u], 'modes': irc.channels[channel].modes, 'parse_as': 'JOIN' } ])
def part(irc, source, args): """<target> <channel1>,[<channel2>],... [<reason>] Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels.""" utils.checkAuthenticated(irc, source, allowOper=False) try: nick = args[0] clist = args[1].split(',') reason = ' '.join(args[2:]) except IndexError: irc.reply( "Error: Not enough arguments. Needs 2: nick, comma separated list of channels." ) return u = utils.nickToUid(irc, nick) if not utils.isManipulatableClient(irc, u): irc.reply( "Error: Cannot force part a protected PyLink services client.") return for channel in clist: if not utils.isChannel(channel): irc.reply("Error: Invalid channel name %r." % channel) return irc.proto.partClient(u, channel, reason) irc.callHooks([ u, 'PYLINK_BOTSPLUGIN_PART', { 'channels': clist, 'text': reason, 'parse_as': 'PART' } ])
def showuser(irc, source, args): """<user> Shows information about <user>.""" try: target = args[0] except IndexError: irc.reply("Error: Not enough arguments. Needs 1: nick.") return u = utils.nickToUid(irc, target) or target # Only show private info if the person is calling 'showuser' on themselves, # or is an oper. verbose = utils.isOper(irc, source) or u == source if u not in irc.users: irc.reply('Error: Unknown user %r.' % target) return f = lambda s: irc.msg(source, s) userobj = irc.users[u] f('Information on user \x02%s\x02 (%s@%s): %s' % (userobj.nick, userobj.ident, userobj.host, userobj.realname)) sid = utils.clientToServer(irc, u) serverobj = irc.servers[sid] ts = userobj.ts f('\x02Home server\x02: %s (%s); \x02Signon time:\x02 %s (%s)' % \ (serverobj.name, sid, ctime(float(ts)), ts)) if verbose: f('\x02Protocol UID\x02: %s; \x02PyLink identification\x02: %s' % \ (u, userobj.identified)) f('\x02User modes\x02: %s' % utils.joinModes(userobj.modes)) f('\x02Real host\x02: %s; \x02IP\x02: %s; \x02Away status\x02: %s' % \ (userobj.realhost, userobj.ip, userobj.away or '\x1D(not set)\x1D')) f('\x02Channels\x02: %s' % (' '.join(userobj.channels).strip() or '\x1D(none)\x1D'))
def _getNick(self, target): """Converts a nick argument to its matching UID. This differs from utils.nickToUid() in that it returns the original text instead of None, if no matching nick is found.""" target = utils.nickToUid(self.irc, target) or target if target not in self.irc.users and not utils.isChannel(target): log.debug( "(%s) Possible desync? Got command target %s, who " "isn't in our user list!", self.irc.name, target) return target
def mode(irc, source, args): """<source> <target> <modes> Admin-only. Sets modes <modes> on <target> from <source>, where <source> is either the nick of a PyLink client, or the SID of a PyLink server. <target> can be either a nick or a channel.""" utils.checkAuthenticated(irc, source, allowOper=False) try: modesource, target, modes = args[0], args[1], args[2:] except IndexError: irc.reply( 'Error: Not enough arguments. Needs 3: source nick, target, modes to set.' ) return target = utils.nickToUid(irc, target) or target extclient = target in irc.users and not utils.isInternalClient(irc, target) parsedmodes = utils.parseModes(irc, target, modes) ischannel = target in irc.channels if not (target in irc.users or ischannel): irc.reply("Error: Invalid channel or nick %r." % target) return elif not parsedmodes: irc.reply("Error: No valid modes were given.") return elif not (ischannel or utils.isManipulatableClient(irc, target)): irc.reply( "Error: Can only set modes on channels or non-protected PyLink clients." ) return if utils.isInternalServer(irc, modesource): # Setting modes from a server. irc.proto.modeServer(modesource, target, parsedmodes) else: # Setting modes from a client. modesource = utils.nickToUid(irc, modesource) irc.proto.modeClient(modesource, target, parsedmodes) irc.callHooks([ modesource, 'PYLINK_BOTSPLUGIN_MODE', { 'target': target, 'modes': parsedmodes, 'parse_as': 'MODE' } ])