From 466fc241e0de5533920f5c031100e2621ae1816e Mon Sep 17 00:00:00 2001 From: aikaterna Date: Sat, 27 Jan 2018 22:03:43 -0800 Subject: [PATCH] Add chatchart --- chatchart/__init__.py | 6 +++ chatchart/chatchart.py | 83 ++++++++++++++++++++++++++++++++++++++++++ chatchart/info.json | 14 +++++++ 3 files changed, 103 insertions(+) create mode 100644 chatchart/__init__.py create mode 100644 chatchart/chatchart.py create mode 100644 chatchart/info.json diff --git a/chatchart/__init__.py b/chatchart/__init__.py new file mode 100644 index 0000000..c687eeb --- /dev/null +++ b/chatchart/__init__.py @@ -0,0 +1,6 @@ +from .chatchart import Chatchart + + +def setup(bot: commands.Bot): + n = Chatchart(bot) + bot.add_cog(n) diff --git a/chatchart/chatchart.py b/chatchart/chatchart.py new file mode 100644 index 0000000..d479ff3 --- /dev/null +++ b/chatchart/chatchart.py @@ -0,0 +1,83 @@ +# Lines 54 through 68 are influenced heavily by cacobot's stats module: +# https://github.com/Orangestar12/cacobot/blob/master/cacobot/stats.py +# Big thanks to Redjumpman for changing the beta version from +# Imagemagick/cairosvg to matplotlib. +# Thanks to violetnyte for suggesting this cog. +import discord +import heapq +import os +from io import BytesIO +import matplotlib +matplotlib.use('agg') +import matplotlib.pyplot as plt +plt.switch_backend('agg') +from discord.ext import commands + + +class Chatchart: + """Show activity.""" + + def __init__(self, bot): + self.bot = bot + + def create_chart(self, top, others): + plt.clf() + sizes = [x[1] for x in top] + labels = ["{} {:g}%".format(x[0], x[1]) for x in top] + if len(top) >= 15: + sizes = sizes + [others] + labels = labels + ["Others {:g}%".format(others)] + + title = plt.title('User activity in the last 5000 messages') + title.set_va("top") + title.set_ha("left") + plt.gca().axis("equal") + colors = ['r', 'darkorange', 'gold', 'y', 'olivedrab', 'green', 'darkcyan', 'mediumblue', 'darkblue', 'blueviolet', 'indigo', 'orchid', 'mediumvioletred', 'crimson', 'chocolate', 'gray'] + pie = plt.pie(sizes, colors=colors, startangle=0) + plt.legend(pie[0], labels, bbox_to_anchor=(0.7, 0.45), loc="center", fontsize=10, + bbox_transform=plt.gcf().transFigure) + plt.subplots_adjust(left=0.0, bottom=0.1, right=0.45) + image_object = BytesIO() + plt.savefig(image_object, format='PNG') + image_object.seek(0) + return image_object + + @commands.command(pass_context=True) + @commands.cooldown(1, 10, commands.BucketType.channel) + async def chatchart(self, ctx): + """ + Generates a pie chart, representing the last 5000 messages in this channel. + """ + channel = ctx.message.channel + e = discord.Embed(description="Loading...", colour=ctx.guild.me.top_role.colour) + e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif") + em = await ctx.send(embed=e) + + channel_history = [] + async for msg in channel.history(limit=5000): + channel_history.append(msg) + msg_data = {'total count': 0, 'users': {}} + + for msg in channel_history: + if msg.author.bot: + pass + elif msg.author.name in msg_data['users']: + msg_data['users'][msg.author.name]['msgcount'] += 1 + msg_data['total count'] += 1 + else: + msg_data['users'][msg.author.name] = {} + msg_data['users'][msg.author.name]['msgcount'] = 1 + msg_data['total count'] += 1 + + for usr in msg_data['users']: + pd = float(msg_data['users'][usr]['msgcount']) / float(msg_data['total count']) + msg_data['users'][usr]['percent'] = round(pd * 100, 1) + + top_ten = heapq.nlargest(15, [(x, msg_data['users'][x][y]) + for x in msg_data['users'] + for y in msg_data['users'][x] + if y == 'percent'], key=lambda x: x[1]) + others = 100 - sum(x[1] for x in top_ten) + img = self.create_chart(top_ten, others) + await em.delete() + await channel.send(file=discord.File(img, 'chart.png')) diff --git a/chatchart/info.json b/chatchart/info.json new file mode 100644 index 0000000..1af67b8 --- /dev/null +++ b/chatchart/info.json @@ -0,0 +1,14 @@ +{ + "author": [ + "Redjumpman and aikaterna" + ], + "description": "Generate a pie chart from the last 5000 messages in a channel to see who's been talking the most.", + "short": "Generate a pie chart from the last 5000 messages", + "tags": [ + "data", + "chart", + "activity" + ], + "requirements": ["matplotlib"], + "type": "COG" +} \ No newline at end of file