예제 #1
0
def mode(irc, event, args):
    """[<channel>] <modes>

    Sets <modes> in <channel>. <channel> is only necessary if the command
    isn't sent in the channel itself.
    """
    try:
        if utils.is_private(event) or irc.is_channel(args[0]):
            if args[0] in irc.state["channels"]:
                channel = args[0]
                setmodes = utils.split_modes(args[1:])
            elif not utils.is_private(event):
                channel = event.target
                setmodes = utils.split_modes(args)
            else:
                irc.reply(event, utils.gethelp("mode"))
                return
        else:
            channel = event.target
            setmodes = utils.split_modes(args)

    except IndexError:
        irc.reply(event, utils.gethelp("mode"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            already_op = irc.is_opped(irc.get_nick(), channel)
            if not already_op:
                setmodes.append("-o {}".format(irc.get_nick()))
            gotop = utils.getop(irc, channel)
            if gotop:
                for modes in utils.unsplit_modes(setmodes):
                    irc.mode(channel, modes)
예제 #2
0
def squiet(irc, event, args):
    """[<channel>] <nick|hostmask> [<nick|hostmask>...]

    Quiets <nick> in <channel> using services. <channel> is only necessary
    if the command isn't sent in the channel itself.
    """
    try:
        if utils.is_private(event):
            channel = args[0]
            nicks = args[1:]
        else:
            if irc.is_channel(args[0]):
                channel = args[0]
                nicks = args[1:]
            else:
                channel = event.target
                nicks = args

    except IndexError:
        irc.reply(event, utils.gethelp("squiet"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            try:
                if irc.channels[channel].get("chanserv", irc.chanserv):
                    irc.privmsg("ChanServ", "QUIET {} {}".format(channel, " ".join(nicks)))
            except KeyError:
                pass
예제 #3
0
def unquiet(irc, event, args):
    """[<channel>] [<nick|hostmask>...]

    Unquiets <nick> (or yourself if no <nick> is specified) in <channel>.
    <channel> is only necessary if the command isn't sent in the channel
    itself.
    """
    setmodes = []
    try:
        if utils.is_private(event):
            channel = args[0]
            if len(args) > 1:
                nicks = args[1:]
            else:
                nicks = [event.source.nick]
        else:
            if len(args) > 0:
                if irc.is_channel(args[0]):
                    channel = args[0]
                    if len(args) > 1:
                        nicks = args[1:]
                    else:
                        nicks = [event.source.nick]
                else:
                    channel = event.target
                    nicks = args
            else:
                channel = event.target
                nicks = [event.source.nick]

    except IndexError:
        irc.reply(event, utils.gethelp("unquiet"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            for nick in nicks:
                if utils.is_hostmask(nick):
                    hmask = nick
                else:
                    hmask = utils.gethm(irc, nick)
                if hmask and channel in irc.state["channels"]:
                    for bmask in irc.state["channels"][channel]["quiets"]:
                        if fnmatch(utils.irclower(hmask), utils.irclower(bmask)):
                            setmodes.append("-q {}".format(bmask))
                else:
                    return
            if len(setmodes) == 0:
                return
            already_op = irc.is_opped(irc.get_nick(), channel)
            if not already_op:
                setmodes.append("-o {}".format(irc.get_nick()))
            gotop = utils.getop(irc, channel)
            if gotop:
                for mode in utils.unsplit_modes(setmodes):
                    irc.mode(channel, mode)
예제 #4
0
def seen(irc, event, args):
    """<nick>

    Returns the last action by <nick> that the bot has seen
    and how long ago.
    """
    try:
        nick = args[0]

    except IndexError:
        irc.reply(event, utils.gethelp("seen"))

    else:
        try:
            last = irc.state["users"][nick]["lastmsg"]
            hmask = irclib.NickMask(utils.gethm(irc, nick))
            if last["command"] == "pubmsg" or last["command"] == "pubnotice":  # \?
                irc.reply(
                    event,
                    '{} ({}@{}) was last seen {} ago in {} saying "{}"'.format(
                        nick, hmask.user, hmask.host, timesince(last["time"]), last["channel"], last["message"].strip()
                    ),
                )
            elif last["command"] == "join":
                irc.reply(
                    event,
                    "{} ({}@{}) was last seen {} ago joining {}".format(
                        nick, hmask.user, hmask.host, timesince(last["time"]), last["channel"]
                    ),
                )
            elif last["command"] == "part":
                irc.reply(
                    event,
                    "{} ({}@{}) was last seen {} ago leaving {} ({})".format(
                        nick, hmask.user, hmask.host, timesince(last["time"]), last["channel"], last["message"]
                    ),
                )
            elif last["command"] == "kick":
                irc.reply(
                    event,
                    "{} ({}@{}) was last seen {} ago being kicked from {} ({})".format(
                        nick, hmask.user, hmask.host, timesince(last["time"]), last["channel"], last["message"]
                    ),
                )
            elif last["command"] == "quit":
                irc.reply(
                    event,
                    "{} ({}@{}) was last seen {} ago quitting ({})".format(
                        nick, hmask.user, hmask.host, timesince(last["time"]), last["message"]
                    ),
                )
        except KeyError:
            irc.reply(event, "I have not seen {}".format(nick))
예제 #5
0
def enforce(irc, event, args):
    """[<channel>] <modes> <nick>

    Enforces a mode to <nick> in the current channel if no channel argument is given.
    """
    
    message = event.arguments[0].split()

    try:
        if irc.is_channel(message[1]):
            unrecognised_modes = []
            unset_modes = []
            set_modes = []
            mode_diff = "+"
            for pos, mode in enumerate(message[2]):
                if mode in utils.argmodes["set"] or mode in utils.argmodes["unset"] or mode in ["+", "-"]:
                    pass
                else: # What on earth is that mode?
                    unrecognised_modes.append(mode)
            for mode in message[2]:
                if mode == "+":
                    mode_diff = "+"
                elif mode == "-":
                    mode_diff = "-"
                else:
                    if mode_diff == "+":
                        if mode in unset_modes:
                            irc.reply(event, "This mode {} is already set and could not be unset for {}".format(mode, message[3]))
                        else:
                            set_modes.append(mode)
                    elif mode_diff == "-": # else but who cares?
                        if mode in set_modes:
                            irc.reply(event, "This mode {} is already set and could not be set for {}".format(mode, message[3]))
                        else:
                            unset_modes.append(mode)
            if unrecognised_modes:
                irc.reply(event, "I could not recognise these modes: {}".format("".join(unrecognised_modes)))
            else:
                if len(message) >= 4:
                    if not "enforce" in irc.channels[message[1]]:
                        irc.channels[message[1]]["enforce"] = {}
                    irc.channels[message[1]]["enforce"][message[3]] = {
                        "set": set_modes or "",
                        "unset": unset_modes or ""
                    }
                else:
                    irc.reply(event, "You didn't specify a nick to enforce modes to")
    except IndexError:
        irc.reply(event, utils.gethelp("enforce"))
예제 #6
0
def quiet(irc, event, args):
    """[<channel>] <nick|hostmask> [<nick|hostmask>...]

    Quiets <nick> in <channel>. <channel> is only necessary if the command
    isn't sent in the channel itself.
    """
    setmodes = []
    affected = []
    try:
        if utils.is_private(event):
            channel = args[0]
            nicks = args[1:]
        else:
            if irc.is_channel(args[0]):
                channel = args[0]
                nicks = args[1:]
            else:
                channel = event.target
                nicks = args

    except IndexError:
        irc.reply(event, utils.gethelp("quiet"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            for nick in nicks:
                if utils.is_hostmask(nick):
                    bmask = nick
                else:
                    bmask = utils.banmask(irc, nick)
                setmodes.append("+q {}".format(bmask))
                for affect in utils.ban_affects(irc, channel, bmask):
                    if affect not in affected and affect != irc.get_nick():
                        affected.append(affect)
            for nick in affected:
                if irc.is_opped(nick, channel):
                    setmodes.append("-o {}".format(nick))
                if irc.is_voiced(nick, channel):
                    setmodes.append("-v {}".format(nick))
            if len(setmodes) == 0:
                return
            already_op = irc.is_opped(irc.get_nick(), channel)
            if not already_op:
                setmodes.append("-o {}".format(irc.get_nick()))
            gotop = utils.getop(irc, channel)
            if gotop:
                for mode in utils.unsplit_modes(setmodes):
                    irc.mode(channel, mode)
예제 #7
0
def extract(irc, event, args):
	try:
		html = requests.get(args[0]).text
		soup = BeautifulSoup(html)
		for script in soup(["script", "style"]):
		    script.extract()
		text = soup.get_text()
		lines = (line.strip() for line in text.splitlines())
		chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
		text = '\n'.join(chunk for chunk in chunks if chunk)
		text = text.encode('ascii', 'ignore')
		irc.reply(event, (text[:350] + '..') if len(text) > 350 else text)
	except IndexError:
		irc.reply(event, utils.gethelp("extract"))
	except:
		irc.reply(event, "Error extracting informations")
예제 #8
0
def kick(irc, event, args):
    """[<channel>] <nick> [<nick>...] [:][<reason>]

    Kicks <nick> in <channel>. <channel> is only necessary if the
    command isn't sent in the channel itself. It is recommended to
    use ':' as a seperator between <nick> and <reason>, otherwise, if
    there's a nick in the channel matching the first word in reason it
    will be kicked.
    """
    prepare_nicks = []
    reason = None
    try:
        if utils.is_private(event):
            channel = args[0]
            nicks = args[1:]

        else:
            if irc.is_channel(args[0]):
                channel = args[0]
                nicks = args[1:]

            else:
                channel = event.target
                nicks = args

    except IndexError:
        irc.reply(event, utils.gethelp("kick"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            for nick in nicks:
                if nick in irc.state["channels"][channel]["names"] and nick not in prepare_nicks and not nick.startswith(":"):
                    prepare_nicks.append(nick)
                else:
                    reason = " ".join(nicks[len(prepare_nicks):]).lstrip(": ")
                    break
            nicks = prepare_nicks
            already_op = irc.is_opped(irc.get_nick(), channel)
            gotop = utils.getop(irc, channel)
            if gotop:
                for nick in nicks:
                    if reason:
                        irc.kick(channel, nick, reason)
                    else:
                        irc.kick(channel, nick)
                if not already_op:
                    irc.mode(channel, "-o {}".format(irc.get_nick()))
예제 #9
0
def deop(irc, event, args):
    """[<channel>] [<nick>...]

    Deops <nick> (or yourself if no <nick> is specified) in <channel>.
    <channel> is only necessary if the command isn't set in the channel
    itself.
    """
    setmodes = []
    try:
        if len(args) == 0:
            nicks = [event.source.nick]
            channel = event.target
        elif irc.is_channel(args[0]):
            channel = args[0]
            if len(args) > 1:
                nicks = args[1:]
            else:
                nicks = [event.source.nick]
        else:
            nicks = args
            channel = event.target

    except IndexError:
        irc.reply(event, utils.gethelp("deop"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            already_op = irc.is_opped(irc.get_nick(), channel)
            if "*" in nicks:
                nicks = irc.state["channels"][channel]["names"]
                if irc.get_nick() in nicks:
                    nicks.remove(irc.get_nick())
            if irc.channels[channel].get("chanserv", irc.chanserv) and "ChanServ" in nicks:
                nicks.remove("ChanServ")
            for nick in nicks:
                if irc.is_opped(nick, channel):
                    setmodes.append("-o {}".format(nick))
            if len(setmodes) == 0:
                return
            if not already_op:
                setmodes.append("-o {}".format(irc.get_nick()))
            gotop = utils.getop(irc, channel)
            if gotop:
                for mode in utils.unsplit_modes(setmodes):
                    irc.mode(channel, mode)
예제 #10
0
def sdevoice(irc, event, args):
    """[<channel>] [<nick>...]

    Devoices <nick> (or the bot if no <nick> is given) in <channel> using services.
    <channel> is only necessary if the command isn't sent in the channel itself.
    """
    try:
        if utils.is_private(event):
            channel = args[0]
            if len(args) > 1:
                nicks = args[1:]
            else:
                nicks = [irc.get_nick()]
        else:
            if len(args) > 0:
                if irc.is_channel(args[0]):
                    channel = args[0]
                    if len(args) > 1:
                        nicks = args[1:]
                    else:
                        nicks = [irc.get_nick()]
                else:
                    channel = event.target
                    nicks = args
            else:
                channel = event.target
                nicks = [irc.get_nick()]

    except IndexError:
        irc.reply(event, utils.gethelp("sdevoice"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            try:
                if irc.channels[channel].get("chanserv", irc.chanserv):
                    for nick in nicks:
                        if not irc.is_voiced(nick, channel):
                            nicks.remove(nick)
                    if len(nicks) > 0:
                        irc.privmsg("ChanServ", "DEVOICE {} {}".format(channel, " ".join(nicks)))
            except KeyError:
                pass
예제 #11
0
def factoid(irc, event, args):
    """<add|remove|list> [<channel>] <factoid> [<text>]

    Adds or removes a factoid for <channel> or globally.
    <channel> is only necessary if the command isn't sent in
    the channel itself, <text> is only necessary if adding a
    factoid. Global factoids are modified by sending the command
    in private with no <channel> specified.
    """
    try:
        if args[0] == "add":
            if irc.is_channel(args[1]):
                channel = args[1]
                factoid = args[2]
                text = " ".join(args[3:])
            elif irc.is_channel(event.target):
                channel = event.target
                factoid = args[1]
                text = " ".join(args[2:])
            else:
                channel = None
                factoid = args[1]
                text = " ".join(args[2:])

            if channel:
                if utils.is_allowed(irc, event.source, channel):
                    if "factoids" not in irc.channels[channel]:
                        irc.channels[channel]["factoids"] = {}
                    irc.channels[channel]["factoids"][factoid] = text
                    irc.reply(event, "Factoid {} added for '{}' in {}".format(factoid, text, channel))
            else:
                if utils.is_allowed(irc, event.source):
                    irc.factoids[factoid] = text
                    irc.reply(event, "Global factoid {} added for '{}'".format(factoid, text))

        elif args[0] == "remove":
            if irc.is_channel(args[1]):
                channel = args[1]
                factoid = args[2]
            elif irc.is_channel(event.target):
                channel = event.target
                factoid = args[1]
            else:
                channel = None
                factoid = args[1]

            if channel:
                if utils.is_allowed(irc, event.source, channel):
                    if "factoids" not in irc.channels[channel]:
                        irc.reply(event, "ERROR: No factoids exist for {}".format(channel))
                    elif factoid in irc.channels[channel]["factoids"]:
                        del (irc.channels[channel]["factoids"][factoid])
                        irc.reply(event, "Factoid {} deleted in {}".format(factoid, channel))
            else:
                if utils.is_allowed(irc, event.source):
                    if factoid in irc.factoids:
                        del (irc.factoids[factoid])
                        irc.reply(event, "Global factoid {} deleted".format(factoid))
                    else:
                        irc.reply(event, "ERROR: No global factoids named {} were found".format(factoid))
        elif args[0] == "list":
            if len(args) > 1:
                if irc.is_channel(args[1]):
                    channel = args[1]
                elif irc.is_channel(event.target):
                    channel = event.target
            elif irc.is_channel(event.target):
                channel = event.target
            else:
                channel = None
            if channel:
                if "factoids" in irc.channels[channel]:
                    irc.reply(
                        event,
                        "Factoids for {} are: {}".format(
                            channel, ", ".join(['"{}"'.format(x) for x in irc.channels[channel]["factoids"]])
                        ),
                    )
                else:
                    irc.reply(event, "No factoids were found for {}".format(channel))
            else:
                irc.reply(event, "Global factoids are: {}".format(", ".join(['"{}"'.format(x) for x in irc.factoids])))
    except (KeyError, IndexError):
        irc.reply(event, utils.gethelp("factoid"))
예제 #12
0
def alias(irc, event, args):
    """<add|remove|list> [<channel>] <alias> [<command>]

    Adds or removes an alias for <channel> or globally.
    <channel> is only necessary if the command isn't sent in
    the channel itself, <command> is only necessary if adding
    an alias. Global aliases are modified by sending the command
    in private with no <channel> specified.
    """
    try:
        if args[0] == "add":
            if irc.is_channel(args[1]):
                channel = args[1]
                alias = args[2]
                command = " ".join(args[3:])
            elif irc.is_channel(event.target):
                channel = event.target
                alias = args[1]
                command = " ".join(args[2:])
            else:
                channel = None
                alias = args[1]
                command = " ".join(args[2:])

            if channel:
                if utils.is_allowed(irc, event.source, channel):
                    if len(command) >= 2 and command.split()[0] in utils.commands: #and alias.lower() not in utils.commands:
                        if "aliases" not in irc.channels[channel]:
                            irc.channels[channel]["aliases"] = {}
                        if alias != alias.lower():
                            irc.reply(event, "The alias name has to be lowercase. Changing alias name...")
                            alias = alias.lower()
                        if alias in utils.commands:
                            irc.reply(event, "Alias \"{}\" is a command and cannot be overwritten".format(alias))
                        else:    
                            irc.channels[channel]["aliases"][alias] = command
                            irc.reply(event, "Alias \"{}\" with arguments \"{}\" added for command \"{}\" in \"{}\"".format(alias, " ".join(command.split()[1:]), command.split()[0], channel))
                    elif command.split()[0] in utils.commands and alias not in utils.commands:
                        if "aliases" not in irc.channels[channel]:
                            irc.channels[channel]["aliases"] = {}
                        if alias != alias.lower():
                            irc.reply(event, "The alias name has to be lowercase. Changing alias name...")
                            alias = alias.lower()
                        irc.reply(event, "testing")
                        irc.channels[channel]["aliases"][alias] = command
                        irc.reply(event, "Alias \"{}\" added for command \"{}\" in \"{}\"".format(alias, command, channel))
                    elif alias in utils.commands:
                        irc.reply(event, "A command with the name \"{}\" already exists".format(alias))
                    elif not command.split()[0] in utils.commands:
                        irc.reply(event, "No command called \"{}\" exists".format(command.split()[0]))
            else:
                if utils.is_allowed(irc, event.source) and command in utils.commands and alias not in utils.commands:
                    irc.aliases[alias] = command
                    irc.reply(event, "Global alias \"{}\" added for command \"{}/\"".format(alias, command))
                elif alias in utils.commands:
                    irc.reply(event, "A command with the name \"{}\" already exists".format(command))
                elif not command in utils.commands:
                    irc.reply(event, "No command called \"{}\" exists".format(command))
        elif args[0] == "remove":
            if irc.is_channel(args[1]):
                channel = args[1]
                alias = args[2]
            elif irc.is_channel(event.target):
                channel = event.target
                alias = args[1]
            else:
                channel = None
                alias = args[1]

            if channel:
                if utils.is_allowed(irc, event.source, channel):
                    if "aliases" not in irc.channels[channel]:
                        irc.reply(event, "ERROR: No aliases exist for \"{}\"".format(channel))
                    elif alias not in irc.channels[channel]["aliases"]:
                        irc.reply(event, "Alias \"{}\" does not exist in \"{}\"".format(alias, channel))
                    elif alias in irc.channels[channel]["aliases"]:
                        del(irc.channels[channel]["aliases"][alias])
                        irc.reply(event, "Alias \"{}\" deleted in \"{}\"".format(alias, channel))
            else:
                if utils.is_allowed(irc, event.source):
                    if alias in irc.aliases:
                        del(irc.aliases[alias])
                        irc.reply(event, "Global alias {} deleted".format(alias))
                    else:
                        irc.reply(event, "ERROR: No global aliases named {} were found".format(alias))
        elif args[0] == "list":
            if len(args) > 1:
                if irc.is_channel(args[1]):
                    channel = args[1]
                elif irc.is_channel(event.target):
                    channel = event.target
            elif irc.is_channel(event.target):
                channel = event.target
            else:
                channel = None
            if channel:
                if "aliases" in irc.channels[channel]:
                    irc.reply(event, "Aliases for {} are: {}".format(channel, ", ".join(["\"{}\"".format(x) for x in irc.channels[channel]["aliases"]])))
                else:
                    irc.reply(event, "No aliases were found for {}".format(channel))
            else:
                irc.reply(event, "Global aliases are: {}".format(", ".join(["\"{}\"".format(x) for x in irc.aliases])))
    except (KeyError, IndexError):
        irc.reply(event, utils.gethelp("alias"))
예제 #13
0
def kban(irc, event, args):
    """[<channel>] <nick|hostmask> [<nick|hostmask>...] [:][<reason>]

    Bans <nick> in <channel> and kicks anyone affected using <reason>
    as the kick message if specified. <channel> is only necessary if
    the command isn't sent in the channel itself. It is recommended to
    use ':' as a seperator between <nick> and <reason>, otherwise, if
    there's a nick in the channel matching the first word in reason it
    will be kicked.
    """
    prepare_nicks = []
    setmodes = []
    affected = []
    reason = None
    try:
        if utils.is_private(event):
            channel = args[0]
            nicks = args[1:]

        else:
            if irc.is_channel(args[0]):
                channel = args[0]
                nicks = args[1:]

            else:
                channel = event.target
                nicks = args

    except IndexError:
        irc.reply(event, utils.gethelp("kban"))

    else:
        if utils.is_allowed(irc, event.source, channel):
            for nick in nicks:
                if nick in irc.state["channels"][channel]["names"] and nick not in prepare_nicks and not nick.startswith(":"):
                    prepare_nicks.append(nick)
                elif utils.is_hostmask(nick):
                    prepare_nicks.append(nick)
                else:
                    reason = " ".join(nicks[len(prepare_nicks):]).lstrip(": ")
                    break
            nicks = prepare_nicks
            for nick in nicks:
                if utils.is_hostmask(nick):
                    bmask = nick
                else:
                    bmask = utils.banmask(irc, nick)
                setmodes.append("+b {}".format(bmask))
                for affect in utils.ban_affects(irc, channel, bmask):
                    if affect not in affected and affect != irc.get_nick():
                        if irc.is_opped(affect, channel):
                            setmodes.append("-o {}".format(affect))
                        if irc.is_voiced(affect, channel):
                            setmodes.append("-v {}".format(affect))
                        affected.append(affect)
            if len(setmodes) == 0:
                return
            already_op = irc.is_opped(irc.get_nick(), channel)
            gotop = utils.getop(irc, channel)
            if gotop:
                for mode in utils.unsplit_modes(setmodes):
                    irc.mode(channel, mode)
                for nick in affected:
                    if reason:
                        irc.kick(channel, nick, reason)
                    else:
                        irc.kick(channel, nick)
                if not already_op:
                    irc.mode(channel, "-o {}".format(irc.get_nick()))