update mangacollec-store

This commit is contained in:
shooter-dev committed 2026-10-07 16:50:57 +02:00
1 parent 4f564e2962
commit 675b9c8b7e
46 files changed
+1146

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "mangacollec-store"
version = "0.1.0"
description = "Persistence library for MangaCollec data."
requires-python = ">=3.12"
dependencies = ["mangacollec==0.1.0"]
[tool.setuptools.packages.find]
where = ["src"]
include = ["mangacollec_store*"]
@@ -0,0 +1 @@
"""Persistence library for MangaCollec data."""
@@ -0,0 +1,11 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement des auteurs dans le store local."""
from libs.store.authors.load_author import LoadAuthor
from libs.store.authors.load_authors import LoadAuthors
__all__ = ["LoadAuthor", "LoadAuthors"]
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.author import Author
from libs.store.core.store_core import Store
def add_authors(store: Store, authors: list[Author]) -> None:
"""Ajouter les auteurs au store."""
for author in authors:
store.authors[author.id] = author
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.job import Job
from libs.store.core.store_core import Store
def add_jobs(store: Store, jobs: list[Job]) -> None:
"""Ajouter les métiers au store."""
for job in jobs:
store.jobs[job.id] = job
@@ -0,0 +1,22 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.task import Task
from libs.store.core.store_core import Store
def add_tasks(store: Store, tasks: list[Task]) -> None:
"""Ajouter les tâches en conservant les champs absents d'une projection."""
for task in tasks:
existing = store.tasks.get(task.id)
task_to_store = task
if existing and "author_id" not in task.model_fields_set:
task_to_store = task_to_store.model_copy(update={"author_id": existing.author_id})
if existing and "job_id" not in task.model_fields_set:
task_to_store = task_to_store.model_copy(update={"job_id": existing.job_id})
store.tasks[task_to_store.id] = task_to_store
@@ -0,0 +1,33 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto import AuthorResponse
from libs.store.authors.add_authors import add_authors
from libs.store.authors.add_jobs import add_jobs
from libs.store.authors.add_tasks import add_tasks
from libs.store.core.store_core import Store
from libs.store.editions.add_editions import add_editions
from libs.store.series.add_serie import add_serie
from libs.store.volumes.add_volumes import add_volumes
class LoadAuthor:
"""Charger un détail d'auteur et ses ressources associées."""
_store: Store
def __init__(self, store: Store) -> None:
"""Initialise le chargeur avec le store cible."""
self._store = store
def execute(self, response: AuthorResponse) -> None:
"""Ajouter les ressources de la réponse au store et le persister."""
add_authors(self._store, response.authors)
add_tasks(self._store, response.tasks)
add_jobs(self._store, response.jobs)
add_serie(self._store, response.series)
add_editions(self._store, response.editions)
add_volumes(self._store, response.volumes)
self._store.save()
@@ -0,0 +1,23 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement de la liste des auteurs dans le store local."""
from libs.mangacollec.dto import AuthorsResponse
from libs.store.authors.add_authors import add_authors
from libs.store.core.store_core import Store
class LoadAuthors:
"""Charger une réponse de liste d'auteurs dans le store local."""
def __init__(self, store: Store) -> None:
"""Initialise le chargeur avec le store cible."""
self._store = store
def execute(self, response: AuthorsResponse) -> None:
"""Ajouter les auteurs de la réponse puis persister le store."""
add_authors(self._store, response.authors)
self._store.save()
@@ -0,0 +1,9 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.store.core.store_core import Store
__all__ = ["Store"]
@@ -0,0 +1,273 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
import json
import logging
from pathlib import Path
from libs.mangacollec.model.catalogue.author import Author
from libs.mangacollec.model.catalogue.box_edition import BoxEdition
from libs.mangacollec.model.catalogue.box_volume import BoxVolume
from libs.mangacollec.model.catalogue.boxe import Boxe
from libs.mangacollec.model.catalogue.edition import Edition
from libs.mangacollec.model.catalogue.job import Job
from libs.mangacollec.model.catalogue.kind import Kind
from libs.mangacollec.model.catalogue.publisher import Publisher
from libs.mangacollec.model.catalogue.serie import Serie
from libs.mangacollec.model.catalogue.serie_type import SerieType
from libs.mangacollec.model.catalogue.task import Task
from libs.mangacollec.model.catalogue.volume import Volume
from libs.mangacollec.model.possessions.box_follow_edition import BoxFollowEdition
from libs.mangacollec.model.possessions.box_possession import BoxPossession
from libs.mangacollec.model.possessions.volume_follow_edition import VolumeFollowEdition
from libs.mangacollec.model.possessions.volume_possession import VolumePossession
from libs.mangacollec.model.reads.read import Read
from libs.store.model.database import Database
from libs.store.model.news import NewsIndex
logger = logging.getLogger(__name__)
class Store:
"""Store Class."""
_path: str | None
_database: Database
def __init__(self, path: str | None = None) -> None:
self._path = path
self._database = Database()
self._read()
@property
def series(self) -> dict[str, Serie]:
"""Retourner les séries."""
return self._database.series
@series.setter
def series(self, value: dict[str, Serie]) -> None:
"""Définir les séries."""
self._database.series = value
@property
def kinds(self) -> dict[str, Kind]:
"""Retourner les types de série."""
return self._database.kinds
@kinds.setter
def kinds(self, value: dict[str, Kind]) -> None:
"""Définir les types de série."""
self._database.kinds = value
@property
def types(self) -> dict[str, SerieType]:
"""Retourner les types."""
return self._database.types
@types.setter
def types(self, value: dict[str, SerieType]) -> None:
"""Définir les types."""
self._database.types = value
@property
def tasks(self) -> dict[str, Task]:
"""Retourner les tâches."""
return self._database.tasks
@tasks.setter
def tasks(self, value: dict[str, Task]) -> None:
"""Définir les tâches."""
self._database.tasks = value
@property
def jobs(self) -> dict[str, Job]:
"""Retourner les métiers."""
return self._database.jobs
@jobs.setter
def jobs(self, value: dict[str, Job]) -> None:
"""Définir les métiers."""
self._database.jobs = value
@property
def authors(self) -> dict[str, Author]:
"""Retourner les auteurs."""
return self._database.authors
@authors.setter
def authors(self, value: dict[str, Author]) -> None:
"""Définir les auteurs."""
self._database.authors = value
@property
def editions(self) -> dict[str, Edition]:
"""Retourner les éditions."""
return self._database.editions
@editions.setter
def editions(self, value: dict[str, Edition]) -> None:
"""Définir les éditions."""
self._database.editions = value
@property
def publishers(self) -> dict[str, Publisher]:
"""Retourner les éditeurs."""
return self._database.publishers
@publishers.setter
def publishers(self, value: dict[str, Publisher]) -> None:
"""Définir les éditeurs."""
self._database.publishers = value
@property
def volumes(self) -> dict[str, Volume]:
"""Retourner les volumes."""
return self._database.volumes
@volumes.setter
def volumes(self, value: dict[str, Volume]) -> None:
"""Définir les volumes."""
self._database.volumes = value
@property
def news(self) -> NewsIndex:
"""Retourner l'index des nouveautés."""
return self._database.news
@news.setter
def news(self, value: NewsIndex) -> None:
"""Définir l'index des nouveautés."""
self._database.news = value
@property
def box_editions(self) -> dict[str, BoxEdition]:
"""Retourner les éditions de boxes."""
return self._database.box_editions
@box_editions.setter
def box_editions(self, value: dict[str, BoxEdition]) -> None:
"""Définir les éditions de boxes."""
self._database.box_editions = value
@property
def boxes(self) -> dict[str, Boxe]:
"""Retourner les boxes."""
return self._database.boxes
@boxes.setter
def boxes(self, value: dict[str, Boxe]) -> None:
"""Définir les boxes."""
self._database.boxes = value
@property
def box_volumes(self) -> dict[str, BoxVolume]:
"""Retourner les volumes de boxes."""
return self._database.box_volumes
@box_volumes.setter
def box_volumes(self, value: dict[str, BoxVolume]) -> None:
"""Définir les volumes de boxes."""
self._database.box_volumes = value
@property
def possessions(self) -> dict[str, VolumePossession]:
"""Retourner les possessions de volumes."""
return self._database.possessions
@possessions.setter
def possessions(self, value: dict[str, VolumePossession]) -> None:
"""Définir les possessions de volumes."""
self._database.possessions = value
@property
def box_possessions(self) -> dict[str, BoxPossession]:
"""Retourner les possessions de boxes."""
return self._database.box_possessions
@box_possessions.setter
def box_possessions(self, value: dict[str, BoxPossession]) -> None:
"""Définir les possessions de boxes."""
self._database.box_possessions = value
@property
def reads(self) -> dict[str, Read]:
"""Retourner les lectures."""
return self._database.reads
@reads.setter
def reads(self, value: dict[str, Read]) -> None:
"""Définir les lectures."""
self._database.reads = value
@property
def follow_editions(self) -> dict[str, VolumeFollowEdition]:
"""Retourner les suivis d'éditions de volumes."""
return self._database.follow_editions
@follow_editions.setter
def follow_editions(self, value: dict[str, VolumeFollowEdition]) -> None:
"""Définir les suivis d'éditions de volumes."""
self._database.follow_editions = value
@property
def box_follow_editions(self) -> dict[str, BoxFollowEdition]:
"""Retourner les suivis d'éditions de boxes."""
return self._database.box_follow_editions
@box_follow_editions.setter
def box_follow_editions(self, value: dict[str, BoxFollowEdition]) -> None:
"""Définir les suivis d'éditions de boxes."""
self._database.box_follow_editions = value
def save(self) -> None:
"""Sauvegarder le store sur disque."""
logger.info("Sauvegarde du store.")
self._write()
def _read(self) -> None:
"""Lire le store depuis disque."""
logger.info("Lecture du store depuis le disque.")
if self._path is None:
return
path = Path(self._path)
if not path.exists():
return
self._database = Database.model_validate(json.loads(path.read_text(encoding="utf-8")))
logger.info("Charger %d Serie(s)", len(self._database.series))
logger.info("Charger %d Kind(s)", len(self._database.kinds))
logger.info("Charger %d Type(s)", len(self._database.types))
logger.info("Charger %d Task(s)", len(self._database.tasks))
logger.info("Charger %d Job(s)", len(self._database.jobs))
logger.info("Charger %d Author(s)", len(self._database.authors))
logger.info("Charger %d Edition(s)", len(self._database.editions))
logger.info("Charger %d Publisher(s)", len(self._database.publishers))
logger.info("Charger %d Volume(s)", len(self._database.volumes))
logger.info("Charger %d News volume(s)", len(self._database.news.volumes))
logger.info("Charger %d News box(es)", len(self._database.news.boxes))
logger.info("Charger %d BoxEdition(s)", len(self._database.box_editions))
logger.info("Charger %d Boxe(s)", len(self._database.boxes))
logger.info("Charger %d BoxVolume(s)", len(self._database.box_volumes))
logger.info("Charger %d FollowEdition(s)", len(self._database.follow_editions))
logger.info("Charger %d BoxFollowEdition(s)", len(self._database.box_follow_editions))
logger.info("Charger %d Possession(s)", len(self._database.possessions))
logger.info("Charger %d BoxPossession(s)", len(self._database.box_possessions))
logger.info("Charger %d Read(s)", len(self._database.reads))
def _write(self) -> None:
"""Écrire le store sur disque."""
logger.info("Écriture du store sur disque.")
if self._path is None:
return
Path(self._path).write_text(
json.dumps(self._database.model_dump(mode="json"), indent=4, ensure_ascii=False) + "\n",
encoding="utf-8",
)
@@ -0,0 +1,10 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement des réponses d'édition dans le store."""
from libs.store.editions.load_edition import LoadEdition
__all__ = ["LoadEdition"]
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue import BoxEdition
from libs.store.core.store_core import Store
def add_box_editions(store: Store, box_editions: list[BoxEdition]) -> None:
"""Ajouter les éditions de boîte au store."""
for box_edition in box_editions:
store.box_editions[box_edition.id] = box_edition
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue import Edition
from libs.store.core.store_core import Store
def add_editions(store: Store, editions: list[Edition]) -> None:
"""Ajouter les éditions au store."""
for edition in editions:
store.editions[edition.id] = edition
@@ -0,0 +1,30 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto.edition_response import EditionResponse
from libs.store.core.store_core import Store
from libs.store.editions.add_editions import add_editions
from libs.store.publishers.add_publishers import add_publishers
from libs.store.series.add_serie import add_serie
from libs.store.series.add_types import add_types
from libs.store.volumes.add_volumes import add_volumes
class LoadEdition:
"""Charger une réponse détaillée d'édition dans le store."""
_store: Store
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: EditionResponse) -> None:
"""Enregistrer l'édition et les ressources liées, puis sauvegarder."""
add_editions(self._store, response.editions)
add_publishers(self._store, response.publishers)
add_serie(self._store, response.series)
add_types(self._store, response.types)
add_volumes(self._store, response.volumes)
self._store.save()
@@ -0,0 +1,9 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.store.kinds.load_kinds import LoadKinds
__all__ = ["LoadKinds"]
@@ -0,0 +1,25 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.kind import Kind
from libs.store.core.store_core import Store
def add_kinds(store: Store, kinds: list[Kind]) -> None:
"""Ajouter les genres en conservant et complétant leurs séries liées."""
for kind in kinds:
existing = store.kinds.get(kind.id)
series_ids = [
*((existing.series_ids if existing else None) or []),
*(kind.series_ids or []),
*(
serie.id
for serie in store.series.values()
if str(kind.id) in {str(kind_id) for kind_id in (serie.kinds_ids or [])}
),
]
unique_series_ids = list(dict.fromkeys(series_ids))
store.kinds[kind.id] = kind.model_copy(update={"series_ids": unique_series_ids}) if unique_series_ids else kind
@@ -0,0 +1,22 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto.kinds_response import KindsResponse
from libs.store.core.store_core import Store
from libs.store.kinds.add_kinds import add_kinds
class LoadKinds:
"""LoadKinds Class."""
_store: Store
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: KindsResponse) -> None:
"""Ajouter les genres au store et le persister."""
add_kinds(self._store, response.kinds)
self._store.save()
@@ -0,0 +1,10 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from .database import Database
from .news import NewsIndex
__all__ = ["Database", "NewsIndex"]
@@ -0,0 +1,48 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from pydantic import BaseModel, Field
from libs.mangacollec.model.catalogue.author import Author
from libs.mangacollec.model.catalogue.box_edition import BoxEdition
from libs.mangacollec.model.catalogue.box_volume import BoxVolume
from libs.mangacollec.model.catalogue.boxe import Boxe
from libs.mangacollec.model.catalogue.edition import Edition
from libs.mangacollec.model.catalogue.job import Job
from libs.mangacollec.model.catalogue.kind import Kind
from libs.mangacollec.model.catalogue.publisher import Publisher
from libs.mangacollec.model.catalogue.serie import Serie
from libs.mangacollec.model.catalogue.serie_type import SerieType
from libs.mangacollec.model.catalogue.task import Task
from libs.mangacollec.model.catalogue.volume import Volume
from libs.mangacollec.model.possessions.box_follow_edition import BoxFollowEdition
from libs.mangacollec.model.possessions.box_possession import BoxPossession
from libs.mangacollec.model.possessions.volume_follow_edition import VolumeFollowEdition
from libs.mangacollec.model.possessions.volume_possession import VolumePossession
from libs.mangacollec.model.reads.read import Read
from libs.store.model.news import NewsIndex
class Database(BaseModel):
"""État complet du store local."""
series: dict[str, Serie] = {}
kinds: dict[str, Kind] = {}
types: dict[str, SerieType] = {}
tasks: dict[str, Task] = {}
jobs: dict[str, Job] = {}
authors: dict[str, Author] = {}
editions: dict[str, Edition] = {}
publishers: dict[str, Publisher] = {}
volumes: dict[str, Volume] = {}
news: NewsIndex = Field(default_factory=NewsIndex)
box_editions: dict[str, BoxEdition] = {}
boxes: dict[str, Boxe] = {}
box_volumes: dict[str, BoxVolume] = {}
follow_editions: dict[str, VolumeFollowEdition] = {}
box_follow_editions: dict[str, BoxFollowEdition] = {}
possessions: dict[str, VolumePossession] = {}
box_possessions: dict[str, BoxPossession] = {}
reads: dict[str, Read] = {}
@@ -0,0 +1,15 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from pydantic import BaseModel, Field
from libs.mangacollec.value_object.id import ID
class NewsIndex(BaseModel):
"""Index persistant des nouveautés affichées par le store local."""
volumes: list[ID] = Field(default_factory=list)
boxes: list[ID] = Field(default_factory=list)
@@ -0,0 +1,10 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement des nouveautés dans le store local."""
from .load_news import LoadNews
__all__ = ["LoadNews"]
@@ -0,0 +1,40 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto.news_response import NewsResponse
from libs.store.core.store_core import Store
from libs.store.editions.add_box_editions import add_box_editions
from libs.store.editions.add_editions import add_editions
from libs.store.model.news import NewsIndex
from libs.store.series.add_serie import add_serie
from libs.store.series.add_types import add_types
from libs.store.volumes.add_box_volumes import add_box_volumes
from libs.store.volumes.add_boxes import add_boxes
from libs.store.volumes.add_volumes import add_volumes
class LoadNews:
"""Charger une réponse de nouveautés dans le store local."""
_store: Store
def __init__(self, store: Store) -> None:
"""Initialise le chargeur avec le store cible."""
self._store = store
def execute(self, response: NewsResponse) -> None:
"""Mettre à jour les entités liées et remplacer l'index des nouveautés."""
add_volumes(self._store, response.volumes)
add_editions(self._store, response.editions)
add_serie(self._store, response.series)
add_types(self._store, response.types)
add_boxes(self._store, response.boxes)
add_box_editions(self._store, response.box_editions)
add_box_volumes(self._store, response.box_volumes)
self._store.news = NewsIndex(
volumes=[volume.id for volume in response.volumes],
boxes=[box.id for box in response.boxes],
)
self._store.save()
@@ -0,0 +1,17 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.store.possessions.delete_box_possessions import DeleteBoxPossessions
from libs.store.possessions.delete_possessions import DeletePossessions
from libs.store.possessions.load_box_possessions import LoadBoxPossessions
from libs.store.possessions.load_volume_possessions import LoadVolumePossessions
__all__ = [
"DeleteBoxPossessions",
"DeletePossessions",
"LoadBoxPossessions",
"LoadVolumePossessions",
]
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.possessions.box_follow_edition import BoxFollowEdition
from libs.store.core.store_core import Store
def add_box_follow_editions(store: Store, box_follow_editions: list[BoxFollowEdition]) -> None:
"""Ajouter les suivis d'édition de boîte au store."""
for box_follow_edition in box_follow_editions:
store.box_follow_editions[box_follow_edition.id] = box_follow_edition
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.possessions.box_possession import BoxPossession
from libs.store.core.store_core import Store
def add_box_possessions(store: Store, box_possessions: list[BoxPossession]) -> None:
"""Ajouter les possessions de boîte au store."""
for box_possession in box_possessions:
store.box_possessions[box_possession.id] = box_possession
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.possessions.volume_follow_edition import VolumeFollowEdition
from libs.store.core.store_core import Store
def add_follow_editions(store: Store, follow_editions: list[VolumeFollowEdition]) -> None:
"""Ajouter les suivis d'édition de volume au store."""
for follow_edition in follow_editions:
store.follow_editions[follow_edition.id] = follow_edition
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.possessions.volume_possession import VolumePossession
from libs.store.core.store_core import Store
def add_possessions(store: Store, possessions: list[VolumePossession]) -> None:
"""Ajouter les possessions de volume au store."""
for possession in possessions:
store.possessions[possession.id] = possession
@@ -0,0 +1,30 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Suppression des possessions de boxes dans le store."""
from libs.mangacollec.dto import (
DeleteBoxPossessionsMultipleResponse,
)
from libs.store.core.store_core import Store
class DeleteBoxPossessions:
"""Synchroniser le store avec une réponse de suppression de l'API."""
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: DeleteBoxPossessionsMultipleResponse) -> None:
"""Retirer du store les ressources effectivement supprimées."""
for possession in response.possessions:
if possession.deleted:
self._store.possessions.pop(str(possession.id), None)
for follow_edition in response.follow_editions:
if follow_edition.deleted:
self._store.follow_editions.pop(str(follow_edition.id), None)
self._store.save()
@@ -0,0 +1,30 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Suppression des possessions dans le store."""
from libs.mangacollec.dto import (
DeleteVolumePossessionsMultipleResponse,
)
from libs.store.core.store_core import Store
class DeletePossessions:
"""Synchroniser le store avec une réponse de suppression de l'API."""
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: DeleteVolumePossessionsMultipleResponse) -> None:
"""Retirer du store les ressources effectivement supprimées."""
for possession in response.possessions:
if possession.deleted:
self._store.possessions.pop(str(possession.id), None)
for follow_edition in response.follow_editions:
if follow_edition.deleted:
self._store.follow_editions.pop(str(follow_edition.id), None)
self._store.save()
@@ -0,0 +1,30 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement des possessions dans le store."""
from libs.mangacollec.dto import (
CreateBoxPossessionsMultipleResponse,
)
from libs.store.core.store_core import Store
from libs.store.possessions.add_box_follow_editions import add_box_follow_editions
from libs.store.possessions.add_box_possessions import add_box_possessions
from libs.store.possessions.add_follow_editions import add_follow_editions
from libs.store.possessions.add_possessions import add_possessions
class LoadBoxPossessions:
"""Charger les possessions et les suivis d'édition dans le store."""
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: CreateBoxPossessionsMultipleResponse) -> None:
"""Enregistrer les possessions et les suivis retournés par l'API."""
add_box_possessions(self._store, response.box_possessions)
add_box_follow_editions(self._store, response.box_follow_editions)
add_possessions(self._store, response.possessions)
add_follow_editions(self._store, response.follow_editions)
self._store.save()
@@ -0,0 +1,26 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement des possessions dans le store."""
from libs.mangacollec.dto import (
CreateVolumePossessionsMultipleResponse,
)
from libs.store.core.store_core import Store
from libs.store.possessions.add_follow_editions import add_follow_editions
from libs.store.possessions.add_possessions import add_possessions
class LoadVolumePossessions:
"""Charger les possessions et les suivis d'édition dans le store."""
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: CreateVolumePossessionsMultipleResponse) -> None:
"""Enregistrer les possessions et les suivis retournés par l'API."""
add_possessions(self._store, response.possessions)
add_follow_editions(self._store, response.follow_editions)
self._store.save()
@@ -0,0 +1,9 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.store.publishers.load_publisher import LoadPublisher
from libs.store.publishers.load_publishers import LoadPublishers
__all__ = ["LoadPublisher", "LoadPublishers"]
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue import Publisher
from libs.store.core.store_core import Store
def add_publishers(store: Store, publishers: list[Publisher]) -> None:
"""Ajouter les éditeurs au store."""
for publisher in publishers:
store.publishers[publisher.id] = publisher
@@ -0,0 +1,34 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto import PublisherResponse
from libs.store.core.store_core import Store
from libs.store.editions.add_box_editions import add_box_editions
from libs.store.editions.add_editions import add_editions
from libs.store.publishers.add_publishers import add_publishers
from libs.store.series.add_serie import add_serie
from libs.store.series.add_types import add_types
from libs.store.volumes.add_boxes import add_boxes
from libs.store.volumes.add_volumes import add_volumes
class LoadPublisher:
"""Charger un éditeur et ses ressources associées."""
_store: Store
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: PublisherResponse) -> None:
"""Ajouter l'éditeur et les ressources liées, puis sauvegarder."""
add_box_editions(self._store, response.box_editions)
add_boxes(self._store, response.boxes)
add_editions(self._store, response.editions)
add_publishers(self._store, response.publishers)
add_serie(self._store, response.series)
add_types(self._store, response.types)
add_volumes(self._store, response.volumes)
self._store.save()
@@ -0,0 +1,23 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto.publishers_response import PublishersResponse
from libs.store.core.store_core import Store
from libs.store.publishers.add_publishers import add_publishers
class LoadPublishers:
"""LoadPublishers Class."""
_store: Store
def __init__(self, store: Store) -> None:
"""."""
self._store = store
def execute(self, response: PublishersResponse) -> None:
"""."""
add_publishers(self._store, response.publishers)
self._store.save()
@@ -0,0 +1,10 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.store.series.load_serie import LoadSerie
from libs.store.series.load_series import LoadSeries
__all__ = ["LoadSerie", "LoadSeries"]
@@ -0,0 +1,31 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.serie import Serie
from libs.store import Store
def add_serie(store: Store, series: list[Serie]) -> None:
"""Ajouter des séries en conservant les champs absents d'une projection."""
for serie in series:
existing = store.series.get(serie.id)
serie_to_store = serie
if existing and "type_id" not in serie.model_fields_set:
serie_to_store = serie_to_store.model_copy(update={"type_id": existing.type_id})
if existing and "kinds_ids" not in serie.model_fields_set:
serie_to_store = serie_to_store.model_copy(update={"kinds_ids": existing.kinds_ids})
if existing and "adult_content" not in serie.model_fields_set:
serie_to_store = serie_to_store.model_copy(update={"adult_content": existing.adult_content})
if existing and "editions_count" not in serie.model_fields_set:
serie_to_store = serie_to_store.model_copy(update={"editions_count": existing.editions_count})
if existing and "tasks_count" not in serie.model_fields_set:
serie_to_store = serie_to_store.model_copy(update={"tasks_count": existing.tasks_count})
store.series[serie_to_store.id] = serie_to_store
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.serie_type import SerieType
from libs.store.core.store_core import Store
def add_types(store: Store, serie_types: list[SerieType]) -> None:
"""Ajouter les types de série au store."""
for serie_type in serie_types:
store.types[serie_type.id] = serie_type
@@ -0,0 +1,44 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto import SerieResponse
from libs.store.authors.add_authors import add_authors
from libs.store.authors.add_jobs import add_jobs
from libs.store.authors.add_tasks import add_tasks
from libs.store.core.store_core import Store
from libs.store.editions.add_box_editions import add_box_editions
from libs.store.editions.add_editions import add_editions
from libs.store.kinds.add_kinds import add_kinds
from libs.store.publishers.add_publishers import add_publishers
from libs.store.series.add_serie import add_serie
from libs.store.series.add_types import add_types
from libs.store.volumes.add_box_volumes import add_box_volumes
from libs.store.volumes.add_boxes import add_boxes
from libs.store.volumes.add_volumes import add_volumes
class LoadSerie:
"""Charger une série et ses ressources associées."""
_store: Store
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: SerieResponse) -> None:
"""Ajouter la série et les ressources liées, puis sauvegarder."""
add_serie(self._store, response.series)
add_types(self._store, response.types)
add_kinds(self._store, response.kinds)
add_tasks(self._store, response.tasks)
add_jobs(self._store, response.jobs)
add_authors(self._store, response.authors)
add_editions(self._store, response.editions)
add_publishers(self._store, response.publishers)
add_volumes(self._store, response.volumes)
add_box_editions(self._store, response.box_editions)
add_boxes(self._store, response.boxes)
add_box_volumes(self._store, response.box_volumes)
self._store.save()
@@ -0,0 +1,24 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto.series_response import SeriesResponse
from libs.store.core.store_core import Store
from libs.store.series.add_serie import add_serie
from libs.store.series.add_types import add_types
class LoadSeries:
"""LoadSeries Class."""
_store: Store
def __init__(self, store: Store) -> None:
self._store = store
def execute(self, response: SeriesResponse) -> None:
"""Ajouter les séries et leurs types, puis sauvegarder."""
add_serie(self._store, response.series)
add_types(self._store, response.types)
self._store.save()
@@ -0,0 +1,10 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
"""Chargement des volumes dans le store local."""
from libs.store.volumes.load_volume import LoadVolume
__all__ = ["LoadVolume"]
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.box_volume import BoxVolume
from libs.store.core.store_core import Store
def add_box_volumes(store: Store, box_volumes: list[BoxVolume]) -> None:
"""Ajouter les volumes de boîte au store."""
for box_volume in box_volumes:
store.box_volumes[box_volume.id] = box_volume
@@ -0,0 +1,13 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.boxe import Boxe
from libs.store.core.store_core import Store
def add_boxes(store: Store, boxes: list[Boxe]) -> None:
"""Ajouter les boîtes au store."""
for box in boxes:
store.boxes[box.id] = box
@@ -0,0 +1,22 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.model.catalogue.volume import Volume
from libs.store.core.store_core import Store
def add_volumes(store: Store, volumes: list[Volume]) -> None:
"""Ajouter les volumes en conservant les champs absents d'une projection."""
for volume in volumes:
existing = store.volumes.get(volume.id)
volume_to_store = volume
if existing and "nb_pages" not in volume.model_fields_set:
volume_to_store = volume_to_store.model_copy(update={"nb_pages": existing.nb_pages})
if existing and "content" not in volume.model_fields_set:
volume_to_store = volume_to_store.model_copy(update={"content": existing.content})
store.volumes[volume_to_store.id] = volume_to_store
@@ -0,0 +1,44 @@
# __ _____ _ __ ____________________ __ _____________________ _____ _______________
# / ___/ / /_ ____ ____ / /_ ___ ____ / __ \ ___ _ __/
# \__ \ / __ \ / __ \ / __ \ / __/ / _ \ / __/ ____ / / / / / _ \ | | / /
# ___/ / / / / / / /_/ / / /_/ / / /_ / __/ / / /___/ / /_/ / / __/ | |/ /
# /____/ /_/ /_/ \____/ \____/ \__/ \___/ /_/ _______ /______/ \___/ |___/
from libs.mangacollec.dto.volume_response import VolumeResponse
from libs.store.core.store_core import Store
from libs.store.editions.add_box_editions import add_box_editions
from libs.store.editions.add_editions import add_editions
from libs.store.publishers.add_publishers import add_publishers
from libs.store.series.add_serie import add_serie
from libs.store.series.add_types import add_types
from libs.store.volumes.add_box_volumes import add_box_volumes
from libs.store.volumes.add_boxes import add_boxes
from libs.store.volumes.add_volumes import add_volumes
class LoadVolume:
"""Charger un détail de volume dans le store local."""
_store: Store
def __init__(self, store: Store) -> None:
"""Initialise le chargeur avec le store cible."""
self._store = store
def execute(self, response: VolumeResponse) -> None:
"""Enregistrer les collections de la réponse puis persister le store."""
add_volumes(self._store, response.volumes)
add_editions(self._store, response.editions)
add_publishers(self._store, response.publishers)
add_serie(self._store, response.series)
add_types(self._store, response.types)
if response.box_volumes is not None:
add_box_volumes(self._store, response.box_volumes)
if response.boxes is not None:
add_boxes(self._store, response.boxes)
if response.box_editions is not None:
add_box_editions(self._store, response.box_editions)
self._store.save()
+1
View File
@@ -0,0 +1 @@
"""Tests for the mangacollec-store library."""