async def buying_item(call: CallbackQuery, callback_data: dict, state: FSMContext): # То, что мы указали в CallbackData попадает в хендлер под callback_data, как словарь, поэтому достаем айдишник item_id = int(callback_data.get("item_id")) await call.message.edit_reply_markup() # Достаем информацию о товаре из базы данных item = await database.Item.get(item_id) if not item: await call.message.answer(_("Такого товара не существует")) return text = _("Вы хотите купить товар \"<b>{name}</b>\" по цене: <i>{price:,}/шт.</i>\n" "Введите количество или нажмите отмена").format(name=item.name, price=item.price / 100) await call.message.answer(text) await states.Purchase.EnterQuantity.set() # Сохраняем в ФСМ класс товара и покупки await state.update_data( item=item, purchase=database.Purchase( item_id=item_id, purchase_time=datetime.datetime.now(), buyer=call.from_user.id ) )
async def register_user(message: types.Message): chat_id = message.from_user.id referral = message.get_args() user = await db.add_new_user(referral=referral) id = user.id count_users = await db.count_users() # Отдадим пользователю клавиатуру с выбором языков languages_markup = InlineKeyboardMarkup(inline_keyboard=[[ InlineKeyboardButton(text="Русский 🇷🇺", callback_data="lang_ru") ], [ [InlineKeyboardButton(text="O'zbek 🇺🇿", callback_data="lang_uz")], ]]) bot_username = (await bot.me).username bot_link = f"https://t.me/{bot_username}?start={id}" # Для многоязычности, все тексты, передаваемые пользователю должны передаваться в функцию "_" # Вместо "текст" передаем _("текст") text = _("Приветствую вас!!\n" "Сейчас в базе {count_users} человек!\n" "\n" "Ваша реферальная ссылка: {bot_link}\n" "Проверить рефералов можно по команде: /referrals\n" "Просмотреть товары: /items").format(count_users=count_users, bot_link=bot_link) if message.from_user.id == admin_id: text += _("\n" "Добавить новый товар: /add_item") await bot.send_message(chat_id, text, reply_markup=languages_markup)
async def buying_item(call: CallbackQuery, callback_data: dict, state: FSMContext): # То, что мы указали в CallbackData попадает в хендлер под callback_data, как словарь, поэтому достаем айдишник item_id = int(callback_data.get("item_id")) await call.message.edit_reply_markup() # Достаем информацию о товаре из базы данных item = await database.Item.get(item_id) if not item: await call.message.answer(_("Такого товара не существует")) return text = _( "Вы хотите забронировать \"<b>{name}</b>\" \n" "Размер <b>ежедневной оплаты состовляет</b>: <i>{price:,}/сутки.</i>\n" "<u>Введите</u> на сколько дней вы планируете остаться у нас.").format( name=item.name, price=item.price / 100) await call.message.answer(text) await states.Purchase.EnterQuantity.set() # Сохраняем в ФСМ класс товара и покупки await state.update_data(item=item, purchase=database.Purchase( item_id=item_id, purchase_time=datetime.datetime.now(), buyer=call.from_user.id, item_name=item.name))
async def checkout(query: PreCheckoutQuery, state: FSMContext): await bot.answer_pre_checkout_query(query.id, True) data = await state.get_data() purchase: database.Purchase = data.get("purchase") success = await check_payment(purchase) if success: await purchase.update( successful=True, shipping_address=query.order_info.shipping_address.to_python() if query.order_info.shipping_address else None, phone_number=query.order_info.phone_number, receiver=query.order_info.name, email=query.order_info.email).apply() await state.reset_state() await bot.send_message(query.from_user.id, _("Спасибо за то, что выбрали нас \(@^0^@)/")) await bot.send_message( query.from_user.id, _("Помните, что хостел — это общежитие.\n" "•Уважайте личное пространство других людей.\n" "•Соблюдайте тишину.\n" "•Не сорите!\n" "•Присматривате за своими вещами.\n" "•Возьмите с собой одежду для сна, беруши и повязку на глаза.\n" "•И самое главное - <b>общайтесь!</b>")) else: await bot.send_message( query.from_user.id, _("Оплата не была подтверждена, попробуйте позже..."))
async def show_items(message: Message): # Достаем товары из базы данных all_items = await db.show_items() # Проходимся по товарам, пронумеровывая for num, item in enumerate(all_items): text = _("<b>Товар</b> \t№{id}: <u>{name}</u>\n" "<b>Цена:</b> \t{price:,}\n") markup = InlineKeyboardMarkup( inline_keyboard= [ [ # Создаем кнопку "купить" и передаем ее айдишник в функцию создания коллбека InlineKeyboardButton(text=_("Купить"), callback_data=buy_item.new(item_id=item.id)) ], ] ) # Отправляем фотку товара с подписью и кнопкой "купить" await message.answer_photo( photo=item.photo, caption=text.format( id=item.id, name=item.name, price=item.price / 100 ), reply_markup=markup ) # Между сообщениями делаем небольшую задержку, чтобы не упереться в лимиты await asyncio.sleep(0.3)
async def admin_quest_menu(): admin_quest_menu = InlineKeyboardMarkup(row_width=1).add( InlineKeyboardButton(_('Add quest'), callback_data='add_quest'), InlineKeyboardButton(_('Edit quests and hints'), callback_data='edit_quest'), InlineKeyboardButton(_('Back'), callback_data='back_to_menu')) return admin_quest_menu
async def edit_quest_kb(quest, page_n, next_page=False, prev_page=False): kb = InlineKeyboardMarkup(row_width=3) edit_date = InlineKeyboardButton(_('Edit date'), callback_data=edit_quest_cb.new( action='edit_date', quest=quest.date, data=page_n)) edit_url = InlineKeyboardButton(_('Edit url'), callback_data=edit_quest_cb.new( action='edit_url', quest=quest.date, data=page_n)) edit_diff = InlineKeyboardButton(_('Edit diff'), callback_data=edit_quest_cb.new( action='edit_diff', quest=quest.date, data=page_n)) edit_hints = InlineKeyboardButton(_('Edit hints'), callback_data=edit_quest_cb.new( action='edit_hints', quest=quest.date, data=page_n)) del_quest = InlineKeyboardButton(_('Delete'), callback_data=edit_quest_cb.new( action='delete_quest', quest=quest.date, data=page_n)) solve = _('Unsolved ❌') if quest.solved: solve = _('Solved ✅') edit_solved = InlineKeyboardButton(solve, callback_data=edit_quest_cb.new( action='edit_solve', quest=quest.date, data=page_n)) kb.add(edit_date, edit_url) kb.add(edit_diff, edit_hints) kb.add(edit_solved, del_quest) if prev_page: prev_page_b = InlineKeyboardButton(_('Prev page'), callback_data=edit_quest_cb.new( action='prev_page', quest=quest.date, data=page_n - 1)) kb.add(prev_page_b) if next_page: next_page_b = InlineKeyboardButton(_('Next page'), callback_data=edit_quest_cb.new( action='next_page', quest=quest.date, data=page_n + 1)) if prev_page: kb.insert(next_page_b) else: kb.add(next_page_b) kb.insert(InlineKeyboardButton(_('Exit'), callback_data='exit_edit_quest')) return kb
async def app_edit_kb(platform): kb = InlineKeyboardMarkup(row_width=2).add( InlineKeyboardButton(_('Edit'), callback_data=edit_apps_cb.new( set='edit', platform=platform)), InlineKeyboardButton(_('Delete'), callback_data=edit_apps_cb.new( set='delete', platform=platform)), InlineKeyboardButton(_('Back'), callback_data='admin_app')) return kb
async def add_edit_hints(call: types.CallbackQuery, state: FSMContext): data = await state.get_data() hint_n = data.get('hint_n') page = data.get('page') q_date = datetime.datetime.strptime(data.get('q_date'), '%Y-%m-%d %H:%M:%S') callback_d = call.data lang = callback_d[:2] hint = await db.get_hints(q_date) hint_text = '-' if lang == 'en': if hint_n[1] == '0': hint_text = '-' elif hint_n[0] == '1': hint_text = hint.hint1 elif hint_n[0] == '2': hint_text = hint.hint2 elif hint_n[0] == '3': hint_text = hint.hint3 elif hint_n[0] == '4': hint_text = hint.hint4 else: if hint_n[2] == '0': hint_text = '-' elif hint_n[0] == '1': hint_text = hint.hint1_ru elif hint_n[0] == '2': hint_text = hint.hint2_ru elif hint_n[0] == '3': hint_text = hint.hint3_ru elif hint_n[0] == '4': hint_text = hint.hint4_ru if callback_d[-1] == 'E': hint_text = '-' msg = _('Please enter hint:') if hint_text != '-': msg = _('This hint is:\n{hint}').format(hint=hint_text) await call.answer() await call.message.delete() await call.message.answer(msg, reply_markup=await keyboards.edit_hint(hint_n[0], q_date, page, lang)) return else: hint = await db.get_hints(q_date) mess = await call.message.answer(msg) await call.message.delete() await call.answer() await AddHints.Confirm.set() await state.update_data(hint=hint, hint_n=hint_n[0], mess=mess, page=page, lang=lang)
async def anno_cancel(confirm=False, img=False): anno_cancel_kb = InlineKeyboardMarkup() if confirm is True: anno_cancel_kb.add( InlineKeyboardButton(_('Confirm'), callback_data='confirm_anno')) if img is True: anno_cancel_kb.add( InlineKeyboardButton(_('No picture needed'), callback_data='anno_no_picture')) anno_cancel_kb.add( InlineKeyboardButton(_('Cancel'), callback_data='anno_cancel')) return anno_cancel_kb
async def del_admin(message: types.Message): msg = _('Incorrect username format. Please use /del_admin @username') args = message.get_args() if args != '' and len(args.split(' ')) == 1 and args[0] == '@': username = args.strip('@') user = await db.get_user_username(username) if user is not None: await user.update(is_admin=False).apply() msg = _('This person is no more an admin!') else: msg = _( 'This user is not in the database, please ask him to start the bot first!' ) await message.reply(msg)
async def edit_hint(hint_n, q_date, page, lang): kb = InlineKeyboardMarkup(row_width=2).add( InlineKeyboardButton(_('Edit'), callback_data=lang + 'E'), InlineKeyboardButton(_('Delete'), callback_data=del_hint_cb.new(hint_n=hint_n, q_date=q_date, page=page, lang=lang)), InlineKeyboardButton( _('Back'), callback_data=edit_quest_cb.new(action='edit_hints', quest=q_date, data=page))) return kb
async def confirm_order(call: types.CallbackQuery,state: FSMContext): await call.message.edit_reply_markup() data = await state.get_data() confirm1 = data.get("confirm1") if confirm1.occupied == False: await confirm1.update(occupied=True).apply() text = _("Комната с номером <b>{id}</b> отмечена как забронированная\n") await state.finish() else: await confirm1.update(occupied=False).apply() text = _("Комната с номером <b>{id}</b> отмечена как свободная\n") await state.finish() await bot.send_message(text = text.format(id = confirm1.id),chat_id = admin_id)
async def edit_news_kb(news, page_n, next_page=False, prev_page=False): kb = InlineKeyboardMarkup(row_width=3) edit_date = InlineKeyboardButton(_('Edit date'), callback_data=edit_news_cb.new( action='edit_date', news=news.date, data=page_n)) edit_url = InlineKeyboardButton(_('Edit english url'), callback_data=edit_news_cb.new( action='edit_url_en', news=news.date, data=page_n)) edit_desc = InlineKeyboardButton(_('Edit english desc'), callback_data=edit_news_cb.new( action='edit_desc_en', news=news.date, data=page_n)) edit_url_ru = InlineKeyboardButton(_('Edit russian url'), callback_data=edit_news_cb.new( action='edit_url_ru', news=news.date, data=page_n)) edit_desc_ru = InlineKeyboardButton(_('Edit russian desc'), callback_data=edit_news_cb.new( action='edit_desc_ru', news=news.date, data=page_n)) delete_news = InlineKeyboardButton(_('Delete'), callback_data=edit_news_cb.new( action='delete_news', news=news.date, data=page_n)) kb.add(edit_date, delete_news) kb.add(edit_url, edit_url_ru) kb.add(edit_desc, edit_desc_ru) if prev_page: prev_page_b = InlineKeyboardButton(_('Prev page'), callback_data=edit_news_cb.new( action='prev_page', news=news.date, data=page_n - 1)) kb.add(prev_page_b) if next_page: next_page_b = InlineKeyboardButton(_('Next page'), callback_data=edit_news_cb.new( action='next_page', news=news.date, data=page_n + 1)) if prev_page: kb.insert(next_page_b) else: kb.add(next_page_b) kb.insert(InlineKeyboardButton(_('Exit'), callback_data='exit_edit_news')) return kb
async def confirm_hints(message: types.Message, state: FSMContext): hint_text = message.text length = len(hint_text) data = await state.get_data() mess = data.get('mess') if length > 200: warning = _('Length of hint is {l} chars.' '\nLength should be less than or equal to 200 chars.' '\nTry again.').format(l=length) try: await mess.delete() except: pass await message.answer(warning) return lang = data.get('lang') page = data.get('page') hint_n = data.get('hint_n') hint = data.get('hint') if lang == 'en': if hint_n == '1': await hint.update(hint1=hint_text).apply() elif hint_n == '2': await hint.update(hint2=hint_text).apply() elif hint_n == '3': await hint.update(hint3=hint_text).apply() elif hint_n == '4': await hint.update(hint4=hint_text).apply() else: if hint_n == '1': await hint.update(hint1_ru=hint_text).apply() elif hint_n == '2': await hint.update(hint2_ru=hint_text).apply() elif hint_n == '3': await hint.update(hint3_ru=hint_text).apply() elif hint_n == '4': await hint.update(hint4_ru=hint_text).apply() msg = _('Hint {n} {lang} was created!' '\nChoose another hint to edit or press finish button.').format( n=hint_n, lang=lang) try: await mess.delete() except: pass await message.answer(msg, reply_markup=await keyboards.admin_hints_kb(hint.date, page)) await state.reset_state()
async def anno_enter_ru(message: types.Message, state: FSMContext): anno_ru = message.text msg = _('anno_img') await message.answer(msg, reply_markup=await keyboards.anno_cancel(img=True)) await Announcement.EnterImg.set() await state.update_data(anno_ru=anno_ru)
async def anno_confirm(call: types.CallbackQuery, state: FSMContext): data = await state.get_data() img_id = data.get('img_id') anno_en = data.get('anno_en') anno_ru = data.get('anno_ru') await state.reset_state() await call.message.edit_reply_markup( reply_markup=await keyboards.admin_kb()) users = await db.get_all_users() for user in users: try: if user.language == 'en': if img_id is None: await bot.send_message(chat_id=user.user_id, text=anno_en) else: await bot.send_photo(chat_id=user.user_id, photo=img_id, caption=anno_en) else: if img_id is None: await bot.send_message(chat_id=user.user_id, text=anno_ru) else: await bot.send_photo(chat_id=user.user_id, photo=img_id, caption=anno_ru) await sleep(0.3) except Exception: pass await call.message.answer(_('Mailing finished.'))
async def edit_quest_solve(call: types.CallbackQuery, callback_data: dict, state: FSMContext): quest_date = datetime.datetime.strptime(callback_data['q_date'], '%Y-%m-%d %H:%M:%S') page = int(callback_data['page']) hint_n = int(callback_data['hint_n'][-1]) lang = callback_data['lang'] hint = await db.get_hints(quest_date) hint_text = None if lang == 'en': if hint_n == 1: await hint.update(hint1=hint_text).apply() elif hint_n == 2: await hint.update(hint2=hint_text).apply() elif hint_n == 3: await hint.update(hint3=hint_text).apply() elif hint_n == 4: await hint.update(hint4=hint_text).apply() else: if hint_n == 1: await hint.update(hint1_ru=hint_text).apply() elif hint_n == 2: await hint.update(hint2_ru=hint_text).apply() elif hint_n == 3: await hint.update(hint3_ru=hint_text).apply() elif hint_n == 4: await hint.update(hint4_ru=hint_text).apply() msg = _('Hint {n} was deleted!' '\nChoose another hint to edit or press finish button.').format( n=hint_n) await call.answer() await state.reset_state() await call.message.edit_text(msg) await call.message.edit_reply_markup( reply_markup=await keyboards.admin_hints_kb(quest_date, page))
async def anno(call: types.CallbackQuery, state: FSMContext): msg = _('anno_enter_en') await call.answer() await call.message.edit_text(msg) await call.message.edit_reply_markup( reply_markup=await keyboards.anno_cancel()) await Announcement.EnterAnno.set()
async def enter_price(call: types.CallbackQuery, state: FSMContext): await call.message.edit_reply_markup() data = await state.get_data() item: Item = data.get("item") await item.create() await call.message.answer(_("Товар удачно создан.")) await state.reset_state()
async def admin_add_news(call: types.CallbackQuery): await call.answer() await call.message.delete() await call.message.answer( _("Enter news date in format DD-MM-YYYY " "or type '-' to assign today's date, or press /cancel")) await AddNews.EnterDate.set()
async def enter_name(message: types.Message, state: FSMContext): name = message.text item = Item() item.name = name await message.answer(_("Введите описание услуги или введите /cancel")) await NewItem.Description.set() await state.update_data(item=item)
async def anno_cancel(call: types.CallbackQuery, state: FSMContext): msg = _('Admin panel.') await call.answer() await call.message.edit_text(msg) await call.message.edit_reply_markup( reply_markup=await keyboards.admin_kb()) await state.reset_state()
async def hints(call: types.CallbackQuery, callback_data: dict): quest_date = datetime.datetime.strptime(callback_data['quest'], '%Y-%m-%d %H:%M:%S') page = callback_data['data'] await call.answer() await call.message.edit_text(_('Choose hint:')) await call.message.edit_reply_markup( reply_markup=await keyboards.admin_hints_kb(quest_date, page))
async def new_app(call: types.CallbackQuery, callback_data: dict, state: FSMContext): platform = callback_data['platform'] await call.answer() await call.message.edit_text( _('Enter app url for {p} platform:').format(p=platform)) await AddApp.Confirm.set() await state.update_data(platform=platform)
async def confirm_edit_app(message: types.Message, state: FSMContext): url = message.text data = await state.get_data() app = data.get('app') await app.update(url=url).apply() await message.answer(_('Choose platform to edit:'), reply_markup=await keyboards.admin_app_kb()) await state.reset_state()
async def confirm_news(call: types.CallbackQuery, state: FSMContext): await call.message.delete() data = await state.get_data() news: News = data.get('news') await news.create() await call.message.answer(_('Admin menu.'), reply_markup=await keyboards.admin_news_menu()) await state.reset_state()
async def cmd_start(message: types.Message): msg = _(':wave: Welcome to the DCA quest bot.\n\n' ':rocket: DCA - Digital Crypto Art is a project dedicated to make interesting quests ' 'by testing your skills and knowledge. In our quests you can win big and small depending ' 'on the difficulty of the quests. The prize can be in any cryptocurrency.\n\n' ':information_source: Here you can find our latest news, as well as our latest quests.\n\n') await db.add_new_user() await message.answer(emojize(msg), reply_markup=await keyboards.main_kb())
async def change_language(call: CallbackQuery): await call.message.edit_reply_markup() # Достаем последние 2 символа (например ru) lang = call.data[-2:] await db.set_language(lang) # После того, как мы поменяли язык, в этой функции все еще указан старый, поэтому передаем locale=lang await call.message.answer(_("Ваш язык был изменен", locale=lang))
async def set_desc(message: types.Message,state:FSMContext): description = message.text data = await state.get_data() item: Item = data.get("item") item.description = description await message.answer(_("\nЗагрузите фотографию или введите /cancel")) await NewItem.Photo.set() await state.update_data(item=item)