баннер с выводом статистики для сервера дискорд. discord.py

Рейтинг: -1Ответов: 1Опубликовано: 23.02.2023

недавно начал изучать библиотеку 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'

Ответы

▲ 2

Смотри, там говориться о пропущенном аргументе - "ctx", также, показано где. Просто вставь его туда куда надо, и все должно заработать! :)

await self.coro(*args, ctx, **kwargs)

Это к примеру