def find_ayat_by_text(query_text: str, offset: int = None): """Найти аят по тексту. Функция находит аят и определяет страницу """ queryset = search_ayat(query_text) logger.debug(queryset) result = [] ayats_count = queryset.count() if ayats_count < 1: return Answer("Аятов не найдено") if offset is None: offset = 1 text = f"По вашему запросу найдено {ayats_count} {format_count_to_text((ayats_count))}:" result.append(Answer(text)) buttons = [( ("<", f"change_query_ayat('{query_text}',{offset - 1})"), (f"{offset}/{ayats_count}", "asdf"), (">", f"change_query_ayat('{query_text}',{offset + 1})"), )] keyboard = InlineKeyboard(buttons).keyboard ayat = queryset[offset - 1] text = ayat.get_content() result.append(Answer(text, keyboard)) return result
def text_message_service(chat_id: int, message_text: str, message_id: int = None) -> Answer: """Функция обрабатывает все текстовые сообщения""" if 'Подкасты' in message_text: logger.info(f"Subscriber={chat_id} getting random podcast") answer = get_podcast_in_answer_type() elif 'Избранное' in message_text: logger.info(f"Subscriber={chat_id} getting favourite ayats") answer = get_favourite_ayats(chat_id) elif 'Конкурс' in message_text: logger.info(f"Subscriber={chat_id} getting ...") answer = get_concourse_info(chat_id) elif ':' in message_text: logger.info(f"Subscriber={chat_id} search ayat query='{message_text}'") try: ayat = get_ayat_by_sura_ayat(message_text) answer = translate_ayat_into_answer(ayat) except AyatDoesNotExists: answer = Answer('Аят не найден') elif (regexp_result := re.search( r'/del\d+', message_text)) and chat_id in get_admins_list(): logger.warning( f"Subscriber={chat_id} try delete mailing ayat query='{message_text}'" ) mailing_pk = re.search(r'\d+', regexp_result.group(0)).group(0) delete_messages_in_mailing(mailing_pk) answer = Answer('Рассылка удалена')
def get_favourite_ayats(chat_id: int): subscriber = Subscriber.objects.get(tg_chat_id=chat_id) ayats = subscriber.favourite_ayats.all() if ayats.count(): text = '' for elem in ayats: text += f'{str(elem)}\n' return Answer(text) return Answer('Вы еще не добавили аятов в "Избранное"')
def _not_created_subscriber_service(subscriber: Subscriber) -> Answer: """Фунция вызывается если пользователь, который уже существует в базе был корректно обработан.""" if subscriber.is_active: return Answer("Вы уже зарегистрированы", chat_id=subscriber.tg_chat_id) _create_action(subscriber, SUBSCRIBER_ACTIONS[2][0]) subscriber.is_active = True subscriber.save(update_fields=["is_active"]) return Answer( f"Рады видеть вас снова, вы продолжите с дня {subscriber.day}", chat_id=subscriber.tg_chat_id)
def _created_subscriber_service(subscriber: Subscriber) -> List[Answer]: """Функция обрабатывает и генерирует ответ для нового подписчика.""" start_message_text = AdminMessage.objects.get(key="start").text day_content = MorningContent.objects.get(day=1).content_for_day() _create_action(subscriber, SUBSCRIBER_ACTIONS[0][0]) answers = [ Answer(start_message_text, chat_id=subscriber.tg_chat_id), Answer(day_content, chat_id=subscriber.tg_chat_id) ] + [ Answer("Зарегестрировался новый пользователь.", chat_id=admin) for admin in get_admins_list() ] return AnswersList(*answers)
def send_prayer_time(date: datetime = None) -> None: """Рассылаем время намаза с кнопками.""" # TODO написать тесты # TODO Переписать на сервисный объект # TODO одинаковы куски кода content.service.do_morning_content_distribution if date is None: date = (datetime.today() + timedelta(days=1)) mailing = Mailing.objects.create() try: for subscriber in Subscriber.objects.filter(city__isnull=False, is_active=True): prayer_times = get_prayer_time(subscriber.city, date) logger.debug(f"{prayer_times=}") text = get_text_prayer_times(prayer_times, subscriber.city.name, date) logger.debug(f"{text=}") keyboard = InlineKeyboard(get_buttons(subscriber, prayer_times.exclude(name="sunrise"))).keyboard message_instance = Answer(text, keyboard=keyboard).send(subscriber.tg_chat_id) message_instance.mailing = mailing message_instance.save(update_fields=["mailing"]) text = f"Рассылка #{mailing.pk} завершена" msg = send_message_to_admin(text) msg.mailing = mailing msg.save(update_fields=["mailing"]) except Exception as e: logger.error(f"Subscriber: {subscriber}, city: {subscriber.city}, dont send prayer time. Error message: {str(e)}")
def send_message_to_admin(message_text: str) -> Message: """Отправляем сообщение админу.""" answer = Answer(message_text) admins_tg_chat_ids = get_admins_list() for admin_tg_chat_id in admins_tg_chat_ids: message_instance = send_answer(answer, admin_tg_chat_id) return message_instance
def get_city_not_found_answer(text: str = None) -> Answer: """Генерирует ответ если подписчик с неустановленным городом пытается получить время намаза.""" if text is None: text = "Город не найден,\nвоспользуйтесь поиском" keyboard = InlineKeyboardMarkup() button = InlineKeyboardButton("Поиск города", switch_inline_query_current_chat="") keyboard.add(button) return Answer(text, keyboard=keyboard)
def get_unread_prayers(chat_id) -> Answer: """Возвращает кол-во непрочитанных намазов с клавиатурой.""" text = "Непрочитано\n\n" unread_prayers = get_unread_prayers_by_chat_id(chat_id) for i in [0, 2, 3, 4, 5]: prayer_name = PRAYER_NAMES[i][0] prayer_type_group = [prayer for prayer in unread_prayers if prayer.prayer.name == prayer_name] text += f"{PRAYER_NAMES[i][1]}: {len(prayer_type_group)}\n" return Answer(text, keyboard=get_keyboard_for_unread_prayers(chat_id))
def handle_query_service(text: str, chat_id: int = None, call_id: int = None, message_id: int = None, message_text: str = None): """Функция для обработки всех нажатий на инлайн кнопки""" if 'get_ayat' in text: answer = _get_ayat(text) return answer elif 'add_in_favourites' in text: text = _add_ayat_in_favourites(text, chat_id) tbot.answer_callback_query(call_id, show_alert=True, text=text) elif 'set_prayer_status_to_read' in text: keyboard = _change_prayer_status(chat_id, text, True) tbot.edit_message_text( text=message_text, chat_id=chat_id, message_id=message_id, reply_markup=keyboard, ) elif 'set_prayer_status_to_unread' in text: keyboard = _change_prayer_status(chat_id, text, False) tbot.edit_message_text( text=message_text, chat_id=chat_id, message_id=message_id, reply_markup=keyboard, ) elif 'unread_prayer_type_minus_one' in text: answer = _unread_prayer_type_minus_one(text) tbot.edit_message_text( text=answer.text, chat_id=chat_id, message_id=message_id, reply_markup=answer.keyboard, ) elif "change_query_ayat" in text: query_text, offset = eval(re.search(r'\(.+\)', text).group(0)) answer = find_ayat_by_text(query_text, offset)[0] tbot.edit_message_text( text=answer.text, reply_markup=answer.keyboard, message_id=message_id, chat_id=chat_id, parse_mode='HTML', ) elif "accept_with_conditions" in text: text = AdminMessage.objects.get(key="print_instructions").text Answer(text=text).send(chat_id) document_file_id = File.objects.get( name="PDF_ramadan_dairy").tg_file_id message = tbot.send_document(chat_id, document_file_id) save_message(message)
def get_prayer_time_or_no(chat_id: int) -> Answer: """Возвращает ответ с временами намазов или приглашением к поиску, если не установлен город.""" subscriber = get_subscriber_by_chat_id(chat_id) if subscriber.city is None: return get_city_not_found_answer( text="Вы не указали город, отправьте местоположение или воспользуйтесь поиском" ) today = datetime.now() prayers = get_prayer_time(subscriber.city, today) text = get_text_prayer_times(prayers, subscriber.city.name, today) keyboard = InlineKeyboard(get_buttons(subscriber, prayers)).keyboard return Answer(text, keyboard=keyboard)
def do_morning_content_distribution(): """Выполняем рассылку утреннего контента.""" # TODO можно заранее сгенерировать контент, Заранее оповещать админов, что контент кончается mailing = Mailing.objects.create() subscriber_content = get_subscribers_with_content() for elem in subscriber_content: chat_id, content = list(elem.items())[0] answer = Answer(content, keyboard=get_default_keyboard() ) # TODO впиши коммент про answers это же не ответ if message_instance := send_answer(answer, chat_id): message_instance.mailing = mailing message_instance.save(update_fields=["mailing"])
def get_audio_answer(audio: File) -> Answer: if (file_id := audio.tg_file_id) and not settings.DEBUG: # Если включен режим отладки, и это не основной бот, file_id работать не будут return Answer(tg_audio_id=file_id)
def send_conditions_for_getting_prise(chat_id: int) -> Answer: text = AdminMessage.objects.get(key="conditions").text buttons = ((("Принять условия", "accept_with_conditions"), ), ) keyboard = InlineKeyboard(buttons) return Answer(text=text, chat_id=chat_id, keyboard=keyboard.keyboard)
def answer_list(subscriber): return AnswersList( Answer(text="wow", chat_id=subscriber.tg_chat_id), Answer(text="wow2", chat_id=subscriber.tg_chat_id), Answer(text="wow3", chat_id=subscriber.tg_chat_id), )
def get_concourse_info(chat_id: int) -> Answer: text = AdminMessage.objects.get(key="concourse").text subscriber = get_subscriber_by_chat_id(chat_id) text += f"\n\nКол-во пользователей зарегистрировавшихся по вашей ссылке: {get_referals_count(subscriber)}" text += f"\n\n{get_referal_link(subscriber)}" return Answer(text=text)
def translate_ayat_into_answer(ayat: Ayat) -> List[Answer]: text = f'<a href="https://umma.ru{ayat.sura.link}">({ayat.sura.number}:{ayat.ayat})</a>\n{ayat.arab_text}\n\n{ayat.content}\n\n<i>{ayat.trans}</i>\n\n' return [ Answer(text=text, keyboard=get_keyboard_for_ayat(ayat)), get_audio_answer(ayat.audio) ]
def answer_without_chat_id(): return Answer(text="wow")
def send_message_to_winners(subscribers_queryset: QuerySet): text = AdminMessage.objects.get(key="concourse_winner_message").text for s in subscribers_queryset: Answer(text=text).send(s.tg_chat_id)
def set_city_to_subscriber(city: City, chat_id: int) -> Answer: """Присваивает город подписчику по инстансу города и идентификатору чата с пользователем.""" subscriber = get_subscriber_by_chat_id(chat_id) subscriber.city = city subscriber.save(update_fields=["city"]) return Answer(f"Вам будет приходить время намаза для г. {city.name}")
def get_referal_answer(chat_id: int) -> Answer: subscriber = get_subscriber_by_chat_id(chat_id) referal_link = get_referal_link(subscriber) referals_count = get_referals_count(subscriber) text = f"Кол-во пользователей зарегистрировавшихся по вашей ссылке: {referals_count}\n\n{referal_link}" return Answer(text=text)
def generate_message_for_referer(self) -> Answer: logger.debug(f"Send message to referer {self.referer.tg_chat_id=}") message = "По вашей реферальной ссылке произошла регистрация" return Answer(text=message, chat_id=self.referer.tg_chat_id)
tbot = get_tbot_instance() def send_conditions_for_getting_prise(chat_id: int) -> Answer: text = AdminMessage.objects.get(key="conditions").text buttons = ((("Принять условия", "accept_with_conditions"), ), ) keyboard = InlineKeyboard(buttons) return Answer(text=text, chat_id=chat_id, keyboard=keyboard.keyboard) def get_audio_answer(audio: File) -> Answer: if (file_id := audio.tg_file_id) and not settings.DEBUG: # Если включен режим отладки, и это не основной бот, file_id работать не будут return Answer(tg_audio_id=file_id) return Answer(audio.link_to_file) def get_podcast_in_answer_type() -> Answer: """Получаем подкаст и упаковываем его для отправки пользователю""" podcast = get_random_podcast() answer = get_audio_answer(podcast.audio) return answer def get_ayat_by_sura_ayat(text: str) -> Ayat: """ Функция возвращает аят по номеру суры и аята Например: пользователь присылает 2:3, по базе ищется данный аят и возвращает 2:1-5 """ sura_num, ayat_num = [int(x) for x in text.split(':')]
def answer(subscriber): return Answer(text="wow", chat_id=subscriber.tg_chat_id)