баннер с выводом статистики для сервера дискорд. discord.py
недавно начал изучать библиотеку pil для discord.py. хочу сделать бота, что будет менять баннер сервера и обновлять статистику каждые 10-15 секунд. писал код да бы понять ,как работает библиотека, но сегодня узнал про метод tasks.loop() и решил попробовать воспользоваться им, но очень много ошибок. переменные не работают. буду благодарен любой помощи!
import discord
from discord.ext import commands , tasks
from discord.utils import get
from PIL import Image, ImageDraw, ImageFont, ImageOps
import asyncio
import os
from time import sleep
import requests
import io
import datetime
bot = commands.Bot(
command_prefix = '.',
intents = discord.Intents.all(),
)
token = 'токен стёртый!'
@bot.event
async def on_ready():
print(f'бот активирован!')
print(f'название бота: {bot.user.name}')
print(f'айди бота: {bot.user.id}')
print(f'токен: {token}')
print(f'')
await bot.change_presence(status = discord.Status.online, activity = discord.Game('morwaezz | dc: morwaezz#5269'))
banner.start()
@tasks.loop(seconds = 10)
async def banner(ctx):
guild = bot.get_guild(1071401936676470864)
members = guild.members
voice_channels = [member for member in members if member.voice and member.voice.channel]
with Image.open('bot morwaezz/banners/banner.png') as image:
# Создание объекта ImageDraw для рисования на изображении
draw = ImageDraw.Draw(image)
# получаем время, которое было 2 часа назад
two_hours_ago = datetime.datetime.utcnow() - datetime.timedelta(hours = 2)
# создаем словарь для хранения количества сообщений каждого участника
message_count = {}
# перебираем все текстовые каналы на сервере
for channel in ctx.guild.text_channels:
# перебираем все сообщения в канале, опубликованные за последние 2 часа
async for message in channel.history(after=two_hours_ago):
# проверяем, что сообщение было отправлено участником сервера
if message.author in members:
# увеличиваем количество сообщений для данного участника
if message.author in message_count:
message_count[message.author] += 1
else:
message_count[message.author] = 1
most_active_member = max(message_count, key=message_count.get)
activity = most_active_member.activity
font = ImageFont.truetype('bot morwaezz/banners/ofont.ru_Montserrat.ttf', size = 59)
draw.text((1077, 555), f' {len(members)}', fill='white', font=font)
bot.guild = bot.get_guild(id)
voice_users = sum(len(vc.members) for vc in bot.guild.voice_channels)
font = ImageFont.truetype('bot morwaezz/banners/ofont.ru_Montserrat.ttf', size = 88)
draw.text((1603, 872), f'{voice_users}', fill = 'white', font=font)
font = ImageFont.truetype('bot morwaezz/banners/ofont.ru_Montserrat.ttf', size = 60)
draw.text((627, 776), f'{activity.name}'[:20], fill='gray', font=font)
if isinstance(most_active_member, discord.Member):
font = ImageFont.truetype('bot morwaezz/banners/ofont.ru_Montserrat.ttf', size = 100)
draw.text((627, 662), f'{most_active_member.name}'[:8], fill='white', font=font)
else:
font = ImageFont.truetype('bot morwaezz/banners/ofont.ru_Montserrat.ttf', size = 100)
draw.text((627, 662), f'{most_active_member}'[:8], fill='white', font=font)
url = str(most_active_member.avatar.url)[:-10]
response = requests.get(url, stream=True)
response = Image.open(io.BytesIO(response.content))
response = response.convert('RGBA')
# Обрезка изображения до круга
response = ImageOps.fit(response, (315, 315), method=Image.LANCZOS, centering=(0.5, 0.5))
mask = Image.new('L', (315, 315), 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0, 315, 315), fill=255)
response.putalpha(mask)
# Вставка изображения
image.paste(response, (222, 601), response)
image.save('bot morwaezz/banners/stats_banner.png')
await guild.edit(file=discord.File('bot morwaezz/banners/stats_banner.png'))
@bot.command()
async def ask_question(ctx):
await ctx.send("Какой ваш любимый цвет?")
def check(message):
return message.author == ctx.author and message.channel == ctx.channel
response = await bot.wait_for('message', check=check)
await ctx.send(f"Ваш любимый цвет - {response.content}!")
@bot.slash_command(description="Test command")
async def test(interaction: discord.Interaction):
await interaction.response.defer(ephemeral = True)
await asyncio.sleep(10)
await interaction.followup.send("My actual content")
bot.run(token)
ошибка:
Unhandled exception in internal background task 'banner'.
Traceback (most recent call last):
File "C:\Users\morwaezz\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\ext\tasks\__init__.py", line 169, in _loop
await self.coro(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: banner() missing 1 required positional argument: 'ctx'
Источник: Stack Overflow на русском