Ejemplo n.º 1
0
    async def followslist(self, ctx, channel: discord.TextChannel = None):
        """List all followed accounts on server or channel"""
        data = await self.bot.db.execute(
            """
            SELECT twitter_user.username, channel_id, added_on
            FROM follow LEFT JOIN twitter_user
            ON twitter_user.user_id = follow.twitter_user_id WHERE follow.guild_id = %s
            """
            + (f" AND channel_id = {channel.id}" if channel is not None else "")
            + " ORDER BY channel_id, added_on DESC",
            ctx.guild.id,
        )
        content = discord.Embed(title="Followed twitter users", color=self.bot.twitter_blue)
        rows = []
        for username, channel_id, added_on in data:
            rows.append(
                (f"<#{channel_id}> < " if channel is None else "")
                + f"**@{username}** (since {added_on} UTC)"
            )

        if not rows:
            rows.append("Nothing yet :(")

        pages = menus.Menu(source=menus.ListMenu(rows, embed=content), clear_reactions_after=True)
        await pages.start(ctx)
Ejemplo n.º 2
0
    async def guilds(self, ctx: commands.Context):
        """Show all connected guilds."""
        content = discord.Embed(
            title=f"Active in {len(self.bot.guilds)} guilds",
            color=self.bot.twitter_blue,
        )

        rows = []
        for i, guild in enumerate(sorted(self.bot.guilds,
                                         key=lambda x: x.member_count,
                                         reverse=True),
                                  start=1):
            rows.append(
                f"`#{i:2}`[`{guild.id}`] **{guild.member_count}** members : **{guild.name}**"
            )

        pages = menus.Menu(source=menus.ListMenu(rows, embed=content),
                           clear_reactions_after=True)
        await pages.start(ctx)
Ejemplo n.º 3
0
    async def remove(self, ctx, channel: discord.TextChannel, *usernames):
        """Remove users from the follow list."""
        if not usernames:
            raise exceptions.Info("You must give at least one twitter user to remove!")

        rows = []
        current_users = await self.bot.db.execute(
            "SELECT twitter_user_id FROM follow WHERE channel_id = %s", channel.id
        )
        successes = 0
        for username in usernames:
            status = None
            try:
                user_id = (await self.api.get_user(username=username)).data.id
            except Exception as e:
                # user not found, maybe changed username
                # try finding username from cache
                user_id = await self.bot.db.execute(
                    "SELECT user_id FROM twitter_user WHERE username = %s", username
                )
                if user_id:
                    user_id = user_id[0][0]
                else:
                    status = f":x: Error {e.args[0][0]['code']}: {e.args[0][0]['message']}"

            if status is None:
                if (user_id,) not in current_users:
                    status = ":x: User is not being followed on this channel"
                else:
                    await self.unfollow(channel.id, user_id)
                    status = ":white_check_mark: Success"
                    successes += 1

            rows.append(f"**@{username}** {status}")

        content = discord.Embed(
            title=f":notepad_spiral: Removed {successes}/{len(usernames)} users from {channel.name}",
            color=self.bot.twitter_blue,
        )
        content.set_footer(text="Changes will take effect within a minute")
        pages = menus.Menu(source=menus.ListMenu(rows, embed=content), clear_reactions_after=True)
        await pages.start(ctx)
Ejemplo n.º 4
0
    async def add(self, ctx, channel: discord.TextChannel, *usernames):
        """Add users to the follow list."""
        if not usernames:
            raise exceptions.Info("You must give at least one twitter user to follow!")

        rows = []
        time_now = arrow.now().datetime
        current_users = await self.bot.db.execute(
            "SELECT twitter_user_id FROM follow WHERE channel_id = %s", channel.id
        )
        guild_follow_current, guild_follow_limit = await queries.get_follow_limit(
            self.bot.db, channel.guild.id
        )
        successes = 0
        for username in usernames:
            status = None
            try:
                user = (await self.api.get_user(username=username)).data
            except Exception as e:
                status = f":x: Error {e}"
            else:
                if (user.id,) in current_users:
                    status = ":x: User already being followed on this channel"
                else:
                    if guild_follow_current >= guild_follow_limit:
                        status = f":lock: Guild follow count limit reached ({guild_follow_limit})"
                    else:
                        await self.follow(channel, user.id, user.username, time_now)
                        status = ":white_check_mark: Success"
                        successes += 1
                        guild_follow_current += 1

            rows.append(f"**@{user.username}** {status}")

        content = discord.Embed(
            title=f":notepad_spiral: Added {successes}/{len(usernames)} users to {channel.name}",
            color=self.bot.twitter_blue,
        )
        content.set_footer(text="Changes will take effect within a minute")
        pages = menus.Menu(source=menus.ListMenu(rows, embed=content), clear_reactions_after=True)
        await pages.start(ctx)
Ejemplo n.º 5
0
    async def purge(self, ctx: commands.Context):
        """Remove all follows from unavailable guilds and channels."""
        data = await self.bot.db.execute(
            """
            SELECT channel_id, guild_id, twitter_user_id, username
            FROM follow
            JOIN twitter_user
            ON twitter_user_id=user_id
            """
        )
        actions = []
        guilds_to_delete = []
        channels_to_delete = []
        users_to_delete = []
        twitter_usernames = {}
        usernames_to_change = []
        for channel_id, guild_id, twitter_uid, username in data:
            if self.bot.get_guild(guild_id) is None:
                actions.append(f"Could not find guild with id: [{guild_id}]")
                guilds_to_delete.append(guild_id)
            elif self.bot.get_channel(channel_id) is None:
                actions.append(f"Could not find channel with id: [{channel_id}]")
                channels_to_delete.append(channel_id)
            else:
                twitter_usernames[twitter_uid] = username

        uids = list(twitter_usernames.keys())
        for uids_chunk in [uids[i : i + 100] for i in range(0, len(uids), 100)]:
            userdata = await self.api.get_users(ids=uids_chunk)
            if userdata.errors:
                for error in userdata.errors:
                    actions.append(error["detail"])
                    users_to_delete.append(int(error["value"]))
            if userdata.data:
                for user in userdata.data:
                    if twitter_usernames[user.id] != user.username:
                        actions.append(
                            f"User has changed username from @{twitter_usernames[user.id]} to @{user.username}"
                        )
                        usernames_to_change.append((user.id, user.username))

        if not actions:
            return await ctx.send("There is nothing to do.")

        content = discord.Embed(
            title="Purge results",
            color=self.bot.twitter_blue,
        )
        pages = menus.Menu(
            source=menus.ListMenu(actions, embed=content),
            clear_reactions_after=True,
        )
        await pages.start(ctx)
        confirm = await menus.Confirm("Run actions?").prompt(ctx)
        if confirm:
            await ctx.send("Running purge...")
            if guilds_to_delete:
                await self.bot.db.execute(
                    "DELETE FROM follow WHERE guild_id IN %s", guilds_to_delete
                )
            if channels_to_delete:
                await self.bot.db.execute(
                    "DELETE FROM follow WHERE channel_id IN %s", channels_to_delete
                )
            if users_to_delete:
                await self.bot.db.execute(
                    "DELETE FROM twitter_user WHERE user_id IN %s", users_to_delete
                )
            for uid, new_name in usernames_to_change:
                await self.bot.db.execute(
                    "UPDATE twitter_user SET username = %s WHERE user_id = %s", new_name, uid
                )
            await ctx.send("Purge complete!")