This repository has been archived on 2025-01-28. You can view files and clone it, but cannot push or open issues or pull requests.
natsuko/cogs/activity_counter.py

116 lines
4.5 KiB
Python
Raw Normal View History

2023-05-03 19:53:01 +03:00
import discord
import schedule
from discord import app_commands
from discord.ext import commands, tasks
from bot import db
from datetime import datetime, timedelta, timezone
from matplotlib import pyplot as plt
from matplotlib import ticker, markers
from loguru import logger
2023-05-16 16:34:50 +03:00
from asyncio import run_coroutine_threadsafe
2023-05-18 22:54:00 +03:00
from utils.translate import get_text
2023-05-03 19:53:01 +03:00
class ActiveCount(commands.Cog):
def __init__(self, bot):
self.bot = bot
plt.style.use(['default', "dark.mplstyle", ])
self.daysoftheweek = ("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday")
for server in bot.guilds:
2023-05-16 16:34:50 +03:00
run_coroutine_threadsafe(self.add_server(server.id), self.bot.loop)
2023-05-03 19:53:01 +03:00
2023-05-16 16:34:50 +03:00
async def add_server(self, server_id: int):
if not (await db.history.find_one({"type": "server", "id": server_id})):
await db.history.insert_one({
2023-05-03 19:53:01 +03:00
"type": "server",
"id": server_id,
"history": {
day: {
str(i): [] for i in range(24)
} for day in self.daysoftheweek
},
"current": {str(i): 0 for i in range(24)},
"yesterday": {str(i): 0 for i in range(24)},
"avarage": {str(i): [] for i in range(24)}
})
# TODO: добавить сервер, если кот зашел на новый сервак
@commands.Cog.listener()
async def on_message(self, message):
if message.guild is None: return
hour = message.created_at.replace(tzinfo=timezone.utc).astimezone(tz=None).hour
2023-05-16 16:55:25 +03:00
await db.history.update_one(
2023-05-03 19:53:01 +03:00
{"type": "server", "id": message.guild.id},
{"$inc": {f"current.{hour}": 1}}
)
@app_commands.command()
async def activity(self, inter):
day = datetime.now().weekday()
fig, ax = plt.subplots(figsize=(8, 5))
2023-05-16 16:34:50 +03:00
server_data = await db.history.find_one({"type": "server", "id": inter.guild_id})
2023-05-03 19:53:01 +03:00
if server_data is None:
await inter.response.send_message("Недостаточно данных! Попробуйте завтра")
return
data = server_data['avarage']
vals = list(map(lambda k: sum(data[k]) / len(data[k]) if len(data[k]) != 0 else 0, data.keys()))
labels = list(map(int, data.keys()))
ax.bar(labels, vals, width=.9, label=await get_string(inter, "Avarage"))
vals = list(map(lambda k: max(data[k]) if len(data[k]) != 0 else 0, data.keys()))
ax.plot(labels, vals, label=await get_string(inter, "Max"), linestyle='', marker="_", markersize=20)
data = server_data['history'][self.daysoftheweek[day]]
vals = list(map(lambda k: sum(data[k]) / len(data[k]) if len(data[k]) != 0 else 0, data.keys()))
labels = list(map(int, data.keys()))
ax.bar(labels, vals, width=.6, label=await get_string(inter, "On this day\nof the week"))
data = server_data['yesterday']
vals = [data[k] for k in data.keys()]
labels = [int(i) for i in data.keys()]
ax.bar(labels, vals, width = .4, hatch='x', label=await get_string(inter, "Yesterday"))
data = server_data['current']
vals = [data[k] for k in data.keys()]
labels = [int(i) for i in data.keys()]
ax.bar(labels, vals, width = .4, label=await get_string(inter, "Today"))
now = datetime.now()
ax.axvline(now.hour+(now.minute/60)-0.5, color='dimgrey')
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1))
ax.xaxis.set_minor_formatter(ticker.ScalarFormatter())
ax.tick_params(axis='x', which='minor', labelsize=8)
ax.legend(loc='upper left')
ax.grid(axis='y')
ax.set_axisbelow(True)
ax.set_xlabel(await get_string(inter, 'Hours'))
ax.set_ylabel(await get_string(inter, 'Experience'))
ax.set_xlim(-0.5, 23.5)
ax.legend().get_frame().set_boxstyle('Round', pad=0.2, rounding_size=1)
ax.legend().get_frame().set_linewidth(0.0)
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
fig.savefig('temp.png')
with open('temp.png', 'rb') as f:
f = discord.File(f)
await inter.response.send_message(file=f)
async def setup(bot):
await bot.add_cog(ActiveCount(bot))