Beispiel #1
0
async def handle_pill_callback_query(callback_query: types.CallbackQuery):
    """
    handle pill callback and let user control it
    :param callback_query:
    :return:
    """
    logger.info(
        f"user_id={callback_query.from_user.id} data={callback_query.data}")
    pill_id = ObjectId(callback_query.data.split(',')[1])

    db = SingletonClient.get_data_base()
    pill = await db.Pills.find_one({"_id": pill_id})
    if not pill:
        return callback_query.answer("I can't find that pill, sorry.")

    string = "Title: {}\n".format(pill.get("title"))

    string += "\nList of times for notifications:"
    for time in pill.get("time_list"):
        string += "\n{}".format(time)

    markup = types.InlineKeyboardMarkup()
    if not pill.get('paused'):
        pause_text = "Pause pill"
    else:
        pause_text = "Unpause pill"
    markup.add(
        types.InlineKeyboardButton(
            pause_text, callback_data=f"{callback_query.data},pause"))
    markup.add(
        types.InlineKeyboardButton(
            "Delete pill", callback_data=f"{callback_query.data},delete"))

    await callback_query.message.edit_text(string, reply_markup=markup)
    await callback_query.answer()
def pills_time_list_markup(pill_time_list: list) -> types.InlineKeyboardMarkup:
    markup = types.InlineKeyboardMarkup()

    lst = []
    for i, pill_time in enumerate(pill_time_list):
        if i % 5 == 0:
            lst.append([
                types.InlineKeyboardButton(
                    text=pill_time,
                    callback_data=f"delete-pill-time,{pill_time}")
            ])
        else:
            lst[i // 5].append(
                types.InlineKeyboardButton(
                    text=pill_time,
                    callback_data=f"delete-pill-time,{pill_time}"))
    for row in lst:
        markup.row(*row)

    one_more_pill_time_button = types.InlineKeyboardButton(
        text="Add one more time", callback_data="add-pill-time")
    save_time_button = types.InlineKeyboardButton(
        text="Save", callback_data="save-pill-time")
    markup.row(one_more_pill_time_button, save_time_button)

    return markup
Beispiel #3
0
async def handle_cs_callback_query(callback_query: types.CallbackQuery):
    """
    Обработчик нажатия на кнопку под сообщением с ближайшей парой.
    Лямбда проверяет, чтобы обрабатывалось только y кнопки
    Args:
        callback_query (types.CallbackQuery): Документация на сайте телеграма
    """

    split_data = callback_query.data.split(',')
    if split_data[1] == 'n':
        return await callback_query.answer(text='Там больше ничего нет...')

    page = int(split_data[2])
    user_id = objectid.ObjectId(split_data[3])

    db = SingletonClient.get_data_base()

    user = await db.Users.find_one({"_id": user_id})

    subjects_cursor = db.Subjects.find(
        {"group_id": objectid.ObjectId(user.get("group_id"))})

    subjects_list = await subjects_cursor.to_list(
        length=await db.Subjects.count_documents({}))

    min_obj = get_min_obj(subjects_list, page)
    min_subj = min_obj[0]

    string, markup = await get_coming_subjects_string(min_obj,
                                                      callback_query.message,
                                                      user)

    # Проверяет, есть ли пары на предыдущих страницах.
    left_min_obj = get_min_obj(subjects_list, page - 1)
    if left_min_obj:
        left_button = types.InlineKeyboardButton(
            text='⬅️', callback_data=f'cs,l,{page - 1},{user_id}')
    else:
        left_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'cs,n,{page},{user_id}')

    # Проверяет, есть ли пары на следующих страницах.
    right_min_obj = get_min_obj(subjects_list, page + 1)
    if right_min_obj:
        right_button = types.InlineKeyboardButton(
            text='➡️', callback_data=f'cs,r,{page + 1},{user_id}')
    else:
        right_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'cs,n,{page},{user_id}')

    markup.row(left_button, right_button)

    _message = await callback_query.message.edit_text(
        string,
        reply_markup=markup,
        parse_mode='HTML',
        disable_web_page_preview=True)
    await callback_query.answer()
Beispiel #4
0
async def coming_subjects(message: types.Message):
    # TODO: 1) найти пользователя 2) найти его группу 3) найти предметы, которые относятся к его группе 4) найти
    #  ближайший и вернуть информацию 5) добавить кнопку, чтобы перелестнуть на следующий ближайший
    telegram_id = message.from_user.id
    db = SingletonClient.get_data_base()

    user = await db.Users.find_one({"telegram_id": telegram_id})

    if not user:
        return await message.reply(
            'Вы не зарегистрированы. Зайдите в бота и напишите <code>/start</code>'
        )
    elif not user.get('group_id'):
        return await message.reply('Вы не указали группу.')

    group = await db.Groups.find_one({"_id": user.get("group_id")})

    subjects_cursor = db.Subjects.find(
        {"group_id": objectid.ObjectId(user.get("group_id"))})

    subjects_list = await subjects_cursor.to_list(
        length=await db.Subjects.count_documents({}))
    logger.info(user)
    logger.info(group)

    logger.info(
        f'from {user["telegram_id"]}, group {group["title"]}, subjects_list {subjects_list}'
    )

    min_obj = get_min_obj(subjects_list)

    logger.info(
        f'from {user["telegram_id"]}, group {group["title"]}, Closest subj {min_obj[0]}'
    )
    min_subj = min_obj[0]

    string, markup = await get_coming_subjects_string(min_obj, message, user)

    # TODO: добавить кнопку "посмотреть ДЗ"
    # перелистывание предметов
    """
    callback_data:
    1) cs - название модуля
    2) l, r, n - left, right, none
    3) int - номер страницы
    4) user_id
    """
    if get_min_obj(subjects_list, 1):
        button_1 = types.InlineKeyboardButton(
            text="❌", callback_data=f'cs,n,0,{user["_id"]}')
        button_2 = types.InlineKeyboardButton(
            text="➡️", callback_data=f'cs,r,1,{user["_id"]}')
        markup.row(button_1, button_2)

    if _id := min_subj.get('teacher_id'):
        teacher = await db.Teachers.find_one({'_id': _id})
        string += f'Преподаватель: {teacher["second_name"] + " " + teacher["first_name"]}\n'
Beispiel #5
0
def sending_file_keyboard():
    markup = types.InlineKeyboardMarkup()

    button = types.InlineKeyboardButton(text="Прикрепить файл",
                                        callback_data='attach_file')
    markup.add(button)

    button = types.InlineKeyboardButton(text="Завершить", callback_data='send')
    markup.add(button)
    return markup
Beispiel #6
0
async def choose_action_menu(message: types.Message):
    string = 'Меню добавления домашнего задания / ссылки на zoom.\nДомашнее задание | Ссылка на zoom | Название | Дата'
    markup = types.ReplyKeyboardMarkup()
    markup.add(types.KeyboardButton(text='Выйти'))
    await message.answer(string, reply_markup=markup)

    telegram_id = message.from_user.id
    db = SingletonClient.get_data_base()

    user = await db.Users.find_one({"telegram_id": telegram_id})

    markup = types.InlineKeyboardMarkup()
    min_obj_list = await get_min_obj_list(user, 0)

    for obj in min_obj_list:
        subj = obj[0]
        string = ''
        hw = await db.Homework.find_one({
            "subject_id": ObjectId(subj['_id']),
            "date": obj[1]
        })
        if hw:
            string += '✅ | '
        else:
            string += '❌ | '
        zm = await db.ZoomLinks.find_one({
            "subject_id": ObjectId(subj['_id']),
            "date": obj[1]
        })
        if zm:
            string += '✅ | '
        else:
            string += '❌ | '
        string += f"{subj['title']} {obj[1].strftime('%H:%M %d.%m.%Y')}"
        button = types.InlineKeyboardButton(
            text=string, callback_data=f'cha,{subj["_id"]},{obj[1]}')
        markup.add(button)
    """
    callback_data:
    1) am - название модуля
    2) l, r, n - left, right, none
    3) int - номер страницы
    4) user_id
    """
    if await get_min_obj_list(user, 1):
        button_1 = types.InlineKeyboardButton(
            text="❌", callback_data=f'am,n,0,{user["_id"]}')
        button_2 = types.InlineKeyboardButton(
            text="➡️", callback_data=f'am,r,1,{user["_id"]}')
        markup.row(button_1, button_2)

    string = 'Список ближайших пар и статус домашнего задания:'
    await message.answer(string,
                         reply_markup=markup,
                         disable_web_page_preview=True)
Beispiel #7
0
def under_event_keyboard():
    markup = types.InlineKeyboardMarkup()

    button = types.InlineKeyboardButton(text="✅ Подтвердить",
                                        callback_data='Accept')
    markup.add(button)

    button = types.InlineKeyboardButton(text="❌ Начать заново",
                                        callback_data='Restart')
    markup.add(button)
    return markup
Beispiel #8
0
async def get_coming_subjects_string(min_obj, message: types.Message, user):
    db = SingletonClient.get_data_base()
    min_subj = min_obj[0]
    markup = types.InlineKeyboardMarkup()
    if message.chat.type == 'private':
        string = '<b>Ваше ближайшее занятие:</b>\n'
    else:
        string = f'<b>Ближайшие занятие для {user["second_name"]} {user["first_name"]}:</b>\n'
    string += f'{min_subj["title"]}\n'
    string += f'Аудитория: {min_subj["audience"]}\n'
    string += f'Когда: {min_obj[1].strftime("<b>%H:%M</b> %d.%m.%Y")}\n'
    # Прикрепление ссылки на зум.
    zoom_link = await db.ZoomLinks.find_one({
        "date": min_obj[1],
        "subject_id": min_subj['_id']
    })
    if zoom_link:
        string += f"Ссылка на <a href=\"{zoom_link['link']}\">zoom</a>."

    # if teacher_id := min_subj.get('teacher_id'):
    #     teacher = await db.Teachers.find_one({
    #         '_id': objectid.ObjectId(teacher_id)
    #     })
    #     teacher_email = teacher['email']
    #     button = types.InlineKeyboardButton(text="📧 Написать преподавателю",
    #                                         callback_data=f'SendEmail,{teacher_email}')
    #     markup.add(button)
    # кнопка подписки на напоминания
    button = types.InlineKeyboardButton(
        text="🔔 Подписаться на напоминания",
        callback_data=f'SubscribeNotifications,{min_subj["_id"]}')
    markup.add(button)

    return string, markup
Beispiel #9
0
def sending_email_keyboard(teacher_email):
    markup = types.InlineKeyboardMarkup()

    button = types.InlineKeyboardButton(text="Написать письмо",
                                        callback_data=teacher_email)
    markup.add(button)
    return markup
Beispiel #10
0
async def handle_pill_arrow_callback_query(
        callback_query: types.CallbackQuery):
    """
    Handle callback with clicks on left and right buttons
    Args:
        callback_query (types.CallbackQuery):
    """

    split_data = callback_query.data.split(',')
    logger.info(f"user_id={callback_query.from_user.id} data={split_data}")
    if split_data[1] == 'n':
        return await callback_query.answer(text='Nothing more...')

    page = int(split_data[2])
    parameter = split_data[3]

    markup = types.InlineKeyboardMarkup()
    markup = get_pills_list_markup(markup, await get_pills(page, parameter))

    string = "List of your current pills:"

    # Checks pills on previous page.
    left_list = await get_pills(page - 1, parameter)
    if left_list:
        left_button = types.InlineKeyboardButton(
            text='⬅️', callback_data=f'pl,l,{page - 1},{parameter}')
    else:
        left_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'pl,n,{page},{parameter}')

    # Checks pills on next page.
    right_list = await get_pills(page + 1, parameter)
    if right_list:
        right_button = types.InlineKeyboardButton(
            text='➡️', callback_data=f'pl,r,{page + 1},{parameter}')
    else:
        right_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'pl,n,{page},{parameter}')

    markup.row(left_button, right_button)

    _message = await callback_query.message.edit_text(string,
                                                      reply_markup=markup)
    await callback_query.answer()
Beispiel #11
0
async def handle_test(callback_query: types.CallbackQuery):
    """
    Обработчик нажатия на кнопку под сообщением со списком транзакций.
    Лямбда проверяет, чтобы обрабатывалось только stats кнопки

    Args:
        callback_query (types.CallbackQuery): Документация на сайте телеграма
    """
    if callback_query.data.split(',')[1] == 'n':
        return await callback_query.answer(text='Там больше ничего нет...')
    split_data = callback_query.data.split(',')

    page = int(split_data[2])
    mention = split_data[3]

    transactions = await get_transcations(page, mention)
    string = f"Донаты пользователя {mention}:\n"
    string += get_transcations_string(transactions)

    markup = types.InlineKeyboardMarkup()

    # Проверяет, есть ли транзакции на предыдущих страницах.
    left_list = await get_transcations(page - 1, mention)
    if left_list:
        left_button = types.InlineKeyboardButton(
            text='⬅️', callback_data=f'stats,l,{page-1},{mention}')
    else:
        left_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'stats,n,{page},{mention}')

    # Проверяет, есть ли транзакции на следующих страницах.
    right_list = await get_transcations(page + 1, mention)
    if right_list:
        right_button = types.InlineKeyboardButton(
            text='➡️', callback_data=f'stats,r,{page+1},{mention}')
    else:
        right_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'stats,n,{page},{mention}')

    markup.row(left_button, right_button)

    _message = await callback_query.message.edit_text(string, reply_markup=markup, parse_mode='HTML')
    await callback_query.answer()
Beispiel #12
0
async def choose_action(callback_query: types.CallbackQuery,
                        state: FSMContext):
    db = SingletonClient.get_data_base()
    subject_id = ObjectId(callback_query.data.split(',')[1])
    date = callback_query.data.split(',')[2]
    subject = await db.Subjects.find_one({'_id': ObjectId(subject_id)})
    await state.update_data(subject=subject)
    await state.update_data(date=date)

    markup = types.InlineKeyboardMarkup()
    markup.add(
        types.InlineKeyboardButton(text='Добавить домашнее задание',
                                   callback_data='tp,homework'))
    markup.add(
        types.InlineKeyboardButton(text='Добавить ссылку на zoom',
                                   callback_data='tp,zoom'))
    await callback_query.message.edit_text(
        f'Выберите что вы хотите добавить для <b>{subject["title"]}</b>:',
        reply_markup=markup)
    await Menu.choose_action.set()
Beispiel #13
0
async def pills_list(message: types.Message):
    """
    Send listable list with pills
    :param message:
    :return:
    """
    logger.info(f"/pills user_id={message.from_user.id}")
    db = SingletonClient.get_data_base()
    user = await db.Users.find_one({"telegram_id": message.from_user.id})
    if not user:
        await start(message)

    db = SingletonClient.get_data_base()
    user = await db.Users.find_one({"telegram_id": message.from_user.id})

    markup = types.InlineKeyboardMarkup()
    """
    callback_data:
    1) pl - module name
    2) l, r, n - left, right, none
    3) int - page num
    4) user_id
    """
    string = "List of your current pills:"
    markup = get_pills_list_markup(markup, await get_pills(0, user.get("_id")))
    if not await get_pills(0, user.get("_id")):
        return await message.answer(
            "You haven't added the pills yet. Try via /new.")

    left_button = types.InlineKeyboardButton(
        text='❌', callback_data=f'pl,l,0,{user.get("_id")}')

    right_list = await get_pills(1, user.get("_id"))
    if right_list:
        right_button = types.InlineKeyboardButton(
            text='➡️', callback_data=f'pl,r,1,{user.get("_id")}')

        markup.row(left_button, right_button)

    _message = await message.answer(string, reply_markup=markup)
Beispiel #14
0
async def stats(message: types.Message):
    """
    Создает сообщение со списком транзакций конкретного пользователя.
    Уточнить пользователя из таблицы можно вторым параметром (/stats username)
    """

    mention = await get_mention(message)

    transactions = await get_transcations(0, mention)
    if transactions is None:
        return await message.reply('Транзакции этого пользователя не найдены')

    string = f"Донаты пользователя {mention}:\n"
    string += get_transcations_string(transactions)

    markup = types.InlineKeyboardMarkup()

    """
    callback_data:
    1) stats - название модуля
    2) l, r, n - left, right, none
    3) int - номер страницы
    4) имя пользователя для поиска в таблице
    """

    left_button = types.InlineKeyboardButton(
        text='❌', callback_data=f'stats,l,0,{mention}')

    right_list = await get_transcations(1, mention)
    if right_list:
        right_button = types.InlineKeyboardButton(
            text='➡️', callback_data=f'stats,r,1,{mention}'
        )

        markup.row(left_button, right_button)
        _message = await message.answer(string, reply_markup=markup, parse_mode='HTML')
    else:
        _message = await message.answer(string, parse_mode='HTML')
Beispiel #15
0
def get_pills_list_markup(markup: types.InlineKeyboardMarkup(),
                          pills: list) -> types.InlineKeyboardMarkup():
    for pill in pills:
        """
        Send inline keyboard
        callback data:
        pil,pill_id
        pil - event list - module name
        pill_id - in string format '5fb05fee9e1ea634f3eecc73'
        """
        callback_data = 'pil,'
        callback_data += str(pill['_id'])

        string = pill['title'][0:15]
        button = types.InlineKeyboardButton(text=string,
                                            callback_data=callback_data)
        markup.row(button)
        logger.info(markup)
    return markup
Beispiel #16
0
def send_keyboard():
    markup = types.InlineKeyboardMarkup()

    button = types.InlineKeyboardButton(text="Отправить", callback_data='send')
    markup.add(button)
    return markup
Beispiel #17
0
ecology_keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=1)
ecology_keyboard.add(ecology_but1)
ecology_keyboard.row_width = 2
ecology_keyboard.add(ecology_but2, ecology_but3)
ecology_keyboard.row_width = 1
ecology_keyboard.add(ecology_but4)


##### INLINE-КЛАВИАТУРА ПРИ СООБЩЕНИИ ОБ ЭКО-КУЛЬТУРЕ
INLINE_CULTURE_BUT1_TEXT = 'Почему необходима эко-культура?'
INLINE_CULTURE_BUT2_TEXT = 'Как формировать эко-культуру?'
INLINE_CULTURE_BUT3_TEXT = 'Эко-привычки'
CALLBACK_CULTURE_BUT1 = '1'
CALLBACK_CULTURE_BUT2 = '2'
CALLBACK_CULTURE_BUT3 = '3'
inline_culture_but1 = types.InlineKeyboardButton(INLINE_CULTURE_BUT1_TEXT, callback_data=CALLBACK_CULTURE_BUT1)
inline_culture_but2 = types.InlineKeyboardButton(INLINE_CULTURE_BUT2_TEXT, callback_data=CALLBACK_CULTURE_BUT2)
inline_culture_but3 = types.InlineKeyboardButton(INLINE_CULTURE_BUT3_TEXT, callback_data=CALLBACK_CULTURE_BUT3)
inline_culture_keyboard = types.InlineKeyboardMarkup(row_width=1)
inline_culture_keyboard.add(inline_culture_but1, inline_culture_but2, inline_culture_but3)

necessary_keyboard = types.InlineKeyboardMarkup(row_width=1)
necessary_keyboard.add(inline_culture_but2, inline_culture_but3)

how_to_form_keyboard = types.InlineKeyboardMarkup(row_width=1)
how_to_form_keyboard.add(inline_culture_but1, inline_culture_but3)

eco_habits_keyboard = types.InlineKeyboardMarkup(row_width=1)
eco_habits_keyboard.add(inline_culture_but1, inline_culture_but2)

async def pills_check():
    """
    Check pills from db every 5 minutes and send notifications if need
    :return:
    """
    logger.info("pills check started")
    db = SingletonClient.get_data_base()
    now = datetime(2021, 1, 1, datetime.now().hour, datetime.now().minute)

    if now.hour == 0 and now.minute == 0:
        result = await db.Pills.update_many({}, {"$set": {"time_status": []}})

    async for pill in db.Pills.find({"paused": {"$ne": True}}):
        user = await db.Users.find_one({"_id": ObjectId(pill.get("user"))})

        time_status = pill.get("time_status")
        logger.info(pill)
        for num, ti in enumerate(pill.get("time_list")):
            t = time.fromisoformat(ti)
            t = datetime(2021, 1, 1, t.hour, t.minute)
            if t > now:
                continue
            try:
                status = time_status[num]
            except IndexError:
                status = False
                time_status.append(False)

            if status:
                # if user accept time don't send notification
                continue

            _t = datetime(2021, 1, 1, t.hour, t.minute) + timedelta(hours=1)
            if now > _t:
                # If more than one hour has elapsed after taking the pill and the person has not taken it
                time_status[num] = True
            else:
                text = "You have to take <b>{}</b> pill at {}.".format(
                    pill.get("title"), ti)
                markup = types.InlineKeyboardMarkup()
                markup.add(
                    types.InlineKeyboardButton(
                        "I took 💊",
                        callback_data=f"took,{pill.get('_id')},{ti}"))
                try:
                    await bot.send_message(user.get("telegram_id"),
                                           text=text,
                                           reply_markup=markup)
                except BotBlocked:
                    result = await db.Pills.delete_many(
                        {'user': pill.get("user")})
                    return logger.info(
                        f"Bot blocked by user user_id={user.get('telegram_id')} pill_id={pill.get('_id')} "
                        f"delete result={result.acknowledged} delete count={result.deleted_count}"
                    )

            result = await db.Pills.update_one(
                {"_id": ObjectId(pill.get("_id"))},
                {"$set": {
                    "time_status": time_status
                }})

            logger.info(
                f"user_id={user.get('telegram_id')} pill_id={pill.get('_id')} "
                f"update_one result={result.acknowledged} time_status={time_status}"
            )
Beispiel #19
0
async def handle_am_callback_query(callback_query: types.CallbackQuery):
    """
    Обработчик нажатия на кнопку под сообщением с ближайшими парами.
    Лямбда проверяет, чтобы обрабатывалось только y кнопки
    Args:
        callback_query (types.CallbackQuery): Документация на сайте телеграма
    """

    split_data = callback_query.data.split(',')
    if split_data[1] == 'n':
        return await callback_query.answer(text='Там больше ничего нет...')

    page = int(split_data[2])
    user_id = ObjectId(split_data[3])

    db = SingletonClient.get_data_base()

    user = await db.Users.find_one({"_id": user_id})

    min_obj_list = await get_min_obj_list(user, page)

    markup = types.InlineKeyboardMarkup()

    for obj in min_obj_list:
        subj = obj[0]
        string = ''
        hw = await db.Homework.find_one({
            "subject_id": ObjectId(subj['_id']),
            "date": obj[1]
        })
        if hw:
            string += '✅ | '
        else:
            string += '❌ | '
        zm = await db.ZoomLinks.find_one({
            "subject_id": ObjectId(subj['_id']),
            "date": obj[1]
        })
        if zm:
            string += '✅ | '
        else:
            string += '❌ | '
        string += f"{subj['title']} {obj[1].strftime('%H:%M %d.%m.%Y')}"
        button = types.InlineKeyboardButton(
            text=string, callback_data=f'cha,{subj["_id"]},{obj[1]}')
        markup.add(button)

    # Проверяет, есть ли пары на предыдущих страницах.
    min_obj_list = await get_min_obj_list(user, page - 1)
    if min_obj_list:
        left_button = types.InlineKeyboardButton(
            text='⬅️', callback_data=f'am,l,{page - 1},{user_id}')
    else:
        left_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'am,n,{page},{user_id}')

    # Проверяет, есть ли пары на следующих страницах.
    min_obj_list = await get_min_obj_list(user, page + 1)
    if min_obj_list:
        right_button = types.InlineKeyboardButton(
            text='➡️', callback_data=f'am,r,{page + 1},{user_id}')
    else:
        right_button = types.InlineKeyboardButton(
            text='❌', callback_data=f'am,n,{page},{user_id}')

    markup.row(left_button, right_button)

    string = 'Список ближайших пар и статус домашнего задания:'
    _message = await callback_query.message.edit_text(
        string,
        reply_markup=markup,
        parse_mode='HTML',
        disable_web_page_preview=True)
    await callback_query.answer()