Ejemplo n.º 1
0
    async def _send(self, image: BytesIO, *kb_list: InlineKeyboardMarkup):
        bot = Bot.get_current()
        user = User.get_current()
        call = CallbackQuery.get_current()
        message = Message.get_current()
        kb_list = [kb for kb in kb_list if kb]  # clean from None

        if call:
            reply_to = call.message.message_id
        elif message:
            reply_to = message and message.message_id
        else:
            reply_to = None

        if len(kb_list) == 0:
            kb = None
        elif len(kb_list) == 1:
            kb = kb_list[0]
        else:
            kb = inline.merge_inline_keyboards(kb_list[0], kb_list[1])

        await bot.send_photo(user.id,
                             image,
                             reply_markup=kb,
                             reply_to_message_id=reply_to)
Ejemplo n.º 2
0
async def process_callback(callback_query: types.CallbackQuery,
                           state: FSMContext):
    """
    Template selection handler
    """
    bot = Bot.get_current()
    await bot.answer_callback_query(callback_query.id)
    template = callback_query.data
    if template not in templates_manager.all_templates():
        await bot.send_message(callback_query.from_user.id,
                               "Такого шаблона не существует")
        return

    size = templates_manager.all_templates()[template].pil_image.size
    await bot.send_message(
        callback_query.from_user.id,
        f"Выбран шаблон {template}, теперь отправьте текст для плаката.\n\n"
        f"Чтобы указать автора цитаты, отправьте его имя после @ в формате 'Текст @ Автор'\n\n"
        f"Вы также можете отправить картинку на фон "
        f"плаката {size[0]}x{size[1]} (картинки других размеров будут растянуты/обрезаны)\n\n"
        f"Чтобы вернуться к списку шаблонов отправьте /templates",
    )
    async with state.proxy() as proxy:
        proxy["template"] = template
        proxy.pop("background")
        proxy.pop("text")
Ejemplo n.º 3
0
async def get_sticker_id(sticker: types.sticker.Sticker):
    bot = Bot.get_current()
    # echo sticker
    # await bot.send_sticker(chat_id=sticker.chat.id, sticker=sticker.sticker.file_id)

    # send sticker id
    await bot.send_message(chat_id=sticker.chat.id,
                           text=sticker.sticker.file_id)
Ejemplo n.º 4
0
 async def is_chat_member(self, user_id: int) -> bool:
     """Check if user is currently member of chat."""
     bot = Bot.get_current()
     try:
         chat_member = await bot.get_chat_member(self.chat, user_id)
         return chat_member.is_chat_member()
     except BadRequest:
         return False
Ejemplo n.º 5
0
async def entry_point(message: types.Message):
    bot = Bot.get_current()
    user = await db_utils.get_user_by_id(message.from_user.id)
    await bot.send_message(
        message.chat.id,
        f"\U0001F4B8       У вас есть {user.money} рублей!         \U0001F4B8",
        reply_markup=main_game_keyboard(),
    )
Ejemplo n.º 6
0
 async def check_referrals(self):
     bot = Bot.get_current()
     user_id = types.User.get_current().id
     user = await self.get_user(user_id)
     referrals = await User.query.where(User.referral == user.id).gino.all()
     return ", ".join([
         f"{num + 1}. " + (await bot.get_chat(referral.user_id)).get_mention(as_html=True)
         for num, referral in enumerate(referrals)
     ])
Ejemplo n.º 7
0
 def __getattribute__(self, name: str):
     attr = super().__getattribute__(name)
     if name == "bot" and attr is None:
         bot = Bot.get_current()
         super().__setattr__(name, bot)
         return bot
     if name == "dispatcher" and attr is None:
         dispatcher = Dispatcher.get_current()
         super().__setattr__(name, dispatcher)
         return dispatcher
     return attr
Ejemplo n.º 8
0
async def main_errors_handler(_, e: Exception):
    if isinstance(e, ZmanimBotBaseException):
        return True
    user = User.get_current()
    bot = Bot.get_current()
    await bot.send_message(user.id, error_occured)

    logger.exception(e)

    sentry_sdk.capture_exception(e)
    return True
Ejemplo n.º 9
0
async def on_err(event: types.Update, exception: Exception):
    bot = Bot.get_current()

    # notifies the admins
    for admin in CONFIG["ADMINS"]:
        await bot.send_message(admin, f"{exception} ocurred on event: {event}")

    # logs the error in the logger
    logger.critical(f"<{exception}> ocurred on event: {event}")

    return True
Ejemplo n.º 10
0
async def download_file(file_id: Optional[str] = None) -> Optional[BytesIO]:
    """
    Download file from Telegram server by ID
    Cached function
    """
    if not file_id:
        return None

    stream = BytesIO()
    bot = Bot.get_current()
    await bot.download_file_by_id(file_id, stream)
    return stream
Ejemplo n.º 11
0
    async def run_update(self, is_last_update: bool = False):
        logger.trace(f'Updating watcher: {self.user_id=}, {self.message_id=}')
        content = await prepare_station_schedule(self.stop_code, is_last_update)
        user = await user_repository.get_user(self.user_id)
        bot = Bot.get_current()

        is_stop_saved = user.is_stop_already_saved(self.stop_code)
        kb = get_kb_for_stop(self.stop_code, is_saved=is_stop_saved) if not is_last_update else None

        try:
            await bot.edit_message_text(content, self.user_id, self.message_id, reply_markup=kb)
        except MessageNotModified:
            pass
Ejemplo n.º 12
0
async def _get_privileges(user_id: int, chat_id: int) -> Privileges:
    """
    Check user access
    :param user_id: user id
    :param chat_id: access chat id
    :return: privileges
    """
    bot = Bot.get_current()
    chat_member = await bot.get_chat_member(chat_id, user_id)
    if chat_member.is_chat_admin():
        return Privileges.admin
    if chat_member.is_chat_member():
        return Privileges.user
    return Privileges.nothing
Ejemplo n.º 13
0
async def ask_question(question: Quests):
    """Send message for each Quest in question [current Chat]."""
    chat = types.Chat.get_current()
    bot = Bot.get_current()

    async def ask_quest(quest: Quest):
        if isinstance(quest, str):
            await bot.send_message(chat.id, quest)
        elif isinstance(quest, QuestText):
            await bot.send_message(chat.id, quest.text, reply_markup=quest.keyboard)
        elif isinstance(quest, QuestFunc):
            await quest.async_func()

    for q in to_list(question):
        await ask_quest(q)
Ejemplo n.º 14
0
async def check_task(query: types.CallbackQuery, callback_data: dict):
    await query.answer()
    bot = Bot.get_current()
    task = await db_utils.get_current_task(query.from_user.id)
    user = await db_utils.get_user_by_id(query.from_user.id)
    if callback_data["skip"] == "0":
        try:
            chat_member = await bot.get_chat_member(task.chat_id, user.user_id)
            if chat_member is not None and chat_member.is_chat_member():
                await db_utils.change_money_amount(user.user_id,
                                                   config.JOIN_GROUP_REWARD)
                user.current_task_id += 1
                await user.commit()
                await bot.edit_message_text(
                    EARN_MENU_TEXT["group_check_success"],
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=markups.get_next_task_markup(),
                )
            else:
                await bot.edit_message_text(
                    EARN_MENU_TEXT["group_check_failed"],
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=markups.get_next_task_markup(),
                )
        except (ChatNotFound, ChatAdminRequired):
            user.current_task_id += 1
            await user.commit()
            await bot.edit_message_text(
                EARN_MENU_TEXT["bad_group"],
                query.message.chat.id,
                query.message.message_id,
                reply_markup=markups.get_next_task_markup(),
            )
    elif callback_data["skip"] == "1":
        user.current_task_id += 1
        await user.commit()
        await bot.edit_message_text(
            EARN_MENU_TEXT["task_cancelled"],
            query.message.chat.id,
            query.message.message_id,
            reply_markup=markups.get_next_task_markup(),
        )
    else:
        await entry_point(query.message,
                          last_message=query.message.message_id,
                          user_id=query.message.chat.id)
Ejemplo n.º 15
0
    async def _update(self, image: BytesIO, *kb_list: InlineKeyboardMarkup):
        bot = Bot.get_current()
        user = User.get_current()
        call = CallbackQuery.get_current()

        media = InputMedia(media=image)

        if len(kb_list) == 0:
            kb = None
        elif len(kb_list) == 1:
            kb = kb_list[0]
        else:
            kb = inline.merge_inline_keyboards(kb_list[0], kb_list[1])

        await bot.edit_message_media(media,
                                     user.id,
                                     call.message.message_id,
                                     reply_markup=kb)
Ejemplo n.º 16
0
    async def __make_request(
        sql: str,
        params: Union[tuple, List[tuple]] = None,
        fetch: bool = False,
        mult: bool = False,
    ):
        if not PostgresConnection.conn:
            bot = Bot.get_current()
            PostgresConnection.conn = await asyncpg.create_pool(
                **bot['config']['db'])

        async with PostgresConnection.conn.transaction():
            conn = PostgresConnection.conn
            if fetch:
                result = await conn.fetch(sql, *params)
                return result
            else:
                await conn.execute(sql, *params)
        await PostgresConnection.conn.close()
Ejemplo n.º 17
0
async def check_group_and_user(chat_id, user_id):
    bot = Bot.get_current()
    user = users_col.find_one({'user_id': user_id})
    if not user:
        users_col.insert_one({'user_id': user_id,
                              'years': 100,
                              'games_finished': 0,
                              'loses': 0})
    grp = await bot.get_chat(chat_id)
    if grp.type == 'private':
        return
    group = groups_col.find_one({'group_id': chat_id})
    if not group:
        groups_col.insert_one({'group_id': chat_id,
                               'users': [user_id]})
        group = groups_col.find_one({'group_id': chat_id})
    if user_id not in group['users']:
        groups_col.update_one({'group_id': chat_id},
                              {'$push': {'users': user_id}})
Ejemplo n.º 18
0
 def _setup_bot(
     self,
     bot: Optional[Bot] = None,
     token: Optional[str] = None,
 ) -> Bot:
     if not (bot or token):
         bot = Bot.get_current()
         if bot:
             self.bot = bot
         else:
             raise AttributeError(
                 'You should either pass a bot instance or a token')
     if bot and token:
         raise AttributeError('You can’t pass both bot and token')
     if bot:
         self.bot = bot
     elif token:
         bot = Bot(token=token)
         self.bot = bot
     return bot
async def check_for_admin(query: types.CallbackQuery, state: FSMContext):
    await query.answer()
    bot = Bot.get_current()
    try:
        async with state.proxy() as storage:
            await bot.get_chat_member(storage["group_id"],
                                      query.message.chat.id)
            chat = await bot.get_chat(storage["group_id"])
            task = models.Task(chat_id=storage["group_id"],
                               channel_name=chat.title,
                               url=await chat.get_url())
            await task.commit()
            await bot.send_message(query.message.chat.id,
                                   ADD_TASKS_MENU_TEXT["add_successful"])
    except (ChatNotFound, ChatAdminRequired):
        await bot.edit_message_text(
            ADD_TASKS_MENU_TEXT["admin_failed"],
            query.message.chat.id,
            query.message.message_id,
            reply_markup=markups.get_check_admin_markup(),
        )
Ejemplo n.º 20
0
async def entry_point(message: types.Message,
                      new=False,
                      last_message=None,
                      user_id=None):
    """
    :param message:
    :param new: if it's true, bot will give out new task
    :param last_message: If last_message is None, bot create new message, so if function get last_message, 
    it means that bot need to edit created message
    :param user_id:
    :return:
    """
    bot = Bot.get_current()
    if user_id is None:
        user_id = types.User.get_current().id
    user = await db_utils.get_user_by_id(user_id)
    if new or user.current_task_id == -1:
        task = await db_utils.get_next_task(user_id)
    else:
        task = await db_utils.get_current_task(user_id)
    if task is None:
        if last_message is None:
            await bot.send_message(message.chat.id, EARN_MENU_TEXT["no_tasks"])
        else:
            await bot.edit_message_text(EARN_MENU_TEXT["no_tasks"],
                                        message.chat.id, last_message)
        return
    if last_message is None:
        await bot.send_message(
            message.chat.id,
            EARN_MENU_TEXT["new_task"].format(channel_name=task.channel_name),
            reply_markup=markups.get_earn_markup(task),
        )
    else:
        await bot.edit_message_text(
            EARN_MENU_TEXT["new_task"].format(channel_name=task.channel_name),
            message.chat.id,
            last_message,
            reply_markup=markups.get_earn_markup(task),
        )
Ejemplo n.º 21
0
async def button_lang(query: types.CallbackQuery):
    user, _ = User.get_or_create(user_id=query.from_user.id,
                                 defaults={"language": "en"})
    bot = Bot.get_current()

    # bad clients can send arbitrary callback data
    if getattr(query, "data", None) not in REPLIES["LANGS"]:
        return

    logger.info(f"{user.user_id} changed language from {user.language} to "
                f"{query.data} via button")

    user.language = query.data
    user.save()

    await query.answer()
    try:
        await bot.edit_message_text(
            text=REPLIES["lang_success"][query.data],
            message_id=query.message.message_id,
            chat_id=query.from_user.id,
        )
    except MessageNotModified:
        pass  # silence this error
Ejemplo n.º 22
0
    async def auth(msg):
        logger.info('/start command called')
        bot: Bot = Bot.get_current()

        token = msg.get_args()
        logger.info('Looking up user by token ' +
                    (token[:10] + '...' if token else 'NONE'))
        user = models.Participant.objects.get_by_token(token)

        if user is None:
            logger.info('Looked up user by token but none found')
            await bot.send_message(
                chat_id=msg.chat.id,
                text=
                "Найдите письмо от Кочерги и активируйте бота по инструкциям из него.",
            )
            return
        logger.info('Found user by token')

        if not msg.from_user.username:
            await bot.send_message(
                chat_id=msg.chat.id,
                text="Перед регистрацией вам нужно зайти в настройки Telegram "
                "и выбрать себе username (имя пользователя).",
            )
            return

        # TODO - create_or_update
        models.TelegramUser.objects.create(
            user=user.user,
            telegram_uid=msg.from_user.username,
            chat_id=msg.chat.id,
        )
        logger.info('Saved user telegram info')

        await start_registration()
Ejemplo n.º 23
0
async def post_wallpaper(channel_id: int, user_id: int) -> None:
    """
    This function is used by the apscheduler to post wallpapers.

    :param channel_id: Channel ID to publish wallpaper in
    :param user_id: User ID
    :return:
    """
    queue_element = (await db.select([
        Wallpaper.id,
        Wallpaper.user_id,
        Wallpaper.channel_id,
        Wallpaper.file_id,
        Wallpaper.extension,
        Wallpaper.custom_signature,
        Channel.enable_signature,
        Channel.signature_text,
        Channel.enable_counter,
        Channel.counter_value,
    ]).select_from(Wallpaper.join(Channel)).where(
        and_(Wallpaper.channel_id == channel_id,
             Wallpaper.user_id == user_id)).gino.first())
    if queue_element is None:
        return

    bot = Bot.get_current()
    job = apscheduler.get_job(
        BASE_JOB_ID.format(channel_id=channel_id, user_id=user_id))
    data = PostingData(*queue_element)

    filename, caption, chat_title = await gather_file_data(bot, data)
    member = await bot.get_chat_member(channel_id, user_id)
    if not member.is_chat_creator() and not member.can_post_messages:
        try:
            await bot.send_message(
                user_id,
                f"Вы потеряли админку в <b>{chat_title}</b>.\nВсе публикации в этот канал отменены."
            )
        finally:
            await Wallpaper.delete.where(
                and_(Wallpaper.user_id == data.user_id,
                     Wallpaper.channel_id == data.channel_id)).gino.status()
            if job is not None:
                job.remove()

    try:
        with await bot.download_file_by_id(data.file_id) as full_image:
            with resize_image(full_image) as preview_image:
                await bot.send_photo(channel_id,
                                     InputFile(preview_image),
                                     caption=caption)
                await bot.send_document(channel_id,
                                        InputFile(full_image,
                                                  filename=filename),
                                        disable_notification=True)

                await Channel.update.values(
                    counter_value=data.counter_value + 1
                ).where(Channel.id == data.channel_id).gino.status()
                await Wallpaper.delete.where(Wallpaper.id == data.wallpaper_id
                                             ).gino.status()
    except exceptions.TelegramAPIError as ex:
        logger.error("{ex} while publishing a wallpaper.", ex=ex)
        try:
            await bot.send_message(
                user_id,
                f"Произошла ошибка при публикации в <b>{chat_title}</b>!\n"
                "Проверьте канал и права бота, затем перезапустите планировщик.",
                reply_markup=keyboard.control_markup,
                disable_web_page_preview=True,
            )
        finally:
            if job is not None:
                job.remove()
Ejemplo n.º 24
0
 def set_running(self):
     self.running = True
     self.countdown: datetime = datetime.datetime.now()
     self.current: str = "Questions"
     self.bot = Bot.get_current()
Ejemplo n.º 25
0
async def callback_results(query: types.CallbackQuery, callback_data: dict):
    bot = Bot.get_current()
    user = await db_utils.get_user_by_id(query.message.chat.id)
    await query.answer()

    if callback_data["action"] in [
            "make", "plus", "minus", "show_current_sum"
    ]:

        if callback_data["action"] == "make" and callback_data["value"] == "1":
            user.current_bet = 1
            await user.commit()

        if callback_data["action"] == "make" and callback_data["value"] == "10":
            user.current_bet = 10
            await user.commit()

        if callback_data["action"] == "make" and callback_data["value"] == "50":
            user.current_bet = 50
            await user.commit()

        if callback_data["action"] == "make" and callback_data[
                "value"] == "100":
            user.current_bet = 100
            await user.commit()

        if callback_data["action"] == "make" and callback_data[
                "value"] == "1000":
            user.current_bet = 1000
            await user.commit()

        if callback_data["action"] == "plus" and callback_data["value"] == "1":
            user.current_bet += 1
            await user.commit()

        if callback_data["action"] == "plus" and callback_data["value"] == "5":
            user.current_bet += 5
            await user.commit()

        if callback_data["action"] == "minus" and callback_data["value"] == "1":
            if user.current_bet >= 1:
                user.current_bet -= 1
                await user.commit()

        if callback_data["action"] == "minus" and callback_data["value"] == "5":
            if user.current_bet >= 5:
                user.current_bet -= 5
                await user.commit()
            else:
                user.current_bet = 0
                await user.commit()

        await bot.edit_message_text(
            f"\U0001F4B8 У вас есть {user.money} рублей и ваша ставка {user.current_bet} рублей \U0001F4B8",
            query.message.chat.id,
            query.message.message_id,
            reply_markup=main_game_keyboard(),
        )
    if callback_data["action"] == "show_rules":

        await bot.send_message(
            query.message.chat.id,
            "Курс биткоина меняется каждую секунду!\nУгадай как он изменится и выиграй деньги!\nВы не можете поставить больше, чем у вас есть.",
            reply_markup=get_menu_button(),
        )

    if callback_data["action"] == "menu":
        await bot.send_message(
            query.message.chat.id,
            f"\U0001F4B8 У вас есть {user.money} рублей! \U0001F4B8",
            reply_markup=main_game_keyboard(),
        )

    if callback_data["action"] in ["play", "up", "down", "play_again"]:
        if user.money >= user.current_bet:
            number = random.randint(0, 20)
            if callback_data["action"] not in ["up", "down", "play_again"]:
                await bot.edit_message_text(
                    "Биткоин вырастет или упадет?",
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=bitcoin(),
                )
            if callback_data["action"] == "up" and number > 5:

                await bot.edit_message_text(
                    f"\U0001F601 Вы выиграли {user.current_bet} рублей! \U0001F601",
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=play_again(),
                )

                user.money += user.current_bet
                await user.commit()
                await db_utils.change_money_amount(query.from_user.id,
                                                   user.current_bet)

            elif callback_data["action"] == "down" and number < 5:

                await bot.edit_message_text(
                    f"\U0001F601 Вы выиграли {user.current_bet} рублей! \U0001F601",
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=play_again(),
                )

                user.money += user.current_bet
                await user.commit()
                await db_utils.change_money_amount(query.from_user.id,
                                                   user.current_bet)

            elif callback_data["action"] == "down" and number > 5:

                await bot.edit_message_text(
                    f"\U0001F614 Вы потеряли {user.current_bet} рублей! \U0001F614",
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=play_again(),
                )

                user.money -= user.current_bet
                await user.commit()
                await db_utils.change_money_amount(query.from_user.id,
                                                   -user.current_bet)

            elif callback_data["action"] == "up" and number < 5:

                await bot.edit_message_text(
                    f"\U0001F614 Вы проиграли {user.current_bet} рублей! \U0001F614",
                    query.message.chat.id,
                    query.message.message_id,
                    reply_markup=play_again(),
                )

                user.money -= user.current_bet
                await user.commit()
                await db_utils.change_money_amount(query.from_user.id,
                                                   -user.current_bet)

            if callback_data["action"] == "play_again":
                if user.money < 1:
                    await bot.edit_message_text(
                        "\U0001F915 У вас недостаточно денег \U0001F915",
                        query.message.chat.id,
                        query.message.message_id,
                    )
                else:
                    await bot.edit_message_text(
                        f"\U0001F4B8 У вас есть {user.money} рублей! \U0001F4B8",
                        query.message.chat.id,
                        query.message.message_id,
                        reply_markup=main_game_keyboard(),
                    )
        else:
            await bot.edit_message_text(
                "\U000026D4	Ваша ставка слишком большая! \U000026D4",
                query.message.chat.id,
                query.message.message_id,
                reply_markup=main_game_keyboard(),
            )
Ejemplo n.º 26
0
async def location_limit_exception_handler(*_):
    user = User.get_current()
    bot = Bot.get_current()
    await bot.send_message(user.id, messages.too_many_locations_error)
    return True
Ejemplo n.º 27
0
async def get_voice_id(message: types.Voice):
    bot = Bot.get_current()
    await bot.send_voice(chat_id=message.chat.id, voice=message.voice.file_id)
Ejemplo n.º 28
0
async def check(user_id, channel: Union[int, str]):
    bot = Bot.get_current()
    member = await bot.get_chat_member(chat_id=channel, user_id=user_id)
    return member.is_chat_member()
Ejemplo n.º 29
0
async def send_to_admin(message_text: str) -> None:
    bot = Bot.get_current()
    await bot.send_message(ADMIN_ID, message_text)
Ejemplo n.º 30
0
 def get_bot() -> Bot:
     return Bot.get_current()