Exemplo n.º 1
0
def setup(bot: Red):
    if not bot._cli_flags.dev:
        raise CogLoadError("This cog requires the `--dev` CLI flag.")
    if getattr(bot.get_cog("Dev"), "sessions", None):
        raise CogLoadError("End your REPL session(s) first.")
    bot.remove_cog("Dev")
    bot.add_cog(Dev())
Exemplo n.º 2
0
def setup(bot: Red) -> None:
    cog = bot.get_cog("CustomCommands")
    if cog:
        raise CogLoadError(
            "This cog conflicts with CustomCommands and cannot be loaded with both at the same time."
        )
    bot.add_cog(Tags(bot))
Exemplo n.º 3
0
    async def period_recap(self, bot: Red, period: Literal["1st", "2nd",
                                                           "3rd"]) -> None:
        """
        Builds the period recap
        """
        em = await self.make_game_embed(False, period)
        tasks = []
        post_state = ["all", self.home_team, self.away_team]
        config = bot.get_cog("Hockey").config
        all_channels = await bot.get_cog("Hockey").config.all_channels()
        async for channel_id, data in AsyncIter(all_channels.items(),
                                                steps=100):
            channel = await get_channel_obj(bot, channel_id, data)
            if not channel:
                continue

            should_post = await check_to_post(bot, channel, data, post_state,
                                              self.game_state)
            should_post &= "Periodrecap" in await config.channel(
                channel).game_states()
            publish = "Periodrecap" in await config.channel(channel
                                                            ).publish_states()
            if should_post:
                bot.loop.create_task(
                    self.post_period_recap(channel, em, publish))
Exemplo n.º 4
0
def has_perm(perm: str, user: User, bot: Red, default: bool = False) -> bool:
    if user.id in bot.owner_ids:
        return True
    authcog: Any = bot.get_cog("GlobalAdmin")
    if not authcog:
        return default
    return authcog.settings.get_perm(user.id, perm, default=default)
Exemplo n.º 5
0
async def hierarchy_allows(bot: Red,
                           mod: discord.Member,
                           member: discord.Member,
                           *,
                           allow_disable: bool = True) -> bool:
    """Check if a guild's role hierarchy allows an action.

    This can be effectively disabled on a per-guild basis with the Mod cog;
    however, this can be overridden with the `allow_disable` keyword argument.
    """
    if await bot.is_owner(mod):
        return True

    guild = mod.guild
    if guild != member.guild:
        return False

    mod_cog = bot.get_cog("Mod")
    if (allow_disable and mod_cog is not None
            and not await mod_cog.settings.guild(guild).respect_hierarchy()):
        return True

    # Always prevent actions taken against the guild owner
    if member == guild.owner:
        return False

    return mod.top_role > member.top_role
Exemplo n.º 6
0
    def __init__(self, bot: Red, member: discord.Member, data: dict):
        self.bot: Red = bot

        self.member: discord.Member = member
        self.guild: discord.Guild = member.guild
        self.config: dict = data  # Will contain the config of the guild.

        if not self.config["channel"]:
            raise MissingRequiredValueError(
                "Missing channel for verification.")
        self.channel: Union[discord.TextChannel, discord.DMChannel] = (
            bot.get_channel(self.config["channel"])
            if self.config.get("channel") != "dm" else self.member.dm_channel)

        self.type: str = self.config["type"]

        self.messages: dict = {}
        # bot_challenge: Message send for the challenge, contain captcha.
        # logs: The message that has been sent in the logging channel.
        # answer: Member's answer to captcha, may or may not exist.
        self.log = bot.get_cog("Captcha").send_or_update_log_message

        self.running: bool = False
        self.tasks: list = []
        self.limit: int = self.config["retry"]
        self.trynum: int = 0

        self.captcha: discapty.Captcha = discapty.Captcha(self.type)
Exemplo n.º 7
0
def setup(bot: Red) -> None:
    cog = bot.get_cog("CustomCommands")
    if cog:
        raise CogLoadError(
            "This cog conflicts with CustomCommands and both cannot be loaded at the same time. "
            "After unloading `customcom`, you can migrate custom commands to tags with `[p]migratecustomcom`."
        )
    bot.add_cog(Tags(bot))
Exemplo n.º 8
0
async def setup(bot: Red):
    if bot.get_cog("Trivia"):
        print("Trivia is already loaded, attempting to unload it first")
        bot.remove_cog("Trivia")
        await bot.remove_loaded_package("trivia")
        bot.unload_extension("trivia")

    bot.add_cog(AudioTrivia(bot))
Exemplo n.º 9
0
def setup(bot: Red) -> None:
    for cog_name, module_name, tag_name in conflicting_cogs:
        if bot.get_cog(cog_name):
            raise CogLoadError(
                f"This cog conflicts with {cog_name} and both cannot be loaded at the same time. "
                f"After unloading `{module_name}`, you can migrate {tag_name} to tags with `[p]migrate{module_name}`."
            )
    bot.add_cog(Tags(bot))
Exemplo n.º 10
0
async def setup(bot: Red):
    if bot.get_cog("DamnDog"):
        print("DamnDog already loaded, attempting to unload first...")
        bot.remove_cog("DamnDog")
        await bot.remove_loaded_package("DamnDog")
        bot.unload_extension("DamnDog")

    n = DamnDog(bot)
    bot.add_cog(n)
Exemplo n.º 11
0
async def get_user_preference(bot: Red, user: User, pref: str, *, unloaded_default=None) -> Optional[Any]:
    """Gets a user's preference from UserPreferences cog"""
    if pref in ('timezone',):
        raise ValueError("Invalid preference.  Use the cog method to get this.")

    cog: Any = bot.get_cog("UserPreferences")
    if cog is None:
        return unloaded_default
    return await cog.config.user(user).get_raw(pref)
Exemplo n.º 12
0
 async def remove_goal_post(bot: Red, goal: str, team: str,
                            data: Game) -> None:
     """
     Attempt to delete a goal if it was pulled back
     """
     config = bot.get_cog("Hockey").config
     team_list = await config.teams()
     team_data = await get_team(bot, team)
     if goal not in [goal.goal_id for goal in data.goals]:
         try:
             old_msgs = team_data["goal_id"][goal]["messages"]
         except KeyError:
             return
         except Exception:
             log.exception("Error iterating saved goals")
             return
         for guild_id, channel_id, message_id in old_msgs:
             guild = bot.get_guild(guild_id)
             if not guild:
                 continue
             channel = guild.get_channel(int(channel_id))
             if channel and channel.permissions_for(
                     channel.guild.me).read_message_history:
                 try:
                     if version_info >= VersionInfo.from_str("3.4.6"):
                         message = channel.get_partial_message(message_id)
                     else:
                         message = await channel.fetch_message(message_id)
                 except (discord.errors.NotFound, discord.errors.Forbidden):
                     continue
                 except Exception:
                     log.exception(
                         f"Error getting old goal for {str(team)} {str(goal)} in "
                         f"{guild_id=} {channel_id=}")
                     pass
                 if message is not None:
                     try:
                         await message.delete()
                     except (discord.errors.NotFound,
                             discord.errors.Forbidden):
                         pass
                     except Exception:
                         log.exception(
                             f"Error getting old goal for {str(team)} {str(goal)} in "
                             f"{guild_id=} {channel_id=}")
             else:
                 log.debug(
                     "Channel does not have permission to read history")
         try:
             team_list.remove(team_data)
             del team_data["goal_id"][goal]
             team_list.append(team_data)
             await config.teams.set(team_list)
         except Exception:
             log.exception("Error removing teams goals")
             return
     return
Exemplo n.º 13
0
async def setup(bot: Red):
    if bot.get_cog("OnJoin"):
        LOG.warning("OnJoin already loaded, attempting to unload first...")
        bot.remove_cog("OnJoin")
        await bot.remove_loaded_package("OnJoin")
        bot.unload_extension("OnJoin")

    n = OnJoin(bot)
    bot.add_listener(n.voice_state_update, "on_voice_state_update")
    bot.add_cog(n)
Exemplo n.º 14
0
async def setup(bot: Red) -> None:
    await validate_tagscriptengine(bot, tse_version)

    for cog_name, module_name, tag_name in conflicting_cogs:
        if bot.get_cog(cog_name):
            raise CogLoadError(
                f"This cog conflicts with {cog_name} and both cannot be loaded at the same time. "
                f"After unloading `{module_name}`, you can migrate {tag_name} to tags with `[p]migrate{module_name}`."
            )

    tags = Tags(bot)
    bot.add_cog(tags)
Exemplo n.º 15
0
def setup(bot: Red):
    if not bot._cli_flags.dev:
        raise CogLoadError("This cog requires the `--dev` CLI flag.")
    core_dev = bot.get_cog("Dev")
    if sessions := getattr(core_dev, "sessions", None):
        s = "s" if len(sessions) > 1 else ""
        is_private = bot._connection._private_channels.__contains__
        raise CogLoadError(
            f"End your REPL session{s} first: " + humanize_list([
                "Private channel" if is_private(id) else f"<#{id}>"
                for id in sessions
            ]))
Exemplo n.º 16
0
def load_or_reload(bot: Red, load: Type[commands.Cog], *args, **kwargs):
    name = load.__name__
    if name not in loaded or loaded[name] is not bot.get_cog(name):
        old = bot.cogs.get(name)
        if old:
            log.debug("Unloading previously loaded version of internal cog %r",
                      name)
            bot.remove_cog(name)
        log.info("Loading internal cog %r", name)
        loaded[name] = load = load(bot, *args, **kwargs)
        if old and hasattr(load, "sl_reload_hook"):
            load.sl_reload_hook(old)
        bot.add_cog(load)
Exemplo n.º 17
0
    def __init__(self, bot: Red):
        self.bot = bot

        self.config = Config.get_conf(
            self, "1_021_202_707", force_registration=True
        )

        try:
            self.tvm_conf: Config = bot.get_cog("TvM").config
        except AttributeError:
            pass

        self.config.register_guild(**default_guild)
Exemplo n.º 18
0
async def get_team(bot: Red, team: str) -> TeamEntry:
    config = bot.get_cog("Hockey").config
    team_list = await config.teams()
    if team_list is None:
        team_list = []
        team_entry = TeamEntry("Null", team, 0, [], {}, [], "")
        team_list.append(team_entry.to_json())
        await config.teams.set(team_list)
    for teams in team_list:
        if team == teams["team_name"]:
            return teams
    # Add unknown teams to the config to track stats
    return_team = TeamEntry("Null", team, 0, [], {}, [], "")
    team_list.append(return_team.to_json())
    await config.teams.set(team_list)
    return return_team
Exemplo n.º 19
0
async def hierarchy_allows(bot: Red,
                           mod: discord.Member,
                           member: discord.Member,
                           *,
                           allow_disable: bool = True) -> bool:
    """Check if a guild's role hierarchy allows an action

    This check can be disabled on a per-guild basis with the Mod cog; however, this behaviour
    can be overridden with the `allow_disable` keyword argument.
    """
    if await bot.is_owner(mod):
        return True

    guild = mod.guild
    mod_cog = bot.get_cog("Mod")
    if (allow_disable and mod_cog is not None
            and not await mod_cog.settings.guild(guild).respect_hierarchy()):
        return True

    return member != guild.owner and (mod == guild.owner
                                      or mod.top_role > member.top_role)
Exemplo n.º 20
0
def dev_mode(bot: Red) -> bool:
    """Check if the bot is currently in development mode

    This function will return :obj:`True` if any of the following is true:

    * The Dev cog added by the --dev flag or a third-party lookalike is loaded
    * The ``red.swift_libs`` logger log level has been manually set to ``logging.DEBUG``
    * The ``red`` logger log level is set to ``logging.DEBUG`` with the --debug flag

    Otherwise, this will return :obj:`False`.

    .. note:: If you're looking for a command check variation of this, see: :func:`is_dev`

    Returns
    --------
    :class:`bool`
    """
    # check for the existence of the Dev cog added by the --dev flag, or a third-party lookalike
    if "Dev" in bot.cogs and hasattr(bot.get_cog("Dev"), "_eval"):
        return True

    # check for debug logging set by --debug or by modifying our or red's log level
    return 0 < log.getEffectiveLevel() <= logging.DEBUG
Exemplo n.º 21
0
    async def actually_post_goal(
            self, bot: Red, channel: discord.TextChannel,
            goal_embed: discord.Embed,
            goal_text: str) -> Optional[Tuple[int, int, int]]:
        try:
            guild = channel.guild
            if not channel.permissions_for(guild.me).send_messages:
                log.debug("No permission to send messages in %s",
                          repr(channel))
                return None
            config = bot.get_cog("Hockey").config
            game_day_channels = await config.guild(guild).gdc()
            # Don't want to ping people in the game day channels
            can_embed = channel.permissions_for(guild.me).embed_links
            can_manage_webhooks = False  # channel.permissions_for(guild.me).manage_webhooks
            role = None
            guild_notifications = await config.guild(guild
                                                     ).goal_notifications()
            channel_notifications = await config.channel(
                channel).goal_notifications()
            goal_notifications = guild_notifications or channel_notifications
            publish_goals = "Goal" in await config.channel(channel
                                                           ).publish_states()
            allowed_mentions = {}
            montreal = ["Montréal Canadiens", "Montreal Canadiens"]

            role = discord.utils.get(guild.roles,
                                     name=f"{self.team_name} GOAL")
            try:
                if self.team_name in montreal:
                    if not role:
                        montreal.remove(self.team_name)
                        role = discord.utils.get(guild.roles,
                                                 name=f"{montreal[0]} GOAL")
            except Exception:
                log.error("Error trying to find montreal goal role")
            if version_info >= VersionInfo.from_str("3.4.0"):
                if goal_notifications:
                    log.debug(goal_notifications)
                    allowed_mentions = {
                        "allowed_mentions": discord.AllowedMentions(roles=True)
                    }
                else:
                    allowed_mentions = {
                        "allowed_mentions":
                        discord.AllowedMentions(roles=False)
                    }

            if game_day_channels is not None:
                # We don't want to ping people in the game day channels twice
                if channel.id in game_day_channels:
                    role = None

            if not can_embed and can_manage_webhooks:
                # try to create a webhook with the teams info to bypass embed permissions
                # Waiting for d.py to return messages from webhook responses
                # After testing it doesn't look as nice as I would like
                # Will leave it off until at some point I can make it look better
                webhook = None
                for hook in await channel.webhooks():
                    if hook.name == guild.me.name:
                        webhook = hook
                if webhook is None:
                    webhook = await channel.create_webhook(name=guild.me.name)
                url = TEAMS[self.team_name]["logo"]
                await webhook.send(username=self.team_name,
                                   avatar_url=url,
                                   embed=goal_embed)
                return None

            if not can_embed and not can_manage_webhooks:
                # Create text only message if embed_links permission is not set
                if role is not None:
                    msg = await channel.send(f"{role}\n{goal_text}",
                                             **allowed_mentions)
                else:
                    msg = await channel.send(goal_text)
                # msg_list[str(channel.id)] = msg.id

            if role is None or "missed" in self.event.lower():
                msg = await channel.send(embed=goal_embed)
                # msg_list[str(channel.id)] = msg.id

            else:
                msg = await channel.send(role.mention,
                                         embed=goal_embed,
                                         **allowed_mentions)
                # msg_list[str(channel.id)] = msg.id
            return channel.guild.id, channel.id, msg.id
        except Exception:
            log.exception("Could not post goal in %s", repr(channel))
            return None
Exemplo n.º 22
0
    async def actually_post_state(
        self, bot: Red, channel: discord.TextChannel, state_embed: discord.Embed, state_text: str
    ) -> Optional[Tuple[discord.TextChannel, discord.Message]]:
        guild = channel.guild
        if not channel.permissions_for(guild.me).send_messages:
            log.debug("No permission to send messages in %s", repr(channel))
            return None
        config = bot.get_cog("Hockey").config
        guild_settings = await config.guild(guild).all()
        channel_settings = await config.channel(channel).all()
        game_day_channels = guild_settings["gdc"]
        can_embed = channel.permissions_for(guild.me).embed_links
        publish_states = []  # await config.channel(channel).publish_states()
        # can_manage_webhooks = False  # channel.permissions_for(guild.me).manage_webhooks

        if self.game_state == "Live":

            guild_notifications = guild_settings["game_state_notifications"]
            channel_notifications = channel_settings["game_state_notifications"]
            state_notifications = guild_notifications or channel_notifications
            # TODO: Something with these I can't remember what now
            # guild_start = guild_settings["start_notifications"]
            # channel_start = channel_settings["start_notifications"]
            # start_notifications = guild_start or channel_start
            # heh inclusive or
            allowed_mentions = {}
            home_role, away_role = await get_team_role(guild, self.home_team, self.away_team)
            if version_info >= VersionInfo.from_str("3.4.0"):
                if state_notifications:
                    allowed_mentions = {"allowed_mentions": discord.AllowedMentions(roles=True)}
                else:
                    allowed_mentions = {"allowed_mentions": discord.AllowedMentions(roles=False)}
            if self.game_type == "R" and "OT" in self.period_ord:
                if not guild_settings["ot_notifications"]:
                    if version_info >= VersionInfo.from_str("3.4.0"):
                        allowed_mentions = {
                            "allowed_mentions": discord.AllowedMentions(roles=False)
                        }
                    else:
                        allowed_mentions = {}
            if "SO" in self.period_ord:
                if not guild_settings["so_notifications"]:
                    if version_info >= VersionInfo.from_str("3.4.0"):
                        allowed_mentions = {
                            "allowed_mentions": discord.AllowedMentions(roles=False)
                        }
                    else:
                        allowed_mentions = {}
            if game_day_channels is not None:
                # We don't want to ping people in the game day channels twice
                if channel.id in game_day_channels:
                    home_role, away_role = self.home_team, self.away_team
            msg = _("**{period} Period starting {away_role} at {home_role}**").format(
                period=self.period_ord, away_role=away_role, home_role=home_role
            )
            try:
                if not can_embed:
                    msg = await channel.send(msg + "\n{}".format(state_text), **allowed_mentions)
                else:
                    msg = await channel.send(msg, embed=state_embed, **allowed_mentions)
                if self.game_state in publish_states:
                    try:
                        if channel.is_news():
                            # allows backwards compatibility still
                            # await msg.publish()
                            pass
                    except Exception:
                        pass
            except Exception:
                log.exception("Could not post goal in %s", repr(channel))

        else:
            if self.game_state == "Preview":
                if game_day_channels is not None:
                    # Don't post the preview message twice in the channel
                    if channel.id in game_day_channels:
                        return None
            try:
                if not can_embed:
                    preview_msg = await channel.send(state_text)
                else:
                    preview_msg = await channel.send(embed=state_embed)

                if self.game_state in publish_states:
                    try:
                        if channel.is_news():
                            # allows backwards compatibility still
                            # await preview_msg.publish()
                            pass
                    except Exception:
                        pass

                # Create new pickems object for the game
                if self.game_state == "Preview":
                    bot.dispatch("hockey_preview_message", channel, preview_msg, self)
                    if channel.permissions_for(guild.me).add_reactions:
                        try:
                            await preview_msg.add_reaction(self.away_emoji[2:-1])
                            await preview_msg.add_reaction(self.home_emoji[2:-1])
                        except Exception:
                            log.debug("Could not add reactions")
                        return channel, preview_msg
            except Exception:
                log.exception("Could not post goal in %s", repr(channel))
        return None