mirror of
				https://github.com/jlu5/PyLink.git
				synced 2025-11-04 00:47:21 +01:00 
			
		
		
		
	bots: make source client names optional (Closes #161)
This commit is contained in:
		
							parent
							
								
									34ca973047
								
							
						
					
					
						commit
						54dc51aed4
					
				
							
								
								
									
										134
									
								
								plugins/bots.py
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								plugins/bots.py
									
									
									
									
									
								
							@ -30,6 +30,7 @@ def quit(irc, source, args):
 | 
			
		||||
 | 
			
		||||
    Admin-only. Quits the PyLink client with nick <target>, if one exists."""
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
    except IndexError:
 | 
			
		||||
@ -38,36 +39,57 @@ def quit(irc, source, args):
 | 
			
		||||
    if irc.pseudoclient.uid == irc.nickToUid(nick):
 | 
			
		||||
        irc.reply("Error: Cannot quit the main PyLink PseudoClient!")
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    u = irc.nickToUid(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.quit(u, quitmsg)
 | 
			
		||||
    irc.callHooks([u, 'PYLINK_BOTSPLUGIN_QUIT', {'text': quitmsg, 'parse_as': 'QUIT'}])
 | 
			
		||||
 | 
			
		||||
def joinclient(irc, source, args):
 | 
			
		||||
    """<target> <channel1>,[<channel2>], etc.
 | 
			
		||||
    """[<target>] <channel1>,[<channel2>], etc.
 | 
			
		||||
 | 
			
		||||
    Admin-only. Joins <target>, the nick of a PyLink client, to a comma-separated list of channels."""
 | 
			
		||||
    Admin-only. Joins <target>, the nick of a PyLink client, to a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
        clist = args[1].split(',')
 | 
			
		||||
        if not clist:
 | 
			
		||||
        # Check if the first argument is an existing PyLink client. If it is not,
 | 
			
		||||
        # then assume that the first argument was actually the channels being joined.
 | 
			
		||||
        u = irc.nickToUid(args[0])
 | 
			
		||||
 | 
			
		||||
        if not irc.isInternalClient(u):  # First argument isn't one of our clients
 | 
			
		||||
            raise IndexError
 | 
			
		||||
    except IndexError:
 | 
			
		||||
        irc.reply("Error: Not enough arguments. Needs 2: nick, comma separated list of channels.")
 | 
			
		||||
 | 
			
		||||
        clist = args[1]
 | 
			
		||||
    except IndexError:  # No nick was given; shift arguments one to the left.
 | 
			
		||||
        u = irc.pseudoclient.uid
 | 
			
		||||
        try:
 | 
			
		||||
            clist = args[0]
 | 
			
		||||
        except IndexError:
 | 
			
		||||
            irc.reply("Error: Not enough arguments. Needs 1-2: nick (optional), comma separated list of channels.")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
    clist = clist.split(',')
 | 
			
		||||
    if not clist:
 | 
			
		||||
        irc.reply("Error: No valid channels given.")
 | 
			
		||||
        return
 | 
			
		||||
    u = irc.nickToUid(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.join(u, channel)
 | 
			
		||||
 | 
			
		||||
        # Call a join hook manually so other plugins like relay can understand it.
 | 
			
		||||
        irc.callHooks([u, 'PYLINK_BOTSPLUGIN_JOIN', {'channel': channel, 'users': [u],
 | 
			
		||||
                                                'modes': irc.channels[channel].modes,
 | 
			
		||||
                                                'parse_as': 'JOIN'}])
 | 
			
		||||
@ -75,76 +97,126 @@ utils.add_cmd(joinclient, name='join')
 | 
			
		||||
 | 
			
		||||
@utils.add_cmd
 | 
			
		||||
def nick(irc, source, args):
 | 
			
		||||
    """<target> <newnick>
 | 
			
		||||
    """[<target>] <newnick>
 | 
			
		||||
 | 
			
		||||
    Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>."""
 | 
			
		||||
    Admin-only. Changes the nick of <target>, a PyLink client, to <newnick>. If <target> is not given, it defaults to the main PyLink client."""
 | 
			
		||||
    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
 | 
			
		||||
        try:
 | 
			
		||||
            nick = irc.pseudoclient.nick
 | 
			
		||||
            newnick = args[0]
 | 
			
		||||
        except IndexError:
 | 
			
		||||
            irc.reply("Error: Not enough arguments. Needs 1-2: nick (optional), newnick.")
 | 
			
		||||
            return
 | 
			
		||||
    u = irc.nickToUid(nick)
 | 
			
		||||
    if newnick in ('0', u):
 | 
			
		||||
 | 
			
		||||
    if newnick in ('0', u):  # Allow /nick 0 to work
 | 
			
		||||
        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.nick(u, newnick)
 | 
			
		||||
    # Ditto above: manually send a NICK change hook payload to other plugins.
 | 
			
		||||
    irc.callHooks([u, 'PYLINK_BOTSPLUGIN_NICK', {'newnick': newnick, 'oldnick': nick, 'parse_as': 'NICK'}])
 | 
			
		||||
 | 
			
		||||
@utils.add_cmd
 | 
			
		||||
def part(irc, source, args):
 | 
			
		||||
    """<target> <channel1>,[<channel2>],... [<reason>]
 | 
			
		||||
    """[<target>] <channel1>,[<channel2>],... [<reason>]
 | 
			
		||||
 | 
			
		||||
    Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels."""
 | 
			
		||||
    Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        nick = args[0]
 | 
			
		||||
        clist = args[1].split(',')
 | 
			
		||||
        clist = args[1]
 | 
			
		||||
        # For the part message, join all remaining arguments into one text string
 | 
			
		||||
        reason = ' '.join(args[2:])
 | 
			
		||||
    except IndexError:
 | 
			
		||||
        irc.reply("Error: Not enough arguments. Needs 2: nick, comma separated list of channels.")
 | 
			
		||||
 | 
			
		||||
        # First, check if the first argument is an existing PyLink client. If it is not,
 | 
			
		||||
        # then assume that the first argument was actually the channels being parted.
 | 
			
		||||
        u = irc.nickToUid(nick)
 | 
			
		||||
        if not irc.isInternalClient(u):  # First argument isn't one of our clients
 | 
			
		||||
            raise IndexError
 | 
			
		||||
 | 
			
		||||
    except IndexError:  # No nick was given; shift arguments one to the left.
 | 
			
		||||
        u = irc.pseudoclient.uid
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            clist = args[0]
 | 
			
		||||
        except IndexError:
 | 
			
		||||
            irc.reply("Error: Not enough arguments. Needs 1-2: nick (optional), comma separated list of channels.")
 | 
			
		||||
            return
 | 
			
		||||
        reason = ' '.join(args[1:])
 | 
			
		||||
 | 
			
		||||
    clist = clist.split(',')
 | 
			
		||||
    if not clist:
 | 
			
		||||
        irc.reply("Error: No valid channels given.")
 | 
			
		||||
        return
 | 
			
		||||
    u = irc.nickToUid(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.part(u, channel, reason)
 | 
			
		||||
 | 
			
		||||
    irc.callHooks([u, 'PYLINK_BOTSPLUGIN_PART', {'channels': clist, 'text': reason, 'parse_as': 'PART'}])
 | 
			
		||||
 | 
			
		||||
@utils.add_cmd
 | 
			
		||||
def msg(irc, source, args):
 | 
			
		||||
    """<source> <target> <text>
 | 
			
		||||
    """[<source>] <target> <text>
 | 
			
		||||
 | 
			
		||||
    Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client."""
 | 
			
		||||
    Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client. If <source> is not given, it defaults to the main PyLink client."""
 | 
			
		||||
    utils.checkAuthenticated(irc, source, allowOper=False)
 | 
			
		||||
 | 
			
		||||
    # Because we want the source nick to be optional, this argument parsing gets a bit tricky.
 | 
			
		||||
    try:
 | 
			
		||||
        msgsource, target, text = args[0], args[1], ' '.join(args[2:])
 | 
			
		||||
        msgsource = args[0]
 | 
			
		||||
        target = args[1]
 | 
			
		||||
        text = ' '.join(args[2:])
 | 
			
		||||
 | 
			
		||||
        # First, check if the first argument is an existing PyLink client. If it is not,
 | 
			
		||||
        # then assume that the first argument was actually the message TARGET.
 | 
			
		||||
        sourceuid = irc.nickToUid(msgsource)
 | 
			
		||||
        if not irc.isInternalClient(sourceuid):  # First argument isn't one of our clients
 | 
			
		||||
            raise IndexError
 | 
			
		||||
 | 
			
		||||
        if not text:
 | 
			
		||||
            raise IndexError
 | 
			
		||||
    except IndexError:
 | 
			
		||||
        irc.reply('Error: Not enough arguments. Needs 3: source nick, target, text.')
 | 
			
		||||
        return
 | 
			
		||||
    sourceuid = irc.nickToUid(msgsource)
 | 
			
		||||
    if not sourceuid:
 | 
			
		||||
        irc.reply('Error: Unknown user %r.' % msgsource)
 | 
			
		||||
        try:
 | 
			
		||||
            sourceuid = irc.pseudoclient.uid
 | 
			
		||||
            target = args[0]
 | 
			
		||||
            text = ' '.join(args[1:])
 | 
			
		||||
        except IndexError:
 | 
			
		||||
            irc.reply('Error: Not enough arguments. Needs 3: source nick, target, text.')
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
    if not text:
 | 
			
		||||
        irc.reply('Error: No text given.')
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    if not utils.isChannel(target):
 | 
			
		||||
        # Convert nick of the message target to a UID, if the target isn't a channel
 | 
			
		||||
        real_target = irc.nickToUid(target)
 | 
			
		||||
        if real_target is None:
 | 
			
		||||
        if real_target is None:  # Unknown target user, if target isn't a valid channel name
 | 
			
		||||
            irc.reply('Error: Unknown user %r.' % target)
 | 
			
		||||
            return
 | 
			
		||||
    else:
 | 
			
		||||
        real_target = target
 | 
			
		||||
    if not text:
 | 
			
		||||
        irc.reply('Error: No text given.')
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    irc.proto.message(sourceuid, real_target, text)
 | 
			
		||||
    irc.callHooks([sourceuid, 'PYLINK_BOTSPLUGIN_MSG', {'target': real_target, 'text': text, 'parse_as': 'PRIVMSG'}])
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user