Запутался в этом Discord.py Rewrite + Reaction Light Code - Требуется объяснение

Итак, хотя все мы, конечно, знаем о том, что все скопируйте и вставьте чужой код, и волшебным образом он работает, он теряет некоторый контекст и понимание, когда выясняется, как этот код на самом деле работает и функционирует.

Я работаю с Discord.py Rewrite и фрагментом кода называется Reaction Light, чтобы создать бот, который позволяет самостоятельно назначать роли в моем Сервер Discord. Бот на 100% функционален и работает по назначению. Теперь я изменил некоторые вещи в их коде, поэтому мои методы находятся в разных местах и ​​вызываются из разных областей.

Вот где я запутался:

У меня есть метод isadmin(), который вызывается всякий раз, когда необходимо выполнить проверку, чтобы выяснить, является ли пользователь, вводящий команду, администратором. Роли администратора определены в файле .env, который я получаю с помощью модуля dotenv. Довольно простой материал. (Я перепишу эту часть позже и, надеюсь, помещу все идентификаторы роли администратора в файл и возьму их оттуда.) Однако я не понимаю, что именно делает третий аргумент этого метода. msg=False

Всякий раз, когда я писал для этого свои винтики, я вызываю этот метод как таковой, не передавая ему аргумент msg, как показано ниже:

admin.py

# admin.py
# Simple ping pong command
@commands.command()
    async def ping(self, ctx):
        if helpers.isadmin(ctx):
            print("Running Command from admin.py")
            await ctx.send('Pong!')

Теперь в моем методе прослушивателя on_message() он передает аргумент msg, а затем выполняет некоторый код, не связанный с командой ping, но связанный с функциональностью самоназначающейся ролевой части бота.

message.py

# message.py
@commands.Cog.listener()
    async def on_message(self, message):
        if helpers.isadmin(message, msg=True):
            # Execute some code here for the self-assigning roles

Насколько мне известно, этот рабочий процесс работает следующим образом, и в качестве примера я буду использовать команду ping, которая вызывается командой r.ping.

  1. on_message () прослушивает все сообщения, отправляемые на сервер
  2. Команда Ping выдана в канале пользователем
  3. on_message () слышит сообщение и проверяет, является ли пользователь администратором, но также передает аргумент msg
  4. Команда ping вызывается из admin.py, а затем проверяет (снова?), Является ли пользователь администратором, и, если он / она, выполняет команду.

Итак, я пытаюсь выяснить, когда или когда не использовать этот msg аргумент, и если он уже проверяет, является ли пользователь администратором в слушателе, мне нужно снова проверить в собственно сама команда? Разве это не избыточно?

Вот метод isadmin() в файле helpers.py.

# helpers.py
def isadmin(self, ctx, msg=False):
        # Checks if command author has one of .env admin role IDs
        try:
            check = (
                [role.id for role in ctx.author.roles]
                if msg
                else [role.id for role in ctx.message.author.roles]
            )
            if self.admin_a in check or self.admin_b in check or self.admin_c in check:
                return True
            return False
        except AttributeError:
            # Error raised from 'fake' users, such as webhooks
            return False

person J. Robinson    schedule 04.03.2020    source источник


Ответы (1)


Честно говоря, я не уверен, почему это так. Если у вас есть доступ к ctx.author, у вас есть доступ к ctx.message, поскольку ctx.author является просто автором этого сообщения, что кажется лишним. Однако я настоятельно рекомендую вам использовать для этого проверки. Например у меня есть:

def is_owner():
    def predicate(ctx):
        return ctx.author.id in ctx.bot.config()["owners"]
    return commands.check(predicate)

и я использую это как декоратор

# utils/checks/checks.py
from utils.checks import checks

@checks.is_owner()
@commands.group(hidden=True, case_insensitive=True, description="Load a module")
async def load(self, ctx):
    if not ctx.invoked_subcommand:
        return await ctx.send_help(ctx.command)

Например, у вас может быть

def is_admin():
    def predicate(ctx):
        role_id = 123123123123123 # replace this with os.getenv("wherever your admin role is")
        return role_id in [x.id for x in ctx.author.roles]
    return commands.check(predicate)

На мой взгляд, он намного чище и проще в использовании / понимании.

person Kanin    schedule 05.03.2020