Exemplo n.º 1
0
    async def _courses_create(self, ctx, role: str, *, sections_num: int = 0):
        """
        Creates a category based on the course name supplied.

        If the role for the course doesn't exist it will
        query to user if it should be created as well.
        """
        if role == "":
            return await ctx.send(error("Role cannot be blank"))

        role = role.lower()

        sections_num = max(sections_num, 0)

        # regisiter the course with the database
        await self._courses_register(ctx, role, sort=True)

        await ctx.channel.send("Done.")
Exemplo n.º 2
0
 async def _save_public_private(
     self,
     ctx: commands.Context,
     autoroom_source: discord.VoiceChannel,
     room_type: str,
 ):
     """Save the public/private setting."""
     async with self.config.guild(ctx.guild).auto_voice_channels() as avcs:
         try:
             avcs[str(autoroom_source.id)]["room_type"] = room_type
         except KeyError:
             await ctx.send(
                 error("{} is not an AutoRoom Source channel.".format(
                     autoroom_source.mention)))
         else:
             await ctx.send(
                 checkmark("New AutoRooms created by {} will be {}.".format(
                     autoroom_source.mention, room_type)))
Exemplo n.º 3
0
    async def max_requestable(self, ctx, count: int):
        """Maximum number of roles that users can request.
        
        If set to -1, there is no limit."""
        if count < -1:
            await self._raw_send_no_mention(
                ctx, error("Maximum must not be negative."))

        await self.config.guild(ctx.guild).max_requestable.set(count)

        if count == -1:
            count_str = "unlimited"
        else:
            count_str = str(count)
        await self._raw_send_no_mention(
            ctx,
            info("The maximum number of requestable roles per user is now {}.".
                 format(count_str)))
Exemplo n.º 4
0
 async def modify_text_enable(
     self,
     ctx: commands.Context,
     autoroom_source: discord.VoiceChannel,
 ):
     """Enable creating a text channel with the AutoRoom."""
     if await self.get_autoroom_source_config(autoroom_source):
         await self.config.custom("AUTOROOM_SOURCE", ctx.guild.id,
                                  autoroom_source.id).text_channel.set(True)
         await ctx.send(
             checkmark(
                 f"New AutoRooms created by **{autoroom_source.mention}** will now get their own text channel."
             ))
     else:
         await ctx.send(
             error(
                 f"**{autoroom_source.mention}** is not an AutoRoom Source channel."
             ))
Exemplo n.º 5
0
 async def skin(self, ctx, player: MCPlayer, overlay: bool = True):
     """Get minecraft skin by nickname"""
     uuid = player.uuid
     stripname = player.name.strip("_")
     files = []
     async with ctx.channel.typing():
         try:
             async with self.session.get(
                     f"https://crafatar.com/renders/head/{uuid}",
                     params="overlay" if overlay else None,
             ) as s:
                 files.append(
                     discord.File(BytesIO(await s.read()),
                                  filename=f"{stripname}_head.png"))
             async with self.session.get(
                     f"https://crafatar.com/skins/{uuid}") as s:
                 files.append(
                     discord.File(BytesIO(await s.read()),
                                  filename=f"{stripname}.png"))
             async with self.session.get(
                     f"https://crafatar.com/renders/body/{uuid}.png",
                     params="overlay" if overlay else None,
             ) as s:
                 files.append(
                     discord.File(BytesIO(await s.read()),
                                  filename=f"{stripname}_body.png"))
         except aiohttp.ClientResponseError as e:
             await ctx.send(
                 chat.error(
                     _("Unable to get data from Crafatar: {}").format(
                         e.message)))
             return
     em = discord.Embed(timestamp=ctx.message.created_at,
                        color=await ctx.embed_color())
     em.set_author(
         name=player.name,
         icon_url=f"attachment://{stripname}_head.png",
         url=f"https://crafatar.com/skins/{uuid}",
     )
     em.set_thumbnail(url=f"attachment://{stripname}.png")
     em.set_image(url=f"attachment://{stripname}_body.png")
     em.set_footer(text=_("Provided by Crafatar"),
                   icon_url="https://crafatar.com/logo.png")
     await ctx.send(embed=em, files=files)
Exemplo n.º 6
0
 async def modify_text_hint_disable(
     self,
     ctx: commands.Context,
     autoroom_source: discord.VoiceChannel,
 ):
     """Disable sending a message to the newly generated text channel."""
     if await self.get_autoroom_source_config(autoroom_source):
         await self.config.custom(
             "AUTOROOM_SOURCE", ctx.guild.id,
             autoroom_source.id).text_channel_hint.clear()
         await ctx.send(
             checkmark(
                 f"New AutoRooms created by **{autoroom_source.mention}** will no longer have a message sent to their text channel."
             ))
     else:
         await ctx.send(
             error(
                 f"**{autoroom_source.mention}** is not an AutoRoom Source channel."
             ))
Exemplo n.º 7
0
    async def rolls(self, ctx: commands.Context, maximum: int):
        """Set the maximum number of dice a user can roll at one time.

        More formally, the maximum number of random numbers the bot will generate for any one dice calculation.
        WARNING:
        Setting this too high will allow other users to slow down/freeze/crash your bot!
        Generating random numbers is easily the most CPU consuming process here,
        so keep this number low (less than one million, and way less than that on a Pi)
        """
        action = "is already set at"
        if maximum == await self.config.max_dice_rolls():
            pass
        elif maximum > 1000000:
            pred = MessagePredicate.yes_or_no(ctx)
            await ctx.send(
                question(
                    f"Are you **sure** you want to set the maximum rolls to {maximum}? (yes/no)\n"
                    "Setting this over one million will allow other users to slow down/freeze/crash your bot!"
                )
            )
            try:
                await ctx.bot.wait_for("message", check=pred, timeout=30)
            except asyncio.TimeoutError:
                pass
            if pred.result:
                await self.config.max_dice_rolls.set(maximum)
                action = "is now set to"
            else:
                await ctx.send(
                    error(
                        f"Maximum dice rolls per user has been left at {await self.config.max_dice_rolls()}"
                    )
                )
                return
        else:
            await self.config.max_dice_rolls.set(maximum)
            action = "is now set to"

        await ctx.send(
            checkmark(
                f"Maximum dice rolls per user {action} {await self.config.max_dice_rolls()}"
            )
        )
Exemplo n.º 8
0
 async def predicate(ctx: commands.Context):
     if (
         not ctx.guild
         or ctx.channel.is_nsfw()
         or ctx.invoked_with == "help"
         or ctx.invoked_subcommand
     ):
         return True
     if ctx.invoked_with not in [k for k in ctx.bot.all_commands]:
         # For this weird issue with last version of discord.py (1.2.3) with non-existing commands.
         # So this check is only for dev version of Red.
         # https://discordapp.com/channels/133049272517001216/133251234164375552/598149067268292648 for reference.
         # It probably need to check in d.py to see what is happening, looks like an issue somewhere.
         # It will probably removed in the future, it's a temporary check.
         return False
     try:
         await ctx.send(chat.error(_("You can't use this command in a non-NSFW channel!")))
     finally:
         return False
Exemplo n.º 9
0
 async def clear(self, ctx):
     """Clears all requestable roles."""
     # requestable list
     role_subset = await self.config.guild(ctx.guild).roles()
     role_objs = [x for x in ctx.author.roles if x.id in role_subset]
     role_count = len(role_objs)
     if role_count > 0:
         await ctx.author.remove_roles(*role_objs)
         if role_count > 1:
             await ctx.send(
                 "Removed {num} of your roles.".format(num=role_count))
         else:
             await ctx.send("Removed {r} from your roles.".format(
                 r=await self._get_role_styled(ctx, role_objs[0])))
         if await self.config.guild(ctx.guild).auto_post_list():
             await self._auto_post_list(ctx)
     else:
         await ctx.send(
             error("You do not have any requestable roles to remove."))
Exemplo n.º 10
0
 async def colour(self,
                  ctx,
                  *,
                  colour: discord.Colour = discord.Colour.default()):
     """Change color of personal role"""
     role = await self.config.member(ctx.author).role()
     role = ctx.guild.get_role(role)
     try:
         await role.edit(colour=colour,
                         reason=get_audit_reason(ctx.author,
                                                 "Personal Role"))
     except discord.Forbidden:
         await ctx.send(
             chat.error(
                 "Unable to edit role.\nRole must be lower than my top role and i must have "
                 "permission \"Manage Roles\""))
     else:
         await ctx.send("Changed color of {}'s personal role to {}".format(
             ctx.message.author.name, colour))
Exemplo n.º 11
0
    async def dice(self, ctx: commands.Context, *, roll: str):
        """Perform die roll based on a dice formula.

        The [PyHedrals](https://github.com/StarlitGhost/pyhedrals) library is used for dice formula parsing.
        Use the link above to learn the notation allowed. Below are a few examples:

        `2d20kh` - Roll 2d20, keep highest die (e.g. initiative advantage)
        `4d4!+2` - Roll 4d4, explode on any 4s, add 2 to result
        `4d6rdl` - Roll 4d6, reroll all 1s, then drop the lowest die
        `6d6c>4` - Roll 6d6, count all dice greater than 4 as successes
        `10d10r<=2kh6` - Roll 10d10, reroll all dice less than or equal to 2, then keep the highest 6 dice

        Modifier order does matter, and usually they allow for specifying a specific number or number ranges after them.
        """
        try:
            dr = pyhedrals.DiceRoller(
                maxDice=await self.config.max_dice_rolls(),
                maxSides=await self.config.max_die_sides(),
            )
            result = dr.parse(roll)
            roll_message = f"\N{GAME DIE} {ctx.message.author.mention} rolled {roll} and got **{result.result}**"
            if len(roll_message) > 2000:
                raise ValueError(
                    "resulting roll message is too big to send in Discord")
            roll_log = "\n".join(result.strings())
            roll_log = self.DROPPED_EXPLODED_RE.sub(r"~~**\1!**~~", roll_log)
            roll_log = self.EXPLODED_RE.sub(r"**\1!**", roll_log)
            roll_log = self.DROPPED_RE.sub(r"~~\1~~", roll_log)
            roll_log = roll_log.replace(",", ", ")
            if len(roll_message) + len(roll_log) > 2000:
                roll_log = "*(Roll log too long to display)*"
            await ctx.send(f"{roll_message}\n{roll_log}")
        except (
                ValueError,
                NotImplementedError,
                pyhedrals.InvalidOperandsException,
                pyhedrals.SyntaxErrorException,
                pyhedrals.UnknownCharacterException,
        ) as exception:
            await ctx.send(
                error(
                    f"{ctx.message.author.mention}, I couldn't parse your dice formula:\n`{str(exception)}`"
                ))
Exemplo n.º 12
0
 async def rule_set(self, ctx, rule_num: int = None, *, rule: str = None):
     """
     Set a guild rule
     Will overwrite an existing rule of the same number.
     """
     if ctx.invoked_subcommand:
         return
     elif rule_num is not None and rule is not None:
         async with self.config.guild(ctx.guild).rules() as rules:
             rules[str(rule_num)] = rule
         await ctx.tick()
     elif rule_num is not None:
         rules = await self.config.guild(ctx.guild).rules()
         try:
             await ctx.send(rules[str(rule_num)])
         except KeyError:
             await ctx.send(chat.error("That rule doesn't exist!"))
     else:
         await self.bot.send_help_for(ctx, self.rule_set)
Exemplo n.º 13
0
    async def embedwiz_edit(self, ctx, message_id: int, *, specification):
        """
        Edits an existing embed according to the spec.
        See [p]help embedwiz for more information.
        """
        channel = ctx.channel
        #member = channel.server and channel.server.get_member(ctx.message.author.id)

        #if channel != ctx.message.channel and not member:
        #await ctx.send(error("Channel is private or you aren't in the server that channel belongs to."))
        #return

        try:
            msg = await ctx.fetch_message(message_id)
            #msg = await self.bot.get_message(channel, str(message_id))
        except discord.errors.NotFound:
            await ctx.send(error('Message not found.'))
            return
        except discord.errors.Forbidden:
            await ctx.send(error('No permissions to read that channel.'))
            return

        if msg.author.id != self.bot.user.id:
            await ctx.send(error("That message isn't mine."))
            return
        elif not msg.embeds:
            await ctx.send(error("That message doesn't have an embed."))
            return

        old_embed = msg.embeds[0]
        override = 0  #self._check_override(member)

        if override:
            pass
        elif 'author' not in old_embed or 'name' not in old_embed['author']:
            await ctx.send(
                error(
                    "That embed doesn't have an author set, and you aren't a mod or admin."
                ))
            return
        elif old_embed['author']['name'].split(
                '(')[-1][:-1] != ctx.message.author.id:
            await ctx.send(error("That embed isn't yours."))
            return

        new_embed = await self._parse_embed(ctx,
                                            specification,
                                            force_author=not override)
        await self.bot.edit_message(msg, embed=new_embed)
        await ctx.send('Embed edited successfully.')
Exemplo n.º 14
0
 async def cleanup_users(self,
                         ctx,
                         days: Optional[int] = 1,
                         *roles: discord.Role):
     """Cleanup inactive server members"""
     if days > 30:
         await ctx.send(
             chat.info(
                 _("Due to Discord Restrictions, you cannot use more than 30 days for that cmd."
                   )))
         days = 30
     elif days <= 0:
         await ctx.send(chat.info(_('"days" arg cannot be less than 1...')))
         days = 1
     to_kick = await ctx.guild.estimate_pruned_members(days=days)
     pred = MessagePredicate.yes_or_no(ctx)
     if not ctx.assume_yes:
         roles_text = _("\nIncluding members in roles: {}\n").format(
             ", ".join(r.mention for r in roles))
         await ctx.send(
             chat.warning(
                 _("You are about to kick **{to_kick}** inactive for **{days}** days members from this server. "
                   '{roles}Are you sure?\nTo agree, type "yes"').format(
                       to_kick=to_kick,
                       days=days,
                       roles=roles_text if roles else "")))
         try:
             await self.bot.wait_for("message", check=pred, timeout=30)
         except AsyncTimeoutError:
             pass
     if ctx.assume_yes or pred.result:
         cleanup = await ctx.guild.prune_members(days=days,
                                                 reason=get_audit_reason(
                                                     ctx.author),
                                                 roles=roles or None)
         await ctx.send(
             chat.info(
                 _("**{removed}**/**{all}** inactive members removed.\n"
                   "(They were inactive for **{days}** days)").format(
                       removed=cleanup, all=to_kick, days=days)))
     else:
         await ctx.send(chat.error(_("Inactive members cleanup canceled.")))
Exemplo n.º 15
0
 async def _save_room_name(
     self,
     ctx: commands.Context,
     autoroom_source: discord.VoiceChannel,
     room_type: str,
 ):
     """Save the room name type."""
     async with self.config.guild(ctx.guild).auto_voice_channels() as avcs:
         try:
             avcs[str(autoroom_source.id)]["channel_name_type"] = room_type
         except KeyError:
             await ctx.send(
                 error(
                     f"**{autoroom_source.mention}** is not an AutoRoom Source channel."
                 ))
         else:
             await ctx.send(
                 checkmark(
                     f"New AutoRooms created by **{autoroom_source.mention}** "
                     f"will use the **{room_type.capitalize()}** format."))
Exemplo n.º 16
0
 async def service_disable(self, ctx: commands.Context, service: str):
     """Disable a service."""
     disabled_services = await self.config.guild(ctx.message.guild
                                                 ).disabled_services()
     if service in self.supported_services and service in disabled_services:
         await ctx.send(
             info("{} is already disabled for this guild.".format(
                 self.get_nice_service_name(service))))
     elif service in self.supported_services:
         disabled_services.append(service)
         await self.config.guild(ctx.message.guild
                                 ).disabled_services.set(disabled_services)
         await ctx.send(
             checkmark(
                 "Ban checking with {} has now been disabled for this guild!"
                 .format(self.get_nice_service_name(service))))
     else:
         await ctx.send(
             error("`{}` is not a valid service name.".format(
                 self.get_nice_service_name(service))))
Exemplo n.º 17
0
 async def _save_public_private(
     self,
     ctx: commands.Context,
     autoroom_source: discord.VoiceChannel,
     room_type: str,
 ):
     """Save the public/private setting."""
     if await self.get_autoroom_source_config(autoroom_source):
         await self.config.custom(
             "AUTOROOM_SOURCE", ctx.guild.id,
             autoroom_source.id).room_type.set(room_type)
         await ctx.send(
             checkmark(
                 f"**{autoroom_source.mention}** will now create `{room_type}` AutoRooms."
             ))
     else:
         await ctx.send(
             error(
                 f"**{autoroom_source.mention}** is not an AutoRoom Source channel."
             ))
Exemplo n.º 18
0
    async def addrole(self, ctx, *, role_name):
        """Adds a role to be requestable."""
        # find matches
        role_to_add = await self._find_role(ctx, role_name)
        if role_to_add is None:
            return

        async with self.config.guild(ctx.guild).roles() as role_subset:
            if role_to_add.id in role_subset:
                await ctx.send(
                    error("Role {r} can already be requested.".format(
                        r=await self._get_role_styled(ctx, role_to_add))))
                return

            role_subset.append(role_to_add.id)
            await ctx.send(
                info("Added {r} to requestable roles list.".format(
                    r=await self._get_role_styled(ctx, role_to_add))))
            if await self.config.guild(ctx.guild).auto_post_list():
                await self._auto_post_list(ctx)
Exemplo n.º 19
0
    async def default(self, ctx: commands.Context,
                      autoroom_source: discord.VoiceChannel):
        """Reset the increment format back to default.

        The default format, for those curious, is ` ({number})`
        (which looks like "Room Name (2)")
        """
        if await self.get_autoroom_source_config(autoroom_source):
            await self.config.custom(
                "AUTOROOM_SOURCE", ctx.guild.id,
                autoroom_source.id).increment_format.clear()
            await ctx.send(
                checkmark(
                    f"Channel name increment format for **{autoroom_source.mention}** has been reset to default."
                ))
        else:
            await ctx.send(
                error(
                    f"**{autoroom_source.mention}** is not an AutoRoom Source channel."
                ))
Exemplo n.º 20
0
    async def set_channel(self,
                          ctx: commands.Context,
                          channel: discord.TextChannel = None):
        """Set the channel you want new user BanCheck notices to go to."""
        if channel is None:
            channel = ctx.message.channel
        await self.config.guild(ctx.message.guild
                                ).notify_channel.set(channel.id)

        try:
            embed = self.embed_maker(
                None,
                discord.Colour.green(),
                checkmark("**I will send all BanCheck notices here.**"),
                self.bot.user.avatar_url,
            )
            await channel.send(embed=embed)
        except (discord.errors.Forbidden, discord.errors.NotFound):
            await channel.send(
                error("**I'm not allowed to send embeds here.**"))
Exemplo n.º 21
0
 async def gettinfo(
     self,
     ctx: commands.Context,
     word_type: WordType,
     word: str,
 ):
     try:
         async with self.session.get(TYPES[word_type]["endpoint"] + word) as session:
             data = await session.json()
     except aiohttp.ClientError:
         await ctx.maybe_send_embed(warning("Failed to connect to the API."))
         return
     else:
         if not data:
             if word_type == "ml":
                 message = "No words found for this definition."
             else:
                 message = "No matches found for this word."
             return await ctx.maybe_send_embed(error(message))
         await self.create_menu(ctx, word_type, word, data)
Exemplo n.º 22
0
    async def build_karma_view(self, ctx, member: discord.Member):
        """
        Displays a user's karma score.
        """
        if not isinstance(member, discord.Member):
            try:
                member = self.bot.get_guild(self.guild_id).get_member(
                    int(member))
            except ValueError:
                msg = f"{member} is not a valid member id."
                logger.exception(msg)
                await ctx.send(
                    warning(
                        "Oops, Something went wrong. Ask an **admin** or **bot-dev** to check the log."
                    ))
                return await self.properties["channels"].log.send(error(msg))

        if member is None:
            return await ctx.send(warning("User not found."))

        def build_field(group):
            return (f"**Current:** {group['current']}\n"
                    f"**All Time:** {group['total']}")

        try:
            been_thanked_val = build_field(
                await self.db.member(member).been_thanked())
            thanked_others_val = build_field(
                await self.db.member(member).thanked_others())
        except KeyError:
            logger.error("Member does not exist.")
            return None
        else:
            embed = discord.Embed(title=f"{member.display_name}'s karma")
            embed.add_field(name="Thanked by others",
                            value=been_thanked_val,
                            inline=False)
            embed.add_field(name="Thanked others",
                            value=thanked_others_val,
                            inline=False)
            return randomize_color(embed)
Exemplo n.º 23
0
 async def discordstatus(self, ctx):
     """Get current discord status from discordstatus.com"""
     async with ctx.typing():
         try:
             async with self.session.get(
                     "https://srhpyqt94yxb.statuspage.io/api/v2/summary.json"
             ) as data:
                 response = await data.json(loads=json.loads)
         except Exception as e:
             await ctx.send(
                 chat.error(
                     _("Unable to get data from https://discordstatus.com: {}"
                       ).format(e)))
             return
         status = response["status"]
         components = response["components"]
         if await ctx.embed_requested():
             embed = discord.Embed(
                 title=_("Discord Status"),
                 description=_(
                     DISCORD_STATUS_NAMES.get(status["indicator"],
                                              status["indicator"])),
                 timestamp=datetime.datetime.fromisoformat(
                     response["page"]["updated_at"]).astimezone(
                         datetime.timezone.utc).replace(
                             tzinfo=None),  # make naive
                 color=await ctx.embed_color(),
                 url="https://discordstatus.com",
             )
             for component in components:
                 embed.add_field(
                     name=component["name"],
                     value=component["status"].capitalize().replace(
                         "_", " "),
                 )
             await ctx.send(embed=embed)
         else:
             await ctx.send(
                 f"{_(DISCORD_STATUS_NAMES.get(status['indicator'], status['indicator']))}\n"
                 f"{chat.box(tabulate([(c['name'], c['status'].capitalize().replace('_', ' ')) for c in components]))}"
             )
Exemplo n.º 24
0
    async def wikipedia(self, ctx: commands.Context, *, query: str):
        """Get information from Wikipedia."""
        can_not_embed_links = not ctx.channel.permissions_for(
            ctx.me).embed_links
        can_not_add_reactions = not ctx.channel.permissions_for(
            ctx.me).add_reactions
        can_not_read_history = not ctx.channel.permissions_for(
            ctx.me).read_message_history
        only_first_result = (can_not_embed_links or can_not_add_reactions
                             or can_not_read_history)
        async with ctx.typing():
            embeds, url = await self.perform_search(
                query, only_first_result=only_first_result)

        if not embeds:
            await ctx.send(
                error(f"I'm sorry, I couldn't find \"{query}\" on Wikipedia"))
        elif can_not_embed_links:
            await ctx.send(
                warning(
                    f"I'm not allowed to do embeds here, so here's the first result:\n{url}"
                ))
        elif can_not_add_reactions:
            embeds[0].set_author(
                name="Result 1 (I need add reactions permission to show more)")
            await ctx.send(embed=embeds[0])
        elif can_not_read_history:
            embeds[0].set_author(
                name=
                "Result 1 (I need read message history permission to show more)"
            )
            await ctx.send(embed=embeds[0])
        elif len(embeds) == 1:
            embeds[0].set_author(name="Result 1 of 1")
            await ctx.send(embed=embeds[0])
        else:
            count = 0
            for embed in embeds:
                count += 1
                embed.set_author(name=f"Result {count} of {len(embeds)}")
            await menu(ctx, embeds, DEFAULT_CONTROLS, timeout=60.0)
Exemplo n.º 25
0
    async def wikipedia(self, ctx: commands.Context, *, query: str):
        """Get information from Wikipedia."""
        async with ctx.typing():
            payload = self.generate_payload(query)
            conn = aiohttp.TCPConnector()
            async with aiohttp.ClientSession(connector=conn) as session:
                async with session.get(
                    "https://en.wikipedia.org/w/api.php",
                    params=payload,
                    headers={"user-agent": "Red-DiscordBot/" + redbot_version},
                ) as res:
                    result = await res.json()

            embeds = []
            if "query" in result and "pages" in result["query"]:
                for page in result["query"]["pages"]:
                    try:
                        embeds.append(self.generate_embed(page))
                        if not ctx.channel.permissions_for(ctx.me).embed_links:
                            # No embeds here :(
                            await ctx.send(
                                warning(
                                    "I'm not allowed to do embeds here...\n{}".format(
                                        page["fullurl"]
                                    )
                                )
                            )
                            return
                        if not ctx.channel.permissions_for(ctx.me).add_reactions:
                            break  # Menu can't function so only show first result
                    except KeyError:
                        pass

        if not embeds:
            await ctx.send(
                error("I'm sorry, I couldn't find \"{}\" on Wikipedia".format(query))
            )
        elif len(embeds) == 1:
            await ctx.send(embed=embeds[0])
        else:
            await menu(ctx, embeds, DEFAULT_CONTROLS, timeout=60.0)
Exemplo n.º 26
0
 async def _save_channel(
     self,
     ctx: commands.Context,
     channel: Optional[discord.TextChannel],
     channel_type: Union[str, list],
 ):
     """Actually save the ReactChannel settings."""
     if channel is None:
         channel = ctx.message.channel
     if isinstance(channel_type, list):
         try:
             for emoji in channel_type:
                 await ctx.message.add_reaction(emoji)
             for emoji in channel_type:
                 await ctx.message.remove_reaction(emoji, self.bot.user)
         except discord.HTTPException:
             await ctx.send(
                 error(
                     f"{'That' if len(channel_type) == 1 else 'One of those emojis'} is not a valid emoji I can use!"
                 ))
             return
     await self.config.custom("REACT_CHANNEL", ctx.guild.id,
                              channel.id).set(
                                  {"channel_type": channel_type})
     channel_type_name = channel_type
     custom_emojis = ""
     if isinstance(channel_type_name, list):
         channel_type_name = "custom"
         custom_emojis = f" ({', '.join(channel_type)})"
     await ctx.send(
         checkmark(
             f"{channel.mention} is now a {channel_type_name} ReactChannel.{custom_emojis}"
         ))
     if (channel_type == "vote"
             and not await self._get_emoji(ctx.guild, "upvote")
             and not await self._get_emoji(ctx.guild, "downvote")):
         await ctx.send(
             warning(
                 "You do not have an upvote or downvote emoji set for this server. "
                 "You will need at least one set in order for this ReactChannel to work. "
                 "Check `[p]reactchannelset emoji` for more information."))
Exemplo n.º 27
0
    async def rot13(self, ctx, *, text):
        """Encodes text using ROT-13."""
        if isinstance(ctx.channel, discord.TextChannel):
            # this not is a DM or group DM
            #message = ctx.message
            #footer = "In channel #{channel} on {guild}".format(channel = ctx.channel, guild = message.guild)
            #async with ctx.typing():
            await ctx.send(content=error(
                "This is a server channel. The ROT-13 command is supported for direct messages only. The purpose is to make an encoded message."
            ))
            #try:
            #    await message.delete()
            #except (discord.Forbidden, discord.HTTPException):
            #    # permissions to delete here denied
            #    await ctx.send(content=error("This is a public location and I do not have permission to delete your message!"))
            #    return

            #embed = discord.Embed(description=self._rot13(text))
            #if message.author.color != discord.Color.default():
            #    embed.color = message.author.color
            #embed.set_author(name=message.author.display_name)
            #embed.set_thumbnail(url=message.author.avatar_url)
            #embed.set_footer(text=footer)
            #embed.timestamp = message.created_at
            ##await user.send(content=self._rot13(message.clean_content))
            #try:
            #    post = await ctx.send(embed=embed)
            #except (discord.Forbidden, discord.HTTPException):
            #    await ctx.send(content=error("This is a public location and I do not have the ability to post an embed!"))
            #    return

            #self.embed_cache.append(int(message.id))

            #settings = await self.config.guild(message.guild).all()
            #try:
            #    await post.add_reaction(settings["react"])
            #except (discord.NotFound, discord.Forbidden, discord.HTTPException):
            #    pass
        else:
            # private location: only reply with text
            await ctx.send(content=self._rot13(text))
Exemplo n.º 28
0
 async def autoban_enable(self, ctx: commands.Context, service: str):
     """Enable a service to ban users automatically."""
     if service not in self.all_supported_services:
         await ctx.send(
             error("{} is not a valid service name.".format(
                 self.get_nice_service_name(service))))
         return
     async with self.config.guild(ctx.guild).services() as config_services:
         if service not in config_services:
             config_services[service] = {}
         config_services[service]["autoban"] = True
         config_services[service]["enabled"] = True
         response = "Automatic banning with {} has now been enabled.".format(
             self.get_nice_service_name(service))
         if not await self.config.guild(ctx.guild).notify_channel():
             response += "\nYou will need to set up AutoCheck in order for this to take effect."
         if not await self.get_api_key(service, config_services):
             response += "\nAn API key is needed in order for this to take effect."
         if not ctx.guild.me.guild_permissions.ban_members:
             response += "\nI will need to be granted the Ban Members permission for this to take effect."
         await ctx.send(checkmark(response))
Exemplo n.º 29
0
 async def discordstatus(self, ctx):
     """Get current discord status from status.discordapp.com"""
     try:
         async with self.session.get("https://srhpyqt94yxb.statuspage.io/api/v2/summary.json") as data:
             response = await data.json()
     except Exception as e:
         await ctx.send(chat.error("Unable to get data from https://status.discordapp.com: {}".format(e)))
         return
     status = response["status"]
     status_indicators = {"none": "OK",
                          "minor": "Minor problems",
                          "major": "Major problems",
                          "critical": "Critical problems"}
     components = response["components"]
     embed = discord.Embed(title="Discord Status", timestamp=parse(response["page"]["updated_at"]),
                           color=await ctx.embed_color(), url="https://status.discordapp.com")
     embed.description = status_indicators.get(status["indicator"], status["indicator"])
     for component in components:
         embed.add_field(name=component["name"],
                         value=component["status"].capitalize().replace("_", " "))
     await ctx.send(embed=embed)
Exemplo n.º 30
0
 async def status(self, ctx):
     """Get status of minecraft services"""
     try:
         async with self.session.get(
                 "https://status.mojang.com/check") as data:
             data = await data.json(loads=json.loads)
         em = discord.Embed(
             title=_("Status of minecraft services"),
             timestamp=ctx.message.created_at,
             color=await ctx.embed_color(),
         )
         for service in data:
             for entry, status in service.items():
                 em.add_field(name=entry,
                              value=_(SERVICE_STATUS.get(status, status)))
         await ctx.send(embed=em)
     except Exception as e:
         await ctx.send(
             chat.error(
                 _("Unable to check. An error has been occurred: {}").
                 format(chat.inline(str(e)))))