[mod-rtfgd] Fini

[mod-perdu] Manque stats
[mod-errors] Petite update
[base-config] les éléments de configuration peuvent etre utilisés comme des attributs
This commit is contained in:
Louis Chauvet 2020-03-20 12:22:13 +01:00
parent 89af9403f1
commit 98ffba74c3
Signed by: fomys
GPG Key ID: 1ECA046A9615ABA0
7 changed files with 166 additions and 16 deletions

View File

@ -1,6 +1,5 @@
from __future__ import annotations
from enum import Enum
from typing import Dict, Any, Optional
@ -74,6 +73,9 @@ class Config:
Do not override"""
self._load()
def __getattr__(self, item):
return self.config.get(item)
def __getitem__(self, item):
return self.config.get(item)

View File

@ -1,16 +1,10 @@
#!/usr/bin/python3
import asyncio
import concurrent
import importlib
import json
import logging
import logging.config
import os
import signal
import socket
import traceback
from concurrent.futures.process import ProcessPoolExecutor
from concurrent.futures.thread import ThreadPoolExecutor
from typing import Dict
import discord
@ -310,6 +304,7 @@ class LBI(discord.Client):
initialized_class.dispatch("load")
if module not in self.config["modules"]:
self.config["modules"].append(module)
self.config.save()
return 0
@modules_edit

View File

@ -1,11 +1,8 @@
import asyncio
import time
import datetime
import collections
import random
import traceback
import collections
import discord
from discord import Message
@ -32,11 +29,13 @@ class MainClass(BaseClassPython):
self.config.init({"dev_chan": [], "memes": [""], "icon": ""})
self.errorsDeque = None
async def on_ready(self):
async def on_load(self):
if self.objects.save_exists('errorsDeque'):
self.errorsDeque = self.objects.load_object('errorsDeque')
else:
self.errorsDeque = collections.deque()
async def on_ready(self):
for i in range(len(self.errorsDeque)):
try:
msg_id = self.errorsDeque.popleft()
@ -73,20 +72,20 @@ class MainClass(BaseClassPython):
title="[Erreur] Aïe :/",
description="```python\n{0}```".format(traceback.format_exc()),
color=self.color)
embed.set_image(url=random.choice(self.config["memes"]))
embed.set_image(url=random.choice(self.config.memes))
message_list = None
# Send message to dev channels
for chanid in self.config["dev_chan"]:
for chanid in self.config.dev_chan:
try:
await self.client.get_channel(chanid).send(
embed=embed.set_footer(text="Ce message ne s'autodétruira pas.", icon_url=self.config["icon"]))
embed=embed.set_footer(text="Ce message ne s'autodétruira pas.", icon_url=self.config.icon))
except BaseException as e:
raise e
# Send message to current channel if exists
if channel is not None:
message = await channel.send(embed=embed.set_footer(text="Ce message va s'autodétruire dans une minute",
icon_url=self.config["icon"]))
icon_url=self.config.icon))
msg_id = {"channel_id": message.channel.id, "msg_id": message.id}
self.errorsDeque.append(msg_id)
# Save message in errorsDeque now to keep them if a reboot happend during next 60 seconds

View File

@ -0,0 +1,113 @@
import datetime
import discord
import utils.emojis
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "Perdu"
help = {
"description": "Module donnant les statistiques sur les perdants",
"commands": {
"`{prefix}{command}`": "Donne le classement des perdants de la semaine",
"`{prefix}{command} all`": "Donne le classement des perdants depuis toujours",
"`{prefix}{command} <nombre de jours>`": "Donne le classement des perdants sur la durée spécifiée",
"`{prefix}{command} stats [@mention]`": "Donne les statistiques d'un perdant",
}
}
help_active = True
command_text = "perdu"
color = 0xff6ba6
def __init__(self, client):
super().__init__(client)
self.config.init({"channel": 0, "lost_role": 0, "min_delta": datetime.timedelta(minutes=30).total_seconds()})
async def on_load(self):
if self.objects.save_exists('history'):
self.history = self.objects.load_object('history')
else:
self.history = {}
async def on_message(self, message: discord.Message):
# Fill history
if message.channel.id == self.config.channel:
if message.author.id not in self.history.keys():
# Add new user if not found
self.history.update(
{message.author.id: ([(message.created_at, datetime.timedelta(seconds=0)), ])}
)
else:
# Update user and precompute timedelta
delta = message.created_at - self.history[message.author.id][-1][0]
if delta.total_seconds() >= self.config.min_delta:
self.history[message.author.id].append((message.created_at, delta))
self.objects.save_object("history", self.history)
await self.parse_command(message)
async def fill_history(self):
self.history = {}
async for message in self.client.get_channel(self.config.channel).history(limit=None):
if message.author.id not in self.history.keys():
# Add new user if not found
self.history.update({message.author.id: ([(message.created_at, datetime.timedelta(seconds=0)), ])})
else:
# Update user and precompute timedelta
delta = self.history[message.author.id][-1][0] - message.created_at
if delta.total_seconds() >= self.config.min_delta:
self.history[message.author.id].append((message.created_at, delta))
self.objects.save_object("history", self.history)
def get_top(self, top=10, since=datetime.datetime(year=1, month=1, day=1)):
"""Return [(userid, [(date, delta), (date,delta), ...]), ... ]"""
# Extract only messages after until
messages = []
for user in self.history.keys():
if self.history[user][-1][0] > since:
messages.append((user, [message for message in self.history[user] if message[0] > since]))
messages.sort(key=lambda x: len(x[1]), reverse=True)
# Extract top-ten
messages = messages[:min(top, len(messages))]
return messages
async def com_fill(self, message: discord.Message, args, kwargs):
if await self.auth(message.author):
async with message.channel.typing():
await self.fill_history()
await message.channel.send("Fait.")
async def com_all(self, message: discord.Message, args, kwargs):
# Get all stats
top = self.get_top()
embed_description = "\n".join(
f"{utils.emojis.write_with_number(i)} : <@{top[i][0]}> a **perdu {len(top[i][1])} fois** depuis la"
f" création du salon à en moyenne **{sum(list(zip(*top[i][1]))[1], datetime.timedelta(0)) / len(top[i][1])} heures d'intervalle.**"
for i in range(len(top))
)[:2000]
await message.channel.send(embed=discord.Embed(title="G-Perdu - Tableau des scores",
description=embed_description,
color=self.color))
async def com_stats(self, message: discord.Message, args, kwargs):
pass
async def command(self, message, args, kwargs):
if message.mentions:
await self.com_stats(message, args, kwargs)
since = datetime.datetime.now() - datetime.timedelta(days=7)
if args[0]:
try:
since = datetime.datetime.now() - datetime.timedelta(days=float(args[0]))
except ValueError:
pass
top = self.get_top(10, since)
embed_description = "\n".join(
f"{utils.emojis.write_with_number(i)} : <@{top[i][0]}> a **perdu {len(top[i][1])} fois** depuis la"
f" création du salon à en moyenne **{sum(list(zip(*top[i][1]))[1], datetime.timedelta(0)) / len(top[i][1])} heures d'intervalle.**"
for i in range(len(top))
)[:2000]
await message.channel.send(embed=discord.Embed(title="G-Perdu - Tableau des scores",
description=embed_description,
color=self.color))

29
modules/rtfgd/__init__.py Normal file
View File

@ -0,0 +1,29 @@
import random
import discord
from modules.base import BaseClassPython
class MainClass(BaseClassPython):
name = "rtfgd"
help = {
"description": "Read the fucking google doc",
"commands": {
"{prefix}{command} <mention>": "Demande gentilment de lire le google doc"
}
}
help_active = True
command_text = "rtfgd"
color = 0xdb1348
def __init__(self, client):
super().__init__(client)
self.config.init({"memes": []})
async def command(self, message, args, kwargs):
await message.channel.send(
" ".join(member.mention for member in message.mentions),
embed=discord.Embed(title="Read da fu**ing GOOGLE DOCS ! (╯°□°)╯︵ ┻━┻",
color=self.color).set_image(url=random.choice(self.config.memes)))

0
utils/__init__.py Normal file
View File

12
utils/emojis.py Normal file
View File

@ -0,0 +1,12 @@
NUMBERS = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟"]
def write_with_number(i):
raw = str(i)
s = ""
for c in str(i):
if raw == ".":
s += "."
else:
s += NUMBERS[int(c)]
return s