예제 #1
0
    async def is_holiday(ctx):
        """Sends a picture of a turkey on Thanksgiving.

        Can be extended to other holidays as well.
        """
        logger.info("global check: checking holiday")
        now = datetime.now(tz=timezone(-timedelta(hours=4))).date()
        us = holidays.US()
        if now in us:
            if us.get(now) == "Thanksgiving":
                await send_bird(
                    ctx,
                    "Wild Turkey",
                    "images",
                    Filter(),
                    message=
                    "**It's Thanksgiving!**\nGo celebrate with your family.",
                )
                raise GenericError(code=666)
            if us.get(now) == "Independence Day":
                await send_bird(
                    ctx,
                    "Bald Eagle",
                    "images",
                    Filter(),
                    message=
                    "**It's Independence Day!**\nEnjoy this birb responsibly.",
                )
                raise GenericError(code=666)
        elif now == date(now.year, 4, 1):
            return await drone_attack(ctx)
        return True
예제 #2
0
파일: core.py 프로젝트: tctree333/Bird-ID
async def valid_bird(bird: str, session=None) -> Tuple[str, bool, str, str]:
    """Checks if a bird is valid.

    This checks first if Macaulay has a valid taxon code for the bird,
    then if the bird is already in one of our lists. If not, then it checks
    if Macaulay has valid images for the bird.

    Returns a tuple: `(input bird, valid bool, reason, detected name (may be empty string))`.
    """
    bird_ = string.capwords(bird.strip().replace("-", " "))
    logger.info(f"checking if {bird} is valid")
    async with contextlib.AsyncExitStack() as stack:
        if session is None:
            session = await stack.enter_async_context(aiohttp.ClientSession())
        try:
            name = (await get_taxon(bird_, session))[1]
        except GenericError as e:
            if e.code in (111, 201):
                return (bird, False, "No taxon code found", "")
            raise e
    if bird_ not in birdListMaster:
        try:
            urls = await _get_urls(session, bird_, "p", Filter())
        except GenericError as e:
            if e.code in (100, 201):
                return (bird, False, "One or less images found", name)
            raise e
        if len(urls) < 2:
            return (bird, False, "One or less images found", name)
    return (bird, True, "All checks passed", name)
예제 #3
0
    async def goatsucker(self, ctx):
        logger.info("command: goatsucker")

        if database.exists(f"race.data:{ctx.channel.id}"):
            await ctx.send("This command is disabled during races.")
            return

        answered = int(database.hget(f"channel:{ctx.channel.id}", "answered"))
        # check to see if previous bird was answered
        if answered:  # if yes, give a new bird
            session_increment(ctx, "total", 1)

            database.hset(f"channel:{ctx.channel.id}", "answered", "0")
            currentBird = random.choice(goatsuckers)
            self.increment_bird_frequency(ctx, currentBird)

            database.hset(f"channel:{ctx.channel.id}", "bird",
                          str(currentBird))
            logger.info("currentBird: " + str(currentBird))
            await send_bird(
                ctx,
                currentBird,
                "images",
                Filter(),
                on_error=self.error_skip(ctx),
                message=GS_MESSAGE,
            )
        else:  # if no, give the same bird
            await send_bird(
                ctx,
                database.hget(f"channel:{ctx.channel.id}",
                              "bird").decode("utf-8"),
                "images",
                Filter(),
                on_error=self.error_skip(ctx),
                message=GS_MESSAGE,
            )
예제 #4
0
async def valid_bird(bird: str, session=None) -> Tuple[str, bool, str, str]:
    """Checks if a bird is valid.

    This checks first if Macaulay has a valid taxon code for the bird,
    then if Macaulay has valid media for the bird based on the requested
    media type. Media can be `p` for pictures, `a` for audio, or `v` for video.

    Returns a tuple: `(input bird, valid bool, reason, detected name (may be empty string))`.
    """
    bird = string.capwords(bird)
    logger.info(f"checking if {bird} is valid")
    async with contextlib.AsyncExitStack() as stack:
        if session is None:
            session = await stack.enter_async_context(aiohttp.ClientSession())
        try:
            name = (await get_taxon(bird, session))[1]
        except GenericError as e:
            if e.code in (111, 201):
                return (bird, False, "No taxon code found", "")
            raise e
        urls = await _get_urls(session, bird, "p", Filter())
        if len(urls) < 2:
            return (bird, False, "One or less images found", name)
        return (bird, True, "All checks passed", name)
예제 #5
0
    async def parse(ctx, args_str: str):
        """Parse arguments for options."""

        args = args_str.split(" ")
        logger.info(f"args: {args}")

        if not database.exists(f"race.data:{ctx.channel.id}"):
            roles = check_state_role(ctx)

            taxon_args = set(taxons.keys()).intersection(
                {arg.lower()
                 for arg in args})
            if taxon_args:
                taxon = " ".join(taxon_args).strip()
            else:
                taxon = ""

            state_args = set(states.keys()).intersection(
                {arg.upper()
                 for arg in args})
            if state_args:
                state = " ".join(state_args).strip()
            else:
                state = ""

            if database.exists(f"session.data:{ctx.author.id}"):
                logger.info("session parameters")

                if taxon_args:
                    current_taxons = set(
                        database.hget(f"session.data:{ctx.author.id}",
                                      "taxon").decode("utf-8").split(" "))
                    logger.info(f"toggle taxons: {taxon_args}")
                    logger.info(f"current taxons: {current_taxons}")
                    taxon_args.symmetric_difference_update(current_taxons)
                    taxon_args.discard("")
                    logger.info(f"new taxons: {taxon_args}")
                    taxon = " ".join(taxon_args).strip()
                else:
                    taxon = database.hget(f"session.data:{ctx.author.id}",
                                          "taxon").decode("utf-8")

                roles = (database.hget(f"session.data:{ctx.author.id}",
                                       "state").decode("utf-8").split(" "))
                if roles[0] == "":
                    roles = []
                if not roles:
                    logger.info("no session lists")
                    roles = check_state_role(ctx)

                session_filter = int(
                    database.hget(f"session.data:{ctx.author.id}", "filter"))
                filters = Filter.parse(args_str, defaults=False)
                if filters.vc:
                    filters.vc = False
                    await ctx.send("**The VC filter is not allowed inline!**")

                default_quality = Filter().quality
                if (Filter.from_int(session_filter).quality == default_quality
                        and filters.quality
                        and filters.quality != default_quality):
                    filters ^= Filter()  # clear defaults
                filters ^= session_filter
            else:
                filters = Filter.parse(args_str)
                if filters.vc:
                    filters.vc = False
                    await ctx.send("**The VC filter is not allowed inline!**")

            if state_args:
                logger.info(f"toggle states: {state_args}")
                logger.info(f"current states: {roles}")
                state_args.symmetric_difference_update(set(roles))
                state_args.discard("")
                logger.info(f"new states: {state_args}")
                state = " ".join(state_args).strip()
            else:
                state = " ".join(roles).strip()

            if "CUSTOM" in state.upper().split(" "):
                if not database.exists(f"custom.list:{ctx.author.id}"):
                    await ctx.send("**You don't have a custom list set!**")
                    state_list = state.split(" ")
                    state_list.remove("CUSTOM")
                    state = " ".join(state_list)
                elif database.exists(f"custom.confirm:{ctx.author.id}"):
                    await ctx.send(
                        "**Please verify or confirm your custom list before using!**"
                    )
                    state_list = state.split(" ")
                    state_list.remove("CUSTOM")
                    state = " ".join(state_list)

        else:
            logger.info("race parameters")

            race_filter = int(
                database.hget(f"race.data:{ctx.channel.id}", "filter"))
            filters = Filter.parse(args_str, defaults=False)
            if filters.vc:
                filters.vc = False
                await ctx.send("**The VC filter is not allowed inline!**")

            default_quality = Filter().quality
            if (Filter.from_int(race_filter).quality == default_quality
                    and filters.quality
                    and filters.quality != default_quality):
                filters ^= Filter()  # clear defaults
            filters ^= race_filter

            taxon = database.hget(f"race.data:{ctx.channel.id}",
                                  "taxon").decode("utf-8")
            state = database.hget(f"race.data:{ctx.channel.id}",
                                  "state").decode("utf-8")

        logger.info(
            f"args: filters: {filters}; taxon: {taxon}; state: {state}")

        return (filters, taxon, state)
예제 #6
0
파일: main.py 프로젝트: tctree333/Bird-ID
async def bird_song(request: Request, bird: str):
    info = await send_bird(request, bird, "songs", Filter())
    return send_file(info[0], media_type=info[2])
예제 #7
0
    def parse(ctx, args_str: str):
        """Parse arguments for options."""

        args = args_str.split(" ")
        logger.info(f"args: {args}")

        if not database.exists(f"race.data:{ctx.channel.id}"):
            roles = check_state_role(ctx)

            taxon_args = set(taxons.keys()).intersection(
                {arg.lower()
                 for arg in args})
            if taxon_args:
                taxon = " ".join(taxon_args).strip()
            else:
                taxon = ""

            state_args = set(states.keys()).intersection(
                {arg.upper()
                 for arg in args})
            if state_args:
                state = " ".join(state_args).strip()
            else:
                state = ""

            if database.exists(f"session.data:{ctx.author.id}"):
                logger.info("session parameters")

                if taxon_args:
                    current_taxons = set(
                        database.hget(f"session.data:{ctx.author.id}",
                                      "taxon").decode("utf-8").split(" "))
                    logger.info(f"toggle taxons: {taxon_args}")
                    logger.info(f"current taxons: {current_taxons}")
                    taxon_args.symmetric_difference_update(current_taxons)
                    logger.info(f"new taxons: {taxon_args}")
                    taxon = " ".join(taxon_args).strip()
                else:
                    taxon = database.hget(f"session.data:{ctx.author.id}",
                                          "taxon").decode("utf-8")

                roles = (database.hget(f"session.data:{ctx.author.id}",
                                       "state").decode("utf-8").split(" "))
                if roles[0] == "":
                    roles = []
                if not roles:
                    logger.info("no session lists")
                    roles = check_state_role(ctx)

                session_filter = int(
                    database.hget(f"session.data:{ctx.author.id}", "filter"))
                filters = Filter.parse(args_str, defaults=False)
                default_quality = Filter().quality
                if (Filter.from_int(session_filter).quality == default_quality
                        and filters.quality
                        and filters.quality != default_quality):
                    filters ^= Filter()  # clear defaults
                filters ^= session_filter
            else:
                filters = Filter.parse(args_str)

            if state_args:
                logger.info(f"toggle states: {state_args}")
                logger.info(f"current states: {roles}")
                state_args.symmetric_difference_update(set(roles))
                logger.info(f"new states: {state_args}")
                state = " ".join(state_args).strip()
            else:
                state = " ".join(roles).strip()

        else:
            logger.info("race parameters")

            race_filter = int(
                database.hget(f"race.data:{ctx.channel.id}", "filter"))
            filters = Filter.parse(args_str, defaults=False)
            default_quality = Filter().quality
            if (Filter.from_int(race_filter).quality == default_quality
                    and filters.quality
                    and filters.quality != default_quality):
                filters ^= Filter()  # clear defaults
            filters ^= race_filter

            taxon = database.hget(f"race.data:{ctx.channel.id}",
                                  "taxon").decode("utf-8")
            state = database.hget(f"race.data:{ctx.channel.id}",
                                  "state").decode("utf-8")

        logger.info(
            f"args: filters: {filters}; taxon: {taxon}; state: {state}")

        return (filters, taxon, state)
예제 #8
0
파일: main.py 프로젝트: scottwedge/Bird-ID
def bird_song(bird):
    path = asyncio.run(get_media(bird, "songs", Filter()))
    return flask.send_file(f"../{path[0]}")