<commit_before>#!/usr/bin/env python

###
# Copyright (c) 2002, <NAME>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

"""
Basic channel management commands.  Many of these commands require their caller
to have the <channel>.op capability.  This plugin is loaded by default.
"""

__revision__ = "$Id$"

import fix

import time
import getopt
from itertools import imap

import conf
import ircdb
import utils
import ircmsgs
import schedule
import ircutils
import privmsgs
import callbacks

class Channel(callbacks.Privmsg):
    def op(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will give all the <nick>s
        you provide ops.  If you don't provide any <nick>s, this will op you.
        <channel> is only necessary if the message isn't sent in the channel
        itself.
        """
        if not args:
            args = [msg.nick]
        if irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.ops(channel, args))
        else:
            irc.error('How can I op you?  I\'m not opped!')
    op = privmsgs.checkChannelCapability(op, 'op')

    def halfop(self, irc, msg, args, channel):
        """[<channel>]

        If you have the #channel.halfop capability, this will give all the
        <nick>s you provide halfops.  If you don't provide any <nick>s, this
        will give you halfops. <channel> is only necessary if the message isn't
        sent in the channel itself.
        """
        if not args:
            args = [msg.nick]
        if irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.halfops(channel, args))
        else:
            irc.error('How can I halfop you?  I\'m not opped!')
    halfop = privmsgs.checkChannelCapability(halfop, 'halfop')

    def voice(self, irc, msg, args, channel):
        """[<channel>]

        If you have the #channel.voice capability, this will voice all the
        <nick>s you provide.  If you don't provide any <nick>s, this will
        voice you. <channel> is only necessary if the message isn't sent in the
        channel itself.
        """
        if not args:
            args = [msg.nick]
        if irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.voices(channel, args))
        else:
            irc.error('How can I voice you?  I\'m not opped!')
    voice = privmsgs.checkChannelCapability(voice, 'voice')

    def deop(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will remove operator
        privileges from all the nicks given.  If no nicks are given, removes
        operator privileges from the person sending the message.
        """
        if not args:
            args.append(msg.nick)
        if irc.nick in args:
            irc.error('I cowardly refuse to deop myself.  If you really want '
                      'me deopped, tell me to op you and then deop me '
                      'yourself.')
        elif irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.deops(channel, args))
        else:
            irc.error('How can I deop someone?  I\'m not opped!')
    deop = privmsgs.checkChannelCapability(deop, 'op')
    
    def dehalfop(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will remove half-operator
        privileges from all the nicks given.  If no nicks are given, removes
        half-operator privileges from the person sending the message.
        """
        if not args:
            args.append(msg.nick)
        if irc.nick in args:
            irc.error('I cowardly refuse to dehalfop myself.  If you really '
                      'want me dehalfopped, tell me to op you and then '
                      'dehalfop me yourself.')
        elif irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.dehalfops(channel, args))
        else:
            irc.error('How can I dehalfop someone?  I\'m not opped!')
    dehalfop = privmsgs.checkChannelCapability(dehalfop, 'op')
    
    def devoice(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will remove voice from all
        the nicks given.  If no nicks are given, removes voice from the person
        sending the message.
        """
        if not args:
            args.append(msg.nick)
        if irc.nick in args:
            irc.error('I cowardly refuse to devoice myself.  If you really '
                      'want me devoiced, tell me to op you and then devoice '
                      'me yourself.')
        elif irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.devoices(channel, args))
        else:
            irc.error('How can I devoice someone?  I\'m not opped!')
    devoice = privmsgs.checkChannelCapability(devoice, 'op')
    
    def cycle(self, irc, msg, args, channel):
        """[<channel>] [<key>]

        If you have the #channel.op capability, this will cause the bot to
        "cycle", or PART and then JOIN the channel. If <key> is given, join
        the channel using that key. <channel> is only necessary if the message
        isn't sent in the channel itself.
        """
        key = privmsgs.getArgs(args, required=0, optional=1)
        if not key:
            key = None
        irc.queueMsg(ircmsgs.part(channel))
        irc.queueMsg(ircmsgs.join(channel, key))
    cycle = privmsgs.checkChannelCapability(cycle, 'op')

    def kick(self, irc, msg, args, channel):
        """[<channel>] <nick> [<reason>]

        Kicks <nick> from <channel> for <reason>.  If <reason> isn't given,
        uses the nick of the person making the command as the reason.
        <channel> is only necessary if the message isn't sent in the channel
        itself.
        """
        if irc.nick in irc.state.channels[channel].ops:
            (nick, reason) = privmsgs.getArgs(args, optional=1)
            if not reason:
                reason = msg.nick
            irc.queueMsg(ircmsgs.kick(channel, nick, reason))
        else:
            irc.error('How can I kick someone?  I\'m not opped!')
    kick = privmsgs.checkChannelCapability(kick, 'op')

    def kban(self, irc, msg, args):
        """[<channel>] <nick> [<seconds>] [--{exact,nick,user,host}]

        If you have the #channel.op capability, this will kickban <nick> for
        as many seconds as you specify, or else (if you specify 0 seconds or
        don't specify a number of seconds) it will ban the person indefinitely.
        --exact bans only the exact hostmask; --nick bans just the nick;
        --user bans just the user, and --host bans just the host.  You can
        combine these options as you choose.
        <channel> is only necessary if the message isn't sent in the channel
        itself.
        """
        channel = privmsgs.getChannel(msg, args)
        (optlist, rest) = getopt.getopt(args, '', ['exact', 'nick',
                                                   'user', 'host'])
        (bannedNick, length) = privmsgs.getArgs(rest, optional=1)
        # Check that they're not trying to make us kickban ourself.<commit_msg>Proper ordering of options in Channel.kban's help<commit_after>#!/usr/bin/env python

###
# Copyright (c) 2002, <NAME>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

"""
Basic channel management commands.  Many of these commands require their caller
to have the <channel>.op capability.  This plugin is loaded by default.
"""

__revision__ = "$Id$"

import fix

import time
import getopt
from itertools import imap

import conf
import ircdb
import utils
import ircmsgs
import schedule
import ircutils
import privmsgs
import callbacks

class Channel(callbacks.Privmsg):
    def op(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will give all the <nick>s
        you provide ops.  If you don't provide any <nick>s, this will op you.
        <channel> is only necessary if the message isn't sent in the channel
        itself.
        """
        if not args:
            args = [msg.nick]
        if irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.ops(channel, args))
        else:
            irc.error('How can I op you?  I\'m not opped!')
    op = privmsgs.checkChannelCapability(op, 'op')

    def halfop(self, irc, msg, args, channel):
        """[<channel>]

        If you have the #channel.halfop capability, this will give all the
        <nick>s you provide halfops.  If you don't provide any <nick>s, this
        will give you halfops. <channel> is only necessary if the message isn't
        sent in the channel itself.
        """
        if not args:
            args = [msg.nick]
        if irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.halfops(channel, args))
        else:
            irc.error('How can I halfop you?  I\'m not opped!')
    halfop = privmsgs.checkChannelCapability(halfop, 'halfop')

    def voice(self, irc, msg, args, channel):
        """[<channel>]

        If you have the #channel.voice capability, this will voice all the
        <nick>s you provide.  If you don't provide any <nick>s, this will
        voice you. <channel> is only necessary if the message isn't sent in the
        channel itself.
        """
        if not args:
            args = [msg.nick]
        if irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.voices(channel, args))
        else:
            irc.error('How can I voice you?  I\'m not opped!')
    voice = privmsgs.checkChannelCapability(voice, 'voice')

    def deop(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will remove operator
        privileges from all the nicks given.  If no nicks are given, removes
        operator privileges from the person sending the message.
        """
        if not args:
            args.append(msg.nick)
        if irc.nick in args:
            irc.error('I cowardly refuse to deop myself.  If you really want '
                      'me deopped, tell me to op you and then deop me '
                      'yourself.')
        elif irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.deops(channel, args))
        else:
            irc.error('How can I deop someone?  I\'m not opped!')
    deop = privmsgs.checkChannelCapability(deop, 'op')
    
    def dehalfop(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will remove half-operator
        privileges from all the nicks given.  If no nicks are given, removes
        half-operator privileges from the person sending the message.
        """
        if not args:
            args.append(msg.nick)
        if irc.nick in args:
            irc.error('I cowardly refuse to dehalfop myself.  If you really '
                      'want me dehalfopped, tell me to op you and then '
                      'dehalfop me yourself.')
        elif irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.dehalfops(channel, args))
        else:
            irc.error('How can I dehalfop someone?  I\'m not opped!')
    dehalfop = privmsgs.checkChannelCapability(dehalfop, 'op')
    
    def devoice(self, irc, msg, args, channel):
        """[<channel>] [<nick> ...]

        If you have the #channel.op capability, this will remove voice from all
        the nicks given.  If no nicks are given, removes voice from the person
        sending the message.
        """
        if not args:
            args.append(msg.nick)
        if irc.nick in args:
            irc.error('I cowardly refuse to devoice myself.  If you really '
                      'want me devoiced, tell me to op you and then devoice '
                      'me yourself.')
        elif irc.nick in irc.state.channels[channel].ops:
            irc.queueMsg(ircmsgs.devoices(channel, args))
        else:
            irc.error('How can I devoice someone?  I\'m not opped!')
    devoice = privmsgs.checkChannelCapability(devoice, 'op')
    
    def cycle(self, irc, msg, args, channel):
        """[<channel>] [<key>]

        If you have the #channel.op capability, this will cause the bot to
        "cycle", or PART and then JOIN the channel. If <key> is given, join
        the channel using that key. <channel> is only necessary if the message
        isn't sent in the channel itself.
        """
        key = privmsgs.getArgs(args, required=0, optional=1)
        if not key:
            key = None
        irc.queueMsg(ircmsgs.part(channel))
        irc.queueMsg(ircmsgs.join(channel, key))
    cycle = privmsgs.checkChannelCapability(cycle, 'op')

    def kick(self, irc, msg, args, channel):
        """[<channel>] <nick> [<reason>]

        Kicks <nick> from <channel> for <reason>.  If <reason> isn't given,
        uses the nick of the person making the command as the reason.
        <channel> is only necessary if the message isn't sent in the channel
        itself.
        """
        if irc.nick in irc.state.channels[channel].ops:
            (nick, reason) = privmsgs.getArgs(args, optional=1)
            if not reason:
                reason = msg.nick
            irc.queueMsg(ircmsgs.kick(channel, nick, reason))
        else:
            irc.error('How can I kick someone?  I\'m not opped!')
    kick = privmsgs.checkChannelCapability(kick, 'op')

    def kban(self, irc, msg, args):
        """[<channel>] [--{exact,nick,user,host}] <nick> [<seconds>] 

        If you have the #channel.op capability, this will kickban <nick> for
        as many seconds as you specify, or else (if you specify 0 seconds or
        don't specify a number of seconds) it will ban the person indefinitely.
        --exact bans only the exact hostmask; --nick bans just the nick;
        --user bans just the user, and --host bans just the host.  You can
        combine these options as you choose.
        <channel> is only necessary if the message isn't sent in the channel
        itself.
        """
        channel = privmsgs.getChannel(msg, args)
        (optlist, rest) = getopt.getopt(args, '', ['exact', 'nick',
                                                   'user', 'host'])
        (bannedNick, length) = privmsgs.getArgs(rest, optional=1)
        # Check that they're not trying to make us kickban ourself.
{'fraction_non_alphanumeric': 0.0920207018142524, 'fraction_numerical': 0.0010237160894045385, 'mean_word_length': 2.4018185335654865, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1301676', 'n_tokens_mistral': 5115, 'n_tokens_neox': 4852, 'n_words': 1985}