Ejemplo n.º 1
0
                    "Number of messages to purge must be a positive integer.")
        return
    async for msg in client.logs_from(message.channel,
                                      limit=int(parameters) + 1):
        try:
            await client.delete_message(msg)
        except:
            pass
    success_msg = await client.send_message(
        message.channel,
        "Successfully purged **" + parameters + "** messages! :thumbsup:")
    await asyncio.sleep(2)
    await client.delete_message(success_msg)


client.command(pass_context=True)


async def serverinfo(message, parameters, recursion=0):
    server = message.server
    text = 0
    voice = 0
    for channel in server.channels:
        if channel.type == discord.ChannelType.text:
            text += 1
        elif channel.type == discord.ChannelType.voice:
            voice += 1
    msg = "```autohotkey\n"
    msg += '                id: {server.id}\n'
    msg += '       server name: {server.name}\n'
    try:
Ejemplo n.º 2
0
    await channel.send(embed=lem.get_embed())


#@client.command(pass_context=True)
async def test(context):
    author = context.message.author
    channel = context.message.channel
    guild = context.message.channel.guild
    if (author.id != JOHNYS_ID and author.id != GHOSTS_ID):
        await context.channel.send("it works")
        return

    await context.channel.send(embed=lem.get_embed())


test = client.command(test)


def get_datetime(timestamp):
    utc = timestamp.replace(tzinfo=timezone('UTC'))
    est = utc.astimezone(timezone('US/Eastern'))
    return est


@client.event
async def on_member_join(member):
    print("%s joined guild: %s" % (member.name, member.guild.name))
    try:
        default_role = discord.utils.get(
            member.guild.roles, id=settings_dict[member.guild].default_role_id)
        await client.add_roles(member, default_role)
Ejemplo n.º 3
0
Archivo: bot.py Proyecto: cxr00/Zote
def initialize_commands(zote: Bot, cfg: Index, dat: dict):

    reactions = dat["reactions"]
    text = dat["text"]
    img = dat["img"]
    che = dat["cache"]
    cogs = dat["cog"]

    def logger(category, reaction):
        def wrap(f):
            def has_permissions(ctx):
                global cooldown
                global lim
                ch_name = ctx.message.channel.name if ctx.message.channel else "DM"
                ch_id = ctx.message.channel.id if ctx.message.channel else None
                s_id = ctx.message.server.id if ctx.message.server else None
                u_id = ctx.message.author.id

                if u_id in cfg["permamute"]:
                    return False
                elif u_id in cfg["mods"]:
                    return True
                elif category == "devplus":
                    return u_id in cfg["devs"]
                elif category == "artsquad":
                    return u_id in cfg["artsquad"] and s_id == cfg["zdn"][
                        "server"]
                elif u_id in cfg["ignored"] or ch_id in cfg["silenced"]:
                    return False
                elif (s_id in cfg
                      and u_id in cfg[s_id]) and category == "clear":
                    return True
                elif isinstance(
                        ctx.message.channel,
                        PrivateChannel) or s_id != cfg["init"]["server"]:
                    return category != "modonly" and cooldown < lim
                elif "clear" != category != "modonly":
                    return ch_name in cfg[category] and cooldown < lim
                else:
                    return False

            async def wrapped(ctx, *args):
                nonlocal che
                ch_id = ctx.message.channel.id if ctx.message.channel else None
                s_id = ctx.message.server.id if ctx.message.server else None

                global cooldown

                if not has_permissions(ctx):
                    print(
                        f"Permission check failed for {f.__name__} by {ctx.message.author.name}#{ctx.message.author.discriminator}"
                    )
                    await zote.add_reaction(ctx.message, reactions["no"])
                else:
                    try:
                        try:
                            log_command_usage(f.__name__, ctx)
                        except Exception:
                            # Yes I know, I'm sorry
                            print(">>>> log error")
                        cooldown += 1
                        await add_reactions(zote, ctx.message, reactions,
                                            reaction)
                        args = await sanitize(zote, ctx.message.channel, *args)
                        await f(ctx, *args)
                        if s_id and "_meme" not in f.__name__ and f.__name__ != "meta":
                            record_msg(ctx.message)
                            while len(che[ch_id]) > 6:
                                try:
                                    m = await zote.get_message(
                                        ctx.message.channel,
                                        che[ch_id].get(index=0).tag)
                                    await zote.delete_message(m)
                                except NotFound:
                                    pass
                                except Forbidden:
                                    pass
                                che[ch_id].remove(0)
                            che.save(echo=False)
                        if f.__name__ in cfg["flaggers"]:
                            cfg.save(echo=False)
                        cooldown -= 1
                    except Exception as exc:
                        log_error_message(f.__name__, exc)
                        cooldown -= 1
                        try:
                            await zote.add_reaction(ctx.message,
                                                    reactions["no"])
                        except Forbidden:
                            pass

            return wrapped

        return wrap

    def record_msg(m: Message):
        if not m.server:
            return
        nonlocal che
        if m.server.id:
            if m.channel.id:
                if m.channel.id in che:
                    if m.id not in che[m.channel.id]:
                        che[m.channel.id] += Property(m.id)
                else:
                    che += Qoid(tag=m.channel.id)
                    che[m.channel.id] += Property(m.id)
                che.save(echo=False)

    def add_bot_cogs():
        @zote.group(pass_context=True)
        async def cog(ctx):
            pass

        @cog.command(name="test", pass_context=True)
        @logger("modonly", ["zote"])
        async def cog_test(ctx, *args):
            await zote.say("Yup")

        @cog.command(name="view", pass_context=True)
        @logger("modonly", ["zote"])
        async def cog_view(ctx, *args):
            cog_name = args[0]
            try:
                ret = cogs[cog_name]
                await zote.say(f"```{str(ret)}```")
            except QoidError:
                await zote.add_reaction(ctx.message, reactions["no"])

        @cog.command(name="create", pass_context=True)
        @logger("modonly", ["zote"])
        async def cog_create(ctx, *args):
            nonlocal cogs
            cog_name = args[0]
            if cog_name not in cogs:
                cogs += Qoid(cog_name)
                cogs.save(echo=False)
                await zote.say("Done")
            else:
                await zote.say("Already exists")
            pass

        @cog.command(name="add", pass_context=True)
        @logger("modonly", ["zote"])
        async def cog_add(ctx, cog_name, cog_tag, cog_val, *args):
            nonlocal cogs
            del args  # Ignored parameters
            try:
                # cog_name = args[0]
                # cog_tag = args[1]
                # cog_val = args[2]
                cogs[cog_name] += Property(cog_tag, cog_val)
                cogs.save(echo=False)
            except IndexError:
                await zote.add_reaction(ctx.message, reactions["no"])

    add_bot_cogs()

    @zote.command(name="ignore", pass_context=True, hidden=True)
    @logger("modonly", ["happygrub"])
    async def ignore(ctx, user, *args):
        """Ignore users based on their ID
        """
        del args  # Ignored parameters
        try:
            if user.id in cfg["mods"]:
                print("Cannot ignore moderators or administrators")
                await zote.add_reaction(ctx, reactions["no"])
            elif user.id not in cfg["ignored"]:
                cfg["ignored"] += Property(tag=user.id, val=None)
                await zote.say(f"Now ignoring {str(user)}")
            else:
                cfg["ignored"] -= user.id
                await zote.say(f"Stopped ignoring {str(user)}")
        except NotFound:
            print("Could not find user")
        except HTTPException:
            print("HTTP error of some sort")

    @zote.command(name="silence", pass_context=True, hidden=True)
    @logger("modonly", ["happygrub"])
    async def silence(ctx, user, *args):
        del args  # Ignored parameters
        if user.id not in cfg["silenced"]:
            cfg["silenced"] += Property(tag=user.id, val=None)
            await zote.add_reaction(ctx.message, reactions["on"])
        else:
            cfg["silenced"] -= user.id
            await zote.add_reaction(ctx.message, reactions["off"])

    @zote.command(name="ignorelist", pass_context=True, hidden=True)
    @logger("modonly", ["happygrub"])
    async def ignorelist(ctx, *args):
        del ctx, args  # ignored parameters
        if len(cfg["ignored"]) > 0:
            out = "**Ignored members**\n"
            for u_id in cfg["ignored"]:
                u = await zote.get_user_info(u_id)
                out += f"{u.name}#{u.discriminator}: {u_id}\n"
            await zote.say(out)
        else:
            await zote.say("No ignored members. Good!")

    @zote.command(name="clear", pass_context=True, hidden=True)
    @logger("clear", [])
    async def clear(ctx, *args):
        if not args:
            await zote.add_reaction(ctx.message, reactions["dunq"])
            return
        del_cmd = False
        del_limit = 500
        # Step 0: gather from args
        delcount = 1
        arg1 = arg2 = None
        try:
            delcount = del_limit if args[0] == "all" else int(args[0])
            if delcount > del_limit:
                print(f"Delete count limited to {del_limit}")
                delcount = del_limit
        except ValueError:
            pass
        if len(args) > 1:
            arg1 = args[1]
            if len(args) > 2:
                arg2 = args[2]

        ch = ctx.message.channel
        us = None
        # Step 1: Guarantee parameter submission is appropriate
        # Note that multiple channels or users will be consumed
        if arg1:
            if isinstance(arg1, Channel):
                ch = arg1
            elif isinstance(arg1, User):
                us = arg1.id

            if isinstance(arg2, Channel):
                ch = arg2
            elif isinstance(arg2, User):
                us = arg2.id
        if not ch:
            ch = zote.get_channel(ctx.message.channel.id)

        if ch.id not in cfg["clear whitelist"] and ch.server.id == cfg["init"][
                "server"]:
            await zote.add_reaction(ctx.message, reactions["no"])
            return

        bf = None
        counter = 0
        marked = []

        try:
            while counter < delcount:
                prev = bf
                async for msg in zote.logs_from(channel=ch,
                                                limit=100,
                                                before=bf,
                                                after=None):
                    if not msg.pinned:
                        if us:
                            if msg.author.id == us:
                                if ctx.message.id == msg.id:
                                    del_cmd = True
                                marked.append(msg)
                                counter += 1
                        else:
                            if ctx.message.id == msg.id:
                                del_cmd = True
                            marked.append(msg)
                            counter += 1
                    bf = msg
                    if counter == delcount:
                        break
                    elif len(marked) == 100:
                        await zote.delete_messages(marked)
                        marked = []
                if prev == bf:
                    break
            if not marked:
                pass
            elif len(marked) == 1:
                await zote.delete_message(marked[0])
            else:
                await zote.delete_messages(marked)
            print(f"{counter} messages cleared")
            if not del_cmd:
                await zote.add_reaction(ctx.message, reactions["yes"])
        except DiscordException as de:
            for e in marked:
                try:
                    await zote.delete_message(e)
                except DiscordException:
                    pass
            print(f">>> >>> {de}")
            if not del_cmd:
                await zote.add_reaction(ctx.message, reactions["dunq"])

    @zote.command(name="members",
                  pass_context=True,
                  hidden=True,
                  aliases=["membercount"])
    @logger("modonly", ["happygrub"])
    async def member_count(ctx, *args):
        del args  # ignored parameters
        m = await zote.say(
            f"**{ctx.message.server.member_count}** members in the server.")
        record_msg(m)

    ###############################
    """CHANNEL-SPECIFIC COMMANDS"""
    ###############################

    @zote.command(name="gitgud", pass_context=True, aliases=["waifu"])
    @logger("meme", ["zote"])
    async def gitgud(ctx, *args):
        del args  # ignored parameters
        chance = randint(0, 10)
        if chance <= 1 or ctx.message.author.id in cfg["mods"] + cfg[
                "woke"] + cfg["devs"] + cfg["hunger"]:
            await zote.add_reaction(ctx.message, reactions["hollowwoke"])
            m = await zote.say(embed=img["reaction"]["gitwoke.jpg"])
            record_msg(m)
        else:
            m = await zote.say(embed=img["reaction"]["gitgud.png"])
            record_msg(m)

    @zote.command(name="random",
                  pass_context=True,
                  aliases=["randomizer", "seed"])
    @logger("speedrunning", ["primalaspid"])
    async def randomizerseed(ctx, *args):
        seed = [randint(1, 9)]
        for k in range(8):
            seed.append(randint(0, 9))
        g = ""
        for each in seed:
            g += str(each)
        if len(args) > 0 and args[0] == "m":
            m = await zote.send_message(
                ctx.message.author,
                f"Your randomizer seed is {g}. {text['randomizer']()}")
            record_msg(m)
        else:
            m = await zote.say(
                f"Your randomizer seed is {g}. {text['randomizer']()}")
            record_msg(m)

    @zote.command(name="wiki",
                  pass_context=True,
                  aliases=["askzote", "<:dunq:335555573481472000>"])
    @logger("ref", ["zote"])
    async def wiki(ctx, *args):
        if len(args) == 0:
            await zote.say(f"{wiki_str}Zote, The Mighty")
        else:
            r = args[0]
            for each in args[1:]:
                r = f"{r} {each.lower()}"
            query = wiki_search(r)
            if query == "None found":
                await zote.add_reaction(ctx.message, reactions["no"])
            else:
                m = await zote.say(f"<{query}>")
                record_msg(m)

    #####################
    """ZOTE'S PRECEPTS"""
    #####################

    zote.precept_num = randint(0, 56)

    @zote.command(name="precept",
                  pass_context=True,
                  aliases=["wisdom", "<:zote:371947495330414595>"])
    @logger("meme", ["zote"])
    async def precept(ctx, *args):
        """Hear the precepts of Zote!

         Specify a number from 1 to 57
         for a specific precept,
         or hear them in order.`
        """
        del ctx  # ignored parameters
        if len(args) > 0 and args[0].isnumeric():
            p = cfg["precepts"].get(index=(int(args[0]) - 1) % 57)
        else:
            p = cfg["precepts"].get(index=zote.precept_num)
            zote.precept_num += 1
        m = await zote.say(f"Precept {p}")
        record_msg(m)

    #################
    """ENEMY ICONS"""
    #################

    @zote.command(name="enemy",
                  pass_context=True,
                  aliases=["monster", "hj", "hunter", "hunterjournal"])
    @logger("ref", ["zote"])
    async def enemy(ctx, *args):
        """See enemy icons! Shows Zote by default, but specify the enemy name (e.g Primal Aspid) to see its icon."""
        if len(args) == 0:
            await zote.add_reaction(ctx.message, reactions["zote"])
        else:
            r = args[0].capitalize()
            for each in args[1:]:
                r = f"{r}_{each.capitalize()}"
            get = img["hj"][r + ".png"]
            if get is not None:
                get.description = r.replace("_", " ")
                m = await zote.say(embed=get)
                record_msg(m)
            else:
                await zote.add_reaction(ctx.message, reactions["primalaspid"])

    @zote.command(name="meta", pass_context=True, hidden=True, aliases=[])
    @logger("meme", [])
    async def meta_command(ctx, *args):
        del args  # ignored parameters
        await zote.delete_message(ctx.message)

    ##################
    # IMAGE COMMANDS #
    ##################

    def get_kind(data):
        async def multi_cmd(ctx, *args):
            del args  # ignored parameters
            em = img.r(data["loc"])
            m = await zote.send_message(destination=ctx.message.channel,
                                        embed=em)
            record_msg(m)
            # if m.author.d == cfg["init"]["zote"]:
            #     if len(m.embeds) > 0:
            #         if m.embeds[0]["image"]["width"] == 0:
            #             print(f">>>>> Missing link at {m.embeds[0]['image']['url']}")
            #             img.remove_image(data["loc"], m.embeds[0]["image"]["url"])

        async def single_cmd(ctx, *args):
            del args  # ignored parameters
            em = img[data["loc"]][data["img"]]
            m = await zote.send_message(destination=ctx.message.channel,
                                        embed=em)
            record_msg(m)

        async def text_cmd(ctx, *args):
            del args  # ignored parameters
            cnt = text[data["loc"]]
            m = await zote.send_message(destination=ctx.message.channel,
                                        content=cnt)
            record_msg(m)

        if data["kind"] == "multi":
            return multi_cmd
        elif data["kind"] == "single":
            return single_cmd
        elif data["kind"] == "text":
            return text_cmd

    for e in cogs:
        try:
            if e.tag:
                # retrieve appropriate function from data
                cmd = get_kind(e)
                cmd.__name__ = e.tag

                # apply parameterized wrapper from logger
                cmd = logger(e["category"], e.all_of("reaction"))(cmd)

                # submit command to client
                zote.command(name=e.tag,
                             pass_context=True,
                             aliases=e.all_of("alias"))(cmd)
        except QoidError:
            print(
                f"Ignoring read exception in #{e.tag}, command was not completed"
            )
        except ClientException as dece:
            print(f"Issue adding command {e.tag}, check aliases", dece)

    #####################
    # IMAGE SUBMISSIONS #
    #####################

    async def clone_img_loc(ctx_message,
                            msg_from,
                            ch_to,
                            del_old=False,
                            kill_meme=False):
        atch = msg_from.attachments[0]
        u = atch["url"]
        u_ext = u.rsplit('.', 1)[-1]
        img_data = requests.get(u).content
        with open(f"data/t-{msg_from.id}.{u_ext}", 'wb+') as img_file:
            img_file.write(img_data)
        ref = await zote.send_file(destination=ch_to,
                                   fp=f"data/t-{msg_from.id}.{u_ext}",
                                   filename=f"{msg_from.id}.{u_ext}")
        if cfg["zdn"]["ded-meme"] != ch_to.id != cfg["zdn"][
                "artist-exclusions"]:
            img.add_image(ch_to.name, ref.attachments[0]["url"])
        await zote.delete_message(ctx_message)
        if del_old:
            ch_from = ctx_message.channel.name
            img.remove_image(
                ch_from,
                u.rsplit("/", 1)[0] if eval(img[ch_from]["tagged"]) else u)
            await zote.delete_message(msg_from)
        os.remove(f"data/t-{msg_from.id}.{u_ext}")

    @zote.command(name="accept", hidden=True, pass_context=True, aliases=["a"])
    @logger("modonly", ["zote"])
    async def accept_meme(ctx, msg, *args):
        repo = args[0] if len(args) else zote.get_channel(cfg["zdn"]["meme"])
        if msg and repo:
            await accept_and_log_meme(
                zote, img, msg, repo, f"Accepted by moderator to #{repo.name}")
            await zote.delete_message(ctx.message)
        else:
            await zote.add_reaction(ctx.message, reactions["no"])

    @zote.command(name="exclude", hidden=True, pass_context=True, aliases=[])
    @logger("artsquad", ["zote"])
    async def exclude_meme(ctx, msg_from: Message, *args):
        del args  # Ignored parameters
        await clone_img_loc(ctx.message,
                            msg_from,
                            zote.get_channel(cfg["zdn"]["artist-exclusions"]),
                            del_old=True)

    @zote.command(name="clone", hidden=True, pass_context=True, aliases=["c"])
    @logger("modonly", ["zote"])
    async def clone_meme(ctx, msg_from: Message, ch_to: Channel, *args):
        del args  # Ignored parameters
        await clone_img_loc(ctx.message, msg_from, ch_to)

    @zote.command(name="delete", hidden=True, pass_context=True, aliases=["d"])
    @logger("modonly", ["zote"])
    async def delete_meme(ctx, msg, *args):
        del args  # Ignored parameters
        n = ctx.message.channel.name
        a = msg.attachments[0]["url"]
        img.remove_image(n,
                         a.rsplit("/", 1)[0] if eval(img[n]["tagged"]) else a)
        await zote.delete_message(ctx.message)
        await zote.delete_message(msg)

    @zote.command(name="deletelink",
                  hidden=True,
                  pass_context=True,
                  aliases=["dl"])
    @logger("modonly", ["zote"])
    async def delete_by_link(ctx, link, *args):
        """
        This is sort of broken right now
        """
        del args  # Ignored parameters
        bf = ctx.message
        link = link.replace("https://", "")
        if ctx.message.server.id == cfg["zdn"]["server"]:
            found = False
            while not found:
                prev = bf
                async for msg in zote.logs_from(channel=ctx.message.channel,
                                                limit=100,
                                                before=bf,
                                                after=None):
                    for each in msg.attachments:
                        if link == each['url']:
                            await zote.delete_message(msg)
                            img.remove_image(ctx.message.channel.name, link)
                            img.save_source(echo=False)
                            found = True
                            break
                    bf = msg
                if prev == bf:
                    try:
                        img.remove_image(ctx.message.channel.name, link)
                    except QoidError:
                        pass
                    await zote.delete_message(ctx.message)
                    break

    @zote.command(name="deletthis", hidden=True, pass_context=True, aliases=[])
    @logger("meme", ["zote"])
    async def delet_this(ctx, *args):
        del args  # ignored parameters
        if len(ctx.message.embeds) > 0:
            for each in ctx.message.embeds:
                em = each["url"]
                await zote.send_message(zote.delet, content=em)

    @zote.command(name="move", hidden=True, pass_context=True, aliases=["m"])
    @logger("modonly", ["zote"])
    async def move_meme(ctx, msg_from, ch_to, *args):
        del args  # Ignored parameters
        await clone_img_loc(ctx.message, msg_from, ch_to, del_old=True)

    @zote.command(name="reject", hidden=True, pass_context=True, aliases=["r"])
    @logger("modonly", ["zote"])
    async def reject_meme(ctx, msg, *args):
        reason = ctx.message.content.split(
            " ", 2)[2] if len(args) >= 2 else "Rejected by moderator"
        await reject_and_log_meme(zote, msg, reason)
        await zote.delete_message(ctx.message)

    @zote.command(name="submit", hidden=True, pass_context=True, aliases=[])
    @logger("meme", ["zote"])
    async def submit_meme(ctx, *args):
        del args  # ignored parameters
        if ctx.message.server.id == cfg["zdn"][
                "server"] or ctx.message.author.id in cfg["mods"]:
            u_name = ctx.message.author.name
            u_id = ctx.message.author.id
            if len(ctx.message.attachments) > 0:
                for each in ctx.message.attachments:
                    await submit_and_mark_meme(zote, each, f"{u_name}: {u_id}",
                                               reactions)
            elif len(ctx.message.embeds) > 0:
                for each in ctx.message.embeds:
                    await submit_and_mark_meme(zote, each, f"{u_name}: {u_id}",
                                               reactions)
        else:
            await zote.add_reaction(ctx.message, reactions["dunq"])

    @zote.command(name="embed",
                  hidden=False,
                  pass_context=True,
                  aliases=["em"])
    @logger("meme", ["zote"])
    async def get_embed(ctx, m: Message, *args):
        del ctx, args  # ignored parameters
        for em in m.embeds:
            m = await zote.say(f"```\n{em}\n```")
            record_msg(m)

    @zote.command(name="echo", hidden=True, pass_context=True, aliases=[])
    @logger("modonly", ["yes"])
    async def echo_thing(ctx, *args):
        del ctx
        o = ' '.join(args)
        m = await zote.send_message(destination=zote.meme, content=o)
        record_msg(m)

    @zote.command(name="neglect",
                  hidden=True,
                  pass_context=True,
                  aliases=["kill", "stop"])
    @logger("modonly", ["zote", "primalaspid"])
    async def neglect(ctx, *args):
        exit()