Ответы пользователя по тегу Python
  • Как сделать рассылку?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Вызвать в цикле bot.send_message на все извлечённые из базы chat_id. Учесть при этом, что у Телеграма ограничение в 30 запросов в секунду. Учесть, что некоторые пользователи уже могли отписаться от бота (отправка им вызовет исключение).
    Ответ написан
    4 комментария
  • Как писать бота через Webhook?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Читать в официальной документации.

    Кратко: либо бот делает запросы getUpdates для получения новых данных, либо бот представляет из себя web-сервер с адресом, за который Телеграм может его дёрнуть при наступлении нового события. Первое намного проще в организации и для небольших ботов с не очень значительным трафиком более чем достаточно.
    Ответ написан
    Комментировать
  • Как сделать чтобы в коллбеке инлайн кнопки сообщение заменяло прошлое?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Вот и надо редактировать предыдущее сообщение. Например:

    bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.id, text='Новый текст')
    bot.edit_message_media(chat_id=call.message.chat.id, message_id=call.message.id, media=types.InputMediaPhoto(open('file.jpg','r').read(), caption='Новая картинка'))
    Ответ написан
    Комментировать
  • Как декодировать строку, полученную от сервера?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Возможно, браузер просто не ту кодировку выбирает. Можно просто выбрать вручную нужную для этой страницы через меню, чтобы в этом убедиться. Можно также добавить кодировку в Content-Type:

    Content-Type: text/html; charset=utf-8
    Ответ написан
    Комментировать
  • Как реализовать подобное на python?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Плохая идея при запросе что-то запускать. Вместо этого правильнее в вызываемом скрипте осмысленную функциональность оформить в функцию, которую и вызывать. Как-то так (на примере flask):

    from my_awesome_module import my_awesome_function
    from flask import Flask, request, Response, abort
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET'], defaults={'path': ''})
    @app.route('/<path:path>', methods=['GET'])
    def serve(path):
      result = my_awesome_function(path)
      if result == 0:
        return Response("OK")
      else:
        return abort(500)
    
    if __name__ == '__main__':
      app.run(host='0.0.0.0', port=123456)
    Ответ написан
    Комментировать
  • Как наложить два списка?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    d1 = [1, 0, 1, 0]
    d2 = ['qwe', 'asd', 'zxc', 'wer']
    
    d3 = [x[1] for x in filter(lambda x:x[0] == 1, zip(d1, d2))]
    
    print (d3)


    Ещё короче:

    d3 = [d2[i] for i in range(0,len(d1)) if d1[i] == 1]
    Ответ написан
    4 комментария
  • Как оформить кнопку "Следующий товар"/"Предыдущий товар"?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Нужно либо помнить позицию текущего пользователя в карусели товаров, чтобы правильно выбирать, какой будет предыдущим/следующим/текущим для добавления (как уже написано выше), либо в качестве callback_data кнопок использовать данные конкретных товаров.

    Например, как-то так (items - словарь товаров с артикулами в качестве ключей):

    #
        numbers = items.keys()
        index_current = numbers.index(number_current)
        if index_current > 0:
            number_prev = numbers[index_current-1]
        else:
            number_prev = numbers[-1]
        if index_current < len(numbers)-1:
            number_next = numbers[index_current+1]
        else:
            number_next = numbers[0]
    
        next =InlineKeyboardButton(text= 'Следующий',callback_data= f'item:{number_next}')
        previous =InlineKeyboardButton(text= 'Предыдущий',callback_data= f'item:{number_prev}')
        add = InlineKeyboardButton(text= 'Добавить в корзину',callback_data= f'add:{number_current}')
    
    ...
    
        if call.data.startswith('item:'):
           number_current = call.data[5:]
           show_this_item_to_user
        if call.data.startswith('add:'):
           number_current = call.data[4:]
           add_this_item_to_basket
    Ответ написан
    6 комментариев
  • Как зациклить функцию отправки сообщения ботом на aiogram?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Так нельзя, это же asyncio, тут любой синхронный код блокирует event loop и всё ломает. Для начала, надо вместо time.sleep использовать asyncio.sleep.

    Потом, таск бота запускается при вызове start_polling уже после цикла. При этом event loop к тому моменту закончился, так как asyncio.run отработал.

    Надо сделать как-то так:

    async def main():
      polling_task = asyncio.create_task(dp.start_polling())
      while True:
        await asyncio.sleep(60)
        await bot.send_message(owner, "Hello!")
    
    loop = asyncio.get_event_loop()
    if __name__ == '__main__':
      loop.run_until_complete(main())
      loop.close()
    Ответ написан
    Комментировать
  • Как делают прогресс бары закрепленные внизу?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    man console_codes

    Читаем про коды, которые перемещают по экрану (ESC[x;yH), меняют цвета (ESC[x;y;zm) и всё такое. Также обратить внимание на scroll region (ESC[top;bottomr), сохранение и восстановление положения курсора (ESC[?s, ESC[?u). Размер терминала можно получить с помощью ioctl TIOCGWINSZ (низкоуровневый вариант) или функции get_terminal_size модуля shutil, изменение размеров терминала в процессе работы можно отслеживать с помощью сигнала SIGWINCH.
    Ответ написан
    Комментировать
  • AIOgram, как лучше обновить код рассылки, чтобы она не останавливалась из-за Flood control?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Не надо использовать time.sleep в асинхронном коде, это блокирует event loop! Вместо этого надо использовать асинхронный вариант asyncio.sleep.

    По существу с таким кодом будет делаться 10 отправок в секунду, а официально лимит 30 в секунду. Но лучше бы дополнительно отлавливать исключение с flood control и по нему делать дополнительный sleep хотя бы на 1 секунду, а то и чуть больше, чтобы счётчик числа попыток на стороне Telegram обнулился за это время.
    Ответ написан
    Комментировать
  • Как объединить 'Привет' и message.text?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    bot.send_message(message.chat.id, 'привет '+message.text)

    или
    bot.send_message(message.chat.id, f'привет {message.text}')
    Ответ написан
    3 комментария
  • Ошибка при работе с модулем scapy Python Debian?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    "Сниффить" может только root.
    Ответ написан
    5 комментариев
  • Как лучше и правильно использовать gettext?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    gettext в простейшем варианте предполагает выбор одного языка, который в дальнейшем используется весь жизненный цикл приложения.

    Надо либо переключать язык на язык конкретного пользователя во всех нужных местах (что приведёт к частым переключениям и до кучи несовместимо с асинхронным кодом), либо использовать gettext в режиме class-based API.

    Похожий вопрос Как сделать мультиязычным приложение python?
    Ответ написан
    Комментировать
  • Как проверить JSON на обновления?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    upd: Каждый объект и каждый запрос имеют ID.
    ID каждого объекта больше предыдущего на 1.


    Помнить самый большой из id уже возвращавшихся, при каждом запросе проверять, нет ли id больше запомненного. Запросы делать с определёнными интервалами (sleep), чтобы их число в единицу времени не превышало лимитов (наприммер, если разрешено максимум 10 запросов в минуту, то нужно сделать интервал не меньше 6 секунд).

    Между прочим, getUpdates в библиотеках telegram используют примерно так же. Более того Bot API позволяет указать в параметре offset нужный id, чтобы в ответ вернулись только более новые.
    Ответ написан
    Комментировать
  • Как дать python программе права администратора?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Довольно кроссплатформенный способ запросить права администратора реализует модуль https://pypi.org/project/elevate/
    Ответ написан
    2 комментария
  • Как сделать возможность писать от лица бота через консоль?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    input - синхронная функция, она блокирует event loop. Для работы с консолью можно использовать асинхронную функцию ainput из модуля aioconsole.

    import asyncio
    from aioconsole import ainput
    
    async def main():
      s = await ainput('Enter something: ')
      print (f"You entered {s}")
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    Ответ написан
    Комментировать
  • Почему пишет значение NULL в столбце "id" если примаре кей?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    primary key и не обязан "сам заполняться" ни в одной базе. Даже в mysql это отдельная фича - auto_increment. А тут для этого нужен sequence или serial. См. например тут: https://www.postgresqltutorial.com/postgresql-serial/
    Ответ написан
    1 комментарий
  • Не запускается проект Github. Прошу помощи?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Можно не клонировать скрипт, а скачать его архивом, нажав Code-Download ZIP.

    Скрипт можно отредактировать локально, git для этого не нужен.

    В 18 строке падает из-за того, что скрипт берёт сенсор с индексом 1 (при нумерации с нуля), а массив сенсоров на этом компьютере имеет длину меньше 2, возможно даже, что нужные сенсоры ядро не понимает и список пустой. Вообще, скрипт, судя по этому месту, какой-то ацкий говнокод, который сломается просто от изменения порядка вывода сенсоров в модуле psutil. Фу на его автора.

    От себя советую избрать путь настоящего джедая: всё то же самое можно получать стандартными командами:

    Информация по процессорам: lscpu
    Информация по процессам: top или более красиво htop (выход у обоих по кнопке q)
    Информация по памяти: free -h
    Информация по сенсорам (температура, вентиляторы и всё такое): sensors
    Информация по месту на дисках: df -h
    Информация по блочным устройствам дисков: lsblk

    Доустанавливать надо будет только пакеты htop и lm-sensors.

    Ну или можно просто использовать виджеты для используемого десктопа.
    Ответ написан
    Комментировать
  • Как понять откуда поступила команда в телеграм-боте?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Передавать нужную информацию в callback_data. Например, можно передавать add:артикул, который в обработчике парсить и по нему определять, что же именно добавить.
    Ответ написан
    2 комментария
  • AIOGRAM - как отправить альбом с контентом из переменных?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Когда имеешь дело с функцией, которая хочет объект file, можно использовать io.StringIO ил io.BytesIO.

    Например:

    media.attach_photo(io.BytesIO(requests.get('http://foo/bar.jpg').content), 'Foo Bar')
    Ответ написан
    Комментировать