mirror of
https://github.com/flibusta-apps/book_library_server.git
synced 2025-12-06 07:05:36 +01:00
Code clean up
This commit is contained in:
@@ -3,8 +3,6 @@ from typing import Optional
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class Author(BaseModel):
|
class Author(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -15,30 +13,6 @@ class Author(BaseModel):
|
|||||||
|
|
||||||
annotation_exists: bool
|
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):
|
class AuthorBook(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -50,9 +24,6 @@ class AuthorBook(BaseModel):
|
|||||||
translators: list[Author]
|
translators: list[Author]
|
||||||
annotation_exists: bool
|
annotation_exists: bool
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TranslatedBook(BaseModel):
|
class TranslatedBook(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -62,6 +33,3 @@ class TranslatedBook(BaseModel):
|
|||||||
available_types: list[str]
|
available_types: list[str]
|
||||||
authors: list[Author]
|
authors: list[Author]
|
||||||
annotation_exists: bool
|
annotation_exists: bool
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -2,33 +2,9 @@ from typing import Optional
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class AuthorAnnotation(BaseModel):
|
class AuthorAnnotation(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
title: str
|
title: str
|
||||||
text: str
|
text: str
|
||||||
file: Optional[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
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from datetime import date
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.author import Author
|
from app.serializers.author import Author
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
from app.serializers.sequence import Sequence
|
from app.serializers.sequence import Sequence
|
||||||
|
|
||||||
|
|
||||||
@@ -28,9 +27,6 @@ class Book(BaseModel):
|
|||||||
translators: list[Author]
|
translators: list[Author]
|
||||||
annotation_exists: bool
|
annotation_exists: bool
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class RemoteBook(Book):
|
class RemoteBook(Book):
|
||||||
source: BookSource
|
source: BookSource
|
||||||
@@ -41,40 +37,3 @@ class BookDetail(RemoteBook):
|
|||||||
sequences: list[Sequence]
|
sequences: list[Sequence]
|
||||||
genres: list[BookGenre]
|
genres: list[BookGenre]
|
||||||
is_deleted: bool
|
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
|
|
||||||
|
|||||||
@@ -2,34 +2,9 @@ from typing import Optional
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class BookAnnotation(BaseModel):
|
class BookAnnotation(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
title: str
|
title: str
|
||||||
text: str
|
text: str
|
||||||
file: Optional[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
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
from pydantic import BaseModel, constr
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class GenreSource(BaseModel):
|
class GenreSource(BaseModel):
|
||||||
@@ -15,28 +13,3 @@ class Genre(BaseModel):
|
|||||||
code: str
|
code: str
|
||||||
description: str
|
description: str
|
||||||
meta: 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
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -3,25 +3,11 @@ from typing import Optional
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class Sequence(BaseModel):
|
class Sequence(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSequence(BaseModel):
|
|
||||||
source: int
|
|
||||||
remote_id: int
|
|
||||||
name: str
|
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Author(BaseModel):
|
class Author(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -30,9 +16,6 @@ class Author(BaseModel):
|
|||||||
last_name: str
|
last_name: str
|
||||||
middle_name: Optional[str]
|
middle_name: Optional[str]
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Book(BaseModel):
|
class Book(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -44,6 +27,3 @@ class Book(BaseModel):
|
|||||||
authors: list[Author]
|
authors: list[Author]
|
||||||
translators: list[Author]
|
translators: list[Author]
|
||||||
annotation_exists: bool
|
annotation_exists: bool
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class Source(BaseModel):
|
class Source(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSource(BaseModel):
|
|
||||||
name: str
|
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from app.serializers.orjson_config import ORJSONConfig
|
|
||||||
|
|
||||||
|
|
||||||
class TranslationBook(BaseModel):
|
class TranslationBook(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -9,9 +7,6 @@ class TranslationBook(BaseModel):
|
|||||||
lang: str
|
lang: str
|
||||||
file_type: str
|
file_type: str
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TranslationTranslator(BaseModel):
|
class TranslationTranslator(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
@@ -19,33 +14,8 @@ class TranslationTranslator(BaseModel):
|
|||||||
last_name: str
|
last_name: str
|
||||||
middle_name: str
|
middle_name: str
|
||||||
|
|
||||||
class Config(ORJSONConfig):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Translation(BaseModel):
|
class Translation(BaseModel):
|
||||||
book: TranslationBook
|
book: TranslationBook
|
||||||
translator: TranslationTranslator
|
translator: TranslationTranslator
|
||||||
position: int
|
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
|
|
||||||
|
|||||||
@@ -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.models import Book as BookDB
|
||||||
from app.serializers.book import CreateBook, CreateRemoteBook
|
|
||||||
from app.services.common import (
|
from app.services.common import (
|
||||||
TRGMSearchService,
|
TRGMSearchService,
|
||||||
MeiliSearchService,
|
MeiliSearchService,
|
||||||
@@ -40,55 +34,6 @@ class BookFilterService(BaseFilterService):
|
|||||||
SELECT_RELATED = ["authors", "translators", "annotations"]
|
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 = """
|
GET_OBJECTS_ID_QUERY = """
|
||||||
WITH filtered_books AS (
|
WITH filtered_books AS (
|
||||||
SELECT id FROM books
|
SELECT id FROM books
|
||||||
|
|||||||
@@ -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)
|
|
||||||
@@ -7,13 +7,7 @@ from app.depends import check_token, get_allowed_langs
|
|||||||
from app.models import Author as AuthorDB
|
from app.models import Author as AuthorDB
|
||||||
from app.models import AuthorAnnotation as AuthorAnnotationDB
|
from app.models import AuthorAnnotation as AuthorAnnotationDB
|
||||||
from app.models import Book as BookDB
|
from app.models import Book as BookDB
|
||||||
from app.serializers.author import (
|
from app.serializers.author import Author, AuthorBook, TranslatedBook
|
||||||
Author,
|
|
||||||
CreateAuthor,
|
|
||||||
UpdateAuthor,
|
|
||||||
AuthorBook,
|
|
||||||
TranslatedBook,
|
|
||||||
)
|
|
||||||
from app.serializers.author_annotation import AuthorAnnotation
|
from app.serializers.author_annotation import AuthorAnnotation
|
||||||
from app.services.author import AuthorMeiliSearchService, GetRandomAuthorService
|
from app.services.author import AuthorMeiliSearchService, GetRandomAuthorService
|
||||||
from app.services.translator import TranslatorMeiliSearchService
|
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)
|
@author_router.get("/random", response_model=Author)
|
||||||
async def get_random_author(
|
async def get_random_author(
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -83,18 +66,6 @@ async def get_author(id: int):
|
|||||||
return author
|
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)
|
@author_router.get("/{id}/annotation", response_model=AuthorAnnotation)
|
||||||
async def get_author_annotation(id: int):
|
async def get_author_annotation(id: int):
|
||||||
annotation = await AuthorAnnotationDB.objects.get_or_none(author__id=id)
|
annotation = await AuthorAnnotationDB.objects.get_or_none(author__id=id)
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
|
|||||||
|
|
||||||
from app.depends import check_token
|
from app.depends import check_token
|
||||||
from app.models import AuthorAnnotation as AuthorAnnotationDB
|
from app.models import AuthorAnnotation as AuthorAnnotationDB
|
||||||
from app.serializers.author_annotation import (
|
from app.serializers.author_annotation import AuthorAnnotation
|
||||||
AuthorAnnotation,
|
|
||||||
CreateAuthorAnnotation,
|
|
||||||
UpdateAuthorAnnotation,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
author_annotation_router = APIRouter(
|
author_annotation_router = APIRouter(
|
||||||
@@ -26,11 +22,6 @@ async def get_author_annotations():
|
|||||||
return await paginate(AuthorAnnotationDB.objects)
|
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)
|
@author_annotation_router.get("/{id}", response_model=AuthorAnnotation)
|
||||||
async def get_author_annotation(id: int):
|
async def get_author_annotation(id: int):
|
||||||
annotation = await AuthorAnnotationDB.objects.get_or_none(id=id)
|
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)
|
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
return annotation
|
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()
|
|
||||||
|
|||||||
@@ -1,28 +1,17 @@
|
|||||||
from typing import Union
|
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Request, HTTPException, status
|
from fastapi import APIRouter, Depends, Request, HTTPException, status
|
||||||
|
|
||||||
from fastapi_pagination import Params
|
from fastapi_pagination import Params
|
||||||
|
|
||||||
from app.depends import check_token, get_allowed_langs
|
from app.depends import check_token, get_allowed_langs
|
||||||
from app.filters.book import get_book_filter
|
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 Book as BookDB
|
||||||
from app.models import BookAnnotation as BookAnnotationDB
|
from app.models import BookAnnotation as BookAnnotationDB
|
||||||
from app.serializers.book import (
|
from app.serializers.book import Book, RemoteBook, BookDetail
|
||||||
Book,
|
|
||||||
RemoteBook,
|
|
||||||
BookDetail,
|
|
||||||
CreateBook,
|
|
||||||
UpdateBook,
|
|
||||||
CreateRemoteBook,
|
|
||||||
)
|
|
||||||
from app.serializers.book_annotation import BookAnnotation
|
from app.serializers.book_annotation import BookAnnotation
|
||||||
from app.services.book import (
|
from app.services.book import (
|
||||||
BookMeiliSearchService,
|
BookMeiliSearchService,
|
||||||
BookFilterService,
|
BookFilterService,
|
||||||
GetRandomBookService,
|
GetRandomBookService,
|
||||||
BookCreator,
|
|
||||||
)
|
)
|
||||||
from app.utils.pagination import CustomPage
|
from app.utils.pagination import CustomPage
|
||||||
|
|
||||||
@@ -49,17 +38,6 @@ async def get_books(
|
|||||||
return await BookFilterService.get(book_filter, request.app.state.redis)
|
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)
|
@book_router.get("/random", response_model=BookDetail)
|
||||||
async def get_random_book(
|
async def get_random_book(
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -110,33 +88,6 @@ async def get_remote_book(source_id: int, remote_id: int):
|
|||||||
return book
|
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)
|
@book_router.get("/{id}/annotation", response_model=BookAnnotation)
|
||||||
async def get_book_annotation(id: int):
|
async def get_book_annotation(id: int):
|
||||||
annotation = await BookAnnotationDB.objects.get(book__id=id)
|
annotation = await BookAnnotationDB.objects.get(book__id=id)
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
|
|||||||
|
|
||||||
from app.depends import check_token
|
from app.depends import check_token
|
||||||
from app.models import BookAnnotation as BookAnnotationDB
|
from app.models import BookAnnotation as BookAnnotationDB
|
||||||
from app.serializers.book_annotation import (
|
from app.serializers.book_annotation import BookAnnotation
|
||||||
BookAnnotation,
|
|
||||||
CreateBookAnnotation,
|
|
||||||
UpdateBookAnnotation,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
book_annotation_router = APIRouter(
|
book_annotation_router = APIRouter(
|
||||||
@@ -26,11 +22,6 @@ async def get_book_annotations():
|
|||||||
return await paginate(BookAnnotationDB.objects)
|
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)
|
@book_annotation_router.get("/{id}", response_model=BookAnnotation)
|
||||||
async def get_book_annotation(id: int):
|
async def get_book_annotation(id: int):
|
||||||
annotation = await BookAnnotationDB.objects.get_or_none(id=id)
|
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)
|
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
return annotation
|
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()
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
|
|||||||
|
|
||||||
from app.depends import check_token
|
from app.depends import check_token
|
||||||
from app.models import Genre as GenreDB
|
from app.models import Genre as GenreDB
|
||||||
from app.serializers.genre import Genre, CreateGenre, UpdateGenre
|
from app.serializers.genre import Genre
|
||||||
|
|
||||||
|
|
||||||
genre_router = APIRouter(
|
genre_router = APIRouter(
|
||||||
@@ -31,24 +31,3 @@ async def get_genre(id: int):
|
|||||||
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
raise HTTPException(status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
return genre
|
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()
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from app.depends import check_token, get_allowed_langs
|
|||||||
from app.models import Book as BookDB
|
from app.models import Book as BookDB
|
||||||
from app.models import Sequence as SequenceDB
|
from app.models import Sequence as SequenceDB
|
||||||
from app.serializers.sequence import Book as SequenceBook
|
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.services.sequence import SequenceMeiliSearchService, GetRandomSequenceService
|
||||||
from app.utils.pagination import CustomPage
|
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(
|
@sequence_router.get(
|
||||||
"/search/{query}",
|
"/search/{query}",
|
||||||
response_model=CustomPage[Sequence],
|
response_model=CustomPage[Sequence],
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from fastapi_pagination.ext.ormar import paginate
|
|||||||
|
|
||||||
from app.depends import check_token
|
from app.depends import check_token
|
||||||
from app.models import Source as SourceDB
|
from app.models import Source as SourceDB
|
||||||
from app.serializers.source import Source, CreateSource
|
from app.serializers.source import Source
|
||||||
|
|
||||||
|
|
||||||
source_router = APIRouter(
|
source_router = APIRouter(
|
||||||
@@ -18,8 +18,3 @@ source_router = APIRouter(
|
|||||||
@source_router.get("", response_model=Page[Source], dependencies=[Depends(Params)])
|
@source_router.get("", response_model=Page[Source], dependencies=[Depends(Params)])
|
||||||
async def get_sources():
|
async def get_sources():
|
||||||
return await paginate(SourceDB.objects)
|
return await paginate(SourceDB.objects)
|
||||||
|
|
||||||
|
|
||||||
@source_router.post("", response_model=Source)
|
|
||||||
async def create_source(data: CreateSource):
|
|
||||||
return await SourceDB.objects.create(**data.dict())
|
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
from typing import Union
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
|
||||||
|
|
||||||
from fastapi_pagination import Params
|
from fastapi_pagination import Params
|
||||||
from fastapi_pagination.ext.ormar import paginate
|
from fastapi_pagination.ext.ormar import paginate
|
||||||
|
|
||||||
from app.depends import check_token
|
from app.depends import check_token
|
||||||
from app.models import Translation as TranslationDB
|
from app.models import Translation as TranslationDB
|
||||||
from app.serializers.translation import (
|
from app.serializers.translation import Translation
|
||||||
Translation,
|
|
||||||
CreateTranslation,
|
|
||||||
CreateRemoteTranslation,
|
|
||||||
)
|
|
||||||
from app.services.translation import TranslationCreator
|
|
||||||
from app.utils.pagination import CustomPage
|
from app.utils.pagination import CustomPage
|
||||||
|
|
||||||
|
|
||||||
@@ -28,26 +21,3 @@ translation_router = APIRouter(
|
|||||||
)
|
)
|
||||||
async def get_translations():
|
async def get_translations():
|
||||||
return await paginate(TranslationDB.objects.select_related(["book", "author"]))
|
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
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import ORJSONResponse
|
||||||
|
|
||||||
import aioredis
|
import aioredis
|
||||||
from fastapi_pagination import add_pagination
|
from fastapi_pagination import add_pagination
|
||||||
@@ -10,7 +11,7 @@ from core.db import database
|
|||||||
|
|
||||||
|
|
||||||
def start_app() -> FastAPI:
|
def start_app() -> FastAPI:
|
||||||
app = FastAPI()
|
app = FastAPI(default_response_class=ORJSONResponse)
|
||||||
|
|
||||||
app.state.database = database
|
app.state.database = database
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user