Compare commits

...
82 Commits
Author SHA1 Message Date
marc 39958ce82f q = queue 2022-01-15 17:00:36 +01:00
marc e89f524916 true lock 2022-01-09 21:27:02 +01:00
marc b0aa32f92d bye 3.8.3 2022-01-09 21:26:26 +01:00
marc e1cb4bf66e pipfile.lock 2022-01-09 21:18:01 +01:00
marc ec98da8d8d fix dire 2022-01-09 21:13:11 +01:00
marc 22bc94fb60 Pipfile.lock 2022-01-09 21:07:28 +01:00
marc f9f3ac3b00 pipfile.lock torrequest 2022-01-09 21:01:02 +01:00
marc 8c462195ea torrequest 2022-01-09 21:00:05 +01:00
marc d5c6156e79 html2text 2022-01-09 20:59:09 +01:00
marc e8a058f40e fake-useragent 2022-01-09 20:56:03 +01:00
marc 07595dd946 selenium 2022-01-09 20:54:55 +01:00
marc 7fe0cdd72b future 2022-01-09 20:53:58 +01:00
marc 81ee2b20d6 unidecode 2022-01-09 20:53:09 +01:00
marc 982a185661 requests-futures 2022-01-09 20:52:19 +01:00
marc 564723fbd9 dns python 2022-01-09 20:44:42 +01:00
marc c5e5de5fc5 clean-dependencies 2022-01-09 20:41:38 +01:00
marc 097107a228 first try 2022-01-09 20:34:59 +01:00
marc 17305f17a5 make deploy 2022-01-09 20:26:18 +01:00
marc 1054f87908 no pipenv 2022-01-09 20:18:03 +01:00
marc 94c74a2b78 dockerignore 2022-01-09 20:17:43 +01:00
marc 3eff882c91 txt 2022-01-09 20:17:13 +01:00
marc a156c36d04 messing with dockerfile 2022-01-09 20:13:34 +01:00
marc e847194f8c Makefile 2022-01-09 19:47:44 +01:00
marc bdbc5273e3 makefile 2022-01-09 19:46:57 +01:00
marc abd5304b9a pipenv in docker 2022-01-09 19:46:14 +01:00
marc 57179d3587 requirements for building 2022-01-09 19:41:41 +01:00
marc 3085797cdc commenting logging level info 2022-01-09 19:41:10 +01:00
marc 965b4afe3d apt-get 2022-01-09 19:25:17 +01:00
marc 699148c98e updated pipfile.lock 2022-01-09 19:24:14 +01:00
marc 3ae73618c8 pipfile.lock 2022-01-09 19:21:17 +01:00
marc c171f5d766 ctx 2022-01-09 19:19:43 +01:00
marc cca0828fb0 cleaned code 2022-01-09 19:17:53 +01:00
marc 14254a8d01 voice channel cog done 2022-01-09 19:15:45 +01:00
marc 4120ac71be Merge branch 'master' into voice-channel 2022-01-08 22:50:51 +01:00
marc 1a090f31fd fix mute if single 2022-01-08 22:47:20 +01:00
marc 9e0b940f28 voice channel 2022-01-05 00:43:01 +01:00
marc 2c4eb0989e changed order 2022-01-04 21:58:44 +01:00
marc 9f2bbc7447 removed doublon 2022-01-04 21:58:10 +01:00
marc 920df7d92a changed order 2022-01-04 21:57:29 +01:00
marc e6db4bc2a4 admin 2022-01-04 20:32:54 +01:00
marc d4b26e1ba2 Merge branch 'master' into shell 2022-01-04 20:21:59 +01:00
marc 48d3e7c6c7 messing with pexpect 2022-01-03 22:54:38 +01:00
marc 035b5ce49c no masters option 2022-01-01 21:17:20 +01:00
marc e930fa1589 fixed circular import and added create_role_if_missing 2022-01-01 21:15:50 +01:00
marc 5988506149 added pexpect 2022-01-01 21:15:28 +01:00
marc 50a994364a Merge branch 'master' into shell 2022-01-01 20:46:43 +01:00
marc f42048d3ed reordered tag 2022-01-01 20:46:36 +01:00
marc f16adfe12a single quote not a space 2022-01-01 20:46:36 +01:00
marc 13d7508913 forgot a space 2022-01-01 20:46:36 +01:00
marc 3511d71444 no test anymore 2022-01-01 20:46:36 +01:00
marc 06c1b40f88 no seconds but build number 2022-01-01 20:46:36 +01:00
marc 1a32e081a0 seconds 2022-01-01 20:46:36 +01:00
marc 5b08b934d7 slash 2022-01-01 20:46:36 +01:00
marc 64bdee1711 tag first 2022-01-01 20:46:36 +01:00
marc b5461dc360 no e option 2022-01-01 20:46:36 +01:00
marc 929704b3d9 short hash 2022-01-01 20:46:36 +01:00
marc d9813ea952 docker api url 2022-01-01 20:46:36 +01:00
marc df4600cc4a fix 2022-01-01 20:46:29 +01:00
marc 7dce6bca00 e option in pip 2022-01-01 20:45:47 +01:00
marc 9b7a8b717c true ids 2022-01-01 20:45:47 +01:00
marc fb33805f35 also faking wolfram alpha 2022-01-01 20:45:47 +01:00
marc f45add002a trying to fake mongo ids 2022-01-01 20:45:47 +01:00
marc 87a3e44e32 trying to cache pip requirements 2022-01-01 20:45:47 +01:00
marc 11ad8063f0 tag 2022-01-01 20:45:47 +01:00
marc 8fe85f9c5b timestamp tag 2022-01-01 20:45:47 +01:00
marc 8618ef3a8d secrets 2022-01-01 20:45:47 +01:00
marc 48c8d5a94c use secrets as env var 2022-01-01 20:45:47 +01:00
marc b4e9c90dd1 discord prefix in readme 2022-01-01 20:45:47 +01:00
marc 15ad71ee41 run the bot in test 2022-01-01 20:45:47 +01:00
marc b94d8e1f36 test workflow 2022-01-01 20:45:47 +01:00
marc 84f95a0e93 live to ok 2022-01-01 20:45:47 +01:00
marc 35d6f79806 live 2022-01-01 20:45:47 +01:00
marc 3163ec5022 home to live 2022-01-01 20:45:47 +01:00
marc ae7ea67a1e healthcheck on localhost even though the servers listens on all interfaces 2022-01-01 20:45:47 +01:00
marc f78665466a one discord.py 2022-01-01 20:45:47 +01:00
marc 91b1cea091 healthcheck 2022-01-01 20:45:47 +01:00
marc 1ce05964c1 create_role_if_missing 2022-01-01 20:44:14 +01:00
marc 581a584c90 shell role 2021-12-27 02:19:54 +01:00
marc 88cfd0deaf Merge branch 'master' into shell 2021-12-27 02:15:50 +01:00
marc 3c4bdf4ebf Merge branch 'master' into shell 2021-12-25 19:16:44 +01:00
marc 28bcbba6c6 shell 2021-12-22 21:38:12 +01:00
marc f774a2acdc docker role 2021-12-12 16:49:23 +01:00
17 changed files with 630 additions and 1052 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ Dockerfile
docker-compose.yml
README.md
Procfile
Pipfile.lock
# requirements.txt
run.sh
runtime.txt
Pipfile
Pipfile.lock
+1 -2
View File
@@ -2,8 +2,7 @@ FROM python:3.8.12-slim
LABEL maintainer="marc.partensky@gmail.com"
LABEL image="https://hub.docker.com/r/marcpartensky/discord-bot"
LABEL source="https://github.com/marcpartensky/discord-bot"
RUN apt-get update && apt-get upgrade -y && apt autoremove -y
# RUN add-apt-repository ppa:mc3man/trusty-media
RUN apt-get update && apt-get upgrade -y && apt-get autoremove -y
RUN apt-get install -y ffmpeg git curl
COPY requirements.txt ./
+5 -4
View File
@@ -2,16 +2,17 @@ start:
pipenv run python .
update:
pipenv lock --pre --clear
pipenv lock -r > requirements.txt
dev:
docker-compose -f docker-compose.yml up -d --build --force-recreate --remove-orphans dev
prod:
docker-compose -f docker-compose.yml up -d --build --force-recreate --remove-orphans prod
build:
build: update
docker-compose -f docker-compose.yml build prod
push: build
docker-compose -f docker-compose.yml push prod
requirements:
pipenv lock -r > requirements.txt
deploy: push
DOCKER_HOST=ssh://vps docker service update vps_esclave
setup:
pip install pipenv
pipenv shell
@@ -19,6 +20,6 @@ setup:
recreate:
docker-compose -f docker-compose.yml up --force-recreate dev
fixwithbrew:
brwe install python@3.8
brew install python@3.8
sudo ln -sf /home/linuxbrew/.linuxbrew/Cellar/python@3.8/3.8.12_1/bin/python3.8 /usr/bin/python3.8
+14 -92
View File
@@ -4,115 +4,38 @@ verify_ssl = true
name = "pypi"
[packages]
aenum = "*"
aiohttp = "*"
appdirs = "*"
astroid = "*"
async-timeout = "*"
attrs = "*"
autopep8 = "*"
beautifulsoup4 = "*"
black = "*"
bs4 = "*"
certifi = "*"
cffi = "*"
cfgv = "*"
chardet = "*"
click = "==7.1.2"
colorama = "*"
commonmark = "*"
cryptography = "*"
# "discord.py[voice]" = "*"
# "discord.py" = {file = "https://github.com/Rapptz/discord.py/archive/async.zip#egg=discord.py[voice]"}
"discord.py" = {git = "https://github.com/Rapptz/discord.py"}
distlib = "*"
dnspython = "*"
fake-useragent = "*"
# fbchat = "*"
fbchat = {git = "git://github.com/carpedm20/fbchat.git"}
filelock = "*"
future = "*"
html2text = "*"
identify = "*"
idna = "*"
inflect = "*"
isort = "*"
"jaraco.itertools" = "*"
jedi = "*"
jeepney = "*"
joblib = "*"
keyring = "*"
"keyrings.alt" = "*"
lazy-object-proxy = "*"
lxml = "*"
mccabe = "*"
more-itertools = "*"
multidict = "*"
mypy-extensions = "*"
"discord.py[voice]" = "*"
fbchat = "*"
# fbchat = {git = "git://github.com/carpedm20/fbchat.git"}
nightcore = "*"
nodeenv = "*"
numpy = "*"
paho-mqtt = "*"
parso = "*"
pathspec = "*"
pluggy = "*"
pre-commit = "*"
profanity-check = "*"
progressbar2 = "*"
pycodestyle = "*"
pycparser = "*"
pydub = "*"
# pyicloud = "*"
pylint = "*"
pymongo = "*"
pyparsing = "*"
python-utils = "*"
pytz = "*"
regex = "*"
requests = "*"
requests-futures = "*"
rich = "*"
scikit-learn = "*"
scipy = "*"
selenium = "*"
six = "*"
soupsieve = "*"
stem = "*"
threadpoolctl = "*"
toml = "*"
torrequest = "*"
tox = "*"
translate = "*"
typed-ast = "*"
typing-extensions = "*"
tzlocal = "*"
urllib3 = "*"
vcrpy = "*"
virtualenv = "*"
websockets = "*"
wikipedia = "*"
wolframalpha = "*"
wrapt = "*"
xmltodict = "*"
yarl = "*"
"zope.interface" = "*"
DateTime = "*"
Deprecated = "*"
html2text = "*"
gTTS = "2.2.1"
gTTS-token = "*"
Pillow = "*"
PyGithub = "*"
Pygments = "*"
PyJWT = "*"
PyMySQL = "*"
PyNaCl = "*"
PySocks = "*"
PyYAML = "*"
SecretStorage = "*"
Unidecode = "*"
youtube_dl = "*"
python-dotenv = "*"
dpy-http-server = "*"
pexpect = "*"
# libs/sherlock
dnspython = "*"
requests-futures = "*"
torrequest = "*"
# libs/google
unidecode = '*'
future = '*'
selenium = "*"
fake-useragent = "*"
[dev-packages]
black = "*"
@@ -120,5 +43,4 @@ pylint = "*"
jedi = "*"
[requires]
# python_version = "3.8.3"
python_version = "3.8.12"
Generated
+240 -796
View File
File diff suppressed because it is too large Load Diff
+4 -10
View File
@@ -1,12 +1,9 @@
from config.config import access, status, delete_after_time, masters, cluster
from config.config import access, cluster
from config import shops
from utils import tools
from discord.ext import commands, tasks
from discord.ext import commands
from models.terminal import Terminal
import discord
import random
import time
import os
import typing
@@ -27,6 +24,7 @@ class Muted(commands.Converter):
class Admin(commands.Cog):
def __init__(self, bot: commands.Bot, **kwargs):
"""Cog pour administrer un serveur."""
super().__init__(**kwargs)
self.bot = bot
self.kick_reason = "c'est la vie"
@@ -245,11 +243,7 @@ class Admin(commands.Cog):
name=self.muted_role_name,
reason="Pour muter les gens trop bavards.",
)
for (
channel
) in (
ctx.guild.channels
): # removes permission to view and send in the channel
for channel in ctx.guild.channels: # removes permission to view and send in the channel
await channel.set_permissions(
role,
send_messages=False,
+1 -2
View File
@@ -7,11 +7,10 @@ __author__ = "Marc Partensky"
# from utils import tools
import os
import discord
import typing
import uuid
import discord
import traceback
import discord
from discord.ext import commands
import server
+1 -4
View File
@@ -142,7 +142,7 @@ class Code(commands.Cog):
author = msg.author
if ctx.author.id in self.users_list:
if msg.content == "?python":
if msg.content == self.bot.command_prefix + "python":
pass
else:
await self.execute(ctx, cmd=code)
@@ -158,9 +158,6 @@ class Code(commands.Cog):
and str(reaction.emoji) in emojis
)
class DestroyReactions(Exception):
"""Destroy the reactions."""
try:
reaction, user = await self.bot.wait_for(
"reaction_add", timeout=60.0, check=check
+7 -2
View File
@@ -219,7 +219,12 @@ class Docker(commands.Cog):
continue
print(content)
texts = []
text = f"{name}\n" + "_" * len(name) + "\n\n " + "".join([f"{word: <10}" for word in content["Titles"]])
text = (
f"{name}\n"
+ "_" * len(name)
+ "\n\n "
+ "".join([f"{word: <10}" for word in content["Titles"]])
)
n = len(text)
for process in content["Processes"]:
line = " \n * " + "".join([f"{word: <10}" for word in process])
@@ -230,7 +235,7 @@ class Docker(commands.Cog):
text += line
texts.append(text)
for text in texts:
text = text.replace('_', '‗')
text = text.replace("_", "‗")
await ctx.send("```md\n" + text + "\n```")
@commands.has_role(DOCKER_ROLE)
+1 -1
View File
@@ -520,7 +520,7 @@ class Music(commands.Cog):
else:
await ctx.send("Vous avez voté pour changer de musique.")
@commands.command(name="queue")
@commands.command(name="queue", aliases=["q"])
async def _queue(self, ctx: commands.Context, *, page: int = 1):
"""Affiche la queue à une page."""
voice_state = self.voice_states[ctx.guild.id]
+85 -11
View File
@@ -1,30 +1,104 @@
#!/usr/bin/env python
"""Control shells."""
from discord.ext import commands
import os
import sys
import typing
import discord
from discord.ext import commands
from discord.ext.commands.core import has_role
from utils import tools
from config.config import access, masters
from config import emoji
from urllib.parse import quote
from utils.tools import create_role_if_missing, Capturing
import requests
import asyncio
import re
import pexpect
SHELL_ROLE = "Shell"
class Shell(commands.Cog):
"""Control shells"""
def __init__(self, bot: commands.Bot):
"""Initialize the cog with the bot."""
self.bot = bot
self.color: discord.Color = discord.Color.darker_grey()
# self.thumbnail: str = (
# "https://cdn0.iconfinder.com/data/icons/development-2/24/terminal-512.png"
# )
self.thumbnail: str = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/GNOME_Terminal_icon_2019.svg/1200px-GNOME_Terminal_icon_2019.svg.png"
self.shells: typing.Dict[int, pexpect.pty_spawn.spawn] = {}
self.timeout = 3600
self.shell_path = os.environ.get("SHELL")
@commands.command()
async def shell(self, ctx: commands.Context, *, command: str):
@has_role(SHELL_ROLE)
@commands.command(aliases=["sh"])
async def shell(self, ctx: commands.Context):
"""Run a command in a shell"""
await ctx.send(command)
await create_role_if_missing(ctx, SHELL_ROLE, self.color)
embed = discord.Embed(color=self.color)
embed.set_thumbnail(url=self.thumbnail)
embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar)
embed.description = self.shell_path
if ctx.author.id in self.shells:
shell = self.shells[ctx.author.id]
shell.close()
del self.shells[ctx.author.id]
embed.title = "Closed shell"
await ctx.send(embed=embed)
else:
embed.title = "Opened shell"
await ctx.send(embed=embed)
shell = pexpect.spawn(command=self.shell_path, encoding="utf-8")
# shell = pexpect.spawn(
# command=self.shell_path, timeout=self.timeout, encoding="utf-8"
# )
# shell.logfile = open(f"/tmp/discord_shell_{ctx.author.id}", "w")
# shell.logfile = sys.stdout
self.shells[ctx.author.id] = shell
@commands.command(name="shells")
async def list_shells(self, ctx: commands.Context):
"""List opened shells."""
if len(self.shells) == 0:
return await ctx.send("> No shell opened.")
embed = discord.Embed(title="Shells :", color=self.color)
embed.set_thumbnail(url=self.thumbnail)
shell_users = []
for shell_user in map(self.bot.fetch_user, self.shells.keys()):
shell_users.append(f"- {await shell_user}")
embed.description = "\n".join(shell_users)
await ctx.send(embed=embed)
@commands.Cog.listener(name="on_message")
async def on_message(self, msg: discord.Message):
"""Read all messages"""
if msg.author == self.bot.user:
return
if msg.content.startswith(self.bot.command_prefix):
return
if msg.author.id in self.shells:
shell = self.shells[msg.author.id]
print(shell.sendline(msg.content))
# output = shell.read()
# output = shell.before
# print(output)
shell.expect(pexpect.EOF)
# shell.expect(".*\$ ")
output = shell.before
# output = "\n".join(output_list)
print(output)
# await msg.channel.send(output)
await msg.channel.send("test")
# async def cog_common_error(self, ctx, error):
# """Close all shell sessions."""
# for shell in self.shells.values():
# shell.close()
def setup(bot):
"""Setup the Shell cog."""
bot.add_cog(Shell(bot))
+5 -1
View File
@@ -4,6 +4,7 @@ import nightcore as nc
import discord
import os
import logging
class TextToSpeech(commands.Cog):
@@ -15,7 +16,10 @@ class TextToSpeech(commands.Cog):
"""Assure que l'opus est chargé."""
music = self.bot.get_cog("Music")
await music.cog_before_invoke(ctx)
await music._join(ctx)
try:
await music._join(ctx)
except discord.errors.ClientException:
logging.debug("attempted to connect to voice channel but already connected")
# if os.environ.get('DEVELOPMENT'):
# if not discord.opus.is_loaded():
# discord.opus.load_opus('libopus.so')
+168
View File
@@ -0,0 +1,168 @@
"""Monitor voice channels."""
import os
import logging
from typing import List
import discord
from discord.ext import commands
from config.config import masters
# logging.basicConfig(level=logging.INFO)
class VoiceChannel(commands.Cog):
"""Monitor voice channels."""
def __init__(self, bot: commands.Bot, **kwargs):
"""Initialize the cog."""
super().__init__(**kwargs)
self.bot = bot
self.role = "Voix"
self.color = discord.Color.teal()
self.notify_channel_id: int = os.environ.get("CHNOTIF")
self.tmp_channel_name = "Temporaire"
async def get_bot_member(self, guild: discord.Guild):
"""Return the member object of the bot."""
return guild.fetch_member(self.bot.user.id)
async def create_role_if_missing(self, guild: discord.Guild):
"""Create the voice role if it doesn't already exist."""
if self.role in [role.name for role in guild.roles]:
return
# Create the role
role = await guild.create_role(name=self.role, colour=self.color)
# Add the role to all the masters
for master in masters:
if member := await guild.fetch_member(master):
if self.role in [role.name for role in member.roles]:
await member.add_roles(role)
@commands.Cog.listener()
async def on_voice_state_update(
self,
member: discord.Member,
before: discord.VoiceState,
after: discord.VoiceState,
):
"""Detect any changes on voice channels"""
await self.create_role_if_missing(member.guild)
if member.bot:
return
if not after.channel:
await self.leave(member, before)
elif not before.channel:
await self.join(member, after)
else:
await self.move(member, before, after)
async def leave(
self,
member: discord.Member,
before: discord.VoiceState,
):
"""Detect when a user leaves."""
logging.info("leave")
logging.info(member)
logging.info(before)
channel: discord.VoiceChannel = before.channel
members: List[discord.Member] = channel.members
await self.mute_if_single(members)
await self.leave_if_alone(members, before.channel)
async def join(
self,
member: discord.Member,
after: discord.VoiceState,
):
"""Detect when a user leaves."""
logging.info("join")
logging.info(member)
logging.info(after)
channel: discord.VoiceChannel = after.channel
members: List[discord.Member] = channel.members
await self.mute_if_single(members)
await self.notify_on_join(member)
await self.join_if_single(members)
async def move(
self,
member: discord.Member,
before: discord.VoiceState,
after: discord.VoiceState,
):
"""Detect when a user leaves."""
logging.info("move")
logging.info(member)
logging.info(before)
logging.info(after)
before_channel: discord.VoiceChannel = before.channel
before_members: List[discord.Member] = before_channel.members
after_channel: discord.VoiceChannel = after.channel
after_members: List[discord.Member] = after_channel.members
await self.mute_if_single(before_members)
await self.join_if_single(after_members)
async def mute_if_single(self, members: List[discord.Member]):
"""Mute a member if single."""
logging.info("mute if single")
logging.info(members)
members = list(filter(lambda m: not m.bot, members))
if len(members) != 1:
return
member = members[0]
if member.voice:
if self.role in map(lambda r: r.name, member.roles):
await member.edit(mute=True)
async def join_if_single(self, members: List[discord.Member]):
"""Mute a member if single."""
logging.info("join if single")
logging.info(members)
members = list(filter(lambda m: not m.bot, members))
if len(members) != 1:
return
member = members[0]
destination = member.voice.channel
for voice_client in self.bot.voice_clients:
if voice_client.channel.id == member.voice.channel.id:
return
elif voice_client.channel in member.guild.voice_channels:
await voice_client.move_to(destination)
return
if self.bot.user.id not in [m.id for m in destination.members]:
await destination.connect()
async def notify_on_join(self, member: discord.Member):
"""Notify me if a member joins."""
logging.info("notify on join")
logging.info(member)
if member.id in masters:
return
if member.bot:
return
chan_id = self.notify_channel_id
channel: discord.TextChannel = await self.bot.fetch_channel(chan_id)
await channel.send(f"> **{member}** a rejoint **{channel}**.", delete_after=60)
async def leave_if_alone(
self, members: List[discord.Member], channel: discord.VoiceChannel
):
"""Mute a member if single."""
logging.info("leave if alone")
true_members = list(filter(lambda m: not m.bot, members))
if len(true_members) > 0:
return
bot_search_results = list(filter(lambda m: m.id == self.bot.user.id, members))
if len(bot_search_results) == 0:
return
for voice_client in self.bot.voice_clients:
if voice_client.channel.id == channel.id:
await voice_client.disconnect()
break
def setup(bot):
bot.add_cog(VoiceChannel(bot))
+6 -9
View File
@@ -1,14 +1,11 @@
from .credentials import mongo_url, wolfram_alpha_id
from utils import access, check
import itertools
from pymongo import MongoClient
import pymongo
import os
import itertools
import wolframalpha
from utils.access import Access
from utils.check import Check
from models.mongo import MongoCluster
from .credentials import mongo_url, wolfram_alpha_id
cluster = MongoCluster(mongo_url)
@@ -32,5 +29,5 @@ status = itertools.cycle(
"finaliser la théorie quantique",
]
)
access = access.Access(masters) # Create access for commands
check = check.Check()
access = Access(masters) # Create access for commands
check = Check()
+39 -94
View File
@@ -1,136 +1,81 @@
#
# These requirements were autogenerated by pipenv
# To regenerate from the project's Pipfile, run:
#
# pipenv lock --requirements
#
-i https://pypi.org/simple
aenum==3.1.5
aenum==2.2.6
aiohttp==3.7.4.post0
appdirs==1.4.4
astroid==2.6.6
async-generator==1.10; python_version >= '3.5'
async-generator==1.10
async-timeout==3.0.1
attrs==21.2.0
autopep8==1.6.0
backports.entry-points-selectable==1.1.1; python_version >= '2.7'
backports.zoneinfo==0.2.1; python_version < '3.9'
attrs==21.4.0
beautifulsoup4==4.10.0
black==21.12b0
bs4==0.0.1
cachetools==5.0.0; python_version ~= '3.7'
certifi==2021.10.8
cffi==1.15.0
cfgv==3.3.1
chardet==4.0.0
charset-normalizer==2.0.9; python_version >= '3'
charset-normalizer==2.0.10
click==7.1.2
colorama==0.4.4
commonmark==0.9.1
cryptography==36.0.1
datetime==4.3
deprecated==1.2.13
distlib==0.3.4
dnspython==2.2.0rc1
Deprecated==1.2.13
discord.py==1.7.3
dnspython==2.1.0
dpy-http-server==0.1.0
fake-useragent==0.1.11
filelock==3.4.2
fbchat==1.9.7
future==0.18.2
git+git://github.com/carpedm20/fbchat.git@916a14062d31f3624dfe8dd4ab672648a3e508c0#egg=fbchat
git+https://github.com/Rapptz/discord.py#egg=discord.py
gtts-token==1.1.4
gtts==2.2.3
h11==0.12.0; python_version >= '3.6'
gTTS==2.2.3
h11==0.12.0
html2text==2020.1.16
identify==2.4.0
idna==3.3
importlib-metadata==4.10.0; python_version >= '3.7'
inflect==5.3.0
isort==5.10.1
jaraco.context==4.1.1; python_version >= '3.6'
jaraco.itertools==6.0.3
jedi==0.18.1
jeepney==0.7.1
jaraco.context==4.1.1
joblib==1.1.0
keyring==23.4.0
keyrings.alt==4.1.0
lazy-object-proxy==1.7.1
libretranslatepy==2.1.1
lxml==4.7.1
mccabe==0.6.1
more-itertools==8.12.0
multidict==5.2.0
mypy-extensions==0.4.3
nightcore==1.1.0
nodeenv==1.6.0
numpy==1.22.0rc3
outcome==1.1.0; python_version >= '3.6'
packaging==21.3; python_version >= '3.6'
numpy==1.22.0
outcome==1.1.0
paho-mqtt==1.6.1
parso==0.8.3
pathspec==0.9.0
pillow==8.4.0
platformdirs==2.4.1; python_version >= '3.7'
pluggy==1.0.0
pre-commit==2.16.0
pexpect==4.8.0
Pillow==9.0.0
profanity-check==1.0.3
progressbar2==3.55.0
pycodestyle==2.8.0
progressbar2==4.0.0
ptyprocess==0.7.0
py==1.11.0
pycparser==2.21
pydub==0.23.1
pygithub==1.55
pygments==2.10.0
pyjwt==2.3.0
pylint==3.0.0a4
PyGithub==1.55
Pygments==2.11.2
PyJWT==2.3.0
pymongo==4.0.1
pymysql==1.0.2
pynacl==1.4.0
pyopenssl==21.0.0
pyparsing==3.0.6
pysocks==1.7.1
PyNaCl==1.4.0
pyOpenSSL==21.0.0
PySocks==1.7.1
pytest==3.0.5
python-dotenv==0.19.2
python-utils==2.6.3
pytz-deprecation-shim==0.1.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'
pytz==2021.3
pyyaml==6.0
regex==2021.11.10
python-utils==3.0.0
PyYAML==6.0
requests==2.27.1
requests-futures==1.0.0
requests==2.26.0
rich==10.16.1
rich==11.0.0
scikit-learn==1.0.2
scipy==1.8.0rc2
secretstorage==3.3.1
scipy==1.7.3
selenium==4.1.0
setuptools==60.1.0; python_version >= '3.7'
sherlock.py==0.3.0
six==1.16.0
sniffio==1.2.0; python_version >= '3.5'
sniffio==1.2.0
sortedcontainers==2.4.0
soupsieve==2.3.1
stem==1.8.0
threadpoolctl==3.0.0
toml==0.10.2
tomli==1.2.3; python_version >= '3.6'
torrequest==0.1.0
tox==4.0.0a9
translate==3.6.1
trio-websocket==0.9.2; python_version >= '3.5'
trio==0.19.0; python_version >= '3.6'
typed-ast==1.5.1
typing-extensions==4.0.1
tzdata==2021.5; python_version >= '3.6'
tzlocal==4.1
unidecode==1.3.2
urllib3==1.26.7
vcrpy==4.1.1
virtualenv==20.10.0
websockets==10.1
trio==0.19.0
trio-websocket==0.9.2
typing_extensions==4.0.1
Unidecode==1.3.2
urllib3==1.26.8
wikipedia==1.4.0
wolframalpha==5.0.0
wrapt==1.12.1
wsproto==1.0.0; python_full_version >= '3.6.1'
wrapt==1.13.3
wsproto==1.0.0
xmltodict==0.12.0
yarl==1.7.2
youtube-dl==2021.12.17
zipp==3.6.0; python_version >= '3.6'
zope.interface==5.4.0
+17 -5
View File
@@ -1,9 +1,21 @@
import inspect
from discord.ext import commands
from utils import tools
from config import emoji
def post_passer(func, *passed_args, **passed_kwargs):
"""Decorator that passes additionnal arguments (after its own) to a function."""
def decorated(*args, **kwargs):
args = list(args)
args.extend(passed_args)
args = tuple(args)
kwargs.update(passed_kwargs)
return func(*args, **kwargs)
return decorated
class Check:
@staticmethod
def same_author(msg, ctx):
@@ -27,7 +39,7 @@ class Check:
try:
msg = await ctx.bot.wait_for(
"message",
check=tools.post_passer(Check.same_author, ctx),
check=post_passer(Check.same_author, ctx),
timeout=self.timeout,
)
if msg.content.lower() in self.yes:
@@ -42,13 +54,13 @@ class Check:
def consent(self, message):
message = self.consent_message + " " + message
return tools.post_passer(self.validation, message=message)
return post_passer(self.validation, message=message)
def validate(self, message):
return tools.post_passer(self.validation, message=message)
return post_passer(self.validation, message=message)
def warn(self, message):
return tools.post_passer(self.validation, message=message, warning=True)
return post_passer(self.validation, message=message, warning=True)
def validation(self, func, message=None, warning=False):
async def decorated(command, ctx: commands.Context, *args):
+34 -17
View File
@@ -1,8 +1,9 @@
import sys
import signal
from contextlib import contextmanager
from io import StringIO
import sys
from discord.ext import commands
from config.config import masters
import discord
@@ -59,19 +60,6 @@ class DictObject(dict):
self.__dict__ = self
def post_passer(func, *passed_args, **passed_kwargs):
"""Decorator that passes additionnal arguments (after its own) to a function."""
def decorated(*args, **kwargs):
args = list(args)
args.extend(passed_args)
args = tuple(args)
kwargs.update(passed_kwargs)
return func(*args, **kwargs)
return decorated
def for_all_cog_methods(decorator_method):
def decorate(cls):
def decorator__new__(new):
@@ -133,7 +121,7 @@ def lazy_embed(
fields: dict,
title: str = None,
description: str = None,
color: bytes = None,
color: discord.Colour = None,
footer: str = None,
url: str = None,
thumbnail: str = None,
@@ -145,8 +133,37 @@ def lazy_embed(
embed.set_thumbnail(url=thumbnail)
if image:
embed.set_image(url=image)
for k, v in fields.items():
embed.add_field(name=k, value=v)
for name, value in fields.items():
embed.add_field(name=name, value=value)
if footer:
embed.set_footer(text=footer)
return embed
async def create_role_if_missing(
ctx: commands.Context, role_name: str, role_color: discord.Color
):
"""Create a role if it does not already exist."""
if not role_name in [role.name for role in ctx.guild.roles]:
# Create the role
role = await ctx.guild.create_role(name=role_name, colour=role_color)
await ctx.send(f"> Created `{role}` role.")
# Define a list of role members
role_members = []
# Add the role to all the masters
for master in masters:
if member := await ctx.guild.fetch_member(master):
if role_name in [role.name for role in member.roles]:
print(member, member.id, master)
await member.add_roles(role)
role_members.append(member)
# Send a message to show the new role members
if role_members:
role_members_text = "\n".join(f"+ {member}" for member in role_members)
await ctx.send(
'```diff\nAdded "'
+ role_name
+ '" role to:\n'
+ role_members_text
+ "```"
)