- feat(bot): Add top-missing cmd

- feat(bot): Refactor referencing handler
  - fix(bot): Refactor DocumentListWidget
1 internal commit(s)

GitOrigin-RevId: 9f388e98c7039711927abf4a048b5c45ea7a2fc3
This commit is contained in:
the-superpirate 2021-04-13 17:23:31 +03:00
parent 422959914c
commit 6de3fb1250
14 changed files with 318 additions and 229 deletions

View File

@ -79,8 +79,6 @@ telegram:
- nexus.bot.handlers.download.DownloadHandler
- nexus.bot.handlers.emoji.EmojiHandler
- nexus.bot.handlers.help.HelpHandler
- nexus.bot.handlers.referencing_to.ReferencingToHandler
- nexus.bot.handlers.referencing_to.ReferencingToPagingHandler
- nexus.bot.handlers.roll.RollHandler
- nexus.bot.handlers.settings.SettingsButtonsHandler
- nexus.bot.handlers.settings.SettingsHandler
@ -88,6 +86,7 @@ telegram:
- nexus.bot.handlers.submit.SubmitHandler
- nexus.bot.handlers.start.StartHandler
- nexus.bot.handlers.stop.StopHandler
- nexus.bot.handlers.top_missed.TopMissedHandler
- nexus.bot.handlers.view.ViewHandler
- nexus.bot.handlers.vote.VoteHandler
- nexus.bot.handlers.noop.NoopHandler

View File

@ -10,7 +10,6 @@ from . import (
help,
legacy,
noop,
referencing_to,
roll,
search,
settings,
@ -18,10 +17,11 @@ from . import (
start,
stop,
submit,
top_missed,
view,
vote,
)
__all__ = ['admin', 'ban', 'contact', 'copyright', 'close', 'donate', 'download', 'emoji', 'help',
'legacy', 'noop', 'referencing_to', 'roll', 'search', 'settings',
'shortlink', 'start', 'stop', 'submit', 'view', 'vote']
'legacy', 'noop', 'roll', 'search', 'settings',
'shortlink', 'start', 'stop', 'submit', 'top_missed', 'view', 'vote']

View File

@ -1,95 +0,0 @@
import re
import time
from grpc.experimental.aio import AioRpcError
from library.telegram.base import RequestContext
from nexus.bot.widgets.document_list_widget import DocumentListWidget
from nexus.translations import t
from telethon import events
from .base import BaseCallbackQueryHandler
class ReferencingToHandler(BaseCallbackQueryHandler):
filter = events.CallbackQuery(pattern=re.compile('^/r_([A-Za-z0-9]+)_([0-9]+)', re.DOTALL))
should_reset_last_widget = False
async def do_request(self, request_context: RequestContext, session_id: str, message_id: int, document_id: int, page: int):
start_time = time.time()
try:
document_list_widget = await DocumentListWidget.create(
application=self.application,
chat=request_context.chat,
session_id=session_id,
message_id=message_id,
request_id=request_context.request_id,
referencing_to=document_id,
page=page,
)
except AioRpcError as e:
raise e
action = 'referencing_to_found'
if len(document_list_widget.scored_documents) == 0:
action = 'referencing_to_not_found'
request_context.statbox(
action=action,
duration=time.time() - start_time,
document_id=document_id,
schema='scimag',
)
serp, buttons = await document_list_widget.render()
return await self.application.telegram_client.edit_message(
request_context.chat.chat_id,
message_id,
serp,
buttons=buttons,
link_preview=False,
)
async def handler(self, event, request_context: RequestContext):
session_id = event.pattern_match.group(1).decode()
document_id = int(event.pattern_match.group(2).decode())
request_context.add_default_fields(
mode='referencing_to',
session_id=session_id,
)
prefetch_message = await event.respond(
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,
document_id=document_id,
page=0,
)
class ReferencingToPagingHandler(ReferencingToHandler):
filter = events.CallbackQuery(pattern=re.compile('^/rp_([A-Za-z0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)', re.DOTALL))
async def handler(self, event: events.ChatAction, request_context: RequestContext):
session_id = event.pattern_match.group(1).decode()
message_id = int(event.pattern_match.group(2).decode())
document_id = int(event.pattern_match.group(3).decode())
page = int(event.pattern_match.group(4).decode())
request_context.add_default_fields(
mode='referencing_to_paging',
session_id=session_id,
)
return await self.do_request(
request_context=request_context,
session_id=session_id,
message_id=message_id,
document_id=document_id,
page=page,
)

View File

@ -1,6 +1,7 @@
import asyncio
import re
import time
from abc import ABC
from grpc import StatusCode
from grpc.experimental.aio import AioRpcError
@ -24,8 +25,9 @@ from .base import (
)
class BaseSearchHandler(BaseHandler):
should_reset_last_widget = False
class BaseSearchHandler(BaseHandler, ABC):
def preprocess_query(self, query):
return query.replace(f'@{self.application.config["telegram"]["bot_external_name"]}', '').strip()
async def do_search(
self,
@ -38,10 +40,9 @@ class BaseSearchHandler(BaseHandler):
):
session_id = self.generate_session_id()
message_id = prefetch_message.id
request_context.add_default_fields(is_group_mode=is_group_mode, mode='search', session_id=session_id)
start_time = time.time()
try:
search_widget = await SearchWidget.create(
application=self.application,
@ -152,7 +153,7 @@ class SearchHandler(BaseSearchHandler):
def parse_pattern(self, event: events.ChatAction):
search_prefix = event.pattern_match.group(1)
query = event.pattern_match.group(2)
query = self.preprocess_query(event.pattern_match.group(2))
is_group_mode = event.is_group or event.is_channel
return search_prefix, query, is_group_mode
@ -185,7 +186,9 @@ class SearchHandler(BaseSearchHandler):
self.application.user_manager.last_widget[request_context.chat.chat_id] = prefetch_message.id
try:
await self.do_search(
event, request_context, prefetch_message,
event=event,
request_context=request_context,
prefetch_message=prefetch_message,
query=query,
is_group_mode=is_group_mode,
is_shortpath_enabled=True,
@ -205,7 +208,7 @@ class SearchEditHandler(BaseSearchHandler):
def parse_pattern(self, event: events.ChatAction):
search_prefix = event.pattern_match.group(1)
query = event.pattern_match.group(2)
query = self.preprocess_query(event.pattern_match.group(2))
is_group_mode = event.is_group or event.is_channel
return search_prefix, query, is_group_mode
@ -231,8 +234,8 @@ class SearchEditHandler(BaseSearchHandler):
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,
request_context,
event=event,
request_context=request_context,
prefetch_message=next_message,
query=query,
is_group_mode=is_group_mode,
@ -249,11 +252,19 @@ class SearchPagingHandler(BaseCallbackQueryHandler):
filter = events.CallbackQuery(pattern='^/search_([A-Za-z0-9]+)_([0-9]+)_([0-9]+)$')
should_reset_last_widget = False
async def handler(self, event: events.ChatAction, request_context: RequestContext):
def preprocess_query(self, query):
return query.replace(f'@{self.application.config["telegram"]["bot_external_name"]}', '').strip()
def parse_pattern(self, event: events.ChatAction):
session_id = event.pattern_match.group(1).decode()
message_id = int(event.pattern_match.group(2).decode())
page = int(event.pattern_match.group(3).decode())
return session_id, message_id, page
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()
@ -265,7 +276,7 @@ class SearchPagingHandler(BaseCallbackQueryHandler):
try:
if not reply_message:
raise MessageHasBeenDeletedError()
query = reply_message.raw_text
query = self.preprocess_query(reply_message.raw_text)
search_widget = await SearchWidget.create(
application=self.application,
chat=request_context.chat,

View File

@ -0,0 +1,54 @@
from library.telegram.base import RequestContext
from nexus.bot.widgets.document_list_widget import DocumentListWidget
from nexus.translations import t
from telethon import events
from .base import BaseHandler
class TopMissedHandler(BaseHandler):
filter = events.NewMessage(incoming=True, pattern='^/tm$')
is_group_handler = False
should_reset_last_widget = False
async def do_request(self, request_context: RequestContext, session_id: str, message_id: int, page: int):
response = await self.application.meta_api_client.top_missed(
page=page,
page_size=10,
session_id=session_id,
request_id=request_context.request_id,
)
document_list_widget = DocumentListWidget(
application=self.application,
chat=request_context.chat,
typed_documents=response.typed_documents,
cmd='tm',
has_next=response.has_next,
session_id=session_id,
message_id=message_id,
request_id=request_context.request_id,
page=page,
)
serp, buttons = await document_list_widget.render()
return await self.application.telegram_client.edit_message(
request_context.chat.chat_id,
message_id,
serp,
buttons=buttons,
link_preview=False,
)
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,
)

View File

@ -1,5 +1,4 @@
import asyncio
import re
from library.telegram.base import RequestContext
from nexus.bot.exceptions import MessageHasBeenDeletedError
@ -20,7 +19,6 @@ class ViewHandler(BaseHandler):
def parse_pattern(self, event: events.ChatAction):
short_schema = event.pattern_match.group(1)
parent_view_type = event.pattern_match.group(2) or 's'
schema = self.short_schema_to_schema(short_schema)
session_id = event.pattern_match.group(3)
old_message_id = int(event.pattern_match.group(4))
@ -29,7 +27,7 @@ class ViewHandler(BaseHandler):
page = int(position / self.application.config['application']['page_size'])
return parent_view_type, schema, session_id, old_message_id, document_id, position, page
return schema, session_id, old_message_id, document_id, position, page
async def process_widgeting(self, has_found_old_widget, old_message_id, request_context: RequestContext):
if has_found_old_widget:
@ -51,29 +49,14 @@ class ViewHandler(BaseHandler):
async def compose_back_command(
self,
parent_view_type,
session_id,
old_message_id,
message_id,
page,
):
back_command = None
if parent_view_type == 's':
back_command = f'/search_{session_id}_{message_id}_{page}'
elif parent_view_type == 'r':
messages = (await self.application.telegram_client(
functions.messages.GetMessagesRequest(id=[old_message_id])
)).messages
if not messages:
raise MessageHasBeenDeletedError()
message = messages[0]
referencing_to = re.search(r'Linked to: ([0-9]+)', message.raw_text).group(1)
back_command = f'/rp_{session_id}_{message_id}_{referencing_to}_{page}'
return back_command
return f'/search_{session_id}_{message_id}_{page}'
async def handler(self, event: events.ChatAction, request_context: RequestContext):
parent_view_type, schema, session_id, old_message_id, document_id, position, page = self.parse_pattern(event)
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)
@ -96,9 +79,7 @@ class ViewHandler(BaseHandler):
)
try:
back_command = await self.compose_back_command(
parent_view_type=parent_view_type,
session_id=session_id,
old_message_id=old_message_id,
message_id=message_id,
page=page,
)

View File

@ -1,9 +1,12 @@
from typing import Optional
from typing import (
List,
Optional,
)
from idm.api.proto.chat_manager_service_pb2 import Chat as ChatPb
from nexus.bot.application import TelegramApplication
from nexus.meta_api.proto.meta_search_service_pb2 import \
ScoredDocument as ScoredDocumentPb
from nexus.models.proto.typed_document_pb2 import \
TypedDocument as TypedDocumentPb
from nexus.translations import t
from nexus.views.telegram.common import close_button
from nexus.views.telegram.registry import parse_typed_document_to_view
@ -15,87 +18,36 @@ class DocumentListWidget:
self,
application: TelegramApplication,
chat: ChatPb,
typed_documents: List[TypedDocumentPb],
cmd: str,
has_next: bool,
session_id: str,
message_id: int,
request_id: str,
referencing_to: int,
page: int = 0,
page_size: int = 5,
):
self.application = application
self.chat = chat
self.typed_documents = typed_documents
self.cmd = cmd
self.has_next = has_next
self.session_id = session_id
self.message_id = message_id
self.request_id = request_id
self.referencing_to = referencing_to
self.page = page
@staticmethod
async def create(
application: TelegramApplication,
chat: ChatPb,
session_id: str,
message_id: int,
request_id: str,
referencing_to: int,
page: int = 0,
) -> 'DocumentListWidget':
document_list_view = DocumentListWidget(
application=application,
chat=chat,
session_id=session_id,
message_id=message_id,
request_id=request_id,
referencing_to=referencing_to,
page=page,
)
await document_list_view._acquire_documents()
return document_list_view
async def _acquire_documents(self):
typed_document_pb = await self.application.meta_api_client.get(
schema='scimag',
document_id=self.referencing_to,
position=0,
request_id=self.request_id,
session_id=self.session_id,
user_id=self.chat.chat_id,
)
self._response = await self.application.meta_api_client.search(
schemas=('scimag',),
query=f'references:"{typed_document_pb.scimag.doi}"',
page=self.page,
request_id=self.request_id,
session_id=self.session_id,
user_id=self.chat.chat_id,
)
@property
def has_next(self) -> bool:
return self._response.has_next
@property
def scored_documents(self) -> list[ScoredDocumentPb]:
return self._response.scored_documents
self.page_size = page_size
async def render(self) -> tuple[str, Optional[list]]:
if not len(self.scored_documents):
if not len(self.typed_documents):
return t('COULD_NOT_FIND_ANYTHING', language=self.chat.language), [close_button(self.session_id)]
serp_elements = [
f'Linked to: {self.referencing_to}',
]
for scored_document in self.scored_documents:
view = parse_typed_document_to_view(scored_document.typed_document)
view_command = view.get_view_command(
session_id=self.session_id,
message_id=self.message_id,
parent_view_type='r',
position=scored_document.position,
)
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,
view_command=view_command,
limit=512 + 128,
)
)
@ -111,17 +63,17 @@ class DocumentListWidget:
buttons = [
Button.inline(
text='<<1' if self.page > 1 else ' ',
data=f'/rp_{self.session_id}_{self.message_id}_{self.referencing_to}_0'
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'/rp_{self.session_id}_{self.message_id}_{self.referencing_to}_{self.page - 1}'
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'/rp_{self.session_id}_{self.message_id}_{self.referencing_to}_{self.page + 1}'
data=f'/{self.cmd}_{self.session_id}_{self.message_id}_{self.page + 1}'
if self.has_next else '/noop',
)
]

View File

@ -16,6 +16,10 @@ from nexus.meta_api.proto.documents_service_pb2 import \
RollRequest as RollRequestPb
from nexus.meta_api.proto.documents_service_pb2 import \
RollResponse as RollResponsePb
from nexus.meta_api.proto.documents_service_pb2 import \
TopMissedRequest as TopMissedRequestPb
from nexus.meta_api.proto.documents_service_pb2 import \
TopMissedResponse as TopMissedResponsePb
from nexus.meta_api.proto.documents_service_pb2 import \
TypedDocumentRequest as TypedDocumentRequestPb
from nexus.meta_api.proto.documents_service_pb2_grpc import DocumentsStub
@ -130,3 +134,23 @@ class MetaApiGrpcClient(AioThing):
('request-id', request_id),
),
)
async def top_missed(
self,
page: int,
page_size: int,
request_id: Optional[str] = None,
session_id: Optional[str] = None,
user_id: Optional[int] = None,
) -> TopMissedResponsePb:
return await self.documents_stub.top_missed(
TopMissedRequestPb(
page=page,
page_size=page_size,
session_id=session_id,
user_id=user_id,
),
metadata=(
('request-id', request_id),
),
)

View File

@ -13,6 +13,18 @@ message RollResponse {
uint64 document_id = 1;
}
message TopMissedRequest {
uint32 page = 1;
uint32 page_size = 2;
string session_id = 3;
int64 user_id = 4;
}
message TopMissedResponse {
repeated nexus.models.proto.TypedDocument typed_documents = 1;
bool has_next = 2;
}
message TypedDocumentRequest {
string schema = 1;
uint64 document_id = 2;
@ -26,4 +38,5 @@ message PutTypedDocumentResponse {}
service Documents {
rpc get (TypedDocumentRequest) returns (nexus.models.proto.TypedDocument) {}
rpc roll (RollRequest) returns (RollResponse) {}
rpc top_missed (TopMissedRequest) returns (TopMissedResponse) {}
}

View File

@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n,nexus/meta_api/proto/documents_service.proto\x12\x14nexus.meta_api.proto\x1a\'nexus/models/proto/typed_document.proto\"D\n\x0bRollRequest\x12\x10\n\x08language\x18\x01 \x01(\t\x12\x12\n\nsession_id\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\x03\"#\n\x0cRollResponse\x12\x13\n\x0b\x64ocument_id\x18\x01 \x01(\x04\"r\n\x14TypedDocumentRequest\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12\x13\n\x0b\x64ocument_id\x18\x02 \x01(\x04\x12\x10\n\x08position\x18\x03 \x01(\r\x12\x12\n\nsession_id\x18\x04 \x01(\t\x12\x0f\n\x07user_id\x18\x05 \x01(\x03\"\x1a\n\x18PutTypedDocumentResponse2\xb4\x01\n\tDocuments\x12V\n\x03get\x12*.nexus.meta_api.proto.TypedDocumentRequest\x1a!.nexus.models.proto.TypedDocument\"\x00\x12O\n\x04roll\x12!.nexus.meta_api.proto.RollRequest\x1a\".nexus.meta_api.proto.RollResponse\"\x00\x62\x06proto3'
serialized_pb=b'\n,nexus/meta_api/proto/documents_service.proto\x12\x14nexus.meta_api.proto\x1a\'nexus/models/proto/typed_document.proto\"D\n\x0bRollRequest\x12\x10\n\x08language\x18\x01 \x01(\t\x12\x12\n\nsession_id\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\x03\"#\n\x0cRollResponse\x12\x13\n\x0b\x64ocument_id\x18\x01 \x01(\x04\"X\n\x10TopMissedRequest\x12\x0c\n\x04page\x18\x01 \x01(\r\x12\x11\n\tpage_size\x18\x02 \x01(\r\x12\x12\n\nsession_id\x18\x03 \x01(\t\x12\x0f\n\x07user_id\x18\x04 \x01(\x03\"a\n\x11TopMissedResponse\x12:\n\x0ftyped_documents\x18\x01 \x03(\x0b\x32!.nexus.models.proto.TypedDocument\x12\x10\n\x08has_next\x18\x02 \x01(\x08\"r\n\x14TypedDocumentRequest\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12\x13\n\x0b\x64ocument_id\x18\x02 \x01(\x04\x12\x10\n\x08position\x18\x03 \x01(\r\x12\x12\n\nsession_id\x18\x04 \x01(\t\x12\x0f\n\x07user_id\x18\x05 \x01(\x03\"\x1a\n\x18PutTypedDocumentResponse2\x95\x02\n\tDocuments\x12V\n\x03get\x12*.nexus.meta_api.proto.TypedDocumentRequest\x1a!.nexus.models.proto.TypedDocument\"\x00\x12O\n\x04roll\x12!.nexus.meta_api.proto.RollRequest\x1a\".nexus.meta_api.proto.RollResponse\"\x00\x12_\n\ntop_missed\x12&.nexus.meta_api.proto.TopMissedRequest\x1a\'.nexus.meta_api.proto.TopMissedResponse\"\x00\x62\x06proto3'
,
dependencies=[nexus_dot_models_dot_proto_dot_typed__document__pb2.DESCRIPTOR,])
@ -106,6 +106,98 @@ _ROLLRESPONSE = _descriptor.Descriptor(
)
_TOPMISSEDREQUEST = _descriptor.Descriptor(
name='TopMissedRequest',
full_name='nexus.meta_api.proto.TopMissedRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='page', full_name='nexus.meta_api.proto.TopMissedRequest.page', index=0,
number=1, type=13, cpp_type=3, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='page_size', full_name='nexus.meta_api.proto.TopMissedRequest.page_size', index=1,
number=2, type=13, cpp_type=3, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='session_id', full_name='nexus.meta_api.proto.TopMissedRequest.session_id', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='user_id', full_name='nexus.meta_api.proto.TopMissedRequest.user_id', index=3,
number=4, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=218,
serialized_end=306,
)
_TOPMISSEDRESPONSE = _descriptor.Descriptor(
name='TopMissedResponse',
full_name='nexus.meta_api.proto.TopMissedResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='typed_documents', full_name='nexus.meta_api.proto.TopMissedResponse.typed_documents', index=0,
number=1, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='has_next', full_name='nexus.meta_api.proto.TopMissedResponse.has_next', index=1,
number=2, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=308,
serialized_end=405,
)
_TYPEDDOCUMENTREQUEST = _descriptor.Descriptor(
name='TypedDocumentRequest',
full_name='nexus.meta_api.proto.TypedDocumentRequest',
@ -161,8 +253,8 @@ _TYPEDDOCUMENTREQUEST = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=218,
serialized_end=332,
serialized_start=407,
serialized_end=521,
)
@ -186,12 +278,15 @@ _PUTTYPEDDOCUMENTRESPONSE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=334,
serialized_end=360,
serialized_start=523,
serialized_end=549,
)
_TOPMISSEDRESPONSE.fields_by_name['typed_documents'].message_type = nexus_dot_models_dot_proto_dot_typed__document__pb2._TYPEDDOCUMENT
DESCRIPTOR.message_types_by_name['RollRequest'] = _ROLLREQUEST
DESCRIPTOR.message_types_by_name['RollResponse'] = _ROLLRESPONSE
DESCRIPTOR.message_types_by_name['TopMissedRequest'] = _TOPMISSEDREQUEST
DESCRIPTOR.message_types_by_name['TopMissedResponse'] = _TOPMISSEDRESPONSE
DESCRIPTOR.message_types_by_name['TypedDocumentRequest'] = _TYPEDDOCUMENTREQUEST
DESCRIPTOR.message_types_by_name['PutTypedDocumentResponse'] = _PUTTYPEDDOCUMENTRESPONSE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@ -210,6 +305,20 @@ RollResponse = _reflection.GeneratedProtocolMessageType('RollResponse', (_messag
})
_sym_db.RegisterMessage(RollResponse)
TopMissedRequest = _reflection.GeneratedProtocolMessageType('TopMissedRequest', (_message.Message,), {
'DESCRIPTOR' : _TOPMISSEDREQUEST,
'__module__' : 'nexus.meta_api.proto.documents_service_pb2'
# @@protoc_insertion_point(class_scope:nexus.meta_api.proto.TopMissedRequest)
})
_sym_db.RegisterMessage(TopMissedRequest)
TopMissedResponse = _reflection.GeneratedProtocolMessageType('TopMissedResponse', (_message.Message,), {
'DESCRIPTOR' : _TOPMISSEDRESPONSE,
'__module__' : 'nexus.meta_api.proto.documents_service_pb2'
# @@protoc_insertion_point(class_scope:nexus.meta_api.proto.TopMissedResponse)
})
_sym_db.RegisterMessage(TopMissedResponse)
TypedDocumentRequest = _reflection.GeneratedProtocolMessageType('TypedDocumentRequest', (_message.Message,), {
'DESCRIPTOR' : _TYPEDDOCUMENTREQUEST,
'__module__' : 'nexus.meta_api.proto.documents_service_pb2'
@ -233,8 +342,8 @@ _DOCUMENTS = _descriptor.ServiceDescriptor(
index=0,
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_start=363,
serialized_end=543,
serialized_start=552,
serialized_end=829,
methods=[
_descriptor.MethodDescriptor(
name='get',
@ -256,6 +365,16 @@ _DOCUMENTS = _descriptor.ServiceDescriptor(
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.MethodDescriptor(
name='top_missed',
full_name='nexus.meta_api.proto.Documents.top_missed',
index=2,
containing_service=None,
input_type=_TOPMISSEDREQUEST,
output_type=_TOPMISSEDRESPONSE,
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
])
_sym_db.RegisterServiceDescriptor(_DOCUMENTS)

View File

@ -27,6 +27,11 @@ class DocumentsStub(object):
request_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollRequest.SerializeToString,
response_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollResponse.FromString,
)
self.top_missed = channel.unary_unary(
'/nexus.meta_api.proto.Documents/top_missed',
request_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TopMissedRequest.SerializeToString,
response_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TopMissedResponse.FromString,
)
class DocumentsServicer(object):
@ -44,6 +49,12 @@ class DocumentsServicer(object):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def top_missed(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_DocumentsServicer_to_server(servicer, server):
rpc_method_handlers = {
@ -57,6 +68,11 @@ def add_DocumentsServicer_to_server(servicer, server):
request_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollRequest.FromString,
response_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollResponse.SerializeToString,
),
'top_missed': grpc.unary_unary_rpc_method_handler(
servicer.top_missed,
request_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TopMissedRequest.FromString,
response_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TopMissedResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'nexus.meta_api.proto.Documents', rpc_method_handlers)
@ -100,3 +116,20 @@ class Documents(object):
nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def top_missed(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/nexus.meta_api.proto.Documents/top_missed',
nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TopMissedRequest.SerializeToString,
nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TopMissedResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

View File

@ -5,8 +5,8 @@ import "nexus/models/proto/typed_document.proto";
message ScoredDocument {
nexus.models.proto.TypedDocument typed_document = 1;
float score = 3;
uint32 position = 4;
float score = 2;
uint32 position = 3;
}
message SearchResponse {

View File

@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n.nexus/meta_api/proto/meta_search_service.proto\x12\x14nexus.meta_api.proto\x1a\'nexus/models/proto/typed_document.proto\"l\n\x0eScoredDocument\x12\x39\n\x0etyped_document\x18\x01 \x01(\x0b\x32!.nexus.models.proto.TypedDocument\x12\r\n\x05score\x18\x03 \x01(\x02\x12\x10\n\x08position\x18\x04 \x01(\r\"b\n\x0eSearchResponse\x12>\n\x10scored_documents\x18\x01 \x03(\x0b\x32$.nexus.meta_api.proto.ScoredDocument\x12\x10\n\x08has_next\x18\x02 \x01(\x08\"\xa3\x01\n\rSearchRequest\x12\x0f\n\x07schemas\x18\x01 \x03(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0c\n\x04page\x18\x03 \x01(\r\x12\x11\n\tpage_size\x18\x04 \x01(\r\x12\x10\n\x08language\x18\x05 \x01(\t\x12\x0f\n\x07user_id\x18\x06 \x01(\x03\x12\x12\n\nsession_id\x18\x07 \x01(\t\x12\x1a\n\x12skip_query_rewrite\x18\t \x01(\x08\x32\x63\n\nMetaSearch\x12U\n\x06search\x12#.nexus.meta_api.proto.SearchRequest\x1a$.nexus.meta_api.proto.SearchResponse\"\x00\x62\x06proto3'
serialized_pb=b'\n.nexus/meta_api/proto/meta_search_service.proto\x12\x14nexus.meta_api.proto\x1a\'nexus/models/proto/typed_document.proto\"l\n\x0eScoredDocument\x12\x39\n\x0etyped_document\x18\x01 \x01(\x0b\x32!.nexus.models.proto.TypedDocument\x12\r\n\x05score\x18\x02 \x01(\x02\x12\x10\n\x08position\x18\x03 \x01(\r\"b\n\x0eSearchResponse\x12>\n\x10scored_documents\x18\x01 \x03(\x0b\x32$.nexus.meta_api.proto.ScoredDocument\x12\x10\n\x08has_next\x18\x02 \x01(\x08\"\x87\x01\n\rSearchRequest\x12\x0f\n\x07schemas\x18\x01 \x03(\t\x12\r\n\x05query\x18\x02 \x01(\t\x12\x0c\n\x04page\x18\x03 \x01(\r\x12\x11\n\tpage_size\x18\x04 \x01(\r\x12\x10\n\x08language\x18\x05 \x01(\t\x12\x0f\n\x07user_id\x18\x06 \x01(\x03\x12\x12\n\nsession_id\x18\x07 \x01(\t2c\n\nMetaSearch\x12U\n\x06search\x12#.nexus.meta_api.proto.SearchRequest\x1a$.nexus.meta_api.proto.SearchResponse\"\x00\x62\x06proto3'
,
dependencies=[nexus_dot_models_dot_proto_dot_typed__document__pb2.DESCRIPTOR,])
@ -45,14 +45,14 @@ _SCOREDDOCUMENT = _descriptor.Descriptor(
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='score', full_name='nexus.meta_api.proto.ScoredDocument.score', index=1,
number=3, type=2, cpp_type=6, label=1,
number=2, type=2, cpp_type=6, label=1,
has_default_value=False, default_value=float(0),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='position', full_name='nexus.meta_api.proto.ScoredDocument.position', index=2,
number=4, type=13, cpp_type=3, label=1,
number=3, type=13, cpp_type=3, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
@ -170,13 +170,6 @@ _SEARCHREQUEST = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='skip_query_rewrite', full_name='nexus.meta_api.proto.SearchRequest.skip_query_rewrite', index=7,
number=9, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
@ -190,7 +183,7 @@ _SEARCHREQUEST = _descriptor.Descriptor(
oneofs=[
],
serialized_start=324,
serialized_end=487,
serialized_end=459,
)
_SCOREDDOCUMENT.fields_by_name['typed_document'].message_type = nexus_dot_models_dot_proto_dot_typed__document__pb2._TYPEDDOCUMENT
@ -230,8 +223,8 @@ _METASEARCH = _descriptor.ServiceDescriptor(
index=0,
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_start=489,
serialized_end=588,
serialized_start=461,
serialized_end=560,
methods=[
_descriptor.MethodDescriptor(
name='search',

View File

@ -6,6 +6,7 @@ from typing import (
)
from urllib.parse import quote
from izihawa_types.safecast import safe_int
from izihawa_utils.common import filter_none
from nexus.models.proto.scimag_pb2 import Scimag as ScimagPb
from nexus.nlptools.utils import (
@ -204,16 +205,17 @@ class ScimagView(BaseView, AuthorMixin, DoiMixin, FileMixin, IssuedAtMixin):
)
if self.ref_by_count:
buttons[-1].append(
Button.inline(
Button.switch_inline(
text=f'🔗 {self.ref_by_count or ""}',
data=f'/r_{session_id}_{self.id}',
query=f'references:"{self.doi}"',
same_peer=True,
)
)
buttons[-1].append(close_button(session_id))
return '\n'.join(parts).strip()[:4096], buttons
def get_view_command(self, session_id: str, message_id: int, parent_view_type: str = 's', position: int = 0) -> str:
return f'/va{parent_view_type}_{session_id}_{message_id}_{self.id}_{position}'
def get_view_command(self, session_id: str, message_id: int, position: int = 0) -> str:
return f'/va_{session_id}_{message_id}_{self.id}_{position}'
def get_robust_journal(self):
if self.type != 'chapter' and self.type != 'book-chapter':
@ -231,5 +233,8 @@ class ScimagView(BaseView, AuthorMixin, DoiMixin, FileMixin, IssuedAtMixin):
if self.volume:
if self.issue:
return f'vol. {self.volume}({self.issue})'
else:
if safe_int(self.volume):
return f'vol. {self.volume}'
else:
return self.volume