def _show_form(update: Update, context: CallbackContext): chat_data = ChatData.from_context(context) user_data = UserData.from_context(context) chat_data.send_form(user_data, callback_data=str(REMOVE)) update.callback_query.answer() return SELECT_ACTION
def _delete_answer(update: Update, context: CallbackContext): user_data = UserData.from_context(context) question = user_data.questions[user_data.current_question] try: del user_data.answers[question] except MissingDataError: pass return _ask_question(update, context)
def _start(update: Update, context: CallbackContext) -> None: logger.debug(f'{update.message.text}') try: UserData.from_context(context) except MissingDataError: UserData(update.message.chat).update_context(context) ChatData(update.message.chat).update_context(context) logger.debug(f'Created new user data: {update.message.chat.id}') update.message.reply_text(text=HELP, parse_mode=ParseMode.MARKDOWN_V2) try: bot_data = BotData.from_context(context) bot_data.owner = (context.args[0], update.message.chat.id) except (IndexError, MissingDataError): pass return _select_level(update, context)
def _withdraw_form(update: Update, context: CallbackContext): user_data = UserData.from_context(context) bot_data = BotData.from_context(context) # Anyway change form status user_data.status = FormStatus.BLOCKING bot_data.pending_forms.remove(user_data.id) update.callback_query.answer('Отправка анкеты отменена.') return _manage_form(update, context)
def __call__(self, parser, namespace, values, option_string = None): bot_data = BotData.from_context(self._context) bot = Dispatcher.get_instance().bot text = [] for var_id in bot_data.pending_forms: user_data = UserData.by_id(var_id) text.append(f'{var_id} ({user_data.mention()})') text = 'Список анкет: ' + ', '.join(text) bot.sendMessage(self._update.effective_chat.id, text)
def _shift_question(update: Update, context: CallbackContext): user_data = UserData.from_context(context) if update.callback_query.data == str(NEXT_QUESTION): user_data.current_question += 1 elif update.callback_query.data == str(PREV_QUESTION): user_data.current_question -= 1 else: logger.error('Incorrect state! IT SHOULD NEVER HAPPEN!') raise ValueError(f'Incorrect converstation state: {update.callback_query.data}') return _ask_question(update, context)
def __call__(self, parser, namespace, values, option_string = None): user_data = UserData.by_id(int(vars(namespace)['id'][0])) bot_data = BotData.from_context(self._context) logger.debug('Trying to reject form..') user_data.status = FormStatus.RETURNED bot_data.pending_forms.remove(user_data.id) user_data.note = ' '.join(values) new_conv_status(user_data.id) logger.info(f'Form was rejected: {str(user_data)}')
def _show_media(update: Update, context: CallbackContext): user_data = UserData.from_context(context) chat_data = ChatData.from_context(context) question = user_data.questions[user_data.current_question] try: chat_data.send_media(user_data, question.question_type) except NoMediaError: pass update.callback_query.answer() return ASK_QUESTION
def _state(func, back = None, *args, **kwargs): # pylint: disable=W1113 chat_data = ChatData.from_context(args[1]) user_data = UserData.from_context(args[1]) if back: user_data.back = back chat_data.clear_error() chat_data.delete_form(chat_data.id) if args[0].callback_query: args[0].callback_query.answer() return func(*args, *kwargs)
def _delete_form(update: Update, context: CallbackContext): bot_data = BotData.from_context(context) user_data = UserData.from_context(context) try: user_data.status = FormStatus.BLOCKING channel = ChatData.by_id(bot_data.dating_channel) except MissingDataError: pass else: channel.delete_form(user_data.id) logger.info(f'Form has been deleted: {str(user_data)}') update.callback_query.answer('Анкета успешно удалена.') return _manage_form(update, context)
def send_form(self, data: UserData, callback_data: str = None) -> None: """Send form to chat.""" msgs = [] for text_item in data.print_body(): msgs.append( self._bot.sendMessage(self._id, text=text_item, parse_mode='MarkdownV2')) reply_id = msgs[0].message_id for media_type in (QuestionType.PHOTO, QuestionType.AUDIO): try: media = self._send_media(data, media_type, reply_id=reply_id) msgs.extend(media) except NoMediaError: pass self.__forms = (data.id, msgs) if callback_data: self._show_button(data.id, callback_data)
def __call__(self, parser, namespace, values, option_string = None): user_data = UserData.by_id(int(values[0])) bot_data = BotData.from_context(self._context) bot = Dispatcher.get_instance().bot if not bot_data.dating_channel: raise CommandError('Не указан канал для публикации!') logger.debug('Trying to post form..') try: channel = ChatData.by_id(bot_data.dating_channel) except MissingDataError: channel = ChatData(bot.getChat(bot_data.dating_channel)) finally: channel.send_form(user_data) bot_data.pending_forms.remove(user_data.id) user_data.status = FormStatus.PUBLISHED new_conv_status(user_data.id) logger.info(f'Form was posted: {str(user_data)}')
def _ask_question(update: Update, context: CallbackContext) -> None: user_data = UserData.from_context(context) chat_data = ChatData.from_context(context) question = user_data.questions[user_data.current_question] show: bool = False remove: bool = False try: answer = user_data.answers[question].value except MissingDataError as exc: if question.question_type in (QuestionType.TEXT, QuestionType.DIGITS): answer = 'Не отвечено' elif question.question_type == QuestionType.AUDIO: answer = 'Нет саундтрека' elif question.question_type == QuestionType.PHOTO: answer = 'Нет фото' else: raise AssertionError from exc else: if question.question_type in (QuestionType.TEXT, QuestionType.DIGITS): pass elif question.question_type == QuestionType.AUDIO: if answer[0]: show = True answer = 'Добавлено аудио' else: answer = answer[1] elif question.question_type == QuestionType.PHOTO: show = True answer = f'Добавлено {len(answer)} фото' else: raise AssertionError remove = True chat_data.print_messages( {'text': _format_question_text(question), 'parse_mode': 'MarkdownV2'}, {'text': answer, 'reply_markup': _question_keyboard(show, remove)} ) return ASK_QUESTION
def _send_form(update: Update, context: CallbackContext): user_data = UserData.from_context(context) bot_data = BotData.from_context(context) bot = Dispatcher.get_instance().bot # Send message to all admins chats (chats have negative ID) for chat in [c for c in bot_data.admins if c < 0]: text = utils.helpers.escape_markdown( f'Новая анкета: {user_data.id} \({user_data.mention()}\)' ) keyboard = InlineKeyboardMarkup.from_button(InlineKeyboardButton( text='Показать', callback_data=f'{str(SHOW)}{user_data.id}' )) bot.sendMessage(chat, text=text, reply_markup=keyboard, parse_mode='MarkdownV2') # Update form status bot_data.pending_forms.append(user_data.id) user_data.status = FormStatus.PENDING logger.info('New form has been sent: {str(user_data)}') update.callback_query.answer('Анкета успешно отправлена!') return _manage_form(update, context)
def __call__(self, parser, namespace, values, option_string = None): bot_data = BotData.from_context(self._context) # Try to add admin by reply (seems to be the easiest way to get user ID) if self._update.message.reply_to_message: reply = self._update.message.reply_to_message bot_data.admins.append(reply.from_user.id) return elif not values: raise CommandError('Укажите ID пльзователя или сделайте реплай на его сообщение.') try: var_id = int(values) except TypeError: try: var_id = UserData.by_username(values) except MissingDataError as exc: raise CommandError('Этот username мне не знаком. :(') from exc try: bot_data.admins.append(var_id) except IncorrectIdError as exc: raise CommandError(f'Некорректный ID: {var_id}') from exc
def _proc_answer(update: Update, context: CallbackContext): user_data = UserData.from_context(context) chat_data = ChatData.from_context(context) question = user_data.questions[user_data.current_question] if question.question_type == QuestionType.PHOTO: queue = context.dispatcher.update_queue updates = [update] for _ in range(queue.qsize()): updates.append(queue.get()) data = [update.message for update in updates] else: data = update.message try: user_data.answers = (question.tag, data) user_data.current_question += 1 return _ask_question(update, context) except AnswerError as exc: chat_data.print_error(str(exc)) return ASK_QUESTION
def __call__(self, parser, namespace, values, option_string = None): bot_data = BotData.from_context(self._context) text = [list(), list()] for admin in bot_data.admins: try: if admin > 0: data = UserData.by_id(admin) else: data = ChatData.by_id(admin) except MissingDataError: logger.warning(f'Unknown ID: {admin}') bot_data.admins.remove(admin) continue item = f'{admin} ({data.mention()})' if admin > 0: text[0].append(item) else: text[1].append(item) text[0] = 'Список админов: ' + ', '.join(text[0]) text[1] = 'Список админских чатов: ' + ', '.join(text[1]) bot_data._bot.send_message(self._update.effective_chat.id, '\n'.join(text))
def _manage_form(update: Update, context: CallbackContext): user_data = UserData.from_context(context) chat_data = ChatData.from_context(context) answer_button = InlineKeyboardButton(text='Ответить на вопросы', callback_data=str(ASK_QUESTION)) show_form_button = InlineKeyboardButton(text='Показать анкету', callback_data=str(SHOW_FORM)) buttons = [[], [], []] text = str() status = user_data.status if status == FormStatus.BLOCKING: buttons[0].append( answer_button ) text = ( 'Заполни анкету для отправки.' ) elif status == FormStatus.IDLE: buttons[0].extend( (answer_button, show_form_button) ) buttons[1].append( InlineKeyboardButton(text='Отправить анкету', callback_data=str(SEND_FORM)) ) text = ( 'Анкета заполнена и готова к отправке на ревью админами.' ) elif status == FormStatus.PENDING: buttons[0].append( show_form_button ) buttons[1].append( InlineKeyboardButton(text='Отозвать анкету', callback_data=str(WITHDRAW_FORM)) ) text = ( 'Анкета отправлена и ожидает ревью. Если хочешь внести правки -- ' 'сначала отзови анкету назад.' ) elif status == FormStatus.PUBLISHED: buttons[1].append( InlineKeyboardButton(text='Удалить анкету', callback_data=str(DELETE_FORM)) ) text = ( 'Анкета успешно опубликована! Поздравляю. В любой момент ты можешь ' 'удалить её из канала.' ) elif status == FormStatus.RETURNED: buttons[0].extend( (answer_button, show_form_button) ) buttons[1].append( InlineKeyboardButton(text='Отправить анкету', callback_data=str(SEND_FORM)) ) text = ( 'К сожалению, твоя анкета не прошла ревью админами. Ознакомься ' 'с замечаниями и попробуй ещё раз.' ) buttons[2].append( InlineKeyboardButton(text='Назад', callback_data=str(BACK)) ) keyboard = InlineKeyboardMarkup(buttons) logger.debug(f'{text}, {keyboard}') chat_data.print_messages( {'text': text}, {'text': user_data.print_status(), 'reply_markup': keyboard} ) return SELECT_ACTION
def __call__(self, parser, namespace, values, option_string = None): user_data = UserData.by_id(int(vars(namespace)['id'][0])) bot = Dispatcher.get_instance().bot bot.send_message(self._update.effective_chat.id, \ f"Edit {user_data.mention()}: {' '.join(values)}")
def _back(update: Update, context: CallbackContext) -> None: user_data = UserData.from_context(context) if user_data.back: logger.debug(f'returning back: {user_data.back}') return user_data.back(update, context) return _select_level(update, context)
def __call__(self, parser, namespace, values, option_string = None): user_data = UserData.by_id(int(values[0])) chat_data = ChatData.from_context(self._context) chat_data.send_form(user_data, callback_data=f'{str(REMOVE)}{user_data.id}')