• Как разобраться с этим шифром?

    Vindicar
    @Vindicar
    RTFM!
    Ну насколько мне видно, тебе интересует только два куска кода.
    Инициализация (сокращено):
    this.d = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    this.e = new SecretKeySpec(this.b, "DESede");
    this.f = "pUJeQ3Tr".getBytes();
    this.g = new IvParameterSpec(this.f);
    this.d.init(2, this.e, this.g);

    Дешифровка:
    str2 = new String(this.d.doFinal(Base64.decode(URLDecoder.decode(str, "UTF-8"), 0)), "UTF-8");

    Если убрать BASE64 и url-кодирование (нужно чтобы засунуть бинарную последовательность в вебстраницу), получаем просто обращение к this.d.doFinal().
    Cipher.getInstance("DESede/CBC/PKCS5Padding") - это явно обращение к библиотечному классу, так что выясняешь, что за класс используется, откуда он, ищешь доки, ищешь допустимые коды шифров.
    Когда поймешь, что за шифр "DESede/CBC/PKCS5Padding" - можешь начинать искать аналоги на Питоне.
    Также поищи, откуда в инициализацию приходит секретный ключ this.b.
    Ответ написан
    6 комментариев
  • Как написать распознавание капчи на python?

    Vindicar
    @Vindicar
    RTFM!
    1. Вырежи каждую цифру отдельно (содержащий прямоугольник).
    2. Нормализуй - переведи в оттенки серого (так проще сравнивать), приведи к какому-то фиксированному размеру.
    3. Сравнивай каждую цифру с эталонными изображениями цифр, прошедших такую же номрализацию. В качестве метрики возьми хотя бы расстояние L1 - т.е. вычитаешь значения попиксельно, берёшь модуль разностей (они могут быть меньше 0), и суммируешь.
    4. Эталон, который дал наименьшее значение метрики, наиболее похож.

    Для примитивной капчи, которая не содержит посторонних элементов и искажений, должно сработать.
    Ответ написан
    Комментировать
  • Как решить проблему с видимостью переменной root?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler(content_types=['text'])
    def get_command(message):
        if message.text == "Start":
          root = tk.Tk()
          img = ImageTk.PhotoImage(Image.open('lol.png'))
          createNewWindow(root, img)
          root.mainloop()
        elif message.text == "Stop":
          root.destroy()

    Ух как всё запущено.
    Во-первых, если ты ввёл Start, то get_command() создаёт локальную root, настраивает её, и уходит в бесконечный цикл внутри root.mainloop(). Я не знаю как pytelegrambotapi разруливает это, но бот после такого должен просто встать колом, пока все окна не будут закрыты. Подозреваю что обработчик вызывается в отдельном потоке, но фз. В любом случае, не надо так делать. Лучше иметь один root, который крутится внутри mainloop() в отдельном потоке всё время работы скрипта, а окна создавать и удалять по мере надобности, не создавая и не убивая root.
    Вообще подружить бота с оконным интерфейсом - задача нетривиальная.
    Во-вторых, переменная root - локальная. Она существует только внутри того экземпляра get_command(), который был вызван с командой старт. Если ты вызываешь его с командой Stop, у тебя запускается отдельный экземпляр, где выполняется только ветка Stop - а в этой ветке root объявлен не был, он был объявлен только в ветке Start, в другом экземпляре.
    В-третьих, окна будут спамиться только на той машине где запущен бот. Это так, на всякий случай.
    Ответ написан
    Комментировать
  • Как правильно реализовать систему непрочитанных сообщений в групповом чате?

    Vindicar
    @Vindicar
    RTFM!
    Ну например, для каждой пары пользователь-чат хранить метку времени отключения от чата (или эквивалентного события). Тогда все сообщения, которые были добавлены в чат после этой метки, будут считаться непрочитанными.
    Ответ написан
  • TypeError: descriptor 'append' for 'list' objects doesn't apply to a 'RetailItem' object?

    Vindicar
    @Vindicar
    RTFM!
    def purchase_item(self, self.__lst, obj): #приобрести товар

    1. Откуда вы вообще взяли такой синтаксис?
    2. У вас есть ссылка на self, по ней вы можете обратиться к любому атрибуту/методу self.
    Ответ написан
    3 комментария
  • Python cv2 как перести многомерный массив в картинку?

    Vindicar
    @Vindicar
    RTFM!
    src = [['255', '255', '255', '190', '190', '160', '76', '45', '78'],
    ['255', '255', '255', '190', '190', '160', '76', '45', '78'],
    ['255', '255', '255', '190', '190', '160', '76', '45', '78']]
    
    int_src = [ list(map(int, row)) for row in src ]
    red = [ row[0::3] for row in src ] #подразумеваю, что у тебя составляющие идут в порядке RGB
    green = [ row[1::3] for row in src ]
    blue = [ row[2::3] for row in src ]
    image = cv2.merge((blue, green, red)) #opencv по умолчанию хранит изображения в BGR, а не RGB
    Ответ написан
    Комментировать
  • Как выполняются декораторы в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Функции(как и методы) в питоне - это объекты первого рода, их можно сохранять в переменные, передавать как параметры и так далее. Соответственно, декоратор - это тоже функция, и тогда
    @decorator("params")
    def myfunc(func_params):
        pass

    это тоже, что и
    def myfunc(func_params):
        pass
    wrapper = decorator("params")
    myfunc = wrapper(myfunc)


    Никто не мешает decorator() и wrapper() в примере сохранять адрес оборачиваемой функции в какую-то структуру данных, используемую затем ботом для диспетчеризации поступающих событий. Пример без класса:
    registered_funcs = []
    
    def decorator(param):
      #вложенная функция - фактический декоратор
      def wrapper(func):
        global registered_funcs
        #запоминаем декорируемую функцию
        registered_funcs.append( (param, func) )
        return func #не забываем её вернуть
      #возвращаем wrapper, чтобы им можно было продекорировать целевую функцию
      return wrapper
    
    #пример использования декоратора
    @decorator("foo")
    def myfunc(x):
      print("Hello from myfunc(), ", x)
    
    print(registered_funcs)
    #>>> [ ("foo", <function myfunc at 0xdeadf00d>) ]
    #и мы можем этим списком пользоваться, например:
    for arg, func in registered_funcs:
      func(arg)
    Ответ написан
    1 комментарий
  • Как получить список игр со всех пользователей?

    Vindicar
    @Vindicar
    RTFM!
    Если не знаете, какие атрибуты есть у объекта, dir() и документация в помощь.
    activities = sum([], (member.activities for member in ctx.guild.members))
    game_names = [item.name for item in activities if instanceof(item, discord.Game)]
    #если нужно только уникальные:
    game_names = set(game_names)
    Ответ написан
    Комментировать
  • Как проводить тесты моделей, где в переопределенном .save() сохранение используется 2 раза?

    Vindicar
    @Vindicar
    RTFM!
    Ты в setUp() не очищаешь тестовую базу? Т.е. к моменту второго теста у тебя остаются данные после первого?
    Это плохая идея.
    Ответ написан
  • Как настроить logger python на запись LEVEL в разные файлы?

    Vindicar
    @Vindicar
    RTFM!
    нужно делать кастомный фильтр.
    Ответ написан
    Комментировать
  • Почему не работает код?

    Vindicar
    @Vindicar
    RTFM!
    Ну написано же прямым текстом
    TypeError [CLIENT_MISSING_INTENTS]: Valid intents must be provided for the Client.

    Интенты боту не прописал.
    Ответ написан
    Комментировать
  • Как реализовать разные скрипты Telegram bot'а в нескольких файлов?

    Vindicar
    @Vindicar
    RTFM!
    Проблема в том, что тебе нужно продекорировать функции через @bot.чтототам, но другие файлы ничего не знают о боте, так как он описан в главном файле. Так?
    Нужно учесть, как работает декоратор. Код вроде
    @bot.message_handler(commands=['anketaone'])
    def null_anketa_step(message):
        pass

    на самом деле работает примерно так:
    temp_wrapper = bot.message_handler(commands=['anketaone'])
    def null_anketa_step(message):
        pass
    null_anketa_step = temp_wrapper(null_anketa_step)

    Т.е. иными словами, декоратор - это просто вызов функции, в которую передаётся функция или класс!
    Тогда самый простой способ будет таким:
    def null_anketa_step(message):
        pass
    #какой-то другой обработчик
    def some_other_handler(message):
        pass
    
    def init_bot(bot):
        #а в этой функции мы регистрируем обработчики
        bot.message_handler(commands=['anketaone']) (null_anketa_step)
        #обрати внимание на две пары скобок. Вызов bot.message_handler() возвращает функцию (wrapper),
        #и мы эту функцию тут же вызываем, передавая в неё обработчик
        bot.message_handler(commands=['somethingelse']) (some_other_handler)

    Тогда в главном файле ты делаешь примерно так:
    bot = ........ #создаём бота
    from second_file import init_bot as init_second #импортируем второй файл
    #функцию импортируем под другим именем, чтобы не было коллизий между файлами
    init_second(bot) #вызываем функцию регистрации init_bot()
    
    if __name__=='__main__':
        bot.polling(none_stop=True)
    Ответ написан
    5 комментариев
  • Как сделать что бы бот в дискорде выдавал роли после правильного ответа на вопрос?

    Vindicar
    @Vindicar
    RTFM!
    Нужно хранить базу пользователей, и для каждого пользователя хранить id, состояние и метку времени.
    Состояние может быть одно из указанных:
    * стартовое - пользователь ничего не сделал
    * пользователю был задан вопрос
    * пользователь получил роль, тогда поле времени хранит момент, когда роль была получена.

    Тогда при реакции на команду или на сообщение ты ищешь ID пользователя в базе, и проверяешь, что он находится в корректном состоянии. Т.е. если реагируешь на личку, то пользователь должен быть в состоянии "задан вопрос". В нужные моменты сохраняешь в базу новое состояние, например, "задан вопрос" -> "выдана роль".
    Чтобы снять роль, время от времени ищешь в базе пользователей в состоянии "выдана роль", у которых с момента выдачи прошло достаточно много времени, снимаешь им роль и записываешь в базу новое состояние (стартовое).
    Ответ написан
    4 комментария
  • Возможно ли собрать python скрипт со всеми зависимостями в один файл?

    Vindicar
    @Vindicar
    RTFM!
    Нельзя, так как среди зависимостей могут быть модули, написанные не на питоне, а на C. Они зависят от ОС и архитектуры проца.
    Можно создать виртуальное окружение на линуксе и поставить зависимости туда, а не прямо в систему.
    Либо можно использовать докер образ, но я не в курсе как докер дружит с виндой, так как не пользовался. Опять же, докер - штука довольно ресурсоемкая, и полезна только когда часто таскаешь рабочий проект туда-сюда.
    Ответ написан
  • Как изменить название категории?

    Vindicar
    @Vindicar
    RTFM!
    В доках всё есть. Получаешь категорию (в терминологии discord.py категория - это разновидность канала), потом редактируешь.
    Ответ написан
  • Как найти объект по координатам в tkinter?

    Vindicar
    @Vindicar
    RTFM!
    Всё что мне приходит в голову - перебрать все виджеты и найти те, чей прямоугольник содержит искомую точку.
    winfo_x()/winfo_y() - позиция виджета относительно родительского виджета.
    winfo_rootx()/winfo_rooty() - если не путаю, позиция виджета относительно начала экрана.
    winfo_width()/winfo_height() - текущий размер виджета
    winfo_children() - список дочерних виджетов для данного виджета.

    Но зачем тебе это понадобилось? Может, есть способ попроще?
    Ответ написан
    3 комментария
  • Что делать если у всех работает, а у меня нет?

    Vindicar
    @Vindicar
    RTFM!
    unexpected indent - у тебя вставлен отступ там, где ему не место.
    Отступ после декоратора не требуется.
    Т.е. вместо
    @bot.event
        async def on_ready():
            #тело функции
    должно быть
    @bot.event
    async def on_ready():
        #тело функции
    Ответ написан
  • Как выполнить подключение через подключения putty?

    Vindicar
    @Vindicar
    RTFM!
    Посмотри в сторону утилиты plink, она вроде входит в пакет putty.

    Либо посмотри в сторону SSH agent forwarding.
    Ответ написан
    Комментировать
  • Как правильно прописать проверку ввода чисел на питоне для ТГ бота?

    Vindicar
    @Vindicar
    RTFM!
    try:
      v = int(message.text)
      #на случай если тебе подойдёт не всякое число
      if v < 0 or v > 99: 
        raise ValueError()
    except ValueError:
      bot.send_message(message.chat.id, "Не число, или недопустимое число.")
    else:
      bot.send_message(message.chat.id, f"Ты ввел число {v}")
    Ответ написан
    Комментировать