<commit_before>import peewee

from peewee import fn, JOIN
from datetime import datetime, timedelta

from disco.bot import CommandLevels
from disco.api.http import APIException
from disco.types.message import MessageEmbed

from rowboat.plugins import RowboatPlugin as Plugin, CommandFail
from rowboat.types.plugin import PluginConfig
from rowboat.types import ChannelField, Field, SlottedModel, ListField, DictField
from rowboat.models.user import StarboardBlock, User
from rowboat.models.message import StarboardEntry, Message
from rowboat.util.timing import Debounce


STAR_EMOJI = u'\U00002B50'
UNKNOWN_MESSAGE = 10008


def is_star_event(e):
    if e.emoji.name == STAR_EMOJI:
        return True


class ChannelConfig(SlottedModel):
    sources = ListField(ChannelField, default=[])

    # Delete the star when the message is deleted
    clear_on_delete = Field(bool, default=True)

    # Min number of stars to post on the board
    min_stars = Field(int, default=1)
    min_stars_pin = Field(int, default=15)

    # The number which represents the "max" star level
    star_color_max = Field(int, default=15)

    # Prevent users from starring their own posts
    prevent_self_star = Field(bool, default=False)

    def get_color(self, count):
        ratio = min(count / float(self.star_color_max), 1.0)

        return (
            (255 << 16) +
            (int((194 * ratio) + (253 * (1 - ratio))) << 8) +
            int((12 * ratio) + (247 * (1 - ratio))))


class StarboardConfig(PluginConfig):
    channels = DictField(ChannelField, ChannelConfig)

    # TODO: validate that each source channel has only one starboard mapping

    def get_board(self, channel_id):
        # Starboards can't work recursively
        if channel_id in self.channels:
            return (None, None)

        for starboard, config in self.channels.items():
            if not config.sources or channel_id in config.sources:
                return (starboard, config)
        return (None, None)


@Plugin.with_config(StarboardConfig)
class StarboardPlugin(Plugin):
    def load(self, ctx):
        super(StarboardPlugin, self).load(ctx)
        self.updates = {}
        self.locks = {}

    @Plugin.command('show', '<mid:snowflake>', group='stars', level=CommandLevels.TRUSTED)
    def stars_show(self, event, mid):
        try:
            star = StarboardEntry.select().join(Message).where(
                (Message.guild_id == event.guild.id) &
                (~(StarboardEntry.star_message_id >> None)) &
                (
                    (Message.id == mid) |
                    (StarboardEntry.star_message_id == mid)
                )
            ).get()
        except StarboardEntry.DoesNotExist:
            raise CommandFail('no starboard message with that id')

        _, sb_config = event.config.get_board(star.message.channel_id)

        try:
            source_msg = self.client.api.channels_messages_get(
                star.message.channel_id,
                star.message_id)
        except:
            raise CommandFail('no starboard message with that id')

        content, embed = self.get_embed(star, source_msg, sb_config)
        event.msg.reply(content, embed=embed)

    @Plugin.command('stats', '[user:user]', group='stars', level=CommandLevels.MOD)
    def stars_stats(self, event, user=None):
        if user:
            try:
                given_stars = list(StarboardEntry.select(
                    fn.COUNT('*'),
                ).join(Message).where(
                    (~ (StarboardEntry.star_message_id >> None)) &
                    (StarboardEntry.stars.contains(user.id)) &
                    (Message.guild_id == event.guild.id)
                ).tuples())[0][0]

                recieved_stars_posts, recieved_stars_total = list(StarboardEntry.select(
                    fn.COUNT('*'),
                    fn.SUM(fn.array_length(StarboardEntry.stars, 1)),
                ).join(Message).where(
                    (~ (StarboardEntry.star_message_id >> None)) &
                    (Message.author_id == user.id) &
                    (Message.guild_id == event.guild.id)
                ).tuples())[0]
            except:
                return event.msg.reply(':warning: failed to crunch the numbers on that user')

            embed = MessageEmbed()
            embed.color = 0xffd700
            embed.title = user.username
            embed.set_thumbnail(url=user.avatar_url)
            embed.add_field(name='Total Stars Given', value=str(given_stars), inline=True)
            embed.add_field(name='Total Posts w/ Stars', value=str(recieved_stars_posts), inline=True)
            embed.add_field(name='Total Stars Recieved', value=str(recieved_stars_total), inline=True)
            # embed.add_field(name='Star Rank', value='#{}'.format(recieved_stars_rank), inline=True)
            return event.msg.reply('', embed=embed)

        total_starred_posts, total_stars = list(StarboardEntry.select(
            fn.COUNT('*'),
            fn.SUM(fn.array_length(StarboardEntry.stars, 1)),
        ).join(Message).where(
            (~ (StarboardEntry.star_message_id >> None)) &
            (Message.guild_id == event.guild.id)
        ).tuples())[0]

        top_users = list(StarboardEntry.select(fn.SUM(fn.array_length(StarboardEntry.stars, 1)), User.user_id).join(
            Message,
        ).join(
            User,
            on=(Message.author_id == User.user_id),
        ).where(
            (~ (StarboardEntry.star_message_id >> None)) &
            (fn.array_length(StarboardEntry.stars, 1) > 0) &
            (Message.guild_id == event.guild.id)
        ).group_by(User).order_by(fn.SUM(fn.array_length(StarboardEntry.stars, 1)).desc()).limit(5).tuples())

        embed = MessageEmbed()
        embed.color = 0xffd700
        embed.title = 'Star Stats'
        embed.add_field(name='Total Stars Given', value=total_stars, inline=True)
        embed.add_field(name='Total Starred Posts', value=total_starred_posts, inline=True)
        embed.add_field(name='Top Star Recievers', value='\n'.join(
            '{}. <@{}> ({})'.format(idx + 1, row[1], row[0]) for idx, row in enumerate(top_users)
        ))
        event.msg.reply('', embed=embed)

    @Plugin.command('check', '<mid:snowflake>', group='stars', level=CommandLevels.ADMIN)<commit_msg>[starboard] exclude blocked starboard entries from stats<commit_after>import peewee

from peewee import fn, JOIN
from datetime import datetime, timedelta

from disco.bot import CommandLevels
from disco.api.http import APIException
from disco.types.message import MessageEmbed

from rowboat.plugins import RowboatPlugin as Plugin, CommandFail
from rowboat.types.plugin import PluginConfig
from rowboat.types import ChannelField, Field, SlottedModel, ListField, DictField
from rowboat.models.user import StarboardBlock, User
from rowboat.models.message import StarboardEntry, Message
from rowboat.util.timing import Debounce


STAR_EMOJI = u'\U00002B50'
UNKNOWN_MESSAGE = 10008


def is_star_event(e):
    if e.emoji.name == STAR_EMOJI:
        return True


class ChannelConfig(SlottedModel):
    sources = ListField(ChannelField, default=[])

    # Delete the star when the message is deleted
    clear_on_delete = Field(bool, default=True)

    # Min number of stars to post on the board
    min_stars = Field(int, default=1)
    min_stars_pin = Field(int, default=15)

    # The number which represents the "max" star level
    star_color_max = Field(int, default=15)

    # Prevent users from starring their own posts
    prevent_self_star = Field(bool, default=False)

    def get_color(self, count):
        ratio = min(count / float(self.star_color_max), 1.0)

        return (
            (255 << 16) +
            (int((194 * ratio) + (253 * (1 - ratio))) << 8) +
            int((12 * ratio) + (247 * (1 - ratio))))


class StarboardConfig(PluginConfig):
    channels = DictField(ChannelField, ChannelConfig)

    # TODO: validate that each source channel has only one starboard mapping

    def get_board(self, channel_id):
        # Starboards can't work recursively
        if channel_id in self.channels:
            return (None, None)

        for starboard, config in self.channels.items():
            if not config.sources or channel_id in config.sources:
                return (starboard, config)
        return (None, None)


@Plugin.with_config(StarboardConfig)
class StarboardPlugin(Plugin):
    def load(self, ctx):
        super(StarboardPlugin, self).load(ctx)
        self.updates = {}
        self.locks = {}

    @Plugin.command('show', '<mid:snowflake>', group='stars', level=CommandLevels.TRUSTED)
    def stars_show(self, event, mid):
        try:
            star = StarboardEntry.select().join(Message).where(
                (Message.guild_id == event.guild.id) &
                (~(StarboardEntry.star_message_id >> None)) &
                (
                    (Message.id == mid) |
                    (StarboardEntry.star_message_id == mid)
                )
            ).get()
        except StarboardEntry.DoesNotExist:
            raise CommandFail('no starboard message with that id')

        _, sb_config = event.config.get_board(star.message.channel_id)

        try:
            source_msg = self.client.api.channels_messages_get(
                star.message.channel_id,
                star.message_id)
        except:
            raise CommandFail('no starboard message with that id')

        content, embed = self.get_embed(star, source_msg, sb_config)
        event.msg.reply(content, embed=embed)

    @Plugin.command('stats', '[user:user]', group='stars', level=CommandLevels.MOD)
    def stars_stats(self, event, user=None):
        if user:
            try:
                given_stars = list(StarboardEntry.select(
                    fn.COUNT('*'),
                ).join(Message).where(
                    (~ (StarboardEntry.star_message_id >> None)) &
                    (StarboardEntry.stars.contains(user.id)) &
                    (Message.guild_id == event.guild.id)
                ).tuples())[0][0]

                recieved_stars_posts, recieved_stars_total = list(StarboardEntry.select(
                    fn.COUNT('*'),
                    fn.SUM(fn.array_length(StarboardEntry.stars, 1)),
                ).join(Message).where(
                    (~ (StarboardEntry.star_message_id >> None)) &
                    (Message.author_id == user.id) &
                    (Message.guild_id == event.guild.id)
                ).tuples())[0]
            except:
                return event.msg.reply(':warning: failed to crunch the numbers on that user')

            embed = MessageEmbed()
            embed.color = 0xffd700
            embed.title = user.username
            embed.set_thumbnail(url=user.avatar_url)
            embed.add_field(name='Total Stars Given', value=str(given_stars), inline=True)
            embed.add_field(name='Total Posts w/ Stars', value=str(recieved_stars_posts), inline=True)
            embed.add_field(name='Total Stars Recieved', value=str(recieved_stars_total), inline=True)
            # embed.add_field(name='Star Rank', value='#{}'.format(recieved_stars_rank), inline=True)
            return event.msg.reply('', embed=embed)

        total_starred_posts, total_stars = list(StarboardEntry.select(
            fn.COUNT('*'),
            fn.SUM(fn.array_length(StarboardEntry.stars, 1)),
        ).join(Message).where(
            (~ (StarboardEntry.star_message_id >> None)) &
            (StarboardEntry.blocked == 0) &
            (Message.guild_id == event.guild.id)
        ).tuples())[0]

        top_users = list(StarboardEntry.select(fn.SUM(fn.array_length(StarboardEntry.stars, 1)), User.user_id).join(
            Message,
        ).join(
            User,
            on=(Message.author_id == User.user_id),
        ).where(
            (~ (StarboardEntry.star_message_id >> None)) &
            (fn.array_length(StarboardEntry.stars, 1) > 0) &
            (StarboardEntry.blocked == 0) &
            (Message.guild_id == event.guild.id)
        ).group_by(User).order_by(fn.SUM(fn.array_length(StarboardEntry.stars, 1)).desc()).limit(5).tuples())

        embed = MessageEmbed()
        embed.color = 0xffd700
        embed.title = 'Star Stats'
        embed.add_field(name='Total Stars Given', value=total_stars, inline=True)
        embed.add_field(name='Total Starred Posts', value=total_starred_posts, inline=True)
        embed.add_field(name='Top Star Recievers', value='\n'.join(
            '{}. <@{}> ({})'.format(idx + 1, row[1], row[0]) for idx, row in enumerate(top_users)
        ))
        event.msg.reply('', embed=embed)

    @Plugin.command('check', '<mid:snowflake>', group='stars', level=CommandLevels.ADMIN)
{'fraction_non_alphanumeric': 0.1186692759295499, 'fraction_numerical': 0.009549902152641879, 'mean_word_length': 2.4390309555854643, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5690540', 'n_tokens_mistral': 3969, 'n_tokens_neox': 3708, 'n_words': 795}