Coverage for otaku_info/external/entities/RedditLnRelease.py: 65%
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 datetime import datetime
21from typing import Optional, List
22from bs4.element import Tag
23from otaku_info.utils.dates import map_month_name_to_month_number
24from otaku_info.external.anilist import load_anilist_info
25from otaku_info.enums import ListService, MediaType
28class RedditLnRelease:
29 """
30 Object that acts as a wrapper around a light novel release on reddit.com
31 """
33 def __init__(
34 self,
35 series_name: str,
36 year: int,
37 release_date_string: str,
38 volume: str,
39 publisher: Optional[str],
40 purchase_link: Optional[str],
41 info_link: Optional[str],
42 digital: bool,
43 physical: bool
44 ):
45 """
46 Initializes the object
47 :param series_name: The name of the series
48 :param year: The year of release
49 :param release_date_string: The month and day of release
50 :param volume: The volume number
51 :param publisher: The publisher of the release
52 :param purchase_link: A purchase link for the release
53 :param info_link: Link to information for the release
54 :param digital: Whether or not the release is digital
55 :param physical: Whether or not the release is physical
56 """
57 self.series_name = series_name
58 self.volume = volume
59 self.publisher = publisher
60 self.purchase_link = purchase_link
61 self.info_link = info_link
62 self.digital = digital
63 self.physical = physical
64 self.year = year
65 self._release_date_string = release_date_string
67 @property
68 def release_date(self) -> datetime:
69 """
70 :return: The release date as a datetime object
71 """
72 month_name, day_string = self._release_date_string.split(" ")
73 month = map_month_name_to_month_number(month_name)
74 if month is None: 74 ↛ 75line 74 didn't jump to line 75, because the condition on line 74 was never true
75 month = 1
76 try:
77 day = int(day_string)
78 except ValueError:
79 day = 1
80 return datetime(year=self.year, month=month, day=day)
82 @property
83 def release_date_string(self) -> str:
84 """
85 :return: The release date as a string (ISO 8601)
86 """
87 return self.release_date.strftime("%Y-%m-%d")
89 @property
90 def myanimelist_id(self) -> Optional[int]:
91 """
92 :return: The myanimelist ID, if available
93 """
94 if self.info_link is None or "myanimelist.net" not in self.info_link:
95 return None
97 url_parts = self.info_link.split("/")
98 index = -1
99 while not url_parts[index].isdigit():
100 index -= 1
101 return int(url_parts[index])
103 @property
104 def anilist_id(self) -> Optional[int]:
105 """
106 :return: The anilist ID, if available
107 """
108 if self.myanimelist_id is None:
109 return None
110 anilist_info = load_anilist_info(
111 self.myanimelist_id, MediaType.MANGA, ListService.MYANIMELIST
112 )
113 if anilist_info is not None:
114 return anilist_info.id
115 else:
116 return None
118 @classmethod
119 def from_parts(cls, year: int, parts: List[Tag]) -> "RedditLnRelease":
120 """
121 Generates a reddit LN release from BeautifulSoup td tags
122 :param year: The year of the release
123 :param parts: The td tags
124 :return: The reddit ln release
125 """
126 purchase_link_item = parts[3].find("a")
127 purchase_link = None
128 if purchase_link_item is not None: 128 ↛ 131line 128 didn't jump to line 131, because the condition on line 128 was never false
129 purchase_link = purchase_link_item["href"]
131 info_link_item = parts[1].find("a")
132 info_link: Optional[str] = None
133 if info_link_item is not None:
134 info_link = info_link_item["href"]
136 digital = "digital" in parts[4].text.lower()
137 physical = "physical" in parts[4].text.lower()
139 return cls(
140 series_name=parts[1].text,
141 year=year,
142 release_date_string=parts[0].text,
143 volume=parts[2].text,
144 publisher=parts[3].text,
145 purchase_link=purchase_link,
146 info_link=info_link,
147 digital=digital,
148 physical=physical
149 )