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

53 statements  

1"""LICENSE 

2Copyright 2020 Hermann Krumrey <hermann@krumreyh.com> 

3 

4This file is part of otaku-info. 

5 

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. 

10 

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. 

15 

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""" 

19 

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 

24 

25 

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 

61 

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"]} 

71 

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 

85 

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 

95 

96 releasing_state = cls.resolve_releasing_state( 

97 data["attributes"]["status"] 

98 ) 

99 

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 

107 

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"] 

112 

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 ) 

123 

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]