示例#1
0
    async def handler(self, event: events.ChatAction, request_context: RequestContext):
        schema, session_id, old_message_id, document_id, position, page = self.parse_pattern(event)

        request_context.add_default_fields(mode='view', session_id=session_id)
        request_context.statbox(action='view', document_id=document_id, position=position, schema=schema)

        has_found_old_widget = old_message_id == self.application.user_manager.last_widget.get(request_context.chat.chat_id)

        try:
            message_id, link_preview = await self.process_widgeting(
                has_found_old_widget=has_found_old_widget,
                old_message_id=old_message_id,
                request_context=request_context
            )

            document_view = await self.resolve_document(
                schema,
                document_id,
                position,
                session_id,
                request_context,
            )
            try:
                back_command = await self.compose_back_command(
                    session_id=session_id,
                    message_id=message_id,
                    page=page,
                )
            except MessageHasBeenDeletedError:
                return await event.respond(
                    t('REPLY_MESSAGE_HAS_BEEN_DELETED', language=request_context.chat.language),
                )

            view, buttons = document_view.get_view(
                language=request_context.chat.language,
                session_id=session_id,
                bot_external_name=self.application.config['telegram']['bot_external_name'],
                position=position,
                back_command=back_command,
            )
            actions = [
                self.application.telegram_client.edit_message(
                    request_context.chat.chat_id,
                    message_id,
                    view,
                    buttons=buttons,
                    link_preview=link_preview,
                ),
                event.delete(),
            ]
            if not has_found_old_widget:
                actions.append(
                    self.application.telegram_client.delete_messages(
                        request_context.chat.chat_id,
                        [old_message_id],
                    )
                )
            return await asyncio.gather(*actions)
        except MessageIdInvalidError:
            await event.reply(t("VIEWS_CANNOT_BE_SHARED", language=request_context.chat.language))
示例#2
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     query = event.pattern_match.group(1)
     if query:
         request_context.statbox(
             action='show',
             mode='copyright',
             query=query,
         )
         await self.application.telegram_client.forward_messages(
             self.application.config['telegram']
             ['copyright_infringement_account'],
             event.message,
         )
         await event.reply(
             t(
                 'COPYRIGHT_INFRINGEMENT_ACCEPTED',
                 language=request_context.chat.language,
             ))
     else:
         request_context.statbox(action='show', mode='copyright')
         await event.reply(
             t(
                 'COPYRIGHT_DESCRIPTION',
                 language=request_context.chat.language,
             ))
示例#3
0
    async def handler(self, event: events.ChatAction, request_context: RequestContext):
        raw_query = event.pattern_match.group(1)
        query = None

        request_context.statbox(action='start', mode='start')

        try:
            query = decode_deep_query(raw_query)
        except DecodeDeepQueryError as e:
            request_context.error_log(e, mode='start', raw_query=raw_query)

        if query:
            request_context.statbox(action='query', mode='start', query=query)
            request_message = await self.application.telegram_client.send_message(event.chat, query)
            prefetch_message = await request_message.reply(
                t("SEARCHING", language=request_context.chat.language),
            )
            self.application.user_manager.last_widget[request_context.chat.chat_id] = prefetch_message.id
            await asyncio.gather(
                event.delete(),
                self.do_search(event, request_context, prefetch_message, query=query,
                               is_shortpath_enabled=True),
            )
        else:
            request_context.statbox(action='show', mode='start')
            await event.reply(t('HELP', language=request_context.chat.language))
示例#4
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     request_context.statbox(action='show', mode='help')
     if event.is_group or event.is_channel:
         await event.reply(t('HELP_FOR_GROUPS',
                             language=request_context.chat.language),
                           buttons=Button.clear())
     else:
         await event.reply(t('HELP',
                             language=request_context.chat.language),
                           buttons=Button.clear())
示例#5
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        session_id, message_id, page = self.parse_pattern(event)

        request_context.add_default_fields(mode='search_paging',
                                           session_id=session_id)
        start_time = time.time()

        message = await event.get_message()
        if not message:
            return await event.answer()

        reply_message = await message.get_reply_message()
        try:
            if not reply_message:
                raise MessageHasBeenDeletedError()
            query = self.preprocess_query(reply_message.raw_text)
            search_widget = await SearchWidget.create(
                application=self.application,
                chat=request_context.chat,
                session_id=session_id,
                message_id=message_id,
                request_id=request_context.request_id,
                query=query,
                page=page,
            )
        except MessageHasBeenDeletedError:
            return await event.respond(
                t('REPLY_MESSAGE_HAS_BEEN_DELETED',
                  language=request_context.chat.language), )
        except AioRpcError as e:
            if e.code() == StatusCode.INVALID_ARGUMENT or e.code(
            ) == StatusCode.CANCELLED:
                request_context.error_log(e)
                return await event.answer(
                    t('MAINTENANCE_WO_PIC',
                      language=request_context.chat.language), )
            raise e

        action = 'documents_found'
        if len(search_widget.scored_documents) == 0:
            action = 'documents_not_found'

        request_context.statbox(
            action=action,
            duration=time.time() - start_time,
            query=f'page:{page} query:{query}',
        )
        serp, buttons = await search_widget.render()
        return await asyncio.gather(
            event.answer(),
            message.edit(serp, buttons=buttons, link_preview=False))
示例#6
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        session_id = self.generate_session_id()

        request_context.add_default_fields(session_id=session_id)
        request_context.statbox(action='show', mode='submit')

        if event.document.mime_type != 'application/pdf':
            request_context.statbox(action='unknown_file_format')
            request_context.error_log(
                UnknownFileFormatError(format=event.document.mime_type))
            return await asyncio.gather(
                event.reply(
                    t('UNKNOWN_FILE_FORMAT_ERROR',
                      language=request_context.chat.language),
                    buttons=[close_button()],
                ),
                event.delete(),
            )

        return await asyncio.gather(
            self.application.hub_client.submit(
                telegram_document=bytes(event.document),
                telegram_file_id=event.file.id,
                chat=request_context.chat,
                request_id=request_context.request_id,
                session_id=session_id,
            ),
            event.delete(),
        )
示例#7
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        schema, session_id, document_id, vote, vote_value = self.parse_pattern(
            event)

        request_context.add_default_fields(mode='vote', session_id=session_id)
        request_context.statbox(
            action='vote',
            document_id=document_id,
            query=vote,
            schema=schema,
        )

        document_operation_pb = DocumentOperationPb(vote=VotePb(
            document_id=document_id,
            value=vote_value,
            voter_id=request_context.chat.chat_id,
        ), )
        logging.getLogger('operation').info(
            msg=MessageToDict(document_operation_pb), )

        message = await event.get_message()

        # ToDo: Generalize nexus.views.telegram.common.remove_button and use it here
        return await asyncio.gather(
            self.application.telegram_client.edit_message(
                request_context.chat.chat_id,
                message.id,
                message.text,
                buttons=None,
            ),
            event.answer(t('TANKS_BRUH')),
        )
示例#8
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        search_prefix, query, is_group_mode = self.parse_pattern(event)
        request_context.add_default_fields(mode='search_edit')

        if is_group_mode and not search_prefix:
            return
        if not is_group_mode and search_prefix:
            query = event.raw_text

        last_messages = await self.get_last_messages_in_chat(event)
        try:
            if not last_messages:
                raise MessageHasBeenDeletedError()
            for next_message in last_messages.messages:
                if next_message.is_reply and event.id == next_message.reply_to_msg_id:
                    request_context.statbox(action='resolved')
                    return await self.do_search(
                        event=event,
                        request_context=request_context,
                        prefetch_message=next_message,
                        query=query,
                        is_group_mode=is_group_mode,
                    )
            raise MessageHasBeenDeletedError()
        except MessageHasBeenDeletedError as e:
            request_context.error_log(e)
            return await event.reply(
                t('REPLY_MESSAGE_HAS_BEEN_DELETED',
                  language=request_context.chat.language), )
示例#9
0
 async def _send_fail_response(self, event,
                               request_context: RequestContext):
     try:
         await event.answer(
             t('MAINTENANCE_WO_PIC',
               language=request_context.chat.language))
     except (ConnectionError, QueryIdInvalidError) as e:
         request_context.error_log(e)
示例#10
0
 async def respond_not_found(self, request_context: RequestContext,
                             document_view):
     return await self.delivery_service.telegram_client.send_message(
         request_context.chat.chat_id,
         t("SOURCES_UNAVAILABLE",
           language=request_context.chat.language).format(
               document=document_view.get_robust_title()),
         buttons=[close_button()])
示例#11
0
 async def _on_fail():
     await self.delivery_service.telegram_client.send_message(
         request_context.chat.chat_id,
         t('MAINTENANCE',
           language=request_context.chat.language).format(
               maintenance_picture_url=self.delivery_service.
               maintenance_picture_url),
         buttons=[close_button()])
示例#12
0
 async def _send_fail_response(self, event: events.ChatAction,
                               request_context: RequestContext):
     try:
         await event.reply(t(
             'MAINTENANCE', language=request_context.chat.language).format(
                 maintenance_picture_url=self.application.
                 config['application']['maintenance_picture_url'], ),
                           buttons=[close_button()])
     except (ConnectionError, QueryIdInvalidError) as e:
         request_context.error_log(e)
示例#13
0
 async def _check_maintenance(self, event: events.ChatAction):
     if (self.application.config['application']['is_maintenance_mode']
             and event.chat_id not in self.application.config['application']
         ['bypass_maintenance']):
         await event.reply(
             t('UPGRADE_MAINTENANCE',
               language='en').format(upgrade_maintenance_picture_url=self.
                                     application.config['application']
                                     ['upgrade_maintenance_picture_url']), )
         raise events.StopPropagation()
示例#14
0
    async def handler(self, event: events.ChatAction, request_context: RequestContext):
        query = event.pattern_match.group(1)
        request_context.statbox(action='start', mode='shortlink', query=query)

        try:
            bot_name = self.application.config["telegram"]["bot_external_name"]
            text = encode_query_to_deep_link(query, bot_name)
        except TooLongQueryError:
            text = t('TOO_LONG_QUERY_FOR_SHORTLINK', language=request_context.chat.language),

        return await event.reply(f'`{text}`', link_preview=False)
示例#15
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     query = event.pattern_match.group(1)
     if query:
         request_context.statbox(action='show', mode='contact', query=query)
         await event.reply(
             t('THANK_YOU_FOR_CONTACT',
               language=request_context.chat.language).format(
                   related_channel=self.application.config['telegram']
                   ['related_channel'], ), )
     else:
         request_context.statbox(action='show', mode='contact')
         await event.reply(
             t('CONTACT', language=request_context.chat.language).format(
                 btc_donate_address=config['application']
                 ['btc_donate_address'],
                 libera_pay_url=config['application']['libera_pay_url'],
                 related_channel=config['telegram']['related_channel'],
             ),
             link_preview=False,
         )
示例#16
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        try:
            self.check_search_ban_timeout(
                user_id=str(request_context.chat.chat_id))
        except BannedUserError as e:
            request_context.error_log(e)
            return await event.reply(
                t('BANNED_FOR_SECONDS',
                  language=request_context.chat.language).format(
                      seconds=e.ban_timeout,
                      reason=t('BAN_MESSAGE_TOO_MANY_REQUESTS',
                               language=request_context.chat.language),
                  ))
        search_prefix, query, is_group_mode = self.parse_pattern(event)

        if is_group_mode and not search_prefix:
            return
        if not is_group_mode and search_prefix:
            query = event.raw_text

        prefetch_message = await event.reply(
            t("SEARCHING", language=request_context.chat.language), )
        self.application.user_manager.last_widget[
            request_context.chat.chat_id] = prefetch_message.id
        try:
            await self.do_search(
                event=event,
                request_context=request_context,
                prefetch_message=prefetch_message,
                query=query,
                is_group_mode=is_group_mode,
                is_shortpath_enabled=True,
            )
        except (AioRpcError, asyncio.CancelledError) as e:
            await asyncio.gather(
                event.delete(),
                prefetch_message.delete(),
            )
            raise e
示例#17
0
 async def external_cancel(self):
     self.task.cancel()
     self.request_context.statbox(
         action='externally_canceled',
         document_id=self.document_view.id,
         schema=self.document_view.schema,
     )
     await self.delivery_service.telegram_client.send_message(
         self.request_context.chat.chat_id,
         t("DOWNLOAD_CANCELED",
           language=self.request_context.chat.language).format(
               document=self.document_view.get_robust_title()),
         buttons=[close_button()])
示例#18
0
    async def handler(self, event, request_context: RequestContext):
        session_id = self.generate_session_id()
        request_context.add_default_fields(mode='top_missed', session_id=session_id)
        request_context.statbox()

        prefetch_message = await event.reply(t("SEARCHING", language=request_context.chat.language))
        message_id = prefetch_message.id

        return await self.do_request(
            request_context=request_context,
            session_id=session_id,
            message_id=message_id,
            page=0,
        )
示例#19
0
 async def _check_ban(self, event: events.ChatAction,
                      request_context: RequestContext, chat: ChatPb):
     if is_banned(chat):
         if chat.ban_message is not None:
             async with safe_execution(
                     request_context=request_context,
                     on_fail=lambda: self._send_fail_response(
                         event, request_context),
             ):
                 await event.reply(
                     t('BANNED', language=chat.language).format(
                         datetime=str(time.ctime(chat.ban_until)),
                         reason=chat.ban_message,
                     ))
         raise events.StopPropagation()
示例#20
0
 async def _check_subscription(self, event: events.ChatAction,
                               request_context: RequestContext,
                               chat: ChatPb):
     if (self.application.config['application']['is_subscription_required']
             and self.is_subscription_required_for_handler
             and not is_subscribed(chat)):
         async with safe_execution(
                 request_context=request_context,
                 on_fail=lambda: self._send_fail_response(
                     event, request_context),
         ):
             await event.reply(
                 t('SUBSCRIBE_TO_CHANNEL', language=chat.language).format(
                     related_channel=self.application.config['telegram']
                     ['related_channel']))
         raise events.StopPropagation()
示例#21
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     request_context.statbox(action='show', mode='donate')
     await event.reply(
         t('DONATE', language=request_context.chat.language).format(
             amazon_gift_card_recipient=config['application'].get(
                 'amazon_gift_card_recipient', '🚫'),
             amazon_gift_card_url=config['application'].get(
                 'amazon_gift_card_url', '🚫'),
             btc_donate_address=config['application'].get(
                 'btc_donate_address', '🚫'),
             libera_pay_url=config['application'].get(
                 'libera_pay_url', '🚫'),
             related_channel=config['telegram'].get('related_channel',
                                                    '🚫'),
         ))
示例#22
0
 async def process_widgeting(self, has_found_old_widget, old_message_id, request_context: RequestContext):
     if has_found_old_widget:
         message_id = old_message_id
         link_preview = None
     else:
         old_message = (await self.application.telegram_client(
             functions.messages.GetMessagesRequest(id=[old_message_id])
         )).messages[0]
         prefetch_message = await self.application.telegram_client.send_message(
             request_context.chat.chat_id,
             t("SEARCHING", language=request_context.chat.language),
             reply_to=old_message.reply_to_msg_id,
         )
         self.application.user_manager.last_widget[request_context.chat.chat_id] = prefetch_message.id
         message_id = prefetch_message.id
         link_preview = True
     return message_id, link_preview
示例#23
0
    async def render(self) -> tuple[str, Optional[list]]:
        if not len(self.typed_documents):
            return t('COULD_NOT_FIND_ANYTHING', language=self.chat.language), [
                close_button(self.session_id)
            ]

        serp_elements = []
        for position, typed_document in enumerate(self.typed_documents):
            view = parse_typed_document_to_view(typed_document)
            serp_elements.append(
                view.get_snippet(
                    language=self.chat.language,
                    limit=512 + 128,
                ))

        promo = self.application.promotioner.choose_promotion(
            language=self.chat.language).format(
                related_channel=self.application.config['telegram']
                ['related_channel'], )
        serp_elements.append(promo)
        serp = '\n\n'.join(serp_elements)

        buttons = []
        if self.has_next or self.page > 0:
            buttons = [
                Button.inline(
                    text='<<1' if self.page > 1 else ' ',
                    data=f'/{self.cmd}_{self.session_id}_{self.message_id}_0'
                    if self.page > 1 else '/noop',
                ),
                Button.inline(
                    text=f'<{self.page}' if self.page > 0 else ' ',
                    data=
                    f'/{self.cmd}_{self.session_id}_{self.message_id}_{self.page - 1}'
                    if self.page > 0 else '/noop',
                ),
                Button.inline(
                    text=f'{self.page + 2}>' if self.has_next else ' ',
                    data=
                    f'/{self.cmd}_{self.session_id}_{self.message_id}_{self.page + 1}'
                    if self.has_next else '/noop',
                )
            ]
        buttons.append(close_button(self.session_id))

        return serp, buttons
    async def render(self):
        text = t('SETTINGS_TEMPLATE', language=self.chat.language).format(
            bot_version=self.application.config['application']['bot_version'],
            nexus_version=self.application.config['application']['nexus_version'],
            language=top_languages.get(self.chat.language, self.chat.language),
        )
        if not self.is_group_mode and self.application.config['application']['views']['settings']['has_discovery_button']:
            text = f"{text}\n\n{t('NEXUS_DISCOVERY_DESCRIPTION', language=self.chat.language)}"
        buttons = []
        if self.has_language_buttons:
            buttons.append([])
            for language in sorted(top_languages):
                if len(buttons[-1]) >= 4:
                    buttons.append([])
                buttons[-1].append(
                    Button.inline(
                        text=top_languages[language],
                        data=f'/settings_sl_{language}'
                    )
                )

        if self.is_group_mode:
            return text, buttons

        if self.application.config['application']['views']['settings']['has_system_messaging_button']:
            buttons.append([
                Button.inline(
                    text=(
                        f'{t("SYSTEM_MESSAGING_OPTION", language=self.chat.language)}: '
                        f'{boolean_emoji[self.chat.is_system_messaging_enabled]}'
                    ),
                    data=f'/settings_ssm_{1 - int(self.chat.is_system_messaging_enabled)}'
                )
            ])
        if self.application.config['application']['views']['settings']['has_discovery_button']:
            buttons.append([
                Button.inline(
                    text=(
                        f'{t("DISCOVERY_OPTION", language=self.chat.language)}: '
                        f'{boolean_emoji[self.chat.is_discovery_enabled]}'
                    ),
                    data=f'/settings_sd_{1 - int(self.chat.is_discovery_enabled)}'
                )
            ])
        return text, buttons
示例#25
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     request_context.statbox(action='show', mode='emoji')
     await event.reply(
         t('TANKS_BRUH', language=request_context.chat.language))
示例#26
0
    async def render(self) -> tuple[str, Optional[list]]:
        if not len(self.scored_documents):
            return t('COULD_NOT_FIND_ANYTHING', language=self.chat.language), [
                close_button(self.session_id)
            ]

        serp_elements = []
        bot_external_name = self.application.config['telegram'][
            'bot_external_name']

        for scored_document in self.scored_documents:
            view = parse_typed_document_to_view(scored_document.typed_document)
            if not self.is_group_mode:
                view_command = view.get_view_command(
                    session_id=self.session_id,
                    message_id=self.message_id,
                    position=scored_document.position,
                )
            else:
                view_command = view.get_deep_link(bot_external_name, text='⬇️')
            serp_elements.append(
                view.get_snippet(
                    language=self.chat.language,
                    view_command=view_command,
                    limit=512 + 128,
                ))
        serp = '\n\n'.join(serp_elements)

        if self.is_group_mode:
            try:
                encoded_query = encode_query_to_deep_link(
                    self.query,
                    bot_external_name,
                )
                serp = (
                    f"{serp}\n\n**{t('DOWNLOAD_AND_SEARCH_MORE', language=self.chat.language)}: **"
                    f'[@{bot_external_name}]'
                    f'({encoded_query})')
            except TooLongQueryError:
                serp = (
                    f"{serp}\n\n**{t('DOWNLOAD_AND_SEARCH_MORE', language=self.chat.language)}: **"
                    f'[@{bot_external_name}]'
                    f'(https://t.me/{bot_external_name})')

        if not self.is_group_mode:
            promo = self.application.promotioner.choose_promotion(
                language=self.chat.language).format(
                    related_channel=self.application.config['telegram']
                    ['related_channel'], )
            serp = f'{serp}\n\n{promo}\n'

        buttons = None
        if not self.is_group_mode:
            buttons = []
            if self.has_next or self.page > 0:
                buttons = [
                    Button.inline(
                        text='<<1' if self.page > 1 else ' ',
                        data=f'/search_{self.session_id}_{self.message_id}_0'
                        if self.page > 1 else '/noop',
                    ),
                    Button.inline(
                        text=f'<{self.page}' if self.page > 0 else ' ',
                        data=
                        f'/search_{self.session_id}_{self.message_id}_{self.page - 1}'
                        if self.page > 0 else '/noop',
                    ),
                    Button.inline(
                        text=f'{self.page + 2}>' if self.has_next else ' ',
                        data=
                        f'/search_{self.session_id}_{self.message_id}_{self.page + 1}'
                        if self.has_next else '/noop',
                    )
                ]
            buttons.append(close_button(self.session_id))

        return serp, buttons
示例#27
0
    async def submit(
        self,
        request: SubmitRequestPb,
        context: ServicerContext,
        metadata: dict,
    ) -> SubmitResponsePb:
        session_id = metadata.get('session-id')
        request_context = RequestContext(
            bot_name=self.service_name,
            chat=request.chat,
            request_id=metadata.get('request-id'),
        )
        request_context.add_default_fields(
            mode='submit',
            session_id=metadata.get('session-id'),
            **self.get_default_service_fields(),
        )

        document = BinaryReader(request.telegram_document).tgread_object()
        if document.size > 20 * 1024 * 1024:
            request_context.error_log(FileTooBigError(size=document.size))
            request_context.statbox(action='file_too_big')
            await self.telegram_client.send_message(
                request_context.chat.chat_id,
                t('FILE_TOO_BIG_ERROR',
                  language=request_context.chat.language),
                buttons=[close_button()],
            )
            return SubmitResponsePb()
        processing_message = await self.telegram_client.send_message(
            request_context.chat.chat_id,
            t("PROCESSING_PAPER",
              language=request_context.chat.language).format(
                  filename=document.attributes[0].file_name, ),
        )
        try:
            file = await self.telegram_client.download_document(
                document=document, file=bytes)
            try:
                processed_document = await self.grobid_client.process_fulltext_document(
                    pdf_file=file)
            except BadRequestError as e:
                request_context.statbox(action='unparsable_document')
                request_context.error_log(e)
                await self.telegram_client.send_message(
                    request_context.chat.chat_id,
                    t('UNPARSABLE_DOCUMENT_ERROR',
                      language=request_context.chat.language).format(
                          filename=document.attributes[0].file_name, ),
                    buttons=[close_button()],
                )
                return SubmitResponsePb()

            if not processed_document.get('doi'):
                request_context.statbox(action='unparsable_doi')
                request_context.error_log(UnparsableDoiError())
                await self.telegram_client.send_message(
                    request_context.chat.chat_id,
                    t('UNPARSABLE_DOI_ERROR',
                      language=request_context.chat.language).format(
                          filename=document.attributes[0].file_name, ),
                    buttons=[close_button()],
                )
                return SubmitResponsePb()

            search_response_pb = await self.meta_api_client.search(
                schemas=('scimag', ),
                query=processed_document['doi'],
                page=0,
                page_size=1,
                request_id=request_context.request_id,
                session_id=session_id,
                user_id=str(request_context.chat.chat_id),
                language=request_context.chat.language,
            )

            if len(search_response_pb.scored_documents) == 0:
                request_context.statbox(action='unavailable_metadata')
                request_context.error_log(
                    UnavailableMetadataError(doi=processed_document['doi']))
                await self.telegram_client.send_message(
                    request_context.chat.chat_id,
                    t('UNAVAILABLE_METADATA_ERROR',
                      language=request_context.chat.language).format(
                          doi=processed_document['doi']),
                    buttons=[close_button()],
                )
                return SubmitResponsePb()

            document_view = ScimagView(
                search_response_pb.scored_documents[0].typed_document.scimag)
            uploaded_message = await self.send_file(
                document_view=document_view,
                file=file,
                request_context=request_context,
                session_id=session_id,
                voting=False,
            )
        finally:
            await processing_message.delete()

        document_operation_pb = DocumentOperationPb(
            update_document=UpdateDocumentPb(
                typed_document=TypedDocumentPb(sharience=ShariencePb(
                    parent_id=document_view.id,
                    uploader_id=request_context.chat.chat_id,
                    updated_at=int(time.time()),
                    md5=hashlib.md5(file).hexdigest(),
                    filesize=document.size,
                    ipfs_multihashes=await self.get_ipfs_hashes(file=file),
                    telegram_file_id=uploaded_message.file.id,
                )), ), )
        request_context.statbox(
            action='success',
            document_id=document_view.id,
            schema='scimag',
        )
        await operation_log(document_operation_pb)
        return SubmitResponsePb()
示例#28
0
 async def _check_read_only(self, event: events.ChatAction):
     if self.application.config['application']['is_read_only_mode']:
         await event.reply(t("READ_ONLY_MODE", language='en'), )
         raise events.StopPropagation()
示例#29
0
    async def download_task(self, request_context: RequestContext,
                            document_view):
        throttle_secs = 2.0

        async def _on_fail():
            await self.delivery_service.telegram_client.send_message(
                request_context.chat.chat_id,
                t('MAINTENANCE',
                  language=request_context.chat.language).format(
                      maintenance_picture_url=self.delivery_service.
                      maintenance_picture_url),
                buttons=[close_button()])

        async with safe_execution(
                request_context=request_context,
                on_fail=_on_fail,
        ):
            progress_bar_download = ProgressBar(
                telegram_client=self.delivery_service.telegram_client,
                request_context=request_context,
                banner=t("LOOKING_AT", language=request_context.chat.language),
                header=f'⬇️ {document_view.get_filename()}',
                tail_text=t('TRANSMITTED_FROM',
                            language=request_context.chat.language),
                throttle_secs=throttle_secs,
            )
            downloads_gauge.inc()
            start_time = time.time()
            try:
                file = await self.download(
                    document_view=document_view,
                    progress_bar=progress_bar_download,
                )
                if not file:
                    request_context.statbox(
                        action='missed',
                        duration=time.time() - start_time,
                        document_id=document_view.id,
                        schema=document_view.schema,
                    )
                    is_served_from_sharience = False
                    if self.delivery_service.is_sharience_enabled:
                        is_served_from_sharience = await self.try_sharience(
                            request_context=request_context,
                            document_view=document_view,
                        )
                    if not is_served_from_sharience:
                        request_context.statbox(
                            action='not_found',
                            document_id=document_view.id,
                            duration=time.time() - start_time,
                            schema=document_view.schema,
                        )
                        await self.respond_not_found(
                            request_context=request_context,
                            document_view=document_view,
                        )
                    return
                else:
                    request_context.statbox(
                        action='downloaded',
                        duration=time.time() - start_time,
                        document_id=document_view.id,
                        len=len(file),
                        schema=document_view.schema,
                    )

                progress_bar_upload = ProgressBar(
                    telegram_client=self.delivery_service.telegram_client,
                    request_context=request_context,
                    message=progress_bar_download.message,
                    banner=t("LOOKING_AT",
                             language=request_context.chat.language),
                    header=f'⬇️ {document_view.get_filename()}',
                    tail_text=t('UPLOADED_TO_TELEGRAM',
                                language=request_context.chat.language),
                    throttle_secs=throttle_secs)

                uploaded_message = await self.delivery_service.send_file(
                    document_view=self.document_view,
                    file=file,
                    progress_callback=progress_bar_upload.callback,
                    request_context=self.request_context,
                    session_id=self.session_id,
                    voting=not is_group_or_channel(
                        self.request_context.chat.chat_id),
                )
                request_context.statbox(
                    action='uploaded',
                    duration=time.time() - start_time,
                    document_id=document_view.id,
                    schema=document_view.schema,
                )
                if self.delivery_service.should_store_hashes:
                    asyncio.create_task(
                        self.store_hashes(
                            document_view=document_view,
                            telegram_file_id=uploaded_message.file.id,
                            file=file,
                        ))
            except DownloadError:
                await self.external_cancel()
            except ProgressBarLostMessageError:
                self.request_context.statbox(
                    action='user_canceled',
                    duration=time.time() - start_time,
                    document_id=document_view.id,
                    schema=document_view.schema,
                )
            except asyncio.CancelledError:
                pass
            finally:
                downloads_gauge.dec()
                messages = filter_none([progress_bar_download.message])
                await self.delivery_service.telegram_client.delete_messages(
                    request_context.chat.chat_id, messages)
示例#30
0
            data=f'/close_{session_id}',
        )
    else:
        return Button.inline(
            text='✖️',
            data='/close',
        )


def vote_button(language: str, session_id: str, schema: str, document_id: int,
                case: str):
    label = f"REPORT_{case.upper()}_FILE"
    case = {'broken': 'b', 'ok': 'o'}[case]
    schema = {'scimag': 'a', 'scitech': 'b'}[schema]
    return Button.inline(
        text=t(label, language=language),
        data=f'/vote{schema}_{session_id}_{document_id}_{case}',
    )


def encode_query_to_deep_link(query, bot_name):
    encoded_query = encode_deep_query(query)
    if len(encoded_query) <= 64:
        return f'https://t.me/{bot_name}?start={encoded_query}'
    raise TooLongQueryError()


def encode_deep_query(query):
    return base64.b64encode(query.encode(), altchars=b'-_').decode()