summaryrefslogtreecommitdiffstatshomepage
path: root/src/hircine/api/types.py
diff options
context:
space:
mode:
authorWolfgang Müller2024-03-05 18:08:09 +0100
committerWolfgang Müller2024-03-05 19:25:59 +0100
commitd1d654ebac2d51e3841675faeb56480e440f622f (patch)
tree56ef123c1a15a10dfd90836e4038e27efde950c6 /src/hircine/api/types.py
downloadhircine-d1d654ebac2d51e3841675faeb56480e440f622f.tar.gz
Initial commit0.1.0
Diffstat (limited to 'src/hircine/api/types.py')
-rw-r--r--src/hircine/api/types.py337
1 files changed, 337 insertions, 0 deletions
diff --git a/src/hircine/api/types.py b/src/hircine/api/types.py
new file mode 100644
index 0000000..b9fe0e7
--- /dev/null
+++ b/src/hircine/api/types.py
@@ -0,0 +1,337 @@
+import datetime
+from typing import Generic, List, Optional, TypeVar
+
+import strawberry
+
+import hircine.scraper.types as scraped
+from hircine.enums import Category, Censorship, Direction, Language, Layout, Rating
+
+T = TypeVar("T")
+
+
+@strawberry.type
+class Base:
+ id: int
+
+ def __init__(self, model):
+ self.id = model.id
+
+
+@strawberry.type
+class MixinName:
+ name: str
+
+ def __init__(self, model):
+ self.name = model.name
+ super().__init__(model)
+
+
+@strawberry.type
+class MixinFavourite:
+ favourite: bool
+
+ def __init__(self, model):
+ self.favourite = model.favourite
+ super().__init__(model)
+
+
+@strawberry.type
+class MixinOrganized:
+ organized: bool
+
+ def __init__(self, model):
+ self.organized = model.organized
+ super().__init__(model)
+
+
+@strawberry.type
+class MixinBookmarked:
+ bookmarked: bool
+
+ def __init__(self, model):
+ self.bookmarked = model.bookmarked
+ super().__init__(model)
+
+
+@strawberry.type
+class MixinCreatedAt:
+ created_at: datetime.datetime
+
+ def __init__(self, model):
+ self.created_at = model.created_at
+ super().__init__(model)
+
+
+@strawberry.type
+class MixinModifyDates(MixinCreatedAt):
+ updated_at: datetime.datetime
+
+ def __init__(self, model):
+ self.updated_at = model.updated_at
+ super().__init__(model)
+
+
+@strawberry.type
+class FilterResult(Generic[T]):
+ count: int
+ edges: List["T"]
+
+
+@strawberry.type
+class Archive(MixinName, MixinOrganized, Base):
+ cover: "Image"
+ path: str
+ size: int
+ page_count: int
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.path = model.path
+ self.cover = Image(model.cover)
+ self.size = model.size
+ self.page_count = model.page_count
+
+
+@strawberry.type
+class FullArchive(MixinCreatedAt, Archive):
+ pages: List["Page"]
+ comics: List["Comic"]
+ mtime: datetime.datetime
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.mtime = model.mtime
+ self.pages = [Page(p) for p in model.pages]
+ self.comics = [Comic(c) for c in model.comics]
+
+
+@strawberry.type
+class Page(Base):
+ path: str
+ image: "Image"
+ comic_id: Optional[int]
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.path = model.path
+ self.image = Image(model.image)
+ self.comic_id = model.comic_id
+
+
+@strawberry.type
+class Image(Base):
+ hash: str
+ width: int
+ height: int
+ aspect_ratio: float
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.hash = model.hash
+ self.width = model.width
+ self.height = model.height
+ self.aspect_ratio = model.aspect_ratio
+
+
+@strawberry.type
+class Comic(MixinFavourite, MixinOrganized, MixinBookmarked, Base):
+ title: str
+ original_title: Optional[str]
+ language: Optional[Language]
+ date: Optional[datetime.date]
+ cover: "Image"
+ rating: Optional[Rating]
+ category: Optional[Category]
+ censorship: Optional[Censorship]
+ tags: List["ComicTag"]
+ artists: List["Artist"]
+ characters: List["Character"]
+ circles: List["Circle"]
+ worlds: List["World"]
+ page_count: int
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.title = model.title
+ self.original_title = model.original_title
+ self.language = model.language
+ self.date = model.date
+ self.cover = Image(model.cover)
+ self.rating = model.rating
+ self.category = model.category
+ self.censorship = model.censorship
+ self.tags = [ComicTag(t.namespace, t.tag) for t in model.tags]
+ self.artists = [Artist(a) for a in model.artists]
+ self.characters = [Character(c) for c in model.characters]
+ self.worlds = [World(w) for w in model.worlds]
+ self.circles = [Circle(g) for g in model.circles]
+ self.page_count = model.page_count
+
+
+@strawberry.type
+class FullComic(MixinModifyDates, Comic):
+ archive: "Archive"
+ url: Optional[str]
+ pages: List["Page"]
+ direction: Direction
+ layout: Layout
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.direction = model.direction
+ self.layout = model.layout
+ self.archive = Archive(model.archive)
+ self.pages = [Page(p) for p in model.pages]
+ self.url = model.url
+
+
+@strawberry.type
+class Tag(MixinName, Base):
+ description: Optional[str]
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.description = model.description
+
+
+@strawberry.type
+class FullTag(Tag):
+ namespaces: List["Namespace"]
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.namespaces = [Namespace(n) for n in model.namespaces]
+
+
+@strawberry.type
+class Namespace(MixinName, Base):
+ sort_name: Optional[str]
+
+ def __init__(self, model):
+ super().__init__(model)
+ self.sort_name = model.sort_name
+
+
+@strawberry.type
+class ComicTag:
+ id: str
+ name: str
+ description: Optional[str]
+
+ def __init__(self, namespace=None, tag=None):
+ tag_name, tag_id = ("", "")
+ ns_name, ns_id = ("", "")
+
+ if tag:
+ tag_name, tag_id = (tag.name, tag.id)
+ if namespace:
+ ns_name, ns_id = (namespace.name, namespace.id)
+
+ self.name = f"{ns_name}:{tag_name}"
+ self.id = f"{ns_id}:{tag_id}"
+ if tag:
+ self.description = tag.description
+
+
+@strawberry.type
+class Artist(MixinName, Base):
+ def __init__(self, model):
+ super().__init__(model)
+
+
+@strawberry.type
+class Character(MixinName, Base):
+ def __init__(self, model):
+ super().__init__(model)
+
+
+@strawberry.type
+class Circle(MixinName, Base):
+ def __init__(self, model):
+ super().__init__(model)
+
+
+@strawberry.type
+class World(MixinName, Base):
+ def __init__(self, model):
+ super().__init__(model)
+
+
+@strawberry.type
+class ComicScraper:
+ id: str
+ name: str
+
+ def __init__(self, id, scraper):
+ self.id = id
+ self.name = scraper.name
+
+
+@strawberry.type
+class ScrapeComicResult:
+ data: "ScrapedComic"
+ warnings: List[str] = strawberry.field(default_factory=lambda: [])
+
+
+@strawberry.type
+class ScrapedComic:
+ title: Optional[str] = None
+ original_title: Optional[str] = None
+ url: Optional[str] = None
+ language: Optional[Language] = None
+ date: Optional[datetime.date] = None
+ rating: Optional[Rating] = None
+ category: Optional[Category] = None
+ censorship: Optional[Censorship] = None
+ direction: Optional[Direction] = None
+ layout: Optional[Layout] = None
+ tags: List[str] = strawberry.field(default_factory=lambda: [])
+ artists: List[str] = strawberry.field(default_factory=lambda: [])
+ characters: List[str] = strawberry.field(default_factory=lambda: [])
+ circles: List[str] = strawberry.field(default_factory=lambda: [])
+ worlds: List[str] = strawberry.field(default_factory=lambda: [])
+
+ @classmethod
+ def from_generator(cls, generator):
+ data = cls()
+
+ seen = set()
+ for item in generator:
+ if not item or item in seen:
+ continue
+
+ seen.add(item)
+
+ match item:
+ case scraped.Title():
+ data.title = item.value
+ case scraped.OriginalTitle():
+ data.original_title = item.value
+ case scraped.URL():
+ data.url = item.value
+ case scraped.Language():
+ data.language = item.value
+ case scraped.Date():
+ data.date = item.value
+ case scraped.Rating():
+ data.rating = item.value
+ case scraped.Category():
+ data.category = item.value
+ case scraped.Censorship():
+ data.censorship = item.value
+ case scraped.Direction():
+ data.direction = item.value
+ case scraped.Layout():
+ data.layout = item.value
+ case scraped.Tag():
+ data.tags.append(item.to_string())
+ case scraped.Artist():
+ data.artists.append(item.name)
+ case scraped.Character():
+ data.characters.append(item.name)
+ case scraped.Circle():
+ data.circles.append(item.name)
+ case scraped.World():
+ data.worlds.append(item.name)
+
+ return data