示例#1
0
 async def bap(self, ctx, *, user: discord.Member):
     """
     Baps a user
     """
     if user.id == ctx.bot.user.id:
         await ctx.send(":newspaper2: :newspaper2: :newspaper2: " +
                        italics(ctx.message.author.display_name))
     else:
         if ctx.guild.id == 508496957350608906:
             await ctx.send(
                 italics(user.display_name) +
                 " <:aureliabagu:678829441178271770>")
         else:
             await ctx.send(":newspaper2: " + italics(user.display_name))
示例#2
0
 async def send_to(self, ctx: Context, content=None):
     if await ctx.embed_requested():
         return await ctx.send(content=content, embed=self)
     content = str(content) if content is not None else None
     if content:
         content = [content, ""]
     else:
         content = []
     next_break = False
     title = self._("title")
     if title:
         content.append(CF.bold(title))
         next_break = True
     name = self._("author.name")
     if name:
         content.append(CF.italics(name))
         next_break = True
     url = self._("thumbnail.url")
     if url and not url.startswith("attachment://"):
         content.append(f"<{url}>")
         next_break = True
     description = self._("description")
     if description:
         content.append(CF.box(CF.escape(description, formatting=True)))
         next_break = False
     if next_break:
         content.append("")
         next_break = False
     for i in range(len(self.fields)):
         inline, name, value = (
             self._("fields", i, "inline"),
             self._("fields", i, "name"),
             self._("fields", i, "value"),
         )
         if not inline or len(name) + len(
                 value) > 78 or "\n" in name or "\n" in value:
             content.append(name)
             content.append(CF.box(CF.escape(value, formatting=True)))
             next_break = False
         else:
             content.append(f"{name}: {value}")
             next_break = True
     if next_break:
         content.append("")
         next_break = False
     url = self._("image.url")
     if url and not url.startswith("attachment://"):
         content.append(f"<{url}>")
     url = self._("video.url")
     if url and not url.startswith("attachment://"):
         content.append(f"<{url}>")
     text, timestamp = self._("footer.text"), self._("timestamp")
     if text and timestamp:
         content.append(f"{text} | {timestamp}")
     elif text:
         content.append(text)
     elif timestamp:
         content.append(f"{timestamp} UTC")
     content = list(CF.pagify("\n".join(map(str, content)), shorten_by=0))
     return await ctx.send_interactive(content)
示例#3
0
    async def grouphug(self, ctx, intensity: int, *users: discord.Member):
        """
        Give a group hug to multiple users!

        If not pinging, you must put quotes around names with spaces
        Can also use user ids
        """
        if not users:
            await self.bot.send_help_for(ctx, "grouphug")
            return

        names = [italics(user.display_name) for user in users]
        names = ", ".join(names)

        if intensity <= 0:
            msg = "(っ˘̩╭╮˘̩)っ {} ⊂(˘̩╭╮˘̩⊂)".format(names)
        elif intensity <= 3:
            msg = "(っ´▽`)っ {} ⊂( ̄▽ ̄⊂)".format(names)
        elif intensity <= 6:
            msg = "╰(*´︶`*)╯ {} ╰(*´︶`*)╯".format(names)
        elif intensity <= 9:
            msg = "(つ≧▽≦)つ {} ⊂(・▽・⊂)".format(names)
        elif intensity >= 10:
            msg = "(づ ̄ ³ ̄)づ {} ⊂(´・ω・`⊂)".format(names)

        await ctx.send(msg)
示例#4
0
    async def act(self, ctx, *, target: Union[discord.Member, str] = None):
        """
        Acts on the specified user.
        """
        if not target or isinstance(target, str):
            return  # no help text

        action = inflection.humanize(ctx.invoked_with).split()
        iverb = -1

        for cycle in range(2):
            if iverb > -1:
                break
            for i, act in enumerate(action):
                act = act.lower()
                if (act in NOLY_ADV or act in CONJ
                        or (act.endswith("ly") and act not in LY_VERBS)
                        or (not cycle and act in SOFT_VERBS)):
                    continue
                action[i] = inflection.pluralize(action[i])
                iverb = max(iverb, i)

        if iverb < 0:
            return
        action.insert(iverb + 1, target.mention)
        await ctx.send(italics(" ".join(action)))
示例#5
0
    async def desc_select(
        self,
        ctx: commands.Context,
        embed: Embed,
        message: discord.Message,
        do_once: bool = True,
    ) -> bool:
        """Requests information from the member about the description of the
        character being registered.

        Args:
            ctx (commands.Context): Same as `RegisterSession.ctx`
            embed (Embed): Same as `RegisterSession.embed`
            message (discord.Message): Same as `RegisterSession.message`
            do_once (bool): The parameter allows not to perform actions that
                are not needed during a recursive method call.

        Returns:
            bool: Whether the correct information is received or not.

        """
        if do_once:
            embed.description = (
                "**Опишите своего персонажа**\n\n"
                "В описании персонажа должно быть **не менее 50** и **не более 2000 символов**.\n"
                "Описание персонажа должно состоять из символов **латинского алфавита** или **кириллицы.**"
            )
            await message.edit(embed=embed)
            do_once = False
        try:
            desc = await self.ctx.bot.wait_for(
                "message",
                timeout=600.0,
                check=MessagePredicate.same_context(ctx))
            desc_content = desc.content
            await desc.delete()
            if not re.match(
                    """[a-zа-яA-ZА-ЯёЁ\d\s!.,%*'";:()\[\]<>\-«»—]{50,2000}""",
                    desc_content):
                incorrect = await ctx.send("Недопустимый ввод!")
                desc_select = await self.desc_select(ctx, embed, message,
                                                     do_once)
                await incorrect.delete()
                if desc_select:
                    return True
                else:
                    await self.cancel(embed, message)
                    return False
            self.char["desc"] = desc_content
            embed.description = italics(desc_content)
            await message.edit(embed=embed)
            return True
        except asyncio.TimeoutError:
            await self.cancel(embed, message)
            return False
示例#6
0
    async def rpsls(self, ctx, choice: ValidChoiceConverter):
        """Play rock, paper, scizzors, lizard, spock.

        Use `[p]rpsls help` for a diagram.
        """
        human_choice, human_number = choice
        bot_choice, bot_number = generate_bot_rpsls()
        if bot_number == human_number:
            phrase = italics("It's a draw! We're fair and square.")
            bot_user = self.bot.user
            human_user = ctx.author
        elif bot_number in IntMapper[human_number]:
            phrase = italics("You won - nice job!")
            bot_user = self.bot.user
            human_user = bold(str(ctx.author))
        else:
            phrase = italics("Damn, better luck next time...")
            bot_user = bold(str(self.bot.user))
            human_user = ctx.author
        bot_emoji = get_emoji_from_name(bot_choice)
        human_emoji = get_emoji_from_name(human_choice)
        message = f"{human_user} {human_emoji} {VS} {bot_emoji} {bot_user}" f"\n> {phrase}"
        await ctx.maybe_send_embed(message)
示例#7
0
 async def theme_list(self, ctx, *, user: discord.User = None):
     """
     Lists your currently set themes.
     """
     if not user:
         user = ctx.author
     themes = await self.maybe_bot_themes(ctx, user)
     if themes:
         message = self.pretty_themes(
             bold(_("{}'s Themes")).format(user.name), themes)
     else:
         message = "{}\n\n{}".format(
             bold(_("{0}'s Themes")),
             italics(_("{0} has not set any themes."))).format(user.name)
     for msg in pagify(message):
         await ctx.maybe_send_embed(msg)
示例#8
0
    async def hug(self, ctx, user: discord.Member, intensity: int = 1):
        """Because everyone likes hugs

        Up to 10 intensity levels."""
        name = italics(user.display_name)
        if intensity <= 0:
            msg = "(っ˘̩╭╮˘̩)っ" + name
        elif intensity <= 3:
            msg = "(っ´▽`)っ" + name
        elif intensity <= 6:
            msg = "╰(*´︶`*)╯" + name
        elif intensity <= 9:
            msg = "(つ≧▽≦)つ" + name
        elif intensity >= 10:
            msg = "(づ ̄ ³ ̄)づ{} ⊂(´・ω・`⊂)".format(name)
        await ctx.send(msg)
示例#9
0
 async def boop(self, ctx, *, boop_target: str):
     """
     Boops a user. 10 intensity levels.
     """
     user, intensity = self.get_user_and_intensity(ctx.guild, boop_target)
     if user is not None:
         name = italics(user.display_name)
         if intensity <= 3:
             msg = "/) {}".format(name)
         elif intensity <= 6:
             msg = "**/)** {}".format(name)
         elif intensity <= 9:
             msg = "**__/)__** {}".format(name)
         elif intensity >= 10:
             msg = "**__/)__** {} **__(\\\__**".format(name)
         await ctx.send(msg)
     else:
         await ctx.send("Can't boop what I can't see!")
示例#10
0
    async def hug(self, ctx, user: discord.Member, intensity: int = 1):
        """Because everyone likes hugs!

        Up to 10 intensity levels.
        """
        name = italics(user.display_name)
        if intensity <= 0:
            msg = "(っ˘̩╭╮˘̩)っ" + name
        elif intensity <= 3:
            msg = "(っ´▽`)っ" + name
        elif intensity <= 6:
            msg = "╰(*´︶`*)╯" + name
        elif intensity <= 9:
            msg = "(つ≧▽≦)つ" + name
        elif intensity >= 10:
            msg = "(づ ̄ ³ ̄)づ{} ⊂(´・ω・`⊂)".format(name)
        else:
            # For the purposes of "msg might not be defined" linter errors
            raise RuntimeError
        await ctx.send(msg)
示例#11
0
    async def hug(self, ctx, user: discord.Member, intensity: int = 1):
        """Because everyone likes hugs!

        Up to 10 intensity levels.
        """
        name = italics(user.display_name)
        if intensity <= 0:
            msg = "(っ˘̩╭╮˘̩)っ" + name
        elif intensity <= 3:
            msg = "(っ´▽`)っ" + name
        elif intensity <= 6:
            msg = "╰(*´︶`*)╯" + name
        elif intensity <= 9:
            msg = "(つ≧▽≦)つ" + name
        elif intensity >= 10:
            msg = "(づ ̄ ³ ̄)づ{} ⊂(´・ω・`⊂)".format(name)
        else:
            # For the purposes of "msg might not be defined" linter errors
            raise RuntimeError
        await ctx.send(msg)
示例#12
0
    async def hug(self, ctx, *, hug_target: str):
        """Hugs a user with optional intensity!
        Example: .hug *username* 4

        Up to 10 intensity levels."""
        user, intensity = self.get_user_and_intensity(ctx.guild, hug_target)

        if user is not None:
            name = italics(user.display_name)
            if intensity <= 0:
                msg = "(っ˘̩╭╮˘̩)っ" + name
            elif intensity <= 3:
                msg = "(っ´▽`)っ" + name
            elif intensity <= 6:
                msg = "╰(*´︶`*)╯" + name
            elif intensity <= 9:
                msg = "(つ≧▽≦)つ" + name
            elif intensity >= 10:
                msg = "(づ ̄ ³ ̄)づ {} ⊂(´・ω・`⊂)".format(name)
            await ctx.send(msg)
        else:
            await ctx.send("Member not found.")
示例#13
0
    async def pypi(self, ctx, project: str):
        """Get information about a project on PyPi."""
        await ctx.trigger_typing()
        async with self.session.get(
                f"https://pypi.org/pypi/{project}/json") as request:
            if request.status != 200:
                embed = discord.Embed(
                    description=f'There were no results for "{project}".')
                return await self.send_embed(ctx, embed)
            request = await request.json()

        info = request["info"]

        kwargs = {}

        embed = discord.Embed(title=f"{info['name']} {info['version']}",
                              url=info["package_url"])
        embed.description = info["summary"] or italics(
            "No description was provided for this project.")

        if (author := info["author"]) and author != " ":
            embed.add_field(name="Author", value=author)
示例#14
0
文件: act.py 项目: Dav-Git/FluffyCogs
    async def act(self, ctx: commands.Context, *, target: Union[discord.Member, str] = None):
        """
        Acts on the specified user.
        """
        if not target or isinstance(target, str):
            return  # no help text

        try:
            if not ctx.guild:
                raise KeyError()
            message = await self.config.guild(ctx.guild).get_raw("custom", ctx.invoked_with)
        except KeyError:
            try:
                message = await self.config.get_raw("custom", ctx.invoked_with)
            except KeyError:
                message = NotImplemented

        if message is None:  # ignored command
            return
        elif message is NotImplemented:  # default
            # humanize action text
            action = inflection.humanize(ctx.invoked_with).split()
            iverb = -1

            for cycle in range(2):
                if iverb > -1:
                    break
                for i, act in enumerate(action):
                    act = act.lower()
                    if (
                        act in NOLY_ADV
                        or act in CONJ
                        or (act.endswith("ly") and act not in LY_VERBS)
                        or (not cycle and act in SOFT_VERBS)
                    ):
                        continue
                    action[i] = inflection.pluralize(action[i])
                    iverb = max(iverb, i)

            if iverb < 0:
                return
            action.insert(iverb + 1, target.mention)
            message = italics(" ".join(action))
        else:
            assert isinstance(message, str)
            message = fmt_re.sub(functools.partial(self.repl, target), message)

        # add reaction gif
        if self.try_after and ctx.message.created_at < self.try_after:
            return await ctx.send(message)
        if not await ctx.embed_requested():
            return await ctx.send(message)
        key = (await ctx.bot.get_shared_api_tokens("tenor")).get("api_key")
        if not key:
            return await ctx.send(message)
        async with aiohttp.request(
            "GET",
            "https://api.tenor.com/v1/search",
            params={
                "q": ctx.invoked_with,
                "key": key,
                "anon_id": str(ctx.author.id ^ ctx.me.id),
                "media_filter": "minimal",
                "contentfilter": "off" if getattr(ctx.channel, "nsfw", False) else "low",
                "ar_range": "wide",
                "limit": "8",
                "locale": get_locale(),
            },
        ) as response:
            json: dict
            if response.status == 429:
                self.try_after = ctx.message.created_at + 30
                json = {}
            elif response.status >= 400:
                json = {}
            else:
                json = await response.json()
        if not json.get("results"):
            return await ctx.send(message)
        message = f"{message}\n\n{random.choice(json['results'])['itemurl']}"
        await ctx.send(
            message,
            allowed_mentions=discord.AllowedMentions(
                users=False if target in ctx.message.mentions else [target]
            ),
        )
示例#15
0
    async def godville(self, ctx, *, godname: str):
        """Get data about godville's god by name"""
        async with self.session.get("{}/{}/{}".format(
                BASE_API, godname.casefold(),
                await self.api_by_god(godname.casefold(), "godville")
                or "")) as sg:
            if sg.status == 404:
                await ctx.send(
                    chat.error(
                        "404 — Sorry, but there is nothing here\nCheck god name and try again"
                    ))
                return
            elif sg.status != 200:
                await ctx.send(
                    chat.error(
                        "Something went wrong. Server returned {}.".format(
                            sg.status)))
                return
            profile = await sg.json()
        profile = GodvilleUser(profile)
        text_header = "{} и его {}\n{}\n" \
            .format(chat.bold(profile.god),
                    chat.bold(profile.name),
                    chat.italics(chat.escape(profile.motto.strip(), formatting=True))
                    if profile.motto else chat.inline("Здесь ничего нет"))
        if profile.arena_is_in_fight:
            text_header += "В сражении: {}\n".format(profile.fight_type_rus)
        if profile.town:
            text_header += "В городе: {}\n".format(profile.town)
        if profile.need_update:
            text_header += chat.bold("! УСТАРЕВШАЯ ИНФОРМАЦИЯ !") + "\n"
        text = ""
        pet = ""
        times = ""
        if profile.gold_approximately:
            text += "Золота: {}\n".format(profile.gold_approximately)
        if profile.distance:
            text += "Столбов от столицы: {}\n".format(profile.distance)
        if profile.quest_progress:
            text += "Задание: {} ({}%)\n".format(profile.quest,
                                                 profile.quest_progress)
        if profile.experience:
            text += "Опыта до следующего уровня: {}%\n".format(
                profile.experience)
        text += "Уровень: {}\n".format(profile.level)
        if profile.godpower:
            text += "Праны: {}/{}\n".format(
                profile.godpower, 200 if profile.savings_date else 100)
        text += "Характер: {}\n".format(profile.alignment)
        text += "Пол: {}\n".format(profile.gender)
        text += "Побед/Поражений: {}/{}\n".format(profile.arena_won,
                                                  profile.arena_lost)
        text += "Гильдия: {} ({})\n".format(profile.clan, profile.clan_position) if profile.clan \
            else "Гильдия: Не состоит\n"
        text += "Кирпичей: {} ({}%)\n".format(profile.bricks,
                                              profile.bricks / 10)
        if profile.inventory:
            text += "Инвентарь: {}/{} ({}%)\n".format(
                profile.inventory, profile.inventory_max,
                int(profile.inventory / profile.inventory_max * 100))
        else:
            text += "Вместимость инвентаря: {}\n".format(profile.inventory_max)
        if profile.health:
            text += "Здоровье: {}/{} ({}%)\n".format(
                profile.health, profile.health_max,
                int(profile.health / profile.health_max * 100))
        else:
            text += "Максимум здоровья: {}\n".format(profile.health_max)
        if profile.ark_male:
            text += "Тварей ♂: {} ({}%)\n".format(profile.ark_male,
                                                  profile.ark_male / 10)
        if profile.ark_female:
            text += "Тварей ♀: {} ({}%)\n".format(profile.ark_female,
                                                  profile.ark_female / 10)
        if profile.savings:
            text += "Сбережений: {}\n".format(profile.savings)
        if profile.trading_level:
            text += "Уровень торговли: {}\n".format(profile.trading_level)
        if profile.wood:
            text += "Поленьев: {} ({}%)\n".format(profile.wood,
                                                  profile.wood / 10)

        # private (api only)
        if profile.diary_last:
            text += "Дневник: {}\n".format(profile.diary_last)
        if profile.activatables:
            text += "Активируемое в инвентаре: {}\n".format(", ".join(
                profile.activatables))
        if profile.aura:
            text += "Аура: {}\n".format(profile.aura)

        # pet
        if profile.pet.name:
            pet += "Имя: {}\n".format(profile.pet.name)
            pet += "Уровень: {}\n".format(profile.pet.level or "Без уровня")
            if profile.pet.type:
                pet += "Тип: {}\n".format(profile.pet.type)
            if profile.pet.wounded:
                pet += "❌ — Контужен"

        # times
        if profile.temple_date:
            times += "Храм достроен: {}\n".format(
                profile.date_string("temple"))
        if profile.ark_date:
            times += "Ковчег достроен: {}\n".format(profile.date_string("ark"))
        if profile.savings_date:
            times += "Пенсия собрана: {}\n".format(
                profile.date_string("savings"))

        finaltext = ""
        finaltext += text_header
        finaltext += chat.box(text)
        if pet:
            finaltext += "Питомец:\n"
            finaltext += chat.box(pet)
        if times:
            finaltext += chat.box(times)
        await ctx.send(finaltext)
示例#16
0
    async def godvillegame(self, ctx, *, godname: str):
        """Get data about godville's god by name"""
        async with self.session.get("{}/{}".format(BASE_API_GLOBAL,
                                                   godname.casefold())) as sg:
            if sg.status == 404:
                await ctx.send(
                    chat.error(
                        "404 — Sorry, but there is nothing here\nCheck god name and try again"
                    ))
                return
            elif sg.status != 200:
                await ctx.send(
                    chat.error(
                        "Something went wrong. Server returned {}.".format(
                            sg.status)))
                return
            profile = await sg.json()
        profile = GodvilleUser(profile)
        text_header = "{} and his {}\n{}\n" \
            .format(chat.bold(profile.god),
                    chat.bold(profile.name),
                    chat.italics(chat.escape(profile.motto.strip(), formatting=True))
                    if profile.motto else chat.inline("Nothing here"))
        if profile.arena_is_in_fight:
            text_header += "In fight: {}\n".format(profile.fight_type_rus)
        if profile.town:
            text_header += "In city: {}\n".format(profile.town)
        if profile.need_update:
            text_header += chat.bold("! INFO OUTDATED !") + "\n"
        text = ""
        pet = ""
        times = ""
        if profile.gold_approximately:
            text += "Gold: {}\n".format(profile.gold_approximately)
        if profile.distance:
            text += "Milestone: {}\n".format(profile.distance)
        if profile.quest_progress:
            text += "Quest: {} ({}%)\n".format(profile.quest,
                                               profile.quest_progress)
        if profile.experience:
            text += "Exp for next level: {}%\n".format(profile.experience)
        text += "Level: {}\n".format(profile.level)
        if profile.godpower:
            text += "Godpower: {}/{}\n".format(
                profile.godpower, 200 if profile.savings_date else 100)
        text += "Personality: {}\n".format(profile.alignment)
        text += "Gender: {}\n".format(profile.gender)
        text += "Wins / Losses: {}/{}\n".format(profile.arena_won,
                                                profile.arena_lost)
        text += "Guild: {} ({})\n".format(profile.clan, profile.clan_position) if profile.clan \
            else "Guild: Not in guild\n"
        text += "Bricks: {} ({}%)\n".format(profile.bricks,
                                            profile.bricks / 10)
        if profile.inventory:
            text += "Inventory: {}/{} ({}%)\n".format(
                profile.inventory, profile.inventory_max,
                int(profile.inventory / profile.inventory_max * 100))
        else:
            text += "Inventory max: {}\n".format(profile.inventory_max)
        if profile.health:
            text += "Health: {}/{} ({}%)\n".format(
                profile.health, profile.health_max,
                int(profile.health / profile.health_max * 100))
        else:
            text += "Health maximum: {}\n".format(profile.health_max)
        if profile.ark_male:
            text += "Manimals: {} ({}%)\n".format(profile.ark_male,
                                                  profile.ark_male / 10)
        if profile.ark_female:
            text += "Fenimals: {} ({}%)\n".format(profile.ark_female,
                                                  profile.ark_female / 10)
        if profile.savings:
            text += "Savings: {}\n".format(profile.savings)
        if profile.trading_level:
            text += "Trading Level: {}\n".format(profile.trading_level)
        if profile.wood:
            text += "Wood: {} ({}%)\n".format(profile.wood, profile.wood / 10)

        # private (api only)
        if profile.diary_last:
            text += "Diary: {}\n".format(profile.diary_last)
        if profile.activatables:
            text += "Activatables in inv: {}\n".format(", ".join(
                profile.activatables))
        if profile.aura:
            text += "Aura: {}\n".format(profile.aura)

        # pet
        if profile.pet.name:
            pet += "Name: {}\n".format(profile.pet.name)
            pet += "Level: {}\n".format(profile.pet.level or "No level")
            if profile.pet.type:
                pet += "Type: {}\n".format(profile.pet.type)
            if profile.pet.wounded:
                pet += "❌ — Knocked out"

        # times
        if profile.temple_date:
            times += "Temple completed: {}\n".format(
                profile.date_string("temple"))
        if profile.ark_date:
            times += "Ark completed: {}\n".format(profile.date_string("ark"))
        if profile.savings_date:
            times += "Pension collected: {}\n".format(
                profile.date_string("savings"))  # ?

        finaltext = ""
        finaltext += text_header
        finaltext += chat.box(text)
        if pet:
            finaltext += "Pet:\n"
            finaltext += chat.box(pet)
        if times:
            finaltext += chat.box(times)
        await ctx.send(finaltext)
示例#17
0
    async def act(self, ctx: commands.Context, *, target: Union[discord.Member, str] = None):
        if not target or isinstance(target, str):
            return  # no help text

        try:
            if not ctx.guild:
                raise KeyError()
            message = await self.config.guild(ctx.guild).get_raw("custom", ctx.invoked_with)
        except KeyError:
            try:
                message = await self.config.get_raw("custom", ctx.invoked_with)
            except KeyError:
                message = NotImplemented

        humanized: Optional[str] = None
        if message is None:  # ignored command
            return
        elif message is NotImplemented:  # default
            # humanize action text
            humanized = inflection.humanize(ctx.invoked_with)
            action = humanized.split()
            iverb = -1

            for cycle in range(2):
                if iverb > -1:
                    break
                for i, act in enumerate(action):
                    act = act.lower()
                    if (
                        act in NOLY_ADV
                        or act in CONJ
                        or (act.endswith("ly") and act not in LY_VERBS)
                        or (not cycle and act in SOFT_VERBS)
                    ):
                        continue
                    action[i] = inflection.pluralize(action[i])
                    iverb = max(iverb, i)

            if iverb < 0:
                return
            action.insert(iverb + 1, target.mention)
            message = italics(" ".join(action))
        else:
            assert isinstance(message, str)
            message = fmt_re.sub(functools.partial(self.repl, target), message)

        send = functools.partial(
            ctx.send,
            allowed_mentions=discord.AllowedMentions(
                users=False if target in ctx.message.mentions else [target]
            ),
        )

        # add reaction gif
        if self.try_after and ctx.message.created_at < self.try_after:
            return await send(message)
        if not await ctx.embed_requested():
            return await send(message)
        key = (await ctx.bot.get_shared_api_tokens("tenor")).get("api_key")
        if not key:
            return await send(message)
        if humanized is None:
            humanized = inflection.humanize(ctx.invoked_with)
        async with aiohttp.request(
            "GET",
            "https://g.tenor.com/v1/search",
            params={
                "q": humanized,
                "key": key,
                "anon_id": str(ctx.author.id ^ ctx.me.id),
                "media_filter": "minimal",
                "contentfilter": "off" if getattr(ctx.channel, "nsfw", False) else "low",
                "ar_range": "wide",
                "limit": 20,
                "locale": i18n.get_locale(),
            },
        ) as response:
            json: dict
            if response.status == 429:
                self.try_after = ctx.message.created_at + timedelta(seconds=30)
                json = {}
            elif response.status >= 400:
                json = {}
            else:
                json = await response.json()
        if not json.get("results"):
            return await send(message)
        # Try to keep gifs more relevant by only grabbing from the top 50% + 1 of results,
        # in case there are only a few results.
        # math.ceiling() is not used since it would be too limiting for smaller lists.
        choice = json["results"][random.randrange(len(json["results"]) // 2 + 1)]
        choice = random.choice(json["results"])
        embed = discord.Embed(
            color=await ctx.embed_color(),
            timestamp=datetime.fromtimestamp(choice["created"], timezone.utc),
            url=choice["itemurl"],
        )
        # This footer is required by Tenor's API: https://tenor.com/gifapi/documentation#attribution
        embed.set_footer(text="Via Tenor")
        embed.set_image(url=choice["media"][0]["gif"]["url"])
        await send(message, embed=embed)
示例#18
0
    async def act(self, ctx, *, target: Union[discord.Member, str] = None):
        """
        Acts on the specified user.
        """
        if not target or isinstance(target, str):
            return  # no help text

        try:
            if not ctx.guild:
                raise KeyError()
            message = await self.config.guild(ctx.guild).get_raw(
                "custom", ctx.invoked_with)
        except KeyError:
            try:
                message = await self.config.get_raw("custom", ctx.invoked_with)
            except KeyError:
                message = NotImplemented

        if message is None:  # ignored command
            return
        elif message is NotImplemented:  # default
            # humanize action text
            action = inflection.humanize(ctx.invoked_with).split()
            iverb = -1

            for cycle in range(2):
                if iverb > -1:
                    break
                for i, act in enumerate(action):
                    act = act.lower()
                    if (act in NOLY_ADV or act in CONJ
                            or (act.endswith("ly") and act not in LY_VERBS)
                            or (not cycle and act in SOFT_VERBS)):
                        continue
                    action[i] = inflection.pluralize(action[i])
                    iverb = max(iverb, i)

            if iverb < 0:
                return
            action.insert(iverb + 1, target.mention)
            message = italics(" ".join(action))
        else:
            message = message.format(target, user=target)

        # add reaction gif
        if not ctx.channel.permissions_for(ctx.me).embed_links:
            return await ctx.send(message)
        key = (await get_shared_api_tokens(ctx.bot, "tenor")).get("api_key")
        if not key:
            return await ctx.send(message)
        async with aiohttp.request(
                "GET",
                "https://api.tenor.com/v1/search",
                params={
                    "q": ctx.invoked_with,
                    "key": key,
                    "anon_id": str(ctx.author.id ^ ctx.me.id),
                    "media_filter": "minimal",
                    "contentfilter": "low",
                    "ar_range": "wide",
                    "locale": get_locale(),
                },
        ) as response:
            if response.status >= 400:
                json: dict = {}
            else:
                json = await response.json()
        if not json.get("results"):
            return await ctx.send(message)
        message = f"{message}\n\n{random.choice(json['results'])['itemurl']}"
        await ctx.send(message)
示例#19
0
     content = kwargs.pop("content")
 except KeyError:
     content = getattr(__dest, "content", None)
 content = str(content) if content is not None else None
 unwrapped = []
 if content:
     unwrapped.extend([content, ""])
 title = _("title")
 if title:
     unwrapped.append(bold(title))
 url = _("url")
 if url:
     unwrapped.append(f"> <{url}>")
 name = _("author.name")
 if name:
     unwrapped.append(italics(name))
 url = _("author.url")
 if url:
     unwrapped.append(f"<{url}>")
 if unwrapped and unwrapped[-1]:
     unwrapped.append("")
 url = _("thumbnail.url")
 if url and not url.startswith("attachment://"):
     unwrapped.append(f"<{url}>")
 description = _("description")
 if description:
     unwrapped.append(quote(description))
 if unwrapped and unwrapped[-1]:
     unwrapped.append("")
 for i in range(len(getattr(self, "_fields", []))):
     inline, name, value = (