Пример #1
0
    async def send_to(self,
                      dest,
                      content=None,
                      files=None,
                      embed=None,
                      allowed_mentions=AllowedMentions(everyone=False,
                                                       roles=False),
                      send_as_slash_command=True,
                      hidden=False,
                      reference=None,
                      mention_author=None,
                      fail_on_dm=None,
                      view=None):
        msg = None

        if fail_on_dm and isinstance(dest, (DMChannel, User, Member)):
            return None

        if isinstance(dest, Webhook):
            msg = await dest.send(content,
                                  username=self.bot_name,
                                  avatar_url=self.bot_avatar,
                                  embed=embed,
                                  files=files,
                                  wait=True,
                                  allowed_mentions=allowed_mentions,
                                  view=view or ui.View())

        elif self.slash_command and send_as_slash_command:
            kwargs = {"content": content, "ephemeral": hidden}
            if embed:
                kwargs["embeds"] = [embed]
            if view:
                kwargs["view"] = view

            if self.sent_first_slash_command:
                msg = InteractionWebhook(await
                                         self.slash_command[1].send(**kwargs),
                                         True)  # webhook
            else:
                await self.slash_command[0].send_message(**kwargs)  # no return
                msg = InteractionWebhook(self.slash_command[2], False)

            if not self.first_slash_command:
                self.first_slash_command = msg
            if not self.sent_first_slash_command:
                self.sent_first_slash_command = True

        else:
            msg = await dest.send(content,
                                  embed=embed,
                                  files=files,
                                  allowed_mentions=allowed_mentions,
                                  reference=reference,
                                  mention_author=mention_author,
                                  view=view)

        self.bot_responses.append(msg.id)

        return msg
Пример #2
0
 def view_func(ctx):
     ui_elements = func(ctx)
     if not isinstance(ui_elements, list):
         ui_elements = [ui_elements]
     ui_view = ui.View(timeout=None)
     for ui_element in ui_elements:
         ui_element.callback = ctx.interaction_payload.callback
         ui_view.add_item(ui_element)
     return ui_view
Пример #3
0
    def create_view(dropdown: InformationDropdown, link: str) -> ui.View:
        """
        Creates the discord.py View for the Discord message components (dropdowns and buttons).

        The discord UI is implemented onto the embed, where the user can choose what information about the kata they
        want, along with a link button to the kata itself.
        """
        view = ui.View()
        view.add_item(dropdown)
        view.add_item(ui.Button(label="View the Kata", url=link))
        return view
Пример #4
0
	async def callback(self, interaction):
		mention = interaction.user.mention
		
		if mention not in self.users:
			self.users[mention]	= self.label		
			await interaction.response.pong()
		else:
			subview = ui.View()
			undo_button = ui.Button(label = "Undo", style = discord.ButtonStyle.danger)
			undo_button.callback = self.undo
			subview.add_item(undo_button)
			
			await interaction.response.send_message(
				content = ":x: | You've already responded.", ephemeral = True, view = subview
			)	
Пример #5
0
    async def trivia(self, ctx, category: typing.Optional[int] = -1):
        catstring = "" if category == -1 else f"&category={category}"
        json = f"https://opentdb.com/api.php?amount=1{catstring}"
        result = await utils.get_json(self.bot.session, json)

        if result["response_code"] == 1:
            raise utils.CustomCommandError(
                "Invalid category code",
                f"Consult `{ctx.clean_prefix}trivia categories` to see the available codes."
            )

        result = result["results"][0]
        info = f"**{result['category']}** | {result['difficulty'].capitalize()}\n\n"
        embed = embeds.GENERIC.create(html.unescape(result["question"]),
                                      info,
                                      heading="Trivia")
        correct = random.randrange(0, 2 if result["type"] == "boolean" else 4)

        answers = result["incorrect_answers"]
        answers.insert(correct, result["correct_answer"])

        embed.description += f"The correct answer will appear in **one minute.**"
        embed.set_footer(text=f"Courtesy of the Open Trivia Database.")

        view = ui.View()
        users = {}
        tuple(
            view.add_item(views.TriviaButton(answer, users))
            for answer in answers)

        message = await ctx.send(embed=embed, view=view)
        await asyncio.sleep(60)

        embed.description = f"{info}The correct answer is: **{html.unescape(answers[correct])}**"
        updated = await message.channel.fetch_message(message.id)

        if updated is None: return  #message deleted

        results = defaultdict(list)

        for user, answer in users.items():
            results[answer].append(user)

        stats = "\n".join(f"- {a}: {','.join(u)} (**{len(u)}**)"
                          for a, u in results.items())
        if stats: embed.description += f"\n\n**Responses:**\n\u0020{stats}"

        await message.edit(embed=embed, view=None)
Пример #6
0
async def wait_for_press(
    ctx: commands.Context,
    items: List[PredItem],
    content: Optional[str] = None,
    embed: Optional[Embed] = None,
    *,
    timeout: float = 180.0,
) -> Any:
    """Wait for a single button press with customisable buttons.

    Only the original author will be allowed to use this.

    Parameters
    ----------
    ctx : commands.Context
        Context to send message to
    items : List[PredItem]
        List of items to send as buttons
    content : Optional[str], optional
        Content of the message, by default None
    embed : Optional[Embed], optional
        Embed of the message, by default None
    timeout : float, optional
        Button timeout, by default 180.0

    Returns
    -------
    Any
        The defined reference of the clicked button

    Raises
    ------
    ValueError
        An empty list was supplied
    asyncio.TimeoutError
        A button was not pressed in time.
    """
    if not items:
        raise ValueError("The `items` argument cannot contain an empty list.")

    view = _PredView(timeout, ctx.author.id)  # type:ignore
    for i in items:
        button = _PredButton(i.ref, i.style, i.label, i.row)
        view.add_item(button)
    message = await ctx.send(content=content, embed=embed, view=view)

    await asyncio.wait_for(view.pressed.wait(), timeout=timeout)

    emptyview = ui.View()
    for i in items:
        button = ui.Button(
            style=i.style if i.ref == view.ref else ButtonStyle.gray,
            label=i.label,
            row=i.row,
            disabled=True,
        )
        emptyview.add_item(button)
    await message.edit(view=emptyview)
    emptyview.stop()

    return view.ref
Пример #7
0
async def wait_for_yes_no(
    ctx: commands.Context,
    content: Optional[str] = None,
    embed: Optional[Embed] = None,
    *,
    timeout: float = 180.0,
) -> bool:
    """Wait for a single button press of pre-defined yes and no buttons, returning True for yes
    and False for no.

    If you want to customise the buttons, I recommend you use the more generic `wait_for_press`.

    Only the original author will be allowed to use this.

    Parameters
    ----------
    ctx : commands.Context
        Context to send message to
    content : Optional[str], optional
        Content of the message, by default None
    embed : Optional[Embed], optional
        Embed of the message, by default None
    timeout : float, optional
        Button timeout, by default 180.0

    Returns
    -------
    bool
        True or False, depending on the clicked button.

    Raises
    ------
    asyncio.TimeoutError
        A button was not pressed in time.
    """
    view = _PredView(timeout, ctx.author.id)  # type:ignore
    view.add_item(_PredButton(True, ButtonStyle.blurple, "Yes"))
    view.add_item(_PredButton(False, ButtonStyle.blurple, "No"))

    message = await ctx.send(content=content, embed=embed, view=view)

    await asyncio.wait_for(view.pressed.wait(), timeout=timeout)

    emptyview = ui.View()
    emptyview.add_item(
        ui.Button(
            style=ButtonStyle.grey
            if view.ref is False else ButtonStyle.blurple,
            label="Yes",
            disabled=True,
        ))
    emptyview.add_item(
        ui.Button(
            style=ButtonStyle.grey
            if view.ref is True else ButtonStyle.blurple,
            label="No",
            disabled=True,
        ))
    await message.edit(view=emptyview)
    emptyview.stop()

    return view.ref
Пример #8
0
class CreateHelpChannelButton(ui.View):
    def __init__(self, bot: HelpCenterBot) -> None:
        """The view below the message in #ask-for-help, to create thread channels."""
        super().__init__(timeout=None)
        self.bot = bot

    @ui.button(label="Nouveau / New",
               custom_id='create_help_channel',
               emoji="➕",
               style=discord.ButtonStyle.blurple)
    async def create_help_channel(self, __: ui.Button,
                                  inter: discord.Interaction) -> None:
        member = inter.guild.get_member(
            inter.user.id) or await inter.guild.fetch_member(inter.user.id)
        await inter.channel.set_permissions(member, send_messages=True)

        await self.bot.set_actual_language(
            inter.user)  # define bot langage for the next text

        content = _(
            "**Give a title to your request.** \n"
            "*Do not send your whole problem, just a very concise description with maximum context. (Language, OS, library used...) *\n\n"
            "> Example: \"[Python - Discord.py] Is it possible to kick any one of a server with its id?\""
        )
        await inter.response.send_message(content, ephemeral=True)

        async def wait_for_title() -> Optional[discord.Message]:
            try:
                return await self.bot.wait_for(
                    "message",
                    check=lambda msg: msg.channel.id == inter.channel_id and
                    msg.author.id == inter.user.id,
                    timeout=300)
            except asyncio.TimeoutError:
                await inter.channel.set_permissions(member, overwrite=None)

        while (message := await
               wait_for_title()) and len(message.content) > 200:
            await self.bot.set_actual_language(
                inter.user)  # define bot langage for the next text
            await inter.edit_original_message(content=_(
                "{0}\n\n"
                "⚠ **This is not your full message of the request, the title must be short (less than 100 characters)**.\n\n"
                "Your current request:```\n{1}\n```").format(
                    content, message.content))
            await message.delete()

        if not message: return  # Timeout reached

        if message.type is discord.MessageType.thread_created:  # The user can created a thread by him-self
            embed = discord.Embed()
            thread = inter.guild.get_channel(message.id)
        else:
            await message.delete()

            thread = await inter.channel.create_thread(
                name=f"{message.content[:100]}",
                auto_archive_duration=1440,
                type=discord.ChannelType.public_thread,
                reason="HelpCenter help-thread system.")

            await inter.channel.set_permissions(member, overwrite=None)

            view = ui.View()
            view.stop()
            view.add_item(
                ui.Button(label=_("Archive"),
                          custom_id=f"archive_help_thread_{inter.user.id}"))
            view.add_item(
                ui.Button(label=_("Delete"),
                          custom_id=f"delete_help_thread_{inter.user.id}"))

            await self.bot.set_actual_language(
                inter.user
            )  # redefine the language, if he was long to write his answer

            embed = discord.Embed(color=discord.Color.yellow(),
                                  title=message.content)
            embed.add_field(
                name=_("Ask your question."),
                value=
                _("Be as clear as possible, remember to send code if there is, or screens highlighting the problem! \n\n"
                  "**\⚠️ Do not share passwords, bot tokens... if anyone in demand, warn a staff member** \⚠️"
                  ),
                inline=False)

            embed.set_footer(text=_("⬇ click to archive the thread"))

            await thread.add_user(inter.user)

        await self.bot.set_actual_language(inter.user)
        embed.add_field(
            name=_('How to ask a question ?'),
            value=
            _(":ballot_box_with_check: have you searched on Google ? [Search](https://google.com/search?q={0})\n"
              ":ballot_box_with_check: have you read the doc ?\n"
              ":ballot_box_with_check: don't ask to ask, just ask. https://dontasktoask.com/\n"
              ":ballot_box_with_check: asking about your attempted solution rather than your actual problem. https://xyproblem.info/"
              ).format(
                  parse.quote_plus(" ".join(
                      word[:50] for word in message.content.split(' ')[:32]))),
            inline=False)

        await thread.send(embed=embed, view=view)