• Что сделать, чтобы bot ловил handler в отдельном файле?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Зачем импортировать dp из всех файлов без разбору? В реальности будет импортирован последний, остальные будут импортированы впустую. Потому что следующий from импортирует другой dp и по имени dp будет доступен уже другой объект из другого модуля.

    Объект dp надо создать один раз в одном месте. В принципе, можно потом его потенциально импортировать куда угодно.

    Если хочется некоторой модульной структуры, то можно сделать в каждом модуле функцию навроде register_all_handlers(dp) и в ней делать https://docs.aiogram.dev/en/latest/dispatcher/inde.... Соответственно, после импорта всех модулей с хендлерами можно вызвать эту функцию от всех модулей:

    Примерно так
    import menu_commands
    import admin_commands
    import message_handlers
    
    dp = создаём_свой_Dispatcher
    
    menu_commands.register_all_handlers(dp)
    admin_commands.register_all_handlers(dp)
    message_handlers.register_all_handlers(dp)
    Ответ написан
    Комментировать
  • Как решить проблему с заморозкой цикла на Python?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Надо просто понимать, что asyncio - это не многопоточность (хотя и указан этот тэг в вопросе). Это один процесс, который выполняет только одну задачу в каждый момент времени. И переключает он задачи только тогда, когда какая-то из них запускает операцию ввода-вывода или что-то ещё подобное (например, asyncio.sleep).

    Например, если мы сделаем запрос к базе данных (с асинхронной библиотекой работы с этой базой обязательно! например, вместо sqlite3 используем aiosqlite), то пока база данных думает над ответом, скрипт может переключиться к какой-то другой ожидающей выполнения задаче. Когда база ответит, то цикл событий (event loop) вернёт управление задаче, которая сделала запрос к базе.

    В приведённом примере кода есть два места, которые могут быть узкими:

    1. Функция logic может быть и объявлена async, но если она делает чисто вычислительные операции без ввода-вывода (асинхронного), то в процессе её работы никогда не будет переключения на цикл события и, как следствие, не будут выполняться другие задачи. Даже если их собственный ввод-вывод уже совершился и задачи могут быть продолжены.

    2. Сама работа с базой может также блокировать цикл событий.

    Например, пусть logic работает 10 секунд, а dbase.search_in_queue - 5 секунд, и обе они содержат только синхронный код. Тогда пока выполняется dbase.search_in_queue свои 5 секунд, не будет выполняться logic, и наоборот.
    Ответ написан
    Комментировать
  • Почему не все переходы с других сайтов попадают в лог apache2 access.log?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    В первую очередь проверить, что на исходном сайте не используется rel=noreferrer.
    https://developer.mozilla.org/en-US/docs/Web/HTML/...
    Ответ написан
  • Как проверить открытие письма?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Из соображений безопасности открытие ресурсов по внешним ссылкам многие почтовые клиенты и почтовые сервисы не делают вообще. Тем более когда речь явно идёт о картинке размера 1x1, которую могут игнорировать намеренно (лучше уж тогда не указывать размеры, пусть клиент скачает картинку эту 1x1 и узнает размер только после этого).

    Надо понимать, что E-mail - это канал с негарантированной доставкой до получателя без шансов проверить факт доставки/прочтения. Письмо может вообще не дойти до получателя, может дойти до "Спама", может дойти но сразу пойти в под нож - но мы об этом не узнаем. Все эти пиксельные картинки, оборачивания ссылок в персонально трекируемые, "запрос подтверждения" - всё эти попытки хоть как-то обойти эти ограничения всё равно ни к чему получателя не обязывают. Получатель может всё это полностью проигнорировать.

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

    Я всегда принципиально отказываюсь от всех подтверждающих получение действий и фокусов, потому что если отправитель ПОЛЕНИЛСЯ приаттачить все картинки к письму - то значит я посмотрю на его письмо без картинок и по ссылкам переходить не буду вообще. Не заслужил. Ничего ценного в таких письмах я ещё ни разу не видел.

    Единственное, для чего все эти средства помогают - примерно оценивать степень прочтения в сравнении с предыдущим опытом. Скажем, вчера письмо прочитало 30% получателей, это может означать что его прочитало, например,на самом деле 60%, но лишь половина подвержена трекингу. А если сегодня прочитало 10%, значит, что-то случилось: письмо хуже дошло до получателей, письмо хуже привлекло их внимание... (Все цифры, конечно, от балды, они имеют иллюстративный характер)

    Да и вообще, в наше время почту читает всё меньше людей.
    Ответ написан
    Комментировать
  • Можно ли получить значение callback_data при реплае?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    По-моему, тут типичная попытка решить простую задачу дурацким способом.

    Пользователь получает сообшение с inline-кнопкой. Вот пусть он эту кнопку и нажмёт, а бот получит в callback_query_handler событие с callback_data и обработает. Зачем ещё какое-то цитирование?

    Или тут попытка в кнопке хранить данные, которые при цитировании ещё и якобы можно будет достать? Сама идея дурацкая. Если надо к сообщениям хранить какие-то данные, то их надо хранить в самом боте: в базе данных, в хранилище FSM, да хотя бы in memory в переменных.
    Ответ написан
    Комментировать
  • Сможет ли Ansible вот такое?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Большинство вещей - без проблем. Например, можно использовать таск authorized_keys для аккуратного прописывания ключа вместо ручного его закидывания на сервер. Есть таски для создания пользователей и групп, установки софта, копирования файлов и создания их по шаблону...

    Некоторые вещи можно делать косвенным путём, копируя и генерируя конфиги, запуская свои кастомные команды через таск shell, итд итп. Например, конфигурить sudo можно через создание файла с нужным содержимым в /etc/sudoers.d, не трогая основной конфиг.

    В общем, даже если останутся некоторые задачи, которые ansible не сможет автоматизировать достаточно хорошо, во всём остальном он очень сильно облегчит сопровождение серверов, особенно подготовку новых.
    Ответ написан
    Комментировать
  • Как набирать телефонные номера в Вотсап без предварительного вбивания их в записную книжку?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Переходим по ссылке: https://wa.me/номер_телефона - получаем чат с контактом - в углу есть трубка для созвона.

    Однако в последнее время есть сообщения, что у некоторых пользователей это не работает, и им возвращается сообщение, что данный номер неверен. Но я не смог это воспроизвести. Проверял браузерную версию и клиент WA под андроид. Возможно, это какое-то особое поведение, и возможно оно используется для борьбы со спамерами, использующими нелегально Web API.
    Ответ написан
  • Как правильно находить готовые коды, плагины на разных языках?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Люди всё правильно говорят. Это не тот вопрос, которым следует заниматься способному в лучшем случае к NoCode управленцу. Так-то найти куски кода, который делает что-то, не так сложно. По ключевым словам легко найти практически что угодно на гихабе, хабре, stackoverflow, куче форумов, в документации к конкретным языкам и библиотекам. Сейчас ещё и расплодились агрегаторы кода, которые по ключевым словам выдёргивают фрагменты кода из кучи опенсурсных проектов, иногда бывают полезны, но чаще раздражают....

    Но даже если найти кусок кода или название библиотеки (на что уйдёт пять минут) - а что дальше? Чтобы понять, что делает этот кусок кода, какие у него достоинства и недостатки, какие ограничения - это нужна уже компетенция квалифицированного программиста. А вдруг этот код или эта библиотека жалко помрёт, если вместо скромных 100 байт из тестового набора скормить мегабайт осмысленных данных?

    Программист намного более эффективно проведёт отбор вариантов (сразу выкинув лишь кажущиеся перспективными, но совершенно бестолковые варианты, делающие не то, что надо, или не так, как это разумно), а затем более квалицифированно разберёт всё, что осталось. Конечно, можно ему сказать "я тут видел XXX и YYY, которые кажутся интересными" (и это не запрещено - почему бы и не сказать?), но программист всё равно сделает этот же поиск с нуля ещё раз и выберет ZZZ, который управленец выкинул при отборе, потому что ошибочно посчитал, что он тут не годится.

    Так-то куски кода никто не запрещает искать (поисковики достаточно хорошо натренированы и неплохо их находят), но делать далеко идущие планы на основе своего неквалифицированного непонимания самостоятельно найденного кода настоятельно не рекомендую.
    Ответ написан
    5 комментариев
  • Можно ли получать ид юзера зная его юзернейм?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Средствами Bot API невозможно по username получить id. Серьёзни, никак. Я недавно отвечал на похожий вопрос https://qna.habr.com/q/1224466

    Но в указанном узком сценарии возможно сделать такое, но с оговорками.

    Во-первых, придётся явно сохранять связку username-id для всех пользователей, пишущих боту.

    Во-вторых, не у всех пользователей есть username.

    В-третьих, пользователь может в любой момент сменить свой username, и бот об этом не узнает.

    По реализации всё достаточно просто: при каждом поступающем сообщении запоминаем пару username-id в базе, а для нужной команды достаём.
    Ответ написан
    Комментировать
  • Как писать в личку тем кто покинул канал?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Изначально бот мог писать только тем пользователям, которые по своей инициативе первыми написали боту. После одного из обновлений появилось дополнительное правило: бот может писать пользователям, которые подписаны на канал, в котором данный бот числится админом. А также если пользователь перешёл по ссылке-инвайту и оставил заявку на вступление. Если же пользователь покинул канал, то ни одно из этих условий выполняться не будет, и отправка сообщений таким пользователям невозможна никак.
    Ответ написан
  • Не отправляются фотографии пользователю в библеотеке telebot, что делать?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Не надо выкладывать такую длинную простыню, в которой трудно что-либо найти...

    Ссылка https://photos.app.goo.gl/6LckVsFKRfKy9ANu6 не является прямой ссылкой на фотографию, да и страница, на которую эта ссылка делает редирект, не является фотографией.
    Ответ написан
  • Состояния в FSM срабатывают со второго раза. Как это исправить?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Как написано - так и работает. Делаем /start - получаем стейт choice и кнопки. Нажимаем "добавить задачу" - получаем стейт add_task и больше в этом обработчике ничего не делается! И только после второго нажатия срабатывает обработчик "добавить задачу" из стейта add_task.

    Правильно убрать вообще обработчик для choice и вместо этого указать условия вида state=choice непосредственно у всех обработчиков.
    Ответ написан
    1 комментарий
  • Как получить ид пользователя по его упоминанию?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    В Bot API невомзожно получить id пользователя по его имени. Возможно только через получение события, с этим пользователем связанное (например, пользователь написал сообщение, пользователь вступил в группу где есть бот, итд). В полученной информации будет и id пользователя, и его username (только если он у пользователя есть).

    Это можно обойти использованием клиентского API (библиотеки telethon, pyrogram). Но этот API выполняет запросы от реального пользователя Telegram, поэтому если злоупотреблять запросами, можно получить бан не бота, а прям своего живого аккаунта.

    От себя рекомендую этой фигнёй не страдать, у Bot API есть свои понятные сценарии работы, и в рамках них id пользователя можно получить вполне легально именно тогда, когда это имеет смысл в рамках функциональности бота.
    Ответ написан
    Комментировать
  • Возможно ли написать Viber-бот на Java или Android для просевания сообщений viber-чата?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Viber Bot (в девичестве Viber Public Account) невозможно добавить в чат. Он может лишь принимать личные входяшие сообщения от пользователей. Да, это сильно меньше, чем позволяет Telegram, но, к сожалению, других возможностей нет.
    Ответ написан
    Комментировать
  • Существуют ли альтернативы LaTeX/TeX?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Такой вопрос надо начинать с предметной области. Какая она? Если это текст с формулами, то ничто другое даже близко не сравнится по удобству.

    Корректировка макета страницы в TeX вообще обычно не представляет проблемы, а в упомянутом примере именно это и требовалось. Более того, скилл поиска ответов по вопросам, связанным с TeX, прокачивается достаточно быстро. Есть много списков команд различной степени подробности, куча готовых решений (в том числе поиском на этом сайте и SO), множество всевозможных пакетов в CTAN...

    Вообще, TeX умеет безумно сложные вещи, о которых многие даже не подозревают. Например, в знаменитом TeXbook от автора TeX есть пример рисования кривых дракона. Язык TeXа является тьюринг-полным.
    Ответ написан
    Комментировать
  • Как добавить новый диск в zfs raid?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Я ввёл в гугле "zpool replace disk in mirror" и получил вагон ссылок по теме, первая же из которых ведёт на официальную документацию на русском языке на сайте Oracle.
    Ответ написан
    Комментировать
  • Как исправить ошибку discord python bot?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Тут сразу несколько ошибок.

    Во-первых, класс discord.ext.commands.Bot унаследован от discord.Client - он расширяет возможность последнего функционалом команд. Использовать оба не нужно.

    Во-вторых, созданный экземпляр этого класса bot нигде не используется.

    В-третьих, в классе discord.Client нет декоратора command - он есть только в commands.Bot.

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

    Правильно discord.Client вообще выкинуть - он тут не нужен.
    Ответ написан
    Комментировать
  • Как обслуживать юзеров по очереди телебот?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    У тебя глобальные urls_list, price_list. Перемести их в функцию sender, они всё равно при каждом её вызове должны инициализироваться заново. Именно это и вызывает сейчас проблемы.
    Ответ написан
    Комментировать
  • Почему postgresql создаёт ещё одну директорию?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Потому что внутри образа postgres:13.3 анонсируется том /var/lib/postgresql/data. Поскольку он никак не описан при создании контейнера, создаётся анонимный том в стандартном хранилище и монтируется в контейнер. То, что в манифесте также объявлен ещё один том, никак не влияет на автосоздание вот этого. В итоге у нас два тома, один описан явно и смонтирован в /app/app/database/pgdata, другой описан в образе и смонтирован в /var/lib/postgresql/data.

    Правильно монтировать свой том в /var/lib/postgresql/data, именно там образ будет хранить базу.

    Посмотреть, что думает образ, можно командой docker inspect postgres:13.3
    Ответ написан
    Комментировать
  • Как правильно спарсить характеристики с сайта и записать в отдельные колонки эксель?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Например, можно автоматически создавать колонки под недостающие параметры по мере анализа. Можно завести словарь, который отображает названия характеристик в номер колонки, если при парсинге страницы обнаружена новая характеристика, которой в словаре нет - добавлять новую запись со следующим номером колонки. При создании новой строчки в выходнойм файле по именам параметров определять их позиции в массиве и подставлять.

    Другой вариант: разные категории помещать на разные листы (в случае с csv писать в разные файлы, ну или перейти на xlsxwriter). В этом случае таблица будет не такой разреженной, что в некоторых случаях может быть более удобно удобно.
    Ответ написан
    Комментировать