def user_message_handler(self, client: 'pyrogram.Client', message: 'pyrogram.types.Message'):
        direction = '=>' if message.outgoing else '<='
        logger.debug(f"user_message_handler: {direction} {message.chat.title or message.chat.first_name}")

        # todo: temp solution
        from .temp import func
        func(client, self.telegram_client, message, logger, self.task_queues)
예제 #2
0
    def start_bot_handler(self, client: 'pyrogram.Client',
                          message: 'pyrogram.types.Message'):
        logger.debug(f"start_bot_handler: {message.command}")

        db_from_user = self.db.get_or_create_user(message.from_user)

        self.say_welcome(client, db_from_user, message)

        if db_from_user.chosen_language_code is None:
            self.choose_language(client, db_from_user)
 def deleted_messages_handler(self, client: 'pyrogram.Client',
                              messages: List['pyrogram.types.Message']):
     logger.debug(f"user_deleted_messages_handler: {messages}")
     estimate_date_of_deletion = arrow.utcnow().timestamp()
     for message in messages:
         if message.chat is None:
             # deleted message is from `saved messages`
             message_id = message.id
         else:
             # deleted message if from other chats
             message_id = message.id
             chat_id: int = message.chat.id
             chat_type: str = message.chat.type.name
예제 #4
0
    def base_commands_handler(self, client: 'pyrogram.Client',
                              message: 'pyrogram.types.Message'):
        logger.debug(f"base_commands_handler: {message.command}")

        db_from_user = self.db.get_or_create_user(message.from_user)

        command = message.command[0]
        if not command or command is None:
            return

        if command == 'lang':
            self.choose_language(client, db_from_user)
        elif command == 'help':
            self.show_help(client, db_from_user, message)
        elif command == 'home':
            self.show_home(client, db_from_user, message)
        else:
            pass
예제 #5
0
    def on_callback_query(self, client: 'pyrogram.Client', callback_query: 'pyrogram.types.CallbackQuery'):
        logger.debug(f"on_callback_query: {callback_query}")
        # callback_query.edit_message_caption(str(arrow.utcnow()),reply_markup=callback_query.message.reply_markup)
        db_user = self.db.get_user_by_user_id(callback_query.from_user.id)

        controller, data = callback_query.data.split('->')
        button = InlineButton.get_button(controller)

        if button:
            button.on_callback_query(
                client,
                callback_query,
                self,
                self.db,
                self.telegram_client,
                db_user,
            )
        else:
            callback_query.answer("", show_alert=False)
    def on_chosen_inline_query(
            self, client: 'pyrogram.Client',
            chosen_inline_result: 'pyrogram.types.ChosenInlineResult'):
        logger.debug(f"on_chosen_inline_query: {chosen_inline_result}")

        # todo: fix this
        db_from_user = self.db.get_user_by_user_id(
            chosen_inline_result.from_user.id)
        if not db_from_user:
            # update the user
            db_from_user = self.db.update_or_create_user(
                chosen_inline_result.from_user)

        reg = re.search(
            "^#(?P<command>[a-zA-Z0-9_]+)(\s(?P<arg1>[a-zA-Z0-9_]+))?",
            chosen_inline_result.query)
        if reg:
            # it's a custom command
            # todo: handle downloads from commands like `#download_history` in non-private chats
            logger.info(chosen_inline_result)

            button = InlineButton.get_button(reg.group("command"))
            if button:
                button.on_chosen_inline_query(
                    client,
                    chosen_inline_result,
                    self,
                    self.db,
                    self.telegram_client,
                    db_from_user,
                    reg,
                )

        else:
            inline_query_id, audio_key = chosen_inline_result.result_id.split(
                "->")

            db_download = self.db.get_or_create_download_from_chosen_inline_query(
                chosen_inline_result, self.telegram_client.telegram_id)
예제 #7
0
    def custom_commands_handler(self, client: 'pyrogram.Client', inline_query: 'pyrogram.types.InlineQuery'):
        logger.debug(f"custom_commands_handler: {inline_query}")
        query_date = get_timestamp()

        # todo: fix this
        db_from_user = self.db.get_user_by_user_id(inline_query.from_user.id)
        if not db_from_user:
            # update the user
            db_from_user = self.db.update_or_create_user(inline_query.from_user)

        reg = re.search("^#(?P<command>[a-zA-Z0-9_]+)(\s(?P<arg1>[a-zA-Z0-9_]+))?", inline_query.query)
        button = InlineButton.get_button(reg.group("command"))
        if button:
            button.on_inline_query(
                client,
                inline_query,
                self,
                self.db,
                self.telegram_client,
                db_from_user,
                reg,
            )
        else:
            pass
 def raw_update_handler(self, client: 'pyrogram.Client',
                        raw_update: '_update',
                        users: List['pyrogram.types.User'],
                        chats: List['pyrogram.types.Chat']):
     logger.debug(f"user_raw_update_handler: {raw_update}")
예제 #9
0
    def downloads_handler(self, client: 'pyrogram.Client',
                          message: 'pyrogram.types.Message'):
        """
        Check if the message is coming from a Telegram client and contains "dl_" regex, and then submit
        a thread to retrieve the searched audio file
        :param client: Telegram Client
        :param message: Telegram message object
        :return:
        """
        logger.debug(f"base_downloads_handler: {message.text}")

        # todo: find a better way to update user when it's necessary
        db_user = self.db.get_user_by_user_id(message.from_user.id)
        if not db_user:
            db_user = self.db.update_or_create_user(message.from_user)

        # todo: handle errors for invalid messages
        download_url = message.text.split('/dl_')[1]
        db_hit = self.db.get_hit_by_download_url(download_url)
        db_audio = self.db.get_audio_from_hit(db_hit)
        db_audio_doc = self.db.get_audio_doc_by_key(db_audio.key)
        if db_audio_doc:
            audio_file_cache = self.db.get_audio_file_from_cache(
                db_audio_doc, self.telegram_client.telegram_id)
            db_chat = self.db.get_chat_by_chat_id(db_audio_doc.chat_id)
            if not audio_file_cache:
                messages = client.get_messages(db_chat.username,
                                               [db_audio_doc.message_id])
                if not messages or not len(messages):
                    # todo: could not get the audio from telegram servers, what to do now?
                    logger.error(
                        "could not get the audio from telegram servers, what to do now?"
                    )
                    return
                file_id = messages[0].audio.file_id
            else:
                file_id = audio_file_cache.file_id

            text = BaseTemplate.registry.audio_caption_template.render(
                AudioCaptionData.parse_from_audio_doc(
                    db_audio_doc,
                    db_user,
                    db_chat,
                    bot_url='https://t.me/bot?start',
                    include_source=True,
                ))

            markup = [
                [
                    InlineButton.get_button(
                        'add_to_playlist').get_inline_keyboard_button(
                            db_user.chosen_language_code, db_hit.download_url),
                ],
                [
                    InlineButton.get_button('home').get_inline_keyboard_button(
                        db_user.chosen_language_code),
                ]
            ]
            markup = InlineKeyboardMarkup(markup)

            message.reply_audio(
                audio=file_id,
                caption=text,
                parse_mode=ParseMode.HTML,
                reply_markup=markup,
            )

            db_download = self.db.get_or_create_download_from_download_url(
                download_url,
                db_user,
                self.telegram_client.telegram_id,
            )
        else:
            # todo: An Error occurred while processing this audio download url, why?
            logger.error(
                f"An error occurred while processing the download URL for this audio: {download_url}"
            )
            message.reply_text(
                _trans(
                    "An error occurred while processing the download URL for this audio",
                    db_user.chosen_language_code))
 def chat_member_update_handler(
         self,
         client: 'pyrogram.Client',
         chat_member_updated: 'pyrogram.types.ChatMemberUpdated'
 ):
     logger.debug(f"chat_member_update_handler: {chat_member_updated}")
예제 #11
0
    'ru': russian,
    'hi': indian,
    'de': german,
    'nl': dutch,
    'pt_BR': portugues,
    'it': italian,
    'es': spanish,
    'fa': persian,
    'ar': arabic,
    'ku': kurdish_sorani,
    'ku_TR': kurdish_kurmanji,
}

if not len(languages):
    for lang_code in language_mapping.keys():
        logger.debug(f"lang_code: {lang_code}")
        lang = gettext.translation('tase',
                                   localedir='../locales',
                                   languages=[lang_code])
        lang.install()
        languages[lang_code] = lang.gettext


def _trans(text: str, lang_code: str = 'en') -> str:
    """
    Translates the given text to another language given by the `lang_code` parameter

    :param text: The text to be translated
    :param lang_code: Code of the language to be translated to. Default is `en` for English
    :return: The translated text
    """
예제 #12
0
    def on_inline_query(self, client: 'pyrogram.Client', inline_query: 'pyrogram.types.InlineQuery'):
        logger.debug(f"on_inline_query: {inline_query}")
        query_date = get_timestamp()

        # todo: fix this
        db_from_user = self.db.get_user_by_user_id(inline_query.from_user.id)
        if not db_from_user:
            # update the user
            db_from_user = self.db.update_or_create_user(inline_query.from_user)

        found_any = True
        from_ = 0
        results = []
        temp_res = []
        next_offset = None

        if inline_query.query is None or not len(inline_query.query):
            # todo: query is empty
            found_any = False
        else:
            if inline_query.offset is not None and len(inline_query.offset):
                from_ = int(inline_query.offset)

            db_audio_docs, query_metadata = self.db.search_audio(inline_query.query, from_, size=15)

            if not db_audio_docs or not len(db_audio_docs) or not len(query_metadata):
                found_any = False

            db_audio_docs: List['elasticsearch_models.Audio'] = db_audio_docs

            chats_dict = self.update_audio_cache(db_audio_docs)

            for db_audio_doc in db_audio_docs:
                db_audio_file_cache = self.db.get_audio_file_from_cache(db_audio_doc, self.telegram_client.telegram_id)

                #  todo: Some audios have null titles, solution?
                if not db_audio_file_cache or not db_audio_doc.title:
                    continue

                # todo: telegram cannot handle these mime types, any alternative?
                if db_audio_doc.mime_type in forbidden_mime_types:
                    continue

                temp_res.append((db_audio_file_cache, db_audio_doc))

            next_offset = str(from_ + len(temp_res) + 1) if len(temp_res) else None
            db_inline_query, db_hits = self.db.get_or_create_inline_query(
                self.telegram_client.telegram_id,
                inline_query,
                query_date=query_date,
                query_metadata=query_metadata,
                audio_docs=db_audio_docs,
                next_offset=next_offset
            )

            if db_inline_query and db_hits:
                for (db_audio_file_cache, db_audio_doc), db_hit in zip(temp_res, db_hits):
                    results.append(
                        AudioItem.get_item(
                            db_audio_file_cache,
                            db_from_user,
                            db_audio_doc,
                            inline_query,
                            chats_dict,
                            db_hit,
                        )
                    )

            # logger.info(
            #     f"{inline_query.id} : {inline_query.query} ({len(results)}) => {inline_query.offset} : {next_offset}")

        if found_any and len(results):
            try:
                inline_query.answer(results, cache_time=1, next_offset=next_offset)
            except Exception as e:
                logger.exception(e)
        else:
            # todo: No results matching the query found, what now?
            if from_ is None or from_ == 0:
                inline_query.answer([NoResultItem.get_item(db_from_user)], cache_time=1)