Ejemplo n.º 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))
Ejemplo n.º 2
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')),
        )
Ejemplo n.º 3
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        session_id = self.generate_session_id()
        request_context.add_default_fields(mode='roll', session_id=session_id)
        request_context.statbox(action='show')

        roll_response_pb = await self.application.meta_api_client.roll(
            language=request_context.chat.language,
            session_id=session_id,
            request_id=request_context.request_id,
            user_id=str(request_context.chat.chat_id),
        )
        scitech_view = await self.resolve_scitech(
            document_id=roll_response_pb.document_id,
            position=0,
            request_context=request_context,
            session_id=session_id,
        )
        view, buttons = scitech_view.get_view(
            language=request_context.chat.language,
            session_id=session_id,
            bot_external_name=self.application.config['telegram']
            ['bot_external_name'],
        )
        actions = [
            self.application.telegram_client.send_message(
                request_context.chat.chat_id,
                view,
                buttons=buttons,
            ),
            event.delete(),
        ]
        return await asyncio.gather(*actions)
Ejemplo n.º 4
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,
             ))
Ejemplo n.º 5
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        chat_id, ban_duration, ban_message, ban_end_date = self.parse_pattern(
            event)

        try:
            await self.application.idm_client.update_chat(
                chat_id=chat_id,
                ban_until=int(ban_end_date.timestamp()),
                ban_message=ban_message,
                request_id=request_context.request_id,
            )
            request_context.statbox(
                action='banned',
                ban_message=ban_message,
                ban_until=ban_end_date.timestamp(),
                banned_chat_id=chat_id,
            )
        except ClientError as e:
            if e.code == 'nonexistent_entity_error':
                await event.reply('Chat not found')
                return
            raise

        await event.reply('User banned until ' +
                          ban_end_date.strftime("%Y-%m-%d %H:%M") + ' UTC')
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
 async def handler(self, event, request_context: RequestContext):
     request_context.statbox(action='show', mode='banlist')
     chat_list = (await self.application.idm_client.list_chats(
         banned_at_moment=int(datetime.utcnow().timestamp()),
         request_id=request_context.request_id,
     )).chats
     banlist_widget_view = BanlistWidget(application=self.application,
                                         chat=request_context.chat)
     widget_content = await banlist_widget_view.render(chat_list=chat_list)
     await event.reply(widget_content)
Ejemplo n.º 8
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)
Ejemplo n.º 9
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())
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     request_context.add_default_fields(mode='settings_router')
     request_context.statbox(action='show')
     settings_widget = SettingsWidget(
         application=self.application,
         chat=request_context.chat,
         is_group_mode=event.is_group or event.is_channel,
         request_id=request_context.request_id,
     )
     text, buttons = await settings_widget.render()
     await event.reply(text, buttons=buttons)
Ejemplo n.º 12
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,
        )
Ejemplo n.º 13
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))
Ejemplo n.º 14
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(),
        )
Ejemplo n.º 15
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',
                                                    '🚫'),
         ))
Ejemplo n.º 16
0
    async def _wrapped_handler(self, event: events.ChatAction) -> None:
        # Checking group permissions
        if (event.is_group or event.is_channel) and not self.is_group_handler:
            return

        await self._check_maintenance(event=event)
        await self._check_read_only(event=event)

        request_id = RequestContext.generate_request_id(
            self.application.config['application']['request_id_length'])
        chat = await self._process_chat(event=event, request_id=request_id)

        request_context = RequestContext(
            bot_name=self.application.config['telegram']['bot_name'],
            chat=chat,
            request_id=request_id,
            request_id_length=self.application.config['application']
            ['request_id_length'],
        )

        if not self._has_access(chat):
            return

        await self._check_subscription(event=event,
                                       request_context=request_context,
                                       chat=chat)
        await self._check_ban(event=event,
                              request_context=request_context,
                              chat=chat)

        if self.should_reset_last_widget:
            self.reset_last_widget(request_context.chat.chat_id)

        async with safe_execution(
                request_context=request_context,
                on_fail=lambda: self._send_fail_response(
                    event, request_context),
        ):
            await self.handler(
                event,
                request_context=request_context,
            )
        if self.stop_propagation:
            raise events.StopPropagation()
Ejemplo n.º 17
0
    async def handler(self, event, request_context: RequestContext):
        chat_id = int(event.pattern_match.group(1))

        try:
            await self.application.idm_client.update_chat(
                chat_id=chat_id,
                ban_until=0,
                request_id=request_context.request_id,
            )
            request_context.statbox(
                action='unbanned',
                unbanned_chat_id=chat_id,
            )
        except ClientError as e:
            if e.code == 'nonexistent_entity_error':
                await event.reply('Chat not found')
                return
            raise

        await event.reply('User unbanned')
Ejemplo n.º 18
0
    async def handler(self, event, request_context: RequestContext):
        session_id = event.pattern_match.group(1)
        if session_id:
            session_id = session_id.decode()
        request_context.add_default_fields(mode='close')

        target_events = [event.answer()]
        message = await event.get_message()

        if message:
            request_context.statbox(
                action='close',
                message_id=message.id,
                session_id=session_id,
            )
            reply_message = await message.get_reply_message()
            if reply_message:
                target_events.append(reply_message.delete())
            target_events.append(message.delete())
        await asyncio.gather(*target_events)
Ejemplo n.º 19
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        short_schema, schema, session_id, document_id, position = self.parse_pattern(
            event)

        self.application.user_manager.last_widget[
            request_context.chat.chat_id] = None

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

        typed_document_pb = await self.get_typed_document_pb(
            schema=schema,
            document_id=document_id,
            request_context=request_context,
            session_id=session_id,
            position=position,
        )
        start_delivery_response_pb = await self.application.hub_client.start_delivery(
            typed_document_pb=typed_document_pb,
            chat=request_context.chat,
            request_id=request_context.request_id,
            session_id=session_id,
        )
        if start_delivery_response_pb.status == StartDeliveryResponsePb.Status.ALREADY_DOWNLOADING:
            await event.answer(
                f'{t("ALREADY_DOWNLOADING", language=request_context.chat.language)}',
            )
            await remove_button(event, '⬇️', and_empty_too=True)
        elif start_delivery_response_pb.status == StartDeliveryResponsePb.Status.TOO_MANY_DOWNLOADS:
            await event.answer(
                f'{t("TOO_MANY_DOWNLOADS", language=request_context.chat.language)}',
            )
        else:
            await remove_button(event, '⬇️', and_empty_too=True)
            self.application.user_manager.last_widget[
                request_context.chat.chat_id] = None
Ejemplo n.º 20
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,
         )
Ejemplo n.º 21
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), )
Ejemplo n.º 22
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
Ejemplo n.º 23
0
    async def handler(self, event, request_context: RequestContext):
        request_context.add_default_fields(mode='settings')
        action_id = event.pattern_match.group(1).decode()
        data = event.pattern_match.group(2).decode()

        request_context.statbox(action='change',
                                query=f'action_id: {action_id} data: {data}')

        settings_widget = SettingsWidget(
            application=self.application,
            chat=request_context.chat,
            is_group_mode=event.is_group or event.is_channel,
            request_id=request_context.request_id,
        )
        is_changed = await settings_widget.process_action(action_id=action_id,
                                                          data=data)
        text, buttons = await settings_widget.render()
        if not is_changed and not (event.is_group or event.is_channel):
            await event.answer()
            return
        if event.is_group or event.is_channel:
            buttons = None
        await event.edit(text, buttons=buttons)
Ejemplo n.º 24
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))
Ejemplo n.º 25
0
 async def start_delivery(
     self,
     request: StartDeliveryRequestPb,
     context: ServicerContext,
     metadata: dict,
 ) -> StartDeliveryResponsePb:
     request_context = RequestContext(
         bot_name=self.service_name,
         chat=request.chat,
         request_id=metadata.get('request-id'),
     )
     request_context.add_default_fields(
         mode='delivery',
         session_id=metadata.get('session-id'),
         **self.get_default_service_fields(),
     )
     document_view = parse_typed_document_to_view(request.typed_document)
     cache_hit = self.should_use_telegram_file_id and document_view.telegram_file_id
     if cache_hit:
         try:
             await self.send_file(
                 document_view=document_view,
                 file=document_view.telegram_file_id,
                 session_id=metadata.get('session-id'),
                 request_context=request_context,
                 voting=not is_group_or_channel(
                     request_context.chat.chat_id),
             )
             request_context.statbox(action='cache_hit',
                                     document_id=document_view.id,
                                     schema=document_view.schema)
         except ValueError:
             cache_hit = False
     if not cache_hit:
         if self.user_manager.has_task(request.chat.chat_id,
                                       document_view.id):
             return StartDeliveryResponsePb(
                 status=StartDeliveryResponsePb.Status.ALREADY_DOWNLOADING)
         if self.user_manager.hit_limits(request.chat.chat_id):
             return StartDeliveryResponsePb(
                 status=StartDeliveryResponsePb.Status.TOO_MANY_DOWNLOADS)
         await DownloadTask(
             delivery_service=self,
             document_view=document_view,
             request_context=request_context,
             session_id=metadata.get('session-id'),
         ).schedule()
     return StartDeliveryResponsePb(
         status=StartDeliveryResponsePb.Status.OK)
Ejemplo n.º 26
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))
Ejemplo n.º 27
0
 async def handler(self, event, request_context: RequestContext):
     request_context.statbox(action='show', mode='admin')
     admin_widget_view = AdminWidget(application=self.application,
                                     chat=request_context.chat)
     text = await admin_widget_view.render()
     await event.reply(text)
Ejemplo n.º 28
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()
Ejemplo n.º 29
0
 async def handler(self, event: events.ChatAction,
                   request_context: RequestContext):
     request_context.statbox(action='start', mode='noop')
     await event.answer()
Ejemplo n.º 30
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)