def setUp(self): self.reserves = [] self.strings = RuReserve self.chat = Chat() self.chat.id = 101 self.user = User() self.user.first_name = "Firstname" self.user.id = 111 dp = Dispatcher() self.data_adapter = MemoryDataAdapter() self.state_manager = StateManager(self.data_adapter) self.processor = ReserveProcessor(dp, self.state_manager, self.strings) message = Message() message.chat = self.chat message.from_user = self.user message.message_id = 121 message.text = "Some text" message.answer = self.answer_mock message.delete = self.delete_mock message.edit_text = self.edit_text_mock self.test_message = message callback = CallbackQuery() callback.bot = Bot() callback.answer = self.callback_answer_mock callback.message = message callback.from_user = User() callback.from_user.id = 101 self.test_callback_query = callback
async def bot_start(message: Message): await message.answer(_('Привіт') + f', {User.get_current().first_name}!', reply_markup=main_menu) db.insert_or_ignore( 'users', { 'id': User.get_current().id, 'first_name': User.get_current().first_name, 'last_name': User.get_current().last_name, 'lang': User.get_current().locale.language }) await message.answer(_('Виберіть мову'), reply_markup=choose_language) await message.answer(_('Натисніть /help, щоб отримати список команд'))
async def change_language(call: CallbackQuery): await call.message.edit_reply_markup() lang = call.data[-2:] db.update('users', User.get_current().id, { 'lang': lang }) # await call.message.edit_text(_("Мова була змінена", locale=lang)) full_lang = { 'uk': 'українська', 'ru': 'русский', 'en': 'English' } await call.message.answer(_("Мова була змінена", locale=lang), reply_markup=ReplyKeyboardRemove()) await call.message.answer(_('Ваша поточна мова', locale=lang) + f': {full_lang[lang]}', reply_markup=get_main_menu(db.get_lang(User.get_current().id)))
def bg(self, user_id: Optional[int] = None, chat_id: Optional[int] = None) -> BgManagerProto: if self.disabled: raise IncorrectBackgroundError("Please call `manager.bg()` " "before starting background task") self.check_disabled() if user_id is not None: user = User(id=user_id) else: user = self.event.from_user if chat_id is not None: chat = Chat(id=chat_id) else: chat = get_chat(self.event) return BgManager( user, chat, self.event.bot, self.registry, self.current_intent(), self.context.state, )
def __init__(self) -> None: headers = { "Authorization": f"Token {settings.API_TOKEN}", "Accept-Language": User.get_current().locale.language, } self._session = aiohttp.ClientSession(headers=headers) self._api_base = furl(settings.API_BASE_URL)
async def check(self, obj: Union[Message, CallbackQuery]): if getattr(obj, "reply_to_message"): logger.info(obj.reply_to_message.from_user.id) if Chat.get_current().id == User.get_current().id: return True return False
async def add_bug_location(msg: types.Message, state: FSMContext): data = await state.get_data() await data.get('message').delete_reply_markup() default_status = await BugStatus.select('id').where( BugStatus.status == 'pending').gino.scalar() photo = data.get('photo') bug = await Bug.create(photo_path=photo.file_id, description=data.get('description'), location=msg.text, status=default_status, user=TgUser.get_current()) photo_path = os.path.join(UPLOAD_DIR, f'bugs/{bug.id}.jpg') await photo.download(photo_path) await bug.update(photo_path=f'bugs/{bug.id}.jpg').apply() await bot.send_photo(ADMIN_CHAT_ID, photo.file_id, caption=f'Баг №{bug.id}\n' f'Місцезнаходження: <i>{msg.text}</i>\n' f'Опис: "<i>{data.get("description")}</i>"', reply_markup=get_admin_decision_kb(bug.id)) await state.finish() await msg.answer( f'Баг № {bug.id} було надіслано адмінам. ' f'Найближчим часом інформацію перевірять, та сповістять вас\n\n' f'Дякуємо за повідомлення 😊')
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)
async def table_handler(call: CallbackQuery): await call.message.edit_reply_markup() task = call.data.split('_')[-1] lang = db.get_lang(User.get_current().id) with open(rf'C:\mpr\football-bot\data\tables\{task}_{lang}.jpg', 'rb') as table_photo: await call.message.answer_photo(table_photo)
def bg( self, user_id: Optional[int] = None, chat_id: Optional[int] = None, stack_id: Optional[str] = None, ) -> "BaseDialogManager": if user_id is not None: user = User(id=user_id) else: user = self.user if chat_id is not None: chat = Chat(id=chat_id) else: chat = self.chat same_chat = (user.id == self.user.id and chat.id == self.chat.id) if stack_id is None: if same_chat: stack_id = self.stack_id intent_id = self.intent_id else: stack_id = DEFAULT_STACK_ID intent_id = None else: intent_id = None return BgManager( user=user, chat=chat, bot=self.bot, registry=self.registry, intent_id=intent_id, stack_id=stack_id, )
async def full_card_number_sent(call: types.CallbackQuery, offer: EscrowOffer): """Confirm that full card number is sent and ask for first and last 4 digits.""" await offer.update_document( {"$set": { "pending_input_from": call.from_user.id }}) await call.answer() if call.from_user.id == offer.init["id"]: counter = offer.counter await tg.send_message( counter["id"], i18n("ask_address {currency}").format(currency=offer.buy)) await tg.send_message( call.message.chat.id, i18n("exchange_continued {user}").format( user=markdown.link(counter["mention"], User(id=counter["id"]).url)), parse_mode=ParseMode.MARKDOWN, ) await offer.update_document( {"$set": { "pending_input_from": counter["id"] }}) counter_state = FSMContext(dp.storage, counter["id"], counter["id"]) await counter_state.set_state(states.Escrow.receive_address.state) await states.Escrow.receive_card_number.set() else: await tg.send_message( call.message.chat.id, i18n("send_first_and_last_4_digits_of_card_number {currency}"). format(currency=offer.sell if offer.type == "buy" else offer.buy), ) await states.Escrow.receive_card_number.set()
async def redirect_to_request_language(): user_id = User.get_current().id kb = menus.get_lang_menu() resp = messages.request_language.value if resp == 'request language': resp = 'Select your language:' await bot.send_message(user_id, resp, reply_markup=kb)
async def test_replies_with_correct_user_mention(self, bot, odesli_api): """Send a reply with correct user mention for a user without username. """ message = make_mock_message( text='check this one: https://www.deezer.com/track/1') message.from_user = User( id=1, is_bot=False, first_name='test_first_name', last_name='test_last_name', username=None, language_code='ru', ) reply_text = ( '<b><a href="tg://user?id=1">test_first_name test_last_name</a> ' 'wrote:</b> check this one: [1]\n' '\n' '1. Test Artist 1 - Test Title 1\n' '<a href="https://www.test.com/d">Deezer</a> | ' '<a href="https://www.test.com/g">Google Music</a> | ' '<a href="https://www.test.com/sc">SoundCloud</a> | ' '<a href="https://www.test.com/yn">Yandex Music</a> | ' '<a href="https://www.test.com/s">Spotify</a> | ' '<a href="https://www.test.com/ym">YouTube Music</a> | ' '<a href="https://www.test.com/y">YouTube</a> | ' '<a href="https://www.test.com/am">Apple Music</a> | ' '<a href="https://www.test.com/t">Tidal</a>') await bot.dispatcher.message_handlers.notify(message) assert message.reply.called_with_text == reply_text
async def prepare_words_data(set_id: int, photo_ids: list, crop_range: list) -> list: words_data = [] user_id = User.get_current().id for photo_id in photo_ids: img_file = BytesIO() await (await bot.get_file(photo_id)).download(destination=img_file) word_img, transl_img = await get_separated_imgs(img_file, *crop_range) logging.info(f" --- {word_img} --- {transl_img} ---") # If some img from the range smaller than the crop size if not word_img: return None word_img_msg = await bot.send_photo(user_id, word_img) word_img_id = word_img_msg.photo[-1].file_id await word_img_msg.delete() transl_img_msg = await bot.send_photo(user_id, transl_img) transl_img_id = transl_img_msg.photo[-1].file_id await transl_img_msg.delete() words_data.append( dict(set_id=set_id, base_img_id=photo_id, word_img_id=word_img_id, transl_img_id=transl_img_id)) return words_data
def bg( self, user_id: Optional[int] = None, chat_id: Optional[int] = None, stack_id: Optional[str] = None, ) -> "BaseDialogManager": if user_id is not None: user = User(id=user_id) else: user = self.event.from_user if chat_id is not None: chat = Chat(id=chat_id) else: chat = get_chat(self.event) same_chat = (user.id == self.event.from_user.id and chat.id == get_chat(self.event).id) intent_id = None if stack_id is None: if same_chat: stack_id = self.current_stack().id if self.current_context(): intent_id = self.current_context().id else: stack_id = DEFAULT_STACK_ID return BgManager( user=user, chat=chat, bot=self.event.bot, registry=self.registry, intent_id=intent_id, stack_id=stack_id, )
async def on_err_unknown_exception(_, e: Exception): if isinstance(e, BotError): return True await bot.send_message(User.get_current().id, texts.unknown_exception) logger.exception(e) sentry_sdk.capture_exception(e) return True
async def register_user(user: types.User, join_time: float) -> None: data = Users.get_user(user.id) if not data: with Controller.conn as conn: c = conn.cursor() sql = 'INSERT INTO `users` (user_id, username, join_time) VALUES (?, ?, ?)' c.execute(sql, (user.id, user.get_mention(), join_time)) conn.commit()
async def get_user(user_id: int) -> User: user = await db_engine.find(User, User.id == user_id) if not user: tg_user = TelegramUser.get_current() await check_user(tg_user.id, tg_user.first_name, tg_user.last_name, tg_user.username, tg_user.language_code) return await get_user(user_id) return user[0]
async def add_new_user(self): full_info = User.get_current() user_info = f"id: {full_info.id}, username: {full_info.username}, first_name: {full_info.first_name}, last_name: {full_info.last_name}" command = self.ADD_NEW_USER id_user = await self.pool.fetchval(command, user_info) return id_user
def get_keyboard(self, chat_id: Optional[int] = None): if chat_id is None: chat_id = User.get_current().id if not self.is_inited(chat_id): raise NotInitedException('inline_calendar is not inited properly') user_info = self._get_user_info(chat_id) kb = types.InlineKeyboardMarkup() kb.row(*self._create_header( chat_id)) # create header with month name and year aka "Aug 2019" kb.row(*self._create_weekdays_buttons( chat_id)) # create buttons with week days f_row = [] mrange = monthrange(user_info.current_date.year, user_info.current_date.month) for i in range(mrange[0]): # adding the days which were passed f_row.append( types.InlineKeyboardButton( text=' ', callback_data=InlineCalendar.CALLBACK_WRONG_CHOICE)) rows = [f_row] for i in range(1, mrange[1] + 1): # adding active days curr_date = datetime.date(day=i, month=user_info.current_date.month, year=user_info.current_date.year) if curr_date.weekday() == 0: rows.append([]) if curr_date < user_info.min_date: rows[-1].append( types.InlineKeyboardButton( text=' ', callback_data=InlineCalendar.CALLBACK_WRONG_CHOICE)) else: rows[-1].append( types.InlineKeyboardButton( text=str(i), callback_data=InlineCalendar.BASE_CALLBACK.new( action=Actions.PICK_DAY.name, data=str(i)))) curr_date = datetime.date(day=mrange[1], month=user_info.current_date.month, year=user_info.current_date.year) for i in range(curr_date.weekday() + 1, 7): # adding inactive days rows[-1].append( types.InlineKeyboardButton( text=' ', callback_data=InlineCalendar.CALLBACK_WRONG_CHOICE)) for r in rows: kb.row(*r) kb.row(*self._create_bottom(chat_id)) # adding buttons for pagination return kb
async def bot_start(msg: types.Message): user = User.get_current() await db.add_user(id=user.id, username=user.username, full_name=user.full_name) await redis_commands.set_new_user(user_id=user.id) scheduler.add_job(greeting, args=(msg, ))
def get_aiogram_user_by_pyrogram(user: pyrogram.types.User) -> User: return User( id=user.id, is_bot=user.is_bot, first_name=user.first_name, last_name=user.last_name, username=user.username, language_code=user.language_code, )
def message(self, rand_user): c = TelegramChat() c.title = 'UnitTesting' u = TelegramUser() u.id = rand_user.id u.first_name = rand_user.first_name class _Message: def __init__(self, user, chat): self.from_user = user self.chat = chat @staticmethod async def reply(text): print(text) await asyncio.sleep(0) yield _Message(u, c)
async def get_user_locale(self, action, args) -> str: user = User.get_current() db = dp.get_current()['db'] try: # пробуем достать локаль из базы return await db.get_user_locale(user.id) except LocaleNotFound: # возвращаем локаль, которую вернул телеграм if user.locale: return user.locale.language return 'ru'
async def get_or_set_omer_flag( omer_flag: Optional[bool] = None, zmanim: Optional[ Any] = None # todo circullar import problem, refactor needed ) -> Optional[bool]: user = User.get_current() if omer_flag: omer_time = zmanim and zmanim.tzeis_8_5_degrees.isoformat() return await set_omer_flag(user, omer_flag, omer_time) return await get_omer_flag(user)
def make_mock_message( text: str, chat_type: ChatType = ChatType.GROUP, raise_on_delete: bool = False, inline: bool = False, is_reply: bool = False, ) -> mock.Mock: """Make a mock message with given text. :param text: text of the message :param chat_type: chat type. See `aiogram.types.ChatType` enum :param raise_on_delete: raise exception on message delete :param inline: message is an inline query :param is_reply: message is a reply :return: mock message """ spec = InlineQuery if inline else Message message = mock.Mock(spec=spec) message.content_type = ContentType.TEXT if inline: message.query = text message.message_id = 'id' else: message.text = text message.from_user = User( id=1, is_bot=False, first_name=None, last_name='TestLastName', username='******', language_code='ru', ) message.chat = mock.Mock(spec=Chat) message.chat.type = chat_type types.User.set_current(message.from_user) types.Chat.set_current(message.chat) async def reply_mock_fn(text, parse_mode, reply=True): """Reply mock.""" assert parse_mode == 'HTML' assert reply == is_reply # Save text argument for assertion reply_mock.called_with_text = text reply_mock = mock.Mock(side_effect=reply_mock_fn) message.reply = reply_mock async def delete_mock_fn(): """Delete mock.""" if raise_on_delete: raise MessageCantBeDeleted(message='Test exception') delete_mock = mock.Mock(side_effect=delete_mock_fn) message.delete = delete_mock return message
async def wrapper(*args, **kwargs): spec = inspect.getfullargspec(func) kwargs = {k: v for k, v in kwargs.items() if k in spec.args} user = User.get_current() msg = Message.get_current() attach_message_text and params.update({'text': msg.text}) posthog.capture(user.id, action, params, message_id=msg.message_id) return await func(*args, **kwargs)
async def update_donor_status(self, user: types.User) -> None: # When you can't use async functions in __init__ if not await has_star(user.id): return if user.username: self.name = f"<a href='https://t.me/{user.username}'>{quote_html(user.full_name)} \u2b50\ufe0f</a>" else: self.name = f"<b>{quote_html(user.full_name)} \u2b50\ufe0f</b>" self.mention = user.get_mention(name=user.full_name + " \u2b50\ufe0f", as_html=True)
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
async def assists_handler(call: CallbackQuery): await call.message.edit_reply_markup() task = call.data.split('_')[-1] lang = db.get_lang(User.get_current().id) if task == 'upl' and lang == 'en': await call.message.answer( 'Assistants for this league has not been given') else: with open(rf'C:\mpr\football-bot\data\assists\{task}_{lang}.jpg', 'rb') as table_photo: await call.message.answer_photo(table_photo)