feat: (BETA) %freq graph

This commit is contained in:
Klemek
2021-07-13 18:04:46 +02:00
parent 07aed12463
commit 8b0fe859a7
4 changed files with 68 additions and 8 deletions
+2
View File
@@ -2,3 +2,5 @@ discord.py==1.7.0
python-dotenv==0.15.0
python-dateutil==2.8.1
git+git://github.com/Klemek/miniscord.git
numpy
matplotlib
+44
View File
@@ -1,6 +1,11 @@
from typing import List
from datetime import timedelta
import calendar
import matplotlib.pyplot as plt
import numpy as np
from io import BytesIO
import discord
import time
from utils import (
from_now,
@@ -30,6 +35,45 @@ class Frequency:
self.longest_streak_start = None
self.longest_streak_author = None
def to_graph(self) -> List[str]:
self.dates.sort()
delta = self.dates[-1] - self.dates[0]
if delta.days == 0:
delta = timedelta(days=1)
day = {j: sum(self.hours[i][j] for i in range(7)) for j in range(24)}
busiest_hour = top_key(day)
n_hours = delta.days
if self.dates[0].hour <= busiest_hour and self.dates[-1].hour >= busiest_hour:
n_hours += 1
plt.style.use('dark_background')
fig, ax = plt.subplots()
fig.patch.set_facecolor('#36393F')
ax.patch.set_alpha(0)
times = range(25)
for i in range(7):
hours = [self.hours[i][hour]*7/n_hours for hour in range(24)] + [self.hours[i][0]*7/n_hours]
ax.plot(times, hours, label=calendar.day_name[i], linestyle='--', linewidth=0.8)
hours = [day[hour]/n_hours for hour in range(24)] + [day[0]/n_hours]
ax.plot(times, hours, c='r', label='average', linewidth=1.5)
ax.set_xlabel('hour of day')
ax.set_xlim([0, 24])
ax.set_ylabel('average messages')
ax.legend(framealpha=0)
with BytesIO() as f:
plt.savefig(f, format='png', facecolor=fig.get_facecolor(), edgecolor='none')
f.seek(0)
return [
discord.File(f, f"{time.time()}-plot.png")
]
def to_string(
self,
*,
+12 -6
View File
@@ -14,11 +14,13 @@ from utils import generate_help
class FrequencyScanner(Scanner):
@staticmethod
def help() -> str:
return generate_help("freq", "Show frequency-related statistics")
return generate_help("freq", "(BETA) Show frequency-related statistics", args=[
"graph - plot hours of week",
],)
def __init__(self):
super().__init__(
valid_args=["all", "everyone"],
valid_args=["all", "everyone", "graph"],
help=FrequencyScanner.help(),
intro_context="Frequency",
)
@@ -27,6 +29,7 @@ class FrequencyScanner(Scanner):
self.freq = Frequency()
self.all_messages = "all" in args or "everyone" in args
self.member_specific = len(self.members) > 0
self.to_graph = "graph" in args
return True
def compute_message(self, channel: ChannelLogs, message: MessageLog):
@@ -36,10 +39,13 @@ class FrequencyScanner(Scanner):
def get_results(self, intro: str) -> List[str]:
FrequencyScanner.compute_results(self.freq)
res = [intro]
res += self.freq.to_string(
member_specific=self.member_specific,
)
if self.to_graph:
res = self.freq.to_graph()
else:
res = [intro]
res += self.freq.to_string(
member_specific=self.member_specific,
)
return res
@staticmethod
+10 -2
View File
@@ -288,15 +288,20 @@ class Scanner(ABC):
if self.mention_users
else discord.AllowedMentions.none()
)
file = None
for r in results:
if r:
if isinstance(r, int) and r == SPLIT_TOKEN:
if isinstance(r, discord.File):
file = r
elif isinstance(r, int) and r == SPLIT_TOKEN:
await message.channel.send(
response,
reference=message if first else None,
allowed_mentions=allowed_mentions,
file=file,
)
first = False
file = None
response = ""
elif isinstance(r, str):
if len(response + "\n" + r) > 2000:
@@ -304,15 +309,18 @@ class Scanner(ABC):
response,
reference=message if first else None,
allowed_mentions=allowed_mentions,
file=file,
)
first = False
file = None
response = ""
response += "\n" + r
if len(response) > 0:
if len(response) > 0 or file is not None:
await message.channel.send(
response,
reference=message if first else None,
allowed_mentions=allowed_mentions,
file=file,
)
command_cache.cache(self, message, args)
# Delete custom progress message