Merge pull request #6 from piskunqa/main

Refactoring of last commit
This commit is contained in:
hyugogirubato
2024-07-01 22:25:14 +02:00
committed by GitHub
3 changed files with 106 additions and 105 deletions
+8 -104
View File
@@ -3,123 +3,26 @@ from __future__ import annotations
import json import json
import zipfile import zipfile
from io import BytesIO from io import BytesIO
from pathlib import Path
from typing import Union from typing import Union
import xmltodict import xmltodict
from langcodes import Language
from pathlib import Path
from cbz import utils from cbz import utils
from cbz.constants import YesNo, Manga, AgeRating, Format, xml_name from cbz.constants import xml_name
from cbz.models import ComicModel from cbz.models import ComicModel
from cbz.page import PageInfo from cbz.page import PageInfo
def rating(value: int) -> int:
assert -1 <= value <= 5, 'Rating must be between 0 and 5'
return value
def language(value: str) -> str:
if value and not Language.get(value).is_valid():
raise ValueError('Invalid language')
return value
class ComicInfo(ComicModel): class ComicInfo(ComicModel):
def __init__(self, pages: [PageInfo], **kwargs): def __init__(self, pages: [PageInfo], **kwargs):
self.__pages = pages self.__pages = pages
# TODO: need change to loop with setattr super(ComicInfo, self).__init__(kwargs)
self.title = str(kwargs.get('title', kwargs.get('Title', '')))
self.series = str(kwargs.get('series', kwargs.get('Series', '')))
self.number = str(kwargs.get('number', kwargs.get('Number', '')))
self.count = int(kwargs.get('count', kwargs.get('Count', -1)))
self.volume = int(kwargs.get('volume', kwargs.get('Volume', -1)))
self.alternate_series = str(kwargs.get('alternate_series', kwargs.get('AlternateSeries', '')))
self.alternate_number = str(kwargs.get('alternate_number', kwargs.get('AlternateNumber', '')))
self.alternate_count = int(kwargs.get('alternate_count', kwargs.get('AlternateCount', -1)))
self.summary = str(kwargs.get('summary', kwargs.get('Summary', '')))
self.notes = str(kwargs.get('notes', kwargs.get('Notes', '')))
self.year = int(kwargs.get('year', kwargs.get('Year', -1)))
self.month = int(kwargs.get('month', kwargs.get('Month', -1)))
self.day = int(kwargs.get('day', kwargs.get('Day', -1)))
self.writer = str(kwargs.get('writer', kwargs.get('Writer', '')))
self.penciller = str(kwargs.get('penciller', kwargs.get('Penciller', '')))
self.inker = str(kwargs.get('inker', kwargs.get('Inker', '')))
self.colorist = str(kwargs.get('colorist', kwargs.get('Colorist', '')))
self.letterer = str(kwargs.get('letterer', kwargs.get('Letterer', '')))
self.cover_artist = str(kwargs.get('cover_artist', kwargs.get('CoverArtist', '')))
self.editor = str(kwargs.get('editor', kwargs.get('Editor', '')))
self.translator = str(kwargs.get('translator', kwargs.get('Translator', '')))
self.publisher = str(kwargs.get('publisher', kwargs.get('Publisher', '')))
self.imprint = str(kwargs.get('imprint', kwargs.get('imprint', 'Imprint')))
self.genre = str(kwargs.get('genre', kwargs.get('Genre', '')))
self.tags = str(kwargs.get('tags', kwargs.get('Tags', '')))
self.web = str(kwargs.get('web', kwargs.get('Web', '')))
self.language_iso = language(kwargs.get('language_iso', kwargs.get('LanguageISO', '')))
self.format = Format(kwargs.get('format', kwargs.get('Format', Format.UNKNOWN)))
self.ean = str(kwargs.get('ean', kwargs.get('EAN', '')))
self.black_white = YesNo(kwargs.get('black_white', kwargs.get('BlackAndWhite', YesNo.UNKNOWN)))
self.manga = Manga(kwargs.get('manga', kwargs.get('Manga', Manga.UNKNOWN)))
self.characters = str(kwargs.get('characters', kwargs.get('Characters', '')))
self.teams = str(kwargs.get('teams', kwargs.get('Teams', '')))
self.locations = str(kwargs.get('locations', kwargs.get('Locations', '')))
self.scan_information = str(kwargs.get('scan_information', kwargs.get('ScanInformation', '')))
self.story_arc = str(kwargs.get('story_arc', kwargs.get('StoryArc', '')))
self.story_arc_number = str(kwargs.get('story_arc_number', kwargs.get('StoryArcNumber', '')))
self.series_group = str(kwargs.get('series_group', kwargs.get('series_group', '')))
self.age_rating = AgeRating(kwargs.get('age_rating', kwargs.get('AgeRating', AgeRating.UNKNOWN)))
self.community_rating = rating(kwargs.get('community_rating', kwargs.get('CommunityRating', -1)))
self.main_character_or_team = str(kwargs.get('main_character_or_team', kwargs.get('MainCharacterOrTeam', '')))
self.review = str(kwargs.get('review', kwargs.get('Review', '')))
def dumps(self) -> dict: def dumps(self) -> dict:
# TODO: need change to loop with getattr return utils.dumps(self._get() | {
return utils.dumps({ "Pages": [{'Image': i, **page.dumps()} for i, page in enumerate(self.__pages)],
'Title': str(self.title), 'PageCount': len(self.__pages)
'Series': str(self.series),
'Number': str(self.number),
'Count': int(self.count),
'Volume': int(self.volume),
'AlternateSeries': str(self.alternate_series),
'AlternateNumber': str(self.alternate_number),
'AlternateCount': int(self.alternate_count),
'Summary': str(self.summary),
'Notes': str(self.notes),
'Year': int(self.year),
'Month': int(self.month),
'Day': int(self.day),
'Writer': str(self.writer),
'Penciller': str(self.penciller),
'Inker': str(self.inker),
'Colorist': str(self.colorist),
'Letterer': str(self.letterer),
'CoverArtist': str(self.cover_artist),
'Editor': str(self.editor),
'Translator': str(self.translator),
'Publisher': str(self.publisher),
'Imprint': str(self.imprint),
'Genre': str(self.genre),
'Tags': str(self.tags),
'Web': str(self.web),
'PageCount': len(self.__pages),
'LanguageISO': language(self.language_iso),
'Format': self.format,
'EAN': str(self.ean),
'BlackAndWhite': self.black_white,
'Manga': self.manga,
'Characters': str(self.characters),
'Teams': str(self.teams),
'Locations': str(self.locations),
'ScanInformation': str(self.scan_information),
'StoryArc': str(self.story_arc),
'StoryArcNumber': str(self.story_arc_number),
'SeriesGroup': str(self.series_group),
'AgeRating': self.age_rating,
'Pages': [{'Image': i, **page.dumps()} for i, page in enumerate(self.__pages)],
'CommunityRating': rating(self.community_rating),
'MainCharacterOrTeam': str(self.main_character_or_team),
'Review': str(self.review)
}) })
def __repr__(self) -> str: def __repr__(self) -> str:
@@ -166,8 +69,9 @@ class ComicInfo(ComicModel):
if not isinstance(path, (Path, str)): if not isinstance(path, (Path, str)):
raise ValueError(f'Expecting Path object or path string, got {path!r}') raise ValueError(f'Expecting Path object or path string, got {path!r}')
self._filepath = path self._filepath = path
new_file = self.pack()
with Path(path).open(mode='wb') as f: with Path(path).open(mode='wb') as f:
f.write(self.pack()) f.write(new_file)
def save(self) -> None: def save(self) -> None:
""" """
+62
View File
@@ -1,4 +1,5 @@
from enum import Enum from enum import Enum
from langcodes import Language
xml_name = "ComicInfo.xml" xml_name = "ComicInfo.xml"
@@ -100,3 +101,64 @@ class Format(Enum):
WEB_COMIC = 'Web Comic' WEB_COMIC = 'Web Comic'
# YEAR_ONE = 'Year 1' # YEAR_ONE = 'Year 1'
YEAR_ONE = 'Year One' YEAR_ONE = 'Year One'
class ValidRating(float):
def __init__(self, val):
assert -1 <= float(val) <= 5, f'Rating must be between 0 and 5, input {val}'
super(ValidRating, self).__init__()
class ValidLanguage(str):
def __init__(self, val):
if val and not Language.get(str(val)).is_valid():
raise ValueError(f'Invalid {val} language')
super(ValidLanguage, self).__init__()
FIELDS = (
# model: (key, xml key): (variable name, (expected type, second expected type,...))
# in case of multiple expected formats, value cast to first type in tuple
(("title", "Title"), ("title", (str,))),
(("series", "Series"), ("series", (str,))),
(("number", "Number"), ("number", (str, int, float))),
(("count", "Count"), ("count", (int,))),
(("volume", "Volume"), ("volume", (int,))),
(("alternate_series", "AlternateSeries"), ("alternate_series", (str,))),
(("alternate_number", "AlternateNumber"), ("alternate_number", (str, int, float))),
(("alternate_count", "AlternateCount"), ("alternate_count", (int,))),
(("summary", "Summary"), ("summary", (str,))),
(("notes", "Notes"), ("notes", (str,))),
(("year", "Year"), ("year", (int,))),
(("month", "Month"), ("month", (int,))),
(("day", "Day"), ("day", (int,))),
(("writer", "Writer"), ("writer", (str,))),
(("penciller", "Penciller"), ("penciller", (str,))),
(("inker", "Inker"), ("inker", (str,))),
(("colorist", "Colorist"), ("colorist", (str,))),
(("letterer", "Letterer"), ("letterer", (str,))),
(("cover_artist", "CoverArtist"), ("cover_artist", (str,))),
(("editor", "Editor"), ("editor", (str,))),
(("translator", "Translator"), ("translator", (str,))),
(("publisher", "Publisher"), ("publisher", (str,))),
(("imprint", "Imprint"), ("imprint", (str,))),
(("genre", "Genre"), ("genre", (str,))),
(("tags", "Tags"), ("tags", (str,))),
(("web", "Web"), ("web", (str,))),
(("format", "Format"), ("format", (Format, str))),
(("ean", "EAN"), ("ean", (str,))),
(("black_white", "BlackAndWhite"), ("black_white", (YesNo, str))),
(("manga", "Manga"), ("manga", (Manga, str))),
(("characters", "Characters"), ("characters", (str,))),
(("teams", "Teams"), ("teams", (str,))),
(("locations", "Locations"), ("locations", (str,))),
(("scan_information", "ScanInformation"), ("scan_information", (str,))),
(("story_arc", "StoryArc"), ("story_arc", (str,))),
(("story_arc_number", "StoryArcNumber"), ("story_arc_number", (str,))),
(("series_group", "SeriesGroup"), ("series_group", (str,))),
(("age_rating", "AgeRating"), ("age_rating", (AgeRating, str))),
(("main_character_or_team", "MainCharacterOrTeam"), ("main_character_or_team", (str,))),
(("review", "Review"), ("review", (str,))),
(("language_iso", "LanguageISO"), ("language_iso", (ValidLanguage, str))),
(("community_rating", "CommunityRating"), ("community_rating", (ValidRating, float, int, str))),
)
+36 -1
View File
@@ -1,4 +1,5 @@
from cbz.constants import YesNo, Manga, AgeRating, Format from cbz.constants import YesNo, Manga, AgeRating, Format, FIELDS
from typing import Any
class ComicModel: class ComicModel:
@@ -45,3 +46,37 @@ class ComicModel:
main_character_or_team: str = "" main_character_or_team: str = ""
review: str = "" review: str = ""
_filepath: str = "" _filepath: str = ""
def __init__(self, kwargs: dict):
"""
Set class variables from input dictionary, check types of input and cast values to correct type
:param kwargs: dictionary of input data
"""
for kwarg_key, kwarg_value in kwargs.items():
for keys, values in FIELDS:
if kwarg_key in keys:
variable, types = values
if hasattr(self, variable):
setattr(self, variable, self._check_type(kwarg_key, kwarg_value, types))
break
@staticmethod
def _check_type(key: str, value: Any, types: tuple) -> Any:
"""
Check type of value, and cast this value to first type of the types
:param key: name of key of variable (using only for best error information)
:param value: value for a check
:param types: list of the allowed types
:return: value with new type
"""
if not isinstance(value, types):
raise ValueError(
f"Unexpected type of {key}, got: {type(value).__name__}, expected: {[i.__name__ for i in types]}")
return types[0](value)
def _get(self) -> dict:
"""
Create dictionary from variables by FIELDS
:return: dictionary with variables value
"""
return {key[1]: self._check_type(value[0], getattr(self, value[0]), value[1]) for key, value in FIELDS}