Beispiel #1
0
    async def botinfo(self, ctx):
        logger.info("command: botinfo")

        await channel_setup(ctx)
        await user_setup(ctx)

        embed = discord.Embed(type="rich", colour=discord.Color.blurple())
        embed.set_author(name="Bird ID - An Ornithology Bot")
        embed.add_field(
            name="Bot Info",
            value="This bot was created by EraserBird and person_v1.32 " +
            "for helping people practice bird identification for Science Olympiad.\n"
            +
            "**By adding this bot to a server, you are agreeing to our `Privacy Policy` and `Terms of Service`**.\n"
            +
            "<https://github.com/tctree333/Bird-ID/blob/master/PRIVACY.md>, " +
            "<https://github.com/tctree333/Bird-ID/blob/master/TERMS.md>",
            inline=False)
        embed.add_field(
            name="Support",
            value="If you are experiencing any issues, have feature requests, "
            +
            "or want to get updates on bot status, join our support server below.",
            inline=False)
        embed.add_field(
            name="Stats",
            value=
            f"This bot can see {len(self.bot.users)} users and is in {len(self.bot.guilds)} servers. "
            +
            f"There are {int(database.zcard('users:global'))} active users in {int(database.zcard('score:global'))} channels. "
            +
            f"The WebSocket latency is {str(round((self.bot.latency*1000)))} ms.",
            inline=False)
        await ctx.send(embed=embed)
        await ctx.send("https://discord.gg/fXxYyDJ")
Beispiel #2
0
async def get_sciname(bird, session=None):
    logger.info(f"getting sciname for {bird}")
    async with contextlib.AsyncExitStack() as stack:
        if session is None:
            session = await stack.enter_async_context(aiohttp.ClientSession())
        try:
            code = await get_taxon(bird, session)
        except GenericError as e:
            if e.code == 111:
                code = bird
            else:
                raise

        sciname_url = SCINAME_URL.format(urllib.parse.quote(code))
        async with session.get(sciname_url) as sciname_response:
            if sciname_response.status != 200:
                raise GenericError(
                    f"An http error code of {sciname_response.status} occured" +
                    f" while fetching {sciname_url} for {code}",
                    code=201
                )
            sciname_data = await sciname_response.json()
            try:
                sciname = sciname_data[0]["sciName"]
            except IndexError:
                raise GenericError(f"No sciname found for {code}", code=111)
    logger.info(f"sciname: {sciname}")
    return sciname
Beispiel #3
0
 async def botinfo(self, ctx):
     logger.info("command: botinfo")
     
     await channel_setup(ctx)
     await user_setup(ctx)
     
     embed = discord.Embed(type="rich", colour=discord.Color.blurple())
     embed.set_author(name=bot_name)
     embed.add_field(
         name="Bot Info",
         value="This bot was created by EraserBird, person_v1.32 and hmmm" +
         "for helping people practice fossil identification for Science Olympiad.",
         inline=False
     )
     embed.add_field(
         name="Support",
         value="If you are experiencing any issues, have feature requests, " +
         "or want to get updates on bot status, join our support server below.",
         inline=False
     )
     embed.add_field(
         name="Stats",
         value=f"This bot can see {len(self.bot.users)} users and is in {len(self.bot.guilds)} servers. " +
         f"There are {int(database.zcard('users:global'))} active users in {int(database.zcard('score:global'))} channels. " +
         f"The WebSocket latency is {str(round((self.bot.latency*1000)))} ms.",
         inline=False
     )
     await ctx.send(embed=embed)
     await ctx.send("https://discord.gg/husFeGG")
Beispiel #4
0
async def get_image(ctx, bird, addOn=None):
    # fetch scientific names of birds
    try:
        sciBird = await get_sciname(bird)
    except GenericError:
        sciBird = bird
    images = await get_files(sciBird, "images", addOn)
    logger.info("images: " + str(images))
    prevJ = int(str(database.hget(f"channel:{str(ctx.channel.id)}", "prevJ"))[2:-1])
    # Randomize start (choose beginning 4/5ths in case it fails checks)
    if images:
        j = (prevJ + 1) % len(images)
        logger.debug("prevJ: " + str(prevJ))
        logger.debug("j: " + str(j))

        for x in range(j, len(images)):  # check file type and size
            image_link = images[x]
            extension = image_link.split('.')[-1]
            logger.debug("extension: " + str(extension))
            statInfo = os.stat(image_link)
            logger.debug("size: " + str(statInfo.st_size))
            if extension.lower() in valid_image_extensions and statInfo.st_size < 8000000:  # 8mb discord limit
                logger.info("found one!")
                break
            elif x == len(images) - 1:
                j = (j + 1) % (len(images))
                raise GenericError("No Valid Images Found", code=999)

        database.hset(f"channel:{str(ctx.channel.id)}", "prevJ", str(j))
    else:
        raise GenericError("No Images Found", code=100)

    return [image_link, extension]
Beispiel #5
0
async def download_media(bird, media_type, addOn="", directory=None, session=None):
    if directory is None:
        directory = f"cache/{media_type}/{bird}{addOn}/"

    if addOn == "female":
        sex = "f"
    else:
        sex = ""

    if addOn == "juvenile":
        age = "j"
    else:
        age = ""

    if media_type == "images":
        media = "p"
    elif media_type == "songs":
        media = "a"

    async with contextlib.AsyncExitStack() as stack:
        if session is None:
            session = await stack.enter_async_context(aiohttp.ClientSession())
        urls = await _get_urls(session, bird, media, sex, age)
        if not os.path.exists(directory):
            os.makedirs(directory)
        paths = [f"{directory}{i}" for i in range(len(urls))]
        filenames = await asyncio.gather(*(_download_helper(path, url, session) for path, url in zip(paths, urls)))
        logger.info(f"downloaded {media_type} for {bird}")
        logger.info(f"filenames: {filenames}")
        return filenames
Beispiel #6
0
async def get_song(ctx, bird):
    # fetch scientific names of birds
    try:
        sciBird = await get_sciname(bird)
    except GenericError:
        sciBird = bird
    songs = await get_files(sciBird, "songs")
    logger.info("songs: " + str(songs))
    prevK = int(str(database.hget(f"channel:{str(ctx.channel.id)}", "prevK"))[2:-1])
    # Randomize start (choose beginning 4/5ths in case it fails checks)
    if songs:
        k = (prevK + 1) % len(songs)
        logger.debug("prevK: " + str(prevK))
        logger.debug("k: " + str(k))

        for x in range(k, len(songs)):  # check file type and size
            song_link = songs[x]
            extension = song_link.split('.')[-1]
            logger.debug("extension: " + str(extension))
            statInfo = os.stat(song_link)
            logger.debug("size: " + str(statInfo.st_size))
            if extension.lower() in valid_audio_extensions and statInfo.st_size < 8000000:  # 8mb discord limit
                logger.info("found one!")
                break
            elif x == len(songs) - 1:
                k = (k + 1) % (len(songs))
                raise GenericError("No Valid Songs Found", code=999)

        database.hset(f"channel:{str(ctx.channel.id)}", "prevK", str(k))
    else:
        raise GenericError("No Songs Found", code=100)

    return [song_link, extension]
Beispiel #7
0
async def precache():
    logger.info("Starting caching")
    with ProcessPoolExecutor(max_workers=4) as executor:
        async with aiohttp.ClientSession() as session:
            await asyncio.gather(*(fetch_images(fossil, session, executor)
                                   for fossil in fossils_list))
    logger.info("Finished caching")
Beispiel #8
0
async def channel_setup(ctx):
    logger.info("checking channel setup")
    if database.exists(f"channel:{str(ctx.channel.id)}"):
        logger.info("channel data ok")
    else:
        database.hmset(
            f"channel:{str(ctx.channel.id)}", {
                "bird": "",
                "answered": 1,
                "sBird": "",
                "sAnswered": 1,
                "goatsucker": "",
                "gsAnswered": 1,
                "prevJ": 20,
                "prevB": "",
                "prevS": "",
                "prevK": 20
            }
        )
        # true = 1, false = 0, index 0 is last arg, prevJ is 20 to define as integer
        logger.info("channel data added")
        await ctx.send("Ok, setup! I'm all ready to use!")

    if database.zscore("score:global", str(ctx.channel.id)) is not None:
        logger.info("channel score ok")
    else:
        database.zadd("score:global", {str(ctx.channel.id): 0})
        logger.info("channel score added")
Beispiel #9
0
    async def userscore(self, ctx, *, user: typing.Optional[typing.Union[discord.Member, str]] = None):
        logger.info("command: userscore")

        await channel_setup(ctx)
        await user_setup(ctx)

        if user is not None:
            if isinstance(user, str):
                await ctx.send("Not a user!")
                return
            usera = user.id
            logger.info(usera)
            if database.zscore("users:global", str(usera)) is not None:
                times = str(int(database.zscore("users:global", str(usera))))
                user = f"<@{str(usera)}>"
            else:
                await ctx.send("This user does not exist on our records!")
                return
        else:
            if database.zscore("users:global", str(ctx.author.id)) is not None:
                user = f"<@{str(ctx.author.id)}>"
                times = str(int(database.zscore("users:global", str(ctx.author.id))))
            else:
                await ctx.send("You haven't used this bot yet! (except for this)")
                return

        embed = discord.Embed(type="rich", colour=discord.Color.blurple())
        embed.set_author(name="Bird ID - An Ornithology Bot")
        embed.add_field(name="User Score:", value=f"{user} has answered correctly {times} times.")
        await ctx.send(embed=embed)
Beispiel #10
0
def _black_and_white(input_image_path):
    logger.info("black and white")
    with Image.open(input_image_path) as color_image:
        bw = color_image.convert('L')
        final_buffer = BytesIO()
        bw.save(final_buffer, "png")
    final_buffer.seek(0)
    return final_buffer
Beispiel #11
0
 async def send_as_bot(self, ctx, *, args):
     logger.info("command: send")
     logger.info(f"args: {args}")
     channel_id = int(args.split(' ')[0])
     message = args.strip(str(channel_id))
     channel = self.bot.get_channel(channel_id)
     await channel.send(message)
     await ctx.send("Ok, sent!")
Beispiel #12
0
 async def view(self, ctx):
     logger.info("command: view session")
     
     await channel_setup(ctx)
     await user_setup(ctx)
     
     if database.exists(f"session.data:{str(ctx.author.id)}"):
         await self._send_stats(ctx)
     else:
         await ctx.send("**There is no session running.** *You can start one with `f!session start`*")
Beispiel #13
0
    async def stop(self, ctx):
        logger.info("command: stop race")

        await channel_setup(ctx)
        await user_setup(ctx)

        if database.exists(f"race.data:{str(ctx.channel.id)}"):
            await self.stop_race_(ctx)
        else:
            await ctx.send("**There is no race in session.** *You can start one with `b!race start`*")
Beispiel #14
0
    async def view(self, ctx):
        logger.info("command: view race")

        await channel_setup(ctx)
        await user_setup(ctx)

        if database.exists(f"race.data:{str(ctx.channel.id)}"):
            await self._send_stats(ctx, f"**Race In Progress**")
        else:
            await ctx.send("**There is no race in session.** *You can start one with `b!race start`*")
Beispiel #15
0
    async def score(self, ctx):
        logger.info("command: score")

        await channel_setup(ctx)
        await user_setup(ctx)

        totalCorrect = int(database.zscore("score:global", str(ctx.channel.id)))
        await ctx.send(
            f"Wow, looks like a total of {str(totalCorrect)} birds have been answered correctly in this channel! " +
            "Good job everyone!"
        )
Beispiel #16
0
    async def _send_stats(self, ctx, preamble):
        placings = 5
        database_key = f"race.scores:{str(ctx.channel.id)}"
        if database.zcard(database_key) is 0:
            logger.info(f"no users in {database_key}")
            await ctx.send("There are no users in the database.")
            return

        if placings > database.zcard(database_key):
            placings = database.zcard(database_key)

        leaderboard_list = database.zrevrangebyscore(
            database_key, "+inf", "-inf", 0, placings, True)
        embed = discord.Embed(
            type="rich", colour=discord.Color.blurple(), title=preamble)
        embed.set_author(name="Bird ID - An Ornithology Bot")
        leaderboard = ""

        for i, stats in enumerate(leaderboard_list):
            if ctx.guild is not None:
                user = ctx.guild.get_member(int(stats[0]))
            else:
                user = None

            if user is None:
                user = self.bot.get_user(int(stats[0]))
                if user is None:
                    user = "******"
                else:
                    user = f"**{user.name}#{user.discriminator}**"
            else:
                user = f"**{user.name}#{user.discriminator}** ({str(user.mention)})"

            leaderboard += f"{str(i+1)}. {user} - {str(int(stats[1]))}\n"

        start = int(database.hget(f"race.data:{str(ctx.channel.id)}", "start"))
        elapsed = str(datetime.timedelta(seconds=round(time.time()) - start))

        embed.add_field(name="Options", value=await self._get_options(ctx), inline=False)
        embed.add_field(
            name="Stats", value=f"**Race Duration:** `{elapsed}`", inline=False)
        embed.add_field(name="Leaderboard", value=leaderboard, inline=False)

        if database.zscore(database_key, str(ctx.author.id)) is not None:
            placement = int(database.zrevrank(
                database_key, str(ctx.author.id))) + 1
            embed.add_field(
                name="You:", value=f"You are #{str(placement)}.", inline=False)
        else:
            embed.add_field(
                name="You:", value="You haven't answered any correctly.")

        await ctx.send(embed=embed)
Beispiel #17
0
    async def hint(self, ctx):
        logger.info("command: hint")

        await channel_setup(ctx)
        await user_setup(ctx)

        current_fossil = str(
            database.hget(f"channel:{str(ctx.channel.id)}", "fossil"))[2:-1]
        if current_fossil != "":
            await ctx.send(f"The first letter is {current_fossil[0]}")
        else:
            await ctx.send("You need to ask for a fossil first!")
Beispiel #18
0
 async def stop(self, ctx):
     logger.info("command: stop session")
     
     await channel_setup(ctx)
     await user_setup(ctx)
     
     if database.exists(f"session.data:{str(ctx.author.id)}"):
         database.hset(f"session.data:{str(ctx.author.id)}", "stop", round(time.time()))
         
         await self._send_stats(ctx)
         database.delete(f"session.data:{str(ctx.author.id)}")
     else:
         await ctx.send("**There is no session running.** *You can start one with `f!session start`*")
Beispiel #19
0
 async def wiki(self, ctx, *, arg):
     logger.info("command: wiki")
     
     await channel_setup(ctx)
     await user_setup(ctx)
     
     try:
         page = wikipedia.page(arg)
         await ctx.send(page.url)
     except wikipedia.exceptions.DisambiguationError:
         await ctx.send("Sorry, that page was not found. Try being more specific.")
     except wikipedia.exceptions.PageError:
         await ctx.send("Sorry, that page was not found.")
Beispiel #20
0
def incorrect_increment(ctx, bird, amount):
    logger.info(f"incrementing incorrect {bird} by {amount}")
    database.zincrby("incorrect:global", amount, str(bird))
    database.zincrby(f"incorrect.user:{ctx.author.id}", amount, str(bird))
    if ctx.guild is not None:
        logger.info("no dm")
        database.zincrby(f"incorrect.server:{ctx.guild.id}", amount, str(bird))
    else:
        logger.info("dm context")
    if database.exists(f"session.data:{str(ctx.author.id)}"):
        logger.info("session in session")
        database.zincrby(f"session.incorrect:{ctx.author.id}", amount, str(bird))
    else:
        logger.info("no session")
Beispiel #21
0
    async def send_song_(self, ctx):
        songAnswered = int(
            database.hget(f"channel:{str(ctx.channel.id)}", "sAnswered"))
        # check to see if previous bird was answered
        if songAnswered:  # if yes, give a new bird
            roles = check_state_role(ctx)
            if database.exists(f"session.data:{ctx.author.id}"):
                logger.info("session active")
                session_increment(ctx, "total", 1)

                roles = str(
                    database.hget(f"session.data:{ctx.author.id}",
                                  "state"))[2:-1].split(" ")
                if roles[0] == "":
                    roles = []
                if len(roles) is 0:
                    logger.info("no session lists")
                    roles = check_state_role(ctx)
                logger.info(f"roles: {roles}")

            if roles:
                birds = list(
                    itertools.chain.from_iterable(states[state]["songBirds"]
                                                  for state in roles))
            else:
                birds = songBirds
            logger.info(f"number of birds: {len(birds)}")

            currentSongBird = random.choice(birds)
            prevS = str(
                database.hget(f"channel:{str(ctx.channel.id)}", "prevS"))[2:-1]
            while currentSongBird == prevS:
                currentSongBird = random.choice(birds)
            database.hset(f"channel:{str(ctx.channel.id)}", "prevS",
                          str(currentSongBird))
            database.hset(f"channel:{str(ctx.channel.id)}", "sBird",
                          str(currentSongBird))
            logger.info("currentSongBird: " + str(currentSongBird))
            await send_birdsong(ctx,
                                currentSongBird,
                                on_error=error_skip_song,
                                message=SONG_MESSAGE)
            database.hset(f"channel:{str(ctx.channel.id)}", "sAnswered", "0")
        else:
            await send_birdsong(
                ctx,
                str(database.hget(f"channel:{str(ctx.channel.id)}",
                                  "sBird"))[2:-1],
                on_error=error_skip_song,
                message=SONG_MESSAGE)
Beispiel #22
0
    async def remove(self, ctx, *, args):
        logger.info("command: remove")

        await channel_setup(ctx)
        await user_setup(ctx)

        raw_roles = ctx.author.roles
        user_role_names = [role.name.lower() for role in raw_roles]
        user_role_ids = [role.id for role in raw_roles]
        args = args.upper().split(" ")

        for arg in args:
            if arg not in list(states.keys()):
                logger.info("invalid state")
                await ctx.send(
                    f"**Sorry, `{arg}` is not a valid state.**\n*Valid States:* `{', '.join(map(str, list(states.keys())))}`"
                )

            elif states[arg]["aliases"][0].lower() not in user_role_names[1:]:
                logger.info("doesn't have role")
                await ctx.send(
                    f"**You don't have the `{arg}` state role!**\n*Your Roles:* `{', '.join(map(str, user_role_names[1:]))}`"
                )

            else:
                logger.info("deleting role")
                index = user_role_names.index(
                    states[arg]["aliases"][0].lower())
                role = ctx.guild.get_role(user_role_ids[index])
                await ctx.author.remove_roles(
                    role, reason="Delete state role for bird list")
                await ctx.send(f"**Ok, role {role.name} deleted!**")
Beispiel #23
0
async def send_bird(ctx, bird, on_error=None, message=None, addOn="", bw=False):
    if bird == "":
        logger.error("error - bird is blank")
        await ctx.send("**There was an error fetching birds.**\n*Please try again.*")
        if on_error is not None:
            on_error(ctx)
        return

    # add special condition for screech owls
    # since screech owl is a genus and SciOly
    # doesn't specify a species
    if bird == "Screech Owl":
        logger.info("choosing specific Screech Owl")
        bird = random.choice(screech_owls)

    delete = await ctx.send("**Fetching.** This may take a while.")
    # trigger "typing" discord message
    await ctx.trigger_typing()

    try:
        response = await get_image(ctx, bird, addOn)
    except GenericError as e:
        await delete.delete()
        await ctx.send(f"**An error has occurred while fetching images.**\n*Please try again.*\n**Reason:** {str(e)}")
        logger.exception(e)
        if on_error is not None:
            on_error(ctx)
        return

    filename = str(response[0])
    extension = str(response[1])
    statInfo = os.stat(filename)
    if statInfo.st_size > 8000000:  # another filesize check
        await delete.delete()
        await ctx.send("**Oops! File too large :(**\n*Please try again.*")
    else:
        if bw:
            loop = asyncio.get_running_loop()
            fn = partial(_black_and_white, filename)
            file_stream = await loop.run_in_executor(None, fn)
        else:
            file_stream = filename

        if message is not None:
            await ctx.send(message)

        # change filename to avoid spoilers
        file_obj = discord.File(file_stream, filename=f"bird.{extension}")
        await ctx.send(file=file_obj)
        await delete.delete()
Beispiel #24
0
    async def list_of_birds(self, ctx, state: str = "blank"):
        logger.info("command: list")

        await channel_setup(ctx)
        await user_setup(ctx)

        state = state.upper()

        if state not in list(states.keys()):
            logger.info("invalid state")
            await ctx.send(
                f"**Sorry, `{state}` is not a valid state.**\n*Valid States:* `{', '.join(map(str, list(states.keys())))}`"
            )
            return

        birdLists = []
        temp = ""
        for bird in states[state]['birdList']:
            temp += f"{str(bird)}\n"
            if len(temp) > 1950:
                birdLists.append(temp)
                temp = ""
        birdLists.append(temp)

        songLists = []
        temp = ""
        for bird in states[state]['songBirds']:
            temp += f"{str(bird)}\n"
            if len(temp) > 1950:
                songLists.append(temp)
                temp = ""
        songLists.append(temp)

        if ctx.author.dm_channel is None:
            await ctx.author.create_dm()

        await ctx.author.dm_channel.send(f"**The {state} bird list:**")
        for birds in birdLists:
            await ctx.author.dm_channel.send(f"```{birds}```")

        await ctx.author.dm_channel.send(f"**The {state} bird songs:**")
        for birds in songLists:
            await ctx.author.dm_channel.send(f"```{birds}```")

        await ctx.send(
            f"The `{state}` bird list has **{str(len(states[state]['birdList']))}** birds.\n"
            +
            f"The `{state}` bird list has **{str(len(states[state]['songBirds']))}** songs.\n"
            + "*A full list of birds has been sent to you via DMs.*")
Beispiel #25
0
    async def skipgoat(self, ctx):
        logger.info("command: skipgoat")

        await channel_setup(ctx)
        await user_setup(ctx)
        
        database.zadd("streak:global", {str(ctx.author.id): 0})
        currentBird = str(database.hget(f"channel:{str(ctx.channel.id)}", "goatsucker"))[2:-1]
        database.hset(f"channel:{str(ctx.channel.id)}", "goatsucker", "")
        database.hset(f"channel:{str(ctx.channel.id)}", "gsAnswered", "1")
        if currentBird != "":  # check if there is bird
            birdPage = wikipedia.page(f"{currentBird} (bird)")
            await ctx.send(f"Ok, skipping {currentBird.lower()}\n{birdPage.url}")  # sends wiki page
        else:
            await ctx.send("You need to ask for a bird first!")
Beispiel #26
0
    async def state(self, ctx, *, args):
        logger.info("command: state set")

        await channel_setup(ctx)
        await user_setup(ctx)

        roles = [role.name.lower() for role in ctx.author.roles]
        args = args.upper().split(" ")

        for arg in args:
            if arg not in list(states.keys()):
                logger.info("invalid state")
                await ctx.send(
                    f"**Sorry, `{arg}` is not a valid state.**\n*Valid States:* `{', '.join(map(str, list(states.keys())))}`"
                )

            elif len(set(roles).intersection(set(
                    states[arg]["aliases"]))) is 0:  # gets similarities
                # need to add roles (does not have role)
                logger.info("add roles")
                raw_roles = ctx.guild.roles
                guild_role_names = [role.name.lower() for role in raw_roles]
                guild_role_ids = [role.id for role in raw_roles]

                if states[arg]["aliases"][0].lower() in guild_role_names:
                    # guild has role
                    index = guild_role_names.index(
                        states[arg]["aliases"][0].lower())
                    role = ctx.guild.get_role(guild_role_ids[index])

                else:
                    # create role
                    logger.info("creating role")
                    role = await ctx.guild.create_role(
                        name=string.capwords(states[arg]["aliases"][0]),
                        permissions=discord.Permissions.none(),
                        hoist=False,
                        mentionable=False,
                        reason="Create state role for bird list")

                await ctx.author.add_roles(
                    role, reason="Set state role for bird list")
                await ctx.send(f"**Ok, added the {role.name} role!**")

            else:
                # have roles already (there were similarities)
                logger.info("already has role")
                await ctx.send(f"**You already have the `{arg}` role!**")
Beispiel #27
0
    async def refresh_cache():
        logger.info("clear cache")
        try:
            shutil.rmtree(r'cache/images/', ignore_errors=True)
            logger.info("Cleared image cache.")
        except FileNotFoundError:
            logger.info("Already cleared image cache.")

        try:
            shutil.rmtree(r'cache/songs/', ignore_errors=True)
            logger.info("Cleared songs cache.")
        except FileNotFoundError:
            logger.info("Already cleared songs cache.")
        event_loop = asyncio.get_event_loop()
        with concurrent.futures.ThreadPoolExecutor(1) as executor:
            await event_loop.run_in_executor(executor, start_precache)
Beispiel #28
0
 async def info(self, ctx, *, arg):
     logger.info("command: info")
     
     await channel_setup(ctx)
     await user_setup(ctx)
     
     matches = get_close_matches(arg, fossils_list, n=1)
     if matches:
         fossil = matches[0]
         
         delete = await ctx.send("Please wait a moment.")
         await send_fossil(ctx, str(fossil), message="Here's the image!")
         await delete.delete()
     
     else:
         await ctx.send("Fossil not found. Are you sure it's on the list?")
Beispiel #29
0
    async def invite(self, ctx):
        logger.info("command: invite")
        
        await channel_setup(ctx)
        await user_setup(ctx)
        
        embed = discord.Embed(type="rich", colour=discord.Color.blurple())
        embed.set_author(name=bot_name)
        embed.add_field(
            name="Invite",
            value="""To invite this bot to your own server, use the following invite link:
https://discordapp.com/api/oauth2/authorize?client_id=639279425631813648&permissions=0&scope=bot""",
            inline=False
        )
        await ctx.send(embed=embed)
        await ctx.send("https://discord.gg/husFeGG")
Beispiel #30
0
async def precache():
    timeout = aiohttp.ClientTimeout(total=10 * 60)
    conn = aiohttp.TCPConnector(limit=100)
    async with aiohttp.ClientSession(connector=conn, timeout=timeout) as session:
        logger.info("Starting cache")
        await asyncio.gather(*(download_media(bird, "images", session=session) for bird in sciBirdListMaster))
        logger.info("Starting females")
        await asyncio.gather(
            *(download_media(bird, "images", addOn="female", session=session) for bird in sciBirdListMaster)
        )
        logger.info("Starting juveniles")
        await asyncio.gather(
            *(download_media(bird, "images", addOn="juvenile", session=session) for bird in sciBirdListMaster)
        )
        logger.info("Starting songs")
        await asyncio.gather(*(download_media(bird, "songs", session=session) for bird in sciSongBirdsMaster))
    logger.info("Images Cached")