Code clean up

This commit is contained in:
2022-04-10 16:40:56 +03:00
parent e536574e84
commit 138e0ffa2f
20 changed files with 12 additions and 525 deletions

View File

@@ -3,8 +3,6 @@ from typing import Optional
from pydantic import BaseModel
from app.serializers.orjson_config import ORJSONConfig
class Author(BaseModel):
id: int
@@ -15,30 +13,6 @@ class Author(BaseModel):
annotation_exists: bool
class Config(ORJSONConfig):
pass
class CreateAuthor(BaseModel):
source: int
remote_id: int
first_name: str
last_name: str
middle_name: Optional[str]
class Config(ORJSONConfig):
pass
class UpdateAuthor(BaseModel):
first_name: str
last_name: str
middle_name: Optional[str]
class Config(ORJSONConfig):
pass
class AuthorBook(BaseModel):
id: int
@@ -50,9 +24,6 @@ class AuthorBook(BaseModel):
translators: list[Author]
annotation_exists: bool
class Config(ORJSONConfig):
pass
class TranslatedBook(BaseModel):
id: int
@@ -62,6 +33,3 @@ class TranslatedBook(BaseModel):
available_types: list[str]
authors: list[Author]
annotation_exists: bool
class Config(ORJSONConfig):
pass

View File

@@ -2,33 +2,9 @@ from typing import Optional
from pydantic import BaseModel
from app.serializers.orjson_config import ORJSONConfig
class AuthorAnnotation(BaseModel):
id: int
title: str
text: str
file: Optional[str]
class Config(ORJSONConfig):
pass
class CreateAuthorAnnotation(BaseModel):
author: int
title: str
text: str
file: Optional[str]
class Config(ORJSONConfig):
pass
class UpdateAuthorAnnotation(BaseModel):
title: str
text: str
file: Optional[str]
class Config(ORJSONConfig):
pass

View File

@@ -3,7 +3,6 @@ from datetime import date
from pydantic import BaseModel
from app.serializers.author import Author
from app.serializers.orjson_config import ORJSONConfig
from app.serializers.sequence import Sequence
@@ -28,9 +27,6 @@ class Book(BaseModel):
translators: list[Author]
annotation_exists: bool
class Config(ORJSONConfig):
pass
class RemoteBook(Book):
source: BookSource
@@ -41,40 +37,3 @@ class BookDetail(RemoteBook):
sequences: list[Sequence]
genres: list[BookGenre]
is_deleted: bool
class CreateBook(BaseModel):
source: int
remote_id: int
title: str
lang: str
file_type: str
uploaded: date
authors: list[int]
class Config(ORJSONConfig):
pass
class UpdateBook(BaseModel):
title: str
lang: str
file_type: str
uploaded: date
authors: list[int]
class Config(ORJSONConfig):
pass
class CreateRemoteBook(BaseModel):
source: int
remote_id: int
title: str
lang: str
file_type: str
uploaded: date
remote_authors: list[int]
class Config(ORJSONConfig):
pass

View File

@@ -2,34 +2,9 @@ from typing import Optional
from pydantic import BaseModel
from app.serializers.orjson_config import ORJSONConfig
class BookAnnotation(BaseModel):
id: int
title: str
text: str
file: Optional[str]
class Config(ORJSONConfig):
pass
class CreateBookAnnotation(BaseModel):
id: int
title: str
text: str
file: Optional[str]
class Config(ORJSONConfig):
pass
class UpdateBookAnnotation(BaseModel):
id: int
title: str
text: str
file: Optional[str]
class Config(ORJSONConfig):
pass

View File

@@ -1,6 +1,4 @@
from pydantic import BaseModel, constr
from app.serializers.orjson_config import ORJSONConfig
from pydantic import BaseModel
class GenreSource(BaseModel):
@@ -15,28 +13,3 @@ class Genre(BaseModel):
code: str
description: str
meta: str
class Config(ORJSONConfig):
pass
class CreateGenre(BaseModel):
source: int
remote_id: int
code: constr(max_length=45) # type: ignore
description: constr(max_length=99) # type: ignore
meta: constr(max_length=45) # type: ignore
class Config(ORJSONConfig):
pass
class UpdateGenre(BaseModel):
source: int
remote_id: int
code: constr(max_length=45) # type: ignore
description: constr(max_length=99) # type: ignore
meta: constr(max_length=45) # type: ignore
class Config(ORJSONConfig):
pass

View File

@@ -1,10 +0,0 @@
import orjson
def orjson_dumps(v, *, default):
return orjson.dumps(v, default=default).decode()
class ORJSONConfig:
json_loads = orjson.loads
json_dumps = orjson_dumps

View File

@@ -3,25 +3,11 @@ from typing import Optional
from pydantic import BaseModel
from app.serializers.orjson_config import ORJSONConfig
class Sequence(BaseModel):
id: int
name: str
class Config(ORJSONConfig):
pass
class CreateSequence(BaseModel):
source: int
remote_id: int
name: str
class Config(ORJSONConfig):
pass
class Author(BaseModel):
id: int
@@ -30,9 +16,6 @@ class Author(BaseModel):
last_name: str
middle_name: Optional[str]
class Config(ORJSONConfig):
pass
class Book(BaseModel):
id: int
@@ -44,6 +27,3 @@ class Book(BaseModel):
authors: list[Author]
translators: list[Author]
annotation_exists: bool
class Config(ORJSONConfig):
pass

View File

@@ -1,18 +1,6 @@
from pydantic import BaseModel
from app.serializers.orjson_config import ORJSONConfig
class Source(BaseModel):
id: int
name: str
class Config(ORJSONConfig):
pass
class CreateSource(BaseModel):
name: str
class Config(ORJSONConfig):
pass

View File

@@ -1,7 +1,5 @@
from pydantic import BaseModel
from app.serializers.orjson_config import ORJSONConfig
class TranslationBook(BaseModel):
id: int
@@ -9,9 +7,6 @@ class TranslationBook(BaseModel):
lang: str
file_type: str
class Config(ORJSONConfig):
pass
class TranslationTranslator(BaseModel):
id: int
@@ -19,33 +14,8 @@ class TranslationTranslator(BaseModel):
last_name: str
middle_name: str
class Config(ORJSONConfig):
pass
class Translation(BaseModel):
book: TranslationBook
translator: TranslationTranslator
position: int
class Config(ORJSONConfig):
pass
class CreateTranslation(BaseModel):
book: int
translator: int
position: int
class Config(ORJSONConfig):
pass
class CreateRemoteTranslation(BaseModel):
source: int
remote_book: int
remote_translator: int
position: int
class Config(ORJSONConfig):
pass

View File

@@ -1,10 +1,4 @@
from typing import Union
from fastapi import HTTPException, status
from app.models import Author as AuthorDB
from app.models import Book as BookDB
from app.serializers.book import CreateBook, CreateRemoteBook
from app.services.common import (
TRGMSearchService,
MeiliSearchService,
@@ -40,55 +34,6 @@ class BookFilterService(BaseFilterService):
SELECT_RELATED = ["authors", "translators", "annotations"]
class BookCreator:
@classmethod
def _raise_bad_request(cls):
raise HTTPException(status.HTTP_404_NOT_FOUND)
@classmethod
async def _create_book(cls, data: CreateBook) -> BookDB:
data_dict = data.dict()
author_ids = data_dict.pop("authors", [])
authors = await AuthorDB.objects.filter(id__in=author_ids).all()
if len(author_ids) != len(authors):
cls._raise_bad_request()
book = await BookDB.objects.create(**data_dict)
for author in authors:
await book.authors.add(author)
return book
@classmethod
async def _create_remote_book(cls, data: CreateRemoteBook) -> BookDB:
data_dict = data.dict()
author_ids = data_dict.pop("remote_authors", [])
authors = await AuthorDB.objects.filter(
source__id=data.source, remote_id__in=author_ids
).all()
if len(author_ids) != len(authors):
cls._raise_bad_request()
book = await BookDB.objects.create(**data_dict)
for author in authors:
await book.authors.add(author)
return book
@classmethod
async def create(cls, data: Union[CreateBook, CreateRemoteBook]) -> BookDB:
if isinstance(data, CreateBook):
return await cls._create_book(data)
if isinstance(data, CreateRemoteBook):
return await cls._create_remote_book(data)
GET_OBJECTS_ID_QUERY = """
WITH filtered_books AS (
SELECT id FROM books

View File

@@ -1,57 +0,0 @@
from typing import Union
from fastapi import HTTPException, status
from app.models import Author as AuthorDB
from app.models import Book as BookDB
from app.models import Source as SourceDB
from app.models import Translation as TranslationDB
from app.serializers.translation import CreateTranslation, CreateRemoteTranslation
class TranslationCreator:
@classmethod
def _raise_bad_request(cls):
raise HTTPException(status.HTTP_404_NOT_FOUND)
@classmethod
async def _create_translation(cls, data: CreateTranslation) -> TranslationDB:
return await TranslationDB.objects.create(**data.dict())
@classmethod
async def _create_remote_translation(
cls, data: CreateRemoteTranslation
) -> TranslationDB:
source = await SourceDB.objects.get_or_none(id=data.source)
if source is None:
cls._raise_bad_request()
book = await BookDB.objects.get_or_none(
source__id=source.id, remote_id=data.remote_book
)
if book is None:
cls._raise_bad_request()
translator = await AuthorDB.objects.get_or_none(
source__id=source.id, remote_id=data.remote_translator
)
if translator is None:
cls._raise_bad_request()
return await TranslationDB.objects.create(
book=book.id,
translator=translator.id,
position=data.position,
)
@classmethod
async def create(
cls, data: Union[CreateTranslation, CreateRemoteTranslation]
) -> TranslationDB:
if isinstance(data, CreateTranslation):
return await cls._create_translation(data)
if isinstance(data, CreateRemoteTranslation):
return await cls._create_remote_translation(data)

View File

@@ -7,13 +7,7 @@ from app.depends import check_token, get_allowed_langs
from app.models import Author as AuthorDB
from app.models import AuthorAnnotation as AuthorAnnotationDB
from app.models import Book as BookDB
from app.serializers.author import (
Author,
CreateAuthor,
UpdateAuthor,
AuthorBook,
TranslatedBook,
)
from app.serializers.author import Author, AuthorBook, TranslatedBook
from app.serializers.author_annotation import AuthorAnnotation
from app.services.author import AuthorMeiliSearchService, GetRandomAuthorService
from app.services.translator import TranslatorMeiliSearchService
@@ -42,17 +36,6 @@ async def get_authors():
)
@author_router.post("/", response_model=Author, dependencies=[Depends(Params)])
async def create_author(data: CreateAuthor):
author = await AuthorDB.objects.create(**data.dict())
return (
await AuthorDB.objects.select_related(SELECT_RELATED_FIELDS)
.prefetch_related(PREFETCH_RELATED_FIELDS)
.get(id=author.id)
)
@author_router.get("/random", response_model=Author)
async def get_random_author(
request: Request,
@@ -83,18 +66,6 @@ async def get_author(id: int):
return author
@author_router.put("/{id}", response_model=Author)
async def update_author(id: int, data: UpdateAuthor):
author = await AuthorDB.objects.get_or_none(id=id)
if author is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
author.update_from_dict(data.dict())
return await author.save()
@author_router.get("/{id}/annotation", response_model=AuthorAnnotation)
async def get_author_annotation(id: int):
annotation = await AuthorAnnotationDB.objects.get_or_none(author__id=id)

View File

@@ -5,11 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token
from app.models import AuthorAnnotation as AuthorAnnotationDB
from app.serializers.author_annotation import (
AuthorAnnotation,
CreateAuthorAnnotation,
UpdateAuthorAnnotation,
)
from app.serializers.author_annotation import AuthorAnnotation
author_annotation_router = APIRouter(
@@ -26,11 +22,6 @@ async def get_author_annotations():
return await paginate(AuthorAnnotationDB.objects)
@author_annotation_router.post("/", response_model=AuthorAnnotation)
async def create_author_annotation(data: CreateAuthorAnnotation):
return await AuthorAnnotationDB.objects.create(**data.dict())
@author_annotation_router.get("/{id}", response_model=AuthorAnnotation)
async def get_author_annotation(id: int):
annotation = await AuthorAnnotationDB.objects.get_or_none(id=id)
@@ -39,15 +30,3 @@ async def get_author_annotation(id: int):
raise HTTPException(status.HTTP_404_NOT_FOUND)
return annotation
@author_annotation_router.put("/{id}", response_model=AuthorAnnotation)
async def update_author_annotation(id: int, data: UpdateAuthorAnnotation):
annotation = await AuthorAnnotationDB.objects.get_or_none(id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
annotation.update_from_dict(data.dict())
return await annotation.save()

View File

@@ -1,28 +1,17 @@
from typing import Union
from fastapi import APIRouter, Depends, Request, HTTPException, status
from fastapi_pagination import Params
from app.depends import check_token, get_allowed_langs
from app.filters.book import get_book_filter
from app.models import Author as AuthorDB
from app.models import Book as BookDB
from app.models import BookAnnotation as BookAnnotationDB
from app.serializers.book import (
Book,
RemoteBook,
BookDetail,
CreateBook,
UpdateBook,
CreateRemoteBook,
)
from app.serializers.book import Book, RemoteBook, BookDetail
from app.serializers.book_annotation import BookAnnotation
from app.services.book import (
BookMeiliSearchService,
BookFilterService,
GetRandomBookService,
BookCreator,
)
from app.utils.pagination import CustomPage
@@ -49,17 +38,6 @@ async def get_books(
return await BookFilterService.get(book_filter, request.app.state.redis)
@book_router.post("/", response_model=Book)
async def create_book(data: Union[CreateBook, CreateRemoteBook]):
book = await BookCreator.create(data)
return (
await BookDB.objects.select_related(SELECT_RELATED_FIELDS)
.prefetch_related(PREFETCH_RELATED_FIELDS)
.get(id=book.id)
)
@book_router.get("/random", response_model=BookDetail)
async def get_random_book(
request: Request,
@@ -110,33 +88,6 @@ async def get_remote_book(source_id: int, remote_id: int):
return book
@book_router.put("/{id}", response_model=Book)
async def update_book(id: int, data: UpdateBook):
book = (
await BookDB.objects.select_related(SELECT_RELATED_FIELDS)
.prefetch_related(PREFETCH_RELATED_FIELDS)
.get_or_none(id=id)
)
if book is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
for author in list(book.authors):
await book.authors.remove(author)
data_dict = data.dict()
author_ids = data_dict.pop("authors", [])
authors = await AuthorDB.objects.filter(id__in=author_ids).all()
book = await BookDB.objects.create(**data_dict)
for author in authors:
await book.authors.add(author)
return book
@book_router.get("/{id}/annotation", response_model=BookAnnotation)
async def get_book_annotation(id: int):
annotation = await BookAnnotationDB.objects.get(book__id=id)

View File

@@ -5,11 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token
from app.models import BookAnnotation as BookAnnotationDB
from app.serializers.book_annotation import (
BookAnnotation,
CreateBookAnnotation,
UpdateBookAnnotation,
)
from app.serializers.book_annotation import BookAnnotation
book_annotation_router = APIRouter(
@@ -26,11 +22,6 @@ async def get_book_annotations():
return await paginate(BookAnnotationDB.objects)
@book_annotation_router.post("/", response_model=BookAnnotation)
async def create_book_annotation(data: CreateBookAnnotation):
return await BookAnnotationDB.objects.create(**data.dict())
@book_annotation_router.get("/{id}", response_model=BookAnnotation)
async def get_book_annotation(id: int):
annotation = await BookAnnotationDB.objects.get_or_none(id=id)
@@ -39,15 +30,3 @@ async def get_book_annotation(id: int):
raise HTTPException(status.HTTP_404_NOT_FOUND)
return annotation
@book_annotation_router.put("/{id}", response_model=BookAnnotation)
async def update_book_annotation(id: int, data: UpdateBookAnnotation):
annotation = await BookAnnotationDB.objects.get_or_none(id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
annotation.update_from_dict(data.dict())
return annotation.save()

View File

@@ -5,7 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token
from app.models import Genre as GenreDB
from app.serializers.genre import Genre, CreateGenre, UpdateGenre
from app.serializers.genre import Genre
genre_router = APIRouter(
@@ -31,24 +31,3 @@ async def get_genre(id: int):
raise HTTPException(status.HTTP_404_NOT_FOUND)
return genre
@genre_router.post("/", response_model=Genre)
async def create_genre(data: CreateGenre):
return await GenreDB.objects.prefetch_related(PREFETCH_RELATED_FIELDS).create(
**data.dict()
)
@genre_router.put("/{id}", response_model=Genre)
async def update_genre(id: int, data: UpdateGenre):
genre = await GenreDB.objects.prefetch_related(PREFETCH_RELATED_FIELDS).get_or_none(
id=id
)
if genre is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
genre.update_from_dict(data.dict())
return await genre.save()

View File

@@ -7,7 +7,7 @@ from app.depends import check_token, get_allowed_langs
from app.models import Book as BookDB
from app.models import Sequence as SequenceDB
from app.serializers.sequence import Book as SequenceBook
from app.serializers.sequence import Sequence, CreateSequence
from app.serializers.sequence import Sequence
from app.services.sequence import SequenceMeiliSearchService, GetRandomSequenceService
from app.utils.pagination import CustomPage
@@ -60,11 +60,6 @@ async def get_sequence_books(
)
@sequence_router.post("/", response_model=Sequence)
async def create_sequence(data: CreateSequence):
return await SequenceDB.objects.create(**data.dict())
@sequence_router.get(
"/search/{query}",
response_model=CustomPage[Sequence],

View File

@@ -5,7 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token
from app.models import Source as SourceDB
from app.serializers.source import Source, CreateSource
from app.serializers.source import Source
source_router = APIRouter(
@@ -18,8 +18,3 @@ source_router = APIRouter(
@source_router.get("", response_model=Page[Source], dependencies=[Depends(Params)])
async def get_sources():
return await paginate(SourceDB.objects)
@source_router.post("", response_model=Source)
async def create_source(data: CreateSource):
return await SourceDB.objects.create(**data.dict())

View File

@@ -1,18 +1,11 @@
from typing import Union
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, Depends
from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token
from app.models import Translation as TranslationDB
from app.serializers.translation import (
Translation,
CreateTranslation,
CreateRemoteTranslation,
)
from app.services.translation import TranslationCreator
from app.serializers.translation import Translation
from app.utils.pagination import CustomPage
@@ -28,26 +21,3 @@ translation_router = APIRouter(
)
async def get_translations():
return await paginate(TranslationDB.objects.select_related(["book", "author"]))
@translation_router.post("/", response_model=Translation)
async def create_translation(data: Union[CreateTranslation, CreateRemoteTranslation]):
translation = await TranslationCreator.create(data)
return await TranslationDB.objects.select_related(["book", "author"]).get(
id=translation.id
)
@translation_router.delete("/{id}", response_model=Translation)
async def delete_translation(id: int):
translation = await TranslationDB.objects.select_related(
["book", "author"]
).get_or_none(id=id)
if translation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
await translation.delete()
return translation