Coverage for otaku_info/external/entities/MangadexItem.py: 87%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""LICENSE
2Copyright 2020 Hermann Krumrey <hermann@krumreyh.com>
4This file is part of otaku-info.
6otaku-info is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
11otaku-info is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
16You should have received a copy of the GNU General Public License
17along with otaku-info. If not, see <http://www.gnu.org/licenses/>.
18LICENSE"""
20from typing import Dict, Any, Optional
21from otaku_info.enums import ListService, ReleasingState
22from otaku_info.mappings import mangadex_external_id_names, \
23 list_service_id_types
26class MangadexItem:
27 """
28 Class that models a general anilist list item
29 Represents the information fetched using anilist's API
30 """
31 def __init__(
32 self,
33 mangadex_id: str,
34 external_ids: Dict[ListService, str],
35 english_title: str,
36 romaji_title: str,
37 cover_url: str,
38 total_chapters: Optional[int],
39 latest_chapter: Optional[int],
40 releasing_state: ReleasingState
41 ):
42 """
43 Initializes the MangadexItem object
44 :param mangadex_id: The mangadex ID of the series
45 :param external_ids: IDs for other services
46 :param english_title: The title of the series in English
47 :param romaji_title: The title of the series in Japanese
48 :param cover_url: URL to a cover image for this series
49 :param total_chapters: The total amount of chapters
50 :param latest_chapter: The latest chapter
51 :param releasing_state: The releasing state
52 """
53 self.mangadex_id = mangadex_id
54 self.external_ids = external_ids
55 self.english_title = english_title
56 self.romaji_title = romaji_title
57 self.cover_url = cover_url
58 self.total_chapters = total_chapters
59 self.latest_chapter = latest_chapter
60 self.releasing_state = releasing_state
62 @classmethod
63 def from_json(cls, data: Dict[str, Any]) \
64 -> "MangadexItem":
65 """
66 Generates a MangadexItem from a dictionary generated by an API query
67 :param data: The data to use
68 :return: The generated MangadexItem
69 """
70 relations = {x["type"]: x["id"] for x in data["relationships"]}
72 ids = {ListService.MANGADEX: data["id"]}
73 links = data["attributes"]["links"]
74 if links is not None: 74 ↛ 86line 74 didn't jump to line 86, because the condition on line 74 was never false
75 for service, identifier in mangadex_external_id_names.items():
76 if identifier in links:
77 _id = links[identifier]
78 id_type = list_service_id_types[service]
79 if id_type == int:
80 _id = "".join([x for x in _id if x.isdigit()])
81 try:
82 ids[service] = str(id_type(_id))
83 except ValueError:
84 pass
86 total_chapters: Optional[int] = None
87 last_chapter: Optional[str] = data["attributes"]["lastChapter"]
88 if last_chapter is not None: 88 ↛ 93line 88 didn't jump to line 93, because the condition on line 88 was never false
89 try:
90 total_chapters = int(float(last_chapter.split("-")[0]))
91 except ValueError:
92 pass
93 if total_chapters == 0: 93 ↛ 94line 93 didn't jump to line 94, because the condition on line 93 was never true
94 total_chapters = None
96 releasing_state = cls.resolve_releasing_state(
97 data["attributes"]["status"]
98 )
100 default_lang, default_title = \
101 list(data["attributes"]["title"].items())[0]
102 alt_titles = data["attributes"]["altTitles"]
103 en_titles = [x for x in alt_titles if "en" in x]
104 jp_titles = [x for x in alt_titles if "jp" in x]
105 english_title = default_title
106 romaji_title = default_title
108 if default_lang == "jp" and len(en_titles) > 0: 108 ↛ 109line 108 didn't jump to line 109, because the condition on line 108 was never true
109 english_title = en_titles[0]["en"]
110 elif default_lang == "en" and len(jp_titles) > 0: 110 ↛ 111line 110 didn't jump to line 111, because the condition on line 110 was never true
111 romaji_title = jp_titles[0]["jp"]
113 return MangadexItem(
114 data["id"],
115 ids,
116 english_title,
117 romaji_title,
118 relations.get("cover_art", ""),
119 total_chapters,
120 total_chapters,
121 releasing_state
122 )
124 @staticmethod
125 def resolve_releasing_state(state: str) -> ReleasingState:
126 """
127 Translates mangadex status tags to releasing states
128 :param state: The status tag to translate
129 :return: The releasing state
130 """
131 return {
132 "ongoing": ReleasingState.RELEASING,
133 "completed": ReleasingState.FINISHED,
134 "cancelled": ReleasingState.CANCELLED,
135 "hiatus": ReleasingState.UNKNOWN
136 }[state]