Add translator endpoints

This commit is contained in:
2022-01-03 13:20:36 +03:00
parent 8188d23405
commit 0461a9918b
5 changed files with 109 additions and 15 deletions

View File

@@ -90,6 +90,20 @@ def upgrade():
unique=False,
postgresql_using="btree",
)
op.create_index(
op.f("translations_book"),
"translations",
["book"],
unique=False,
postgresql_using="btree",
)
op.create_index(
op.f("translations_author"),
"translations",
["author"],
unique=False,
postgresql_using="btree",
)
# ### end Alembic commands ###
@@ -108,4 +122,6 @@ def downgrade():
op.drop_index(op.f("book_authors_author"), table_name="book_authors")
op.drop_index(op.f("book_sequences_book"), table_name="book_sequences")
op.drop_index(op.f("book_sequences_sequence"), table_name="book_sequences")
op.drop_index(op.f("translations_book"), table_name="translations")
op.drop_index(op.f("translations_author"), table_name="translations")
# ### end Alembic commands ###

View File

@@ -19,6 +19,7 @@ class TRGMSearchService(Generic[T]):
SELECT_RELATED: Optional[Union[list[str], str]] = None
PREFETCH_RELATED: Optional[Union[list[str], str]] = None
GET_OBJECT_IDS_QUERY: Optional[str] = None
CUSTOM_CACHE_PREFIX: Optional[str] = None
CACHE_TTL = 60 * 60
@classmethod
@@ -66,9 +67,14 @@ class TRGMSearchService(Generic[T]):
return row["array"]
@classmethod
@property
def cache_prefix(cls) -> str:
return cls.CUSTOM_CACHE_PREFIX or cls.model.__class__.__name__
@classmethod
def get_cache_key(cls, query_data: str, allowed_langs: list[str]) -> str:
model_class_name = cls.model.__class__.__name__
model_class_name = cls.cache_prefix
allowed_langs_part = ",".join(allowed_langs)
return f"{model_class_name}_{query_data}_{allowed_langs_part}"

View File

@@ -0,0 +1,52 @@
from app.models import Author
from app.services.common import TRGMSearchService
GET_OBJECT_IDS_QUERY = """
SELECT ARRAY(
WITH filtered_authors AS (
SELECT
id,
GREATEST(
similarity(
(last_name || ' ' || first_name || ' ' || middle_name),
:query
),
similarity((last_name || ' ' || first_name), :query),
similarity((last_name), :query)
) as sml,
(
SELECT count(*) FROM translations
LEFT JOIN books
ON (books.id = book AND
books.is_deleted = 'f' AND
books.lang = ANY(:langs ::text[]))
WHERE author = authors.id
) as books_count
FROM authors
WHERE (
(last_name || ' ' || first_name || ' ' || middle_name) % :query OR
(last_name || ' ' || first_name) % :query OR
(last_name) % :query
) AND
EXISTS (
SELECT * FROM translations
LEFT JOIN books
ON (books.id = book AND
books.is_deleted = 'f' AND
books.lang = ANY(:langs ::text[]))
WHERE author = authors.id
)
)
SELECT fauthors.id FROM filtered_authors as fauthors
ORDER BY fauthors.sml DESC, fauthors.books_count DESC
LIMIT 210
);
"""
class TranslatorTGRMSearchService(TRGMSearchService):
MODEL_CLASS = Author
CUSTOM_CACHE_PREFIX = "translator"
PREFETCH_RELATED = ["source", "annotations"]
GET_OBJECT_IDS_QUERY = GET_OBJECT_IDS_QUERY

View File

@@ -1,4 +1,4 @@
from app.views.author import author_router
from app.views.author import author_router, translator_router
from app.views.author_annotation import author_annotation_router
from app.views.book import book_router
from app.views.book_annotation import book_annotation_router
@@ -10,6 +10,7 @@ from app.views.translation import translation_router
routers = [
source_router,
author_router,
translator_router,
author_annotation_router,
book_router,
book_annotation_router,

View File

@@ -16,6 +16,7 @@ from app.serializers.author import (
)
from app.serializers.author_annotation import AuthorAnnotation
from app.services.author import AuthorTGRMSearchService, GetRandomAuthorService
from app.services.translator import TranslatorTGRMSearchService
from app.utils.pagination import CustomPage
@@ -97,19 +98,6 @@ async def get_author_books(
)
@author_router.get("/{id}/translated_books", response_model=CustomPage[TranslatedBook])
async def get_translated_books(
id: int, allowed_langs: list[str] = Depends(get_allowed_langs)
):
return await paginate(
BookDB.objects.select_related(["source", "annotations", "translators"]).filter(
translations__translator__id=id,
lang__in=allowed_langs,
is_deleted=False,
)
)
@author_router.get(
"/search/{query}", response_model=CustomPage[Author], dependencies=[Depends(Params)]
)
@@ -119,3 +107,34 @@ async def search_authors(
return await AuthorTGRMSearchService.get(
query, request.app.state.redis, allowed_langs
)
translator_router = APIRouter(
prefix="/api/v1/translators",
tags=["author"],
dependencies=[Depends(check_token)],
)
@translator_router.get("/{id}/books", response_model=CustomPage[TranslatedBook])
async def get_translated_books(
id: int, allowed_langs: list[str] = Depends(get_allowed_langs)
):
return await paginate(
BookDB.objects.select_related(["source", "annotations", "authors"]).filter(
translators__id=id,
lang__in=allowed_langs,
is_deleted=False,
)
)
@translator_router.get(
"/search/{query}", response_model=CustomPage[Author], dependencies=[Depends(Params)]
)
async def search_translators(
query: str, request: Request, allowed_langs: list[str] = Depends(get_allowed_langs)
):
return await TranslatorTGRMSearchService.get(
query, request.app.state.redis, allowed_langs
)