from datetime import date import ormar from sqlalchemy import text from core.db import metadata, database class BaseMeta(ormar.ModelMeta): metadata = metadata database = database class Source(ormar.Model): class Meta(BaseMeta): tablename = "sources" id: int = ormar.SmallInteger(primary_key=True, nullable=False) # type: ignore name: str = ormar.String(max_length=32, nullable=False, unique=True) # type: ignore class Genre(ormar.Model): class Meta(BaseMeta): tablename = "genres" constraints = [ ormar.UniqueColumns("source", "remote_id"), ] id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore source: Source = ormar.ForeignKey(Source, nullable=False) remote_id: int = ormar.Integer(minimum=0, nullable=False) # type: ignore code: str = ormar.String(max_length=45, nullable=False) # type: ignore description: str = ormar.String(max_length=99, nullable=False) # type: ignore meta: str = ormar.String(max_length=45, nullable=False) # type: ignore class Author(ormar.Model): class Meta(BaseMeta): tablename = "authors" constraints = [ ormar.UniqueColumns("source", "remote_id"), ] id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore source: Source = ormar.ForeignKey(Source, nullable=False) remote_id: int = ormar.Integer(minimum=0, nullable=False) # type: ignore first_name: str = ormar.String(max_length=256, nullable=False) # type: ignore last_name: str = ormar.String(max_length=256, nullable=False) # type: ignore middle_name: str = ormar.String(max_length=256, nullable=True) # type: ignore class AuthorAnnotation(ormar.Model): class Meta(BaseMeta): tablename = "author_annotations" id = ormar.Integer(primary_key=True, nullable=False) author: Author = ormar.ForeignKey(Author, nullable=False, unique=True) title: str = ormar.String(max_length=256, nullable=False, default="") # type: ignore text: str = ormar.Text(nullable=False, default="") # type: ignore file: str = ormar.String(max_length=256, nullable=True) # type: ignore class Sequence(ormar.Model): class Meta(BaseMeta): tablename = "sequences" constraints = [ ormar.UniqueColumns("source", "remote_id"), ] id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore source: Source = ormar.ForeignKey(Source, nullable=False) remote_id: int = ormar.Integer(minimum=0, nullable=False) # type: ignore name: str = ormar.String(max_length=256, nullable=False, index=True) # type: ignore class BookAuthors(ormar.Model): class Meta(BaseMeta): tablename = "book_authors" id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore class BookGenres(ormar.Model): class Meta(BaseMeta): tablename = "book_genres" id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore class BookSequences(ormar.Model): class Meta(BaseMeta): tablename = "book_sequences" id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore position: int = ormar.SmallInteger(minimum=0, nullable=False) # type: ignore class Translation(ormar.Model): class Meta(BaseMeta): tablename = "translations" constraints = [ # ormar.UniqueColumns("book", "translator"), ] id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore position: int = ormar.SmallInteger(nullable=False) # type: ignore class Book(ormar.Model): class Meta(BaseMeta): tablename = "books" constraints = [ ormar.UniqueColumns("source", "remote_id"), ] id: int = ormar.Integer(primary_key=True, nullable=False) # type: ignore source: Source = ormar.ForeignKey(Source, nullable=False) remote_id: int = ormar.Integer(minimum=0, nullable=False) # type: ignore title: str = ormar.String(max_length=256, nullable=False, index=True) # type: ignore lang: str = ormar.String(max_length=3, nullable=False) # type: ignore file_type: str = ormar.String(max_length=4, nullable=False) # type: ignore uploaded: date = ormar.Date() # type: ignore is_deleted: bool = ormar.Boolean(default=False, server_default=text("false"), nullable=False) authors = ormar.ManyToMany(Author, through=BookAuthors) translators = ormar.ManyToMany(Author, through=Translation, related_name="translated_books") genres = ormar.ManyToMany(Genre, through=BookGenres) sequences = ormar.ManyToMany(Sequence, through=BookSequences) @ormar.property_field def available_types(self) -> list[str]: if self.file_type == 'fb2' and self.source.name == 'flibusta': return ['fb2', 'epub', 'mobi'] return [self.file_type] class BookAnnotation(ormar.Model): class Meta(BaseMeta): tablename = "book_annotations" id = ormar.Integer(primary_key=True, nullable=False) book: Book = ormar.ForeignKey(Book, nullable=False, unique=True) title: str = ormar.String(max_length=256, nullable=False, default="") # type: ignore text: str = ormar.Text(nullable=False, default="") # type: ignore file: str = ormar.String(max_length=256, nullable=True) # type: ignore