diff --git a/README.md b/README.md index c863a53..39d904f 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,12 @@ https://kuryana.vercel.app/seasonal/{year}/{quarter} https://kuryana.vercel.app/list/{id} ``` +- [Get User Dramalist](https://kuryana.vercel.app/dramalist/) + +``` +https://kuryana.vercel.app/dramalist/{user_id} +``` + ### Error Messages ```js @@ -111,7 +117,7 @@ You can start the development server in two ways: - Or with `uvicorn` (`localhost:8000`) ```sh - uvicorn api.main --reload + uvicorn api.main:app --reload ``` - The api will be `http://localhost:8000/*` diff --git a/api/fetch.py b/api/fetch.py index a936ae7..057aa7d 100644 --- a/api/fetch.py +++ b/api/fetch.py @@ -37,7 +37,11 @@ def _get_main_container(self) -> None: # SYNOPSIS synopsis = container.find("div", class_="show-synopsis").find("p") - self.info["synopsis"] = synopsis.get_text().replace("Edit Translation", "").strip() if synopsis else "" + self.info["synopsis"] = ( + synopsis.get_text().replace("Edit Translation", "").strip() + if synopsis + else "" + ) # CASTS __casts = container.find_all("li", class_="list-item col-sm-4") @@ -351,6 +355,72 @@ def _get(self) -> None: self._get_main_container() +class FetchDramaList(BaseFetch): + def __init__(self, soup: BeautifulSoup, query: str, code: int, ok: bool) -> None: + super().__init__(soup, query, code, ok) + + def _get_main_container(self) -> None: + container = self.soup.find_all("div", class_="mdl-style-list") + titles = [self._parse_title(item) for item in container] + dramas = [self._parse_drama(item) for item in container] + stats = [self._parse_total_stats(item) for item in container] + + items = dict() + for title, drama, stat in zip(titles, dramas, stats): + items[title] = {"items": drama, "stats": stat} + + self.info["list"] = items + + def _parse_title(self, item: BeautifulSoup) -> str: + return item.find("h3", class_="mdl-style-list-label").get_text(strip=True) + + def _parse_total_stats(self, item: BeautifulSoup) -> Dict[str, str]: + drama_stats = item.find("label", class_="mdl-style-dramas") + tvshows_stats = item.find("label", class_="mdl-style-tvshows") + episodes_stats = item.find("label", class_="mdl-style-episodes") + movies_stats = item.find("label", class_="mdl-style-movies") + days_stats = item.find("label", class_="mdl-style-days") + return { + label.find("span", class_="name") + .get_text(strip=True): label.find("span", class_="cnt") + .get_text(strip=True) + for label in [ + drama_stats, + tvshows_stats, + episodes_stats, + movies_stats, + days_stats, + ] + } + + def _parse_drama(self, item: BeautifulSoup) -> Dict[str, str]: + item_names = item.find_all("a", class_="title") + item_scores = item.find_all("span", class_="score") + item_episode_seens = item.find_all("span", class_="episode-seen") + item_episode_totals = item.find_all("span", class_="episode-total") + + parsed_data = [] + for name, score, seen, total in zip( + item_names, + item_scores, + item_episode_seens, + item_episode_totals, + ): + parsed_item = { + "name": name.get_text(strip=True), + "id": name.get("href", "").split("/")[-1], + "score": score.get_text(strip=True), + "episode_seen": seen.get_text(strip=True), + "episode_total": total.get_text(strip=True), + } + parsed_data.append(parsed_item) + + return parsed_data + + def _get(self) -> None: + self._get_main_container() + + class FetchList(BaseFetch): def __init__(self, soup: BeautifulSoup, query: str, code: int, ok: bool) -> None: super().__init__(soup, query, code, ok) diff --git a/api/main.py b/api/main.py index b18b9a3..6e19f51 100644 --- a/api/main.py +++ b/api/main.py @@ -68,6 +68,14 @@ async def person(person_id: str, response: Response) -> Dict[str, Any]: return r +@app.get("/dramalist/{user_id}") +async def dramalist(user_id: str, response: Response) -> Dict[str, Any]: + code, r = await fetch_func(query=f"dramalist/{user_id}", t="dramalist") + + response.status_code = code + return r + + @app.get("/list/{list_id}") async def lists(list_id: str, response: Response) -> Dict[str, Any]: code, r = await fetch_func(query=f"list/{list_id}", t="lists") diff --git a/api/utils.py b/api/utils.py index d790444..82251a4 100644 --- a/api/utils.py +++ b/api/utils.py @@ -1,7 +1,14 @@ from typing import Dict, Any, Tuple from api.search import Search -from api.fetch import FetchDrama, FetchList, FetchPerson, FetchCast, FetchReviews +from api.fetch import ( + FetchDrama, + FetchList, + FetchPerson, + FetchCast, + FetchReviews, + FetchDramaList, +) def error(code: int, description: str) -> Dict[str, Any]: @@ -31,6 +38,7 @@ async def search_func(query: str) -> Tuple[int, Dict[str, Any]]: "cast": FetchCast, "reviews": FetchReviews, "lists": FetchList, + "dramalist": FetchDramaList, } diff --git a/tests/fixture/dramalist.html b/tests/fixture/dramalist.html new file mode 100644 index 0000000..9bc1d67 --- /dev/null +++ b/tests/fixture/dramalist.html @@ -0,0 +1,78 @@ + + +
+Title | + + + +Score | +Progress | +
---|---|---|
+ Death's Game
+ Korean Drama
+ |
+
+
+
+ 0.0 | +4/4 | +
+ Tomorrow
+ Korean Drama
+ |
+
+
+
+ 0.0 | +4/16 | +
+ Welcome to Samdal-ri airing
+ Korean Drama
+ |
+
+
+
+ 0.0 | +14/16 | +