Ejemplo n.º 1
0
    async def topservers(self, ctx, user: discord.User = None):
        """See your top servers with miso bot."""
        if user is None:
            user = ctx.author

        data = db.query(
            """SELECT guild_id, %s FROM activity
            WHERE user_id = ? GROUP BY guild_id ORDER BY %s DESC""" %
            (ALLSUM, ALLSUM),
            (user.id, ),
        )
        rows = []
        total_xp = 0
        for i, (guild_id, xp) in enumerate(data, start=1):
            guild = self.bot.get_guild(guild_id)
            if guild is None:
                guild = guild_id
            else:
                guild = guild.name

            level = util.get_level(xp)
            total_xp += xp
            rows.append(f"`#{i}` **{guild}** — Level **{level}**")

        content = discord.Embed()
        content.set_author(name=f"{user.name}'s top servers",
                           icon_url=ctx.author.avatar_url)
        content.set_footer(text=f"Global level {util.get_level(total_xp)}")
        content.colour = ctx.author.color
        await util.send_as_pages(ctx, content, rows)
Ejemplo n.º 2
0
    async def activity(self,
                       ctx,
                       user: typing.Optional[discord.Member] = None,
                       scope=""):
        """See your hourly activity chart (GMT)."""
        if user is None:
            user = ctx.author

        is_global = scope.lower() == "global"

        if is_global:
            activitydata = db.global_activitydata(user.id)
        else:
            activitydata = db.get_user_activity(ctx.guild.id, user.id)

        if activitydata is None:
            return await ctx.send("No activity found!")

        activities = list(activitydata)
        xp = sum(activities)
        level = util.get_level(xp)

        title = (
            f"LVL {level} | {xp - util.get_xp(level)}/"
            f"{util.xp_to_next_level(level)} XP to levelup | Total xp: {xp}")

        await self.bot.loop.run_in_executor(
            None, lambda: plotter.create_graph(
                activities, str(user.color), title=title))

        with open("downloads/graph.png", "rb") as img:
            await ctx.send(
                f"`Hourly cumulative {'global' if is_global else 'server'} activity for {user}`",
                file=discord.File(img),
            )
Ejemplo n.º 3
0
    async def activity(self, ctx, user: discord.Member = None):
        """See your hourly server activity chart (GMT)"""
        if user is None:
            user = ctx.author

        activitydata = db.activitydata(ctx.guild.id, user.id)
        if activitydata is None:
            return await ctx.send(
                f"No activity for `{user}` found on this server")

        activities = list(activitydata[3:])
        xp = sum(activities)
        level = util.get_level(xp)

        title = f"LVL {level} | {xp - util.get_xp(level)}/" \
                f"{util.xp_to_next_level(level)} XP to levelup | Total xp: {xp}"

        await self.bot.loop.run_in_executor(
            None, lambda: plotter.create_graph(
                activities, str(user.color), title=title))

        with open("downloads/graph.png", "rb") as img:
            await ctx.send(f"`Hourly cumulative server activity for {user}`",
                           file=discord.File(img))
Ejemplo n.º 4
0
    async def profile(self, ctx, user: discord.Member = None):
        """Your personal customizable user profile."""
        if user is None:
            user = ctx.author

        activity = str(db.get_user_activity(ctx.guild.id, user.id))
        fishydata = db.fishdata(user.id)

        local_xp_rows = db.query(
            "SELECT * FROM activity WHERE user_id = ? AND guild_id = ?",
            (user.id, ctx.guild.id))
        local_xp = 0
        if local_xp_rows is not None:
            local_xp = sum(list(local_xp_rows[0][3:]))
            local_rank = await self.get_rank(ctx, user, 'activity')

        global_xp_rows = db.query("SELECT * FROM activity WHERE user_id = ?",
                                  (user.id, ))
        global_xp = 0
        if global_xp_rows is not None:
            global_xp = sum(sum(row[3:]) for row in global_xp_rows)
            global_rank = await self.get_rank(ctx,
                                              user,
                                              'activity',
                                              _global=True)

        patrons = db.query(
            "select user_id from patrons where currently_active = 1")
        if user.id == self.bot.owner.id:
            corner_icon = 'fa-dev'
        elif patrons is not None and user.id in [x[0] for x in patrons]:
            corner_icon = 'fa-patreon'
        else:
            corner_icon = ''

        activity_formatted = util.activityhandler(user.activities)

        description = db.query(
            "SELECT description FROM profiles WHERE user_id = ?", (user.id, ))
        if description is None or description[0][0] is None:
            description = "<p>use >editprofile to change your description</p>"
        else:
            cleaner = clean.Cleaner(safe_attrs_only=True)
            description = cleaner.clean_html(description[0][0].replace(
                '\n', '<br>'))

        background_url = db.query(
            "SELECT background_url FROM profiles WHERE user_id = ?",
            (user.id, ))
        if background_url is None:
            background_url = ''
        else:
            background_url = background_url[0][0]

        replacements = {
            'BACKGROUND_IMAGE': background_url,
            'ACCENT_COLOR': user.color,
            'AVATAR_URL': user.avatar_url_as(size=128, format='png'),
            'USERNAME': f"{user.name} #{user.discriminator}",
            'DESCRIPTION': description,
            'FISHY': fishydata.fishy if fishydata is not None else 0,
            'LVL_LOCAL': util.get_level(local_xp),
            'RANK_LOCAL': local_rank,
            'LVL_GLOBAL': util.get_level(global_xp),
            'RANK_GLOBAL': global_rank,
            'ACTIVITY_ICON': activity_formatted.get('icon'),
            'ACTIVITY_TEXT': activity_formatted.get('text'),
            'ACTIVITY_DATA': activity,
            'PATREON': corner_icon
        }

        def dictsub(m):
            return str(replacements[m.group().strip('%')])

        formatted_html = re.sub(r'%%(\S*)%%', dictsub, self.profile_html)

        async with aiohttp.ClientSession() as session:
            data = {
                'html': formatted_html,
                'width': 512,
                'height': 512,
                'imageFormat': 'png'
            }
            async with session.post('http://localhost:3000/html',
                                    data=data) as response:
                with open("downloads/profile.png", "wb") as f:
                    while True:
                        block = await response.content.read(1024)
                        if not block:
                            break
                        f.write(block)

        with open("downloads/profile.png", "rb") as f:
            await ctx.send(file=discord.File(f))
Ejemplo n.º 5
0
    async def on_message(self, message):
        """Listener that gets called on every message."""
        # make sure cache is ready
        if not self.bot.is_ready:
            return

        # ignore DMs
        if message.guild is None:
            return

        # votechannels

        data = db.query(
            """SELECT channeltype FROM votechannels
            WHERE guild_id = ? and channel_id = ?""",
            (message.guild.id, message.channel.id),
        )
        if data is not None:
            if data[0][0] == "rating":
                for e in ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣"]:
                    await message.add_reaction(e)
            else:
                await message.add_reaction(emojis.UPVOTE)
                await message.add_reaction(emojis.DOWNVOTE)

        # xp gain
        message_xp = util.xp_from_message(message)
        currenthour = message.created_at.hour
        db.add_activity(message.guild.id, message.author.id, message_xp,
                        currenthour)

        # if bot account, ignore everything after this
        if message.author.bot:
            return

        if db.get_setting(message.guild.id, "autoresponses") == 1:
            await self.easter_eggs(message)

        # log emojis
        unicode_emojis = util.find_unicode_emojis(message.content)
        custom_emojis = util.find_custom_emojis(message.content)
        if unicode_emojis or custom_emojis:
            db.log_emoji_usage(message, custom_emojis, unicode_emojis)

        # level up message
        announce = db.get_setting(message.guild.id, "levelup_toggle")
        if announce != 0:
            activity_data = db.get_user_activity(message.guild.id,
                                                 message.author.id)
            if activity_data is None:
                return

            xp = sum(activity_data)
            level_before = util.get_level(xp - message_xp)
            level_now = util.get_level(xp)

            if level_now > level_before:
                try:
                    await message.channel.send(
                        f"{message.author.mention} just leveled up! (level **{level_now}**)",
                        delete_after=5,
                    )
                except discord.errors.Forbidden:
                    pass
Ejemplo n.º 6
0
    async def on_message(self, message):
        """Listener that gets called on every message."""
        # ignore DMs
        if message.guild is None:
            return

        # votechannels
        if db.query("select * from votechannels where guild_id = ? and channel_id = ?",
                    (message.guild.id, message.channel.id)) is not None:
            await message.add_reaction(self.bot.get_emoji(
                db.query("select id from emojis where name = 'upvote'")[0][0]))
            await message.add_reaction(self.bot.get_emoji(
                db.query("select id from emojis where name = 'downvote'")[0][0]))

        # xp gain
        message_xp = util.xp_from_message(message)
        currenthour = message.created_at.hour
        db.add_activity(message.guild.id, message.author.id, message_xp, currenthour)
        
        # if bot account, ignore everything after this
        if message.author.bot:
            return
        
        # stfu
        if self.stfu_regex.findall(message.content) and random.randint(0, 1) == 0:
            try:
                await message.channel.send("no u")
            except discord.errors.Forbidden:
                pass
        
        # hi
        if message.content.lower().strip("!.?~ ") == "hi" and random.randint(0, 19) == 0:
            try:
                await message.channel.send('hi')
            except discord.errors.Forbidden:
                pass

        # git gud
        if message.content.lower().startswith("git "):
            gitcommand = re.search(r'git (\S+)', message.content)
            if gitcommand is not None:
                try:
                    gitcommand = gitcommand.group(1)
                    if gitcommand == "--help":
                        msg = "```\n" \
                              "usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]\n" \
                              "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n" \
                              "           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n" \
                              "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n" \
                              "           <command> [<args>]```"
                        await message.channel.send(msg)
                    elif gitcommand == "--version":
                        await message.channel.send("`git version 2.17.1`")
                    elif gitcommand in ["commit", "push", "pull", "checkout", "status", "init", "add"]:
                        pass
                    else:
                        await message.channel.send(f"`git: '{gitcommand}' is not a git command. See 'git --help'.`")
                except discord.errors.Forbidden:
                    pass

        # log emojis
        unicode_emojis = util.find_unicode_emojis(message.content)
        custom_emojis = util.find_custom_emojis(message.content)
        if unicode_emojis or custom_emojis:
            db.log_emoji_usage(message, custom_emojis, unicode_emojis)

        # level up message
        announce = util.int_to_bool(db.get_setting(message.guild.id, "levelup_toggle"))
        if announce:
            activity_data = db.get_user_activity(message.guild.id, message.author.id)
            if activity_data is None:
                return

            xp = sum(activity_data)
            level_before = util.get_level(xp-message_xp)
            level_now = util.get_level(xp)

            if level_now > level_before:
                try:
                    await message.channel.send(f"{message.author.mention} just leveled up! (level **{level_now}**)")
                except discord.errors.Forbidden:
                    pass
Ejemplo n.º 7
0
    async def profile(self, ctx, user: discord.Member = None):
        """Your personal customizable user profile."""
        if user is None:
            user = ctx.author

        badges = []
        badge_classes = {
            "dev": "fab fa-dev",
            "patreon": "fab fa-patreon",
            "lastfm": "fab fa-lastfm",
            "sunsign": "fas fa-sun",
            "location": "fas fa-compass",
            "bot": "fas fa-robot",
        }

        def get_font_size(username):
            length = len(username)
            if length < 15:
                return "24px"
            elif length < 20:
                return "18px"
            elif length < 25:
                return "15px"
            else:
                return "11px"

        def make_badge(classname):
            return f'<li class="badge-container"><i class="corner-logo {classname}"></i></li>'

        # activity = db.get_user_activity(ctx.guild.id, user.id)
        activity = db.global_activitydata(user.id)
        fishydata = db.fishdata(user.id)

        local_xp_rows = db.query(
            "SELECT * FROM activity WHERE user_id = ? AND guild_id = ?",
            (user.id, ctx.guild.id),
        )
        local_xp = 0
        if local_xp_rows is not None:
            local_xp = sum(list(local_xp_rows[0][3:]))

        global_xp_rows = db.query("SELECT * FROM activity WHERE user_id = ?",
                                  (user.id, ))
        global_xp = 0
        if global_xp_rows is not None:
            global_xp = sum(sum(row[3:]) for row in global_xp_rows)

        if user.id == self.bot.owner_id:
            badges.append(make_badge(badge_classes["dev"]))

        if user.bot:
            badges.append(make_badge(badge_classes["bot"]))

        patrons = db.query(
            "select user_id from patrons where currently_active = 1")
        if patrons is not None and user.id in [x[0] for x in patrons]:
            badges.append(make_badge(badge_classes["patreon"]))

        description = db.query(
            "SELECT description FROM profiles WHERE user_id = ?", (user.id, ))
        if description is None or description[0][0] is None:
            if user.bot:
                description = "I am a bot<br>BEEP BOOP"
            else:
                description = "You should change this by using<br>>editprofile description"
        else:
            description = bleach.clean(
                description[0][0].replace("\n", "<br>"),
                tags=bleach.sanitizer.ALLOWED_TAGS + ["br"],
            )

        background_url = db.query(
            "SELECT background_url FROM profiles WHERE user_id = ?",
            (user.id, ))
        custom_bg = background_url is not None and str(
            background_url[0][0]).lower() != "none"

        command_count = 0
        command_uses = db.query(
            """
            SELECT SUM(count) FROM command_usage WHERE user_id = ? GROUP BY user_id
            """,
            (user.id, ),
        )
        if command_uses is not None:
            command_count = command_uses[0][0]

        replacements = {
            "BACKGROUND_IMAGE": background_url[0][0] if custom_bg else "",
            "WRAPPER_CLASS": "custom-bg" if custom_bg else "",
            "SIDEBAR_CLASS": "blur" if custom_bg else "",
            "OVERLAY_CLASS": "overlay" if custom_bg else "",
            "USER_COLOR": user.color,
            "AVATAR_URL": user.avatar_url_as(size=128, format="png"),
            "USERNAME": user.name,
            "DISCRIMINATOR": f"#{user.discriminator}",
            "DESCRIPTION": description,
            "FISHY_AMOUNT": fishydata.fishy if fishydata is not None else 0,
            "SERVER_LEVEL": util.get_level(local_xp),
            "GLOBAL_LEVEL": util.get_level(global_xp),
            "ACTIVITY_DATA": str(activity),
            "CHART_MAX": max(activity),
            "COMMANDS_USED": command_count,
            "BADGES": "\n".join(badges),
            "USERNAME_SIZE": get_font_size(user.name),
        }

        def dictsub(m):
            return str(replacements[m.group().strip("%")])

        formatted_html = re.sub(r"%%(\S*)%%", dictsub, self.profile_html)

        async with aiohttp.ClientSession() as session:
            data = {
                "html": formatted_html,
                "width": 600,
                "height": 400,
                "imageFormat": "png",
            }
            async with session.post("http://localhost:3000/html",
                                    data=data) as response:
                with open("downloads/profile.png", "wb") as f:
                    while True:
                        block = await response.content.read(1024)
                        if not block:
                            break
                        f.write(block)

        with open("downloads/profile.png", "rb") as f:
            await ctx.send(file=discord.File(f))