Skip to content

Commit

Permalink
Merge pull request #30 from debakarr/master
Browse files Browse the repository at this point in the history
Add endpoint for getting dramalist for a user
  • Loading branch information
tbdsux authored Jan 21, 2024
2 parents 5de9769 + 0355762 commit 7fa05fe
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 3 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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/*`
Expand Down
72 changes: 71 additions & 1 deletion api/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
10 changes: 9 additions & 1 deletion api/utils.py
Original file line number Diff line number Diff line change
@@ -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]:
Expand Down Expand Up @@ -31,6 +38,7 @@ async def search_func(query: str) -> Tuple[int, Dict[str, Any]]:
"cast": FetchCast,
"reviews": FetchReviews,
"lists": FetchList,
"dramalist": FetchDramaList,
}


Expand Down
78 changes: 78 additions & 0 deletions tests/fixture/dramalist.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Example Drama List - MyDramaList</title>
</style>
</head>
<body>
<div class="mdl-style-list mdl-style-list-1 box">
<div class="mdl-style-table-header box-header">
<div class="box-tool">
<a class="showNotes" href="/dramalist/ExampleList/watching?notes=1">View Notes</a>
</div>
<h3 class="mdl-style-list-label">Currently Watching</h3>
</div>
<div id="mylist_1" class="mdl-style-list-body section mylist table-responsive">
<table id="list_1" class="mdl-style-table table table-striped m-b-0">
<thead class="primary">
<tr>
<th width="30" class="mdl-style-thead-num text-center hidden-sm-down">#</th>
<th width="300" class="mdl-style-thead-title left"><a href="javascript:sortTable(1,1, 'asc')">Title <i class="fa fa-caret-down"></i></a></th>
<th width="100" class="mdl-style-thead-country text-center hidden-sm-down"><a href="javascript:sortTable(2,1)">Country <i class="fa fa-caret-down"></i></a></th>
<th width="85" class="mdl-style-thead-year text-center hidden-sm-down"><a href="javascript:sortTable(3,1)">Year <i class="fa fa-caret-down"></i></a></th>
<th width="85" class="mdl-style-thead-type text-center hidden-sm-down"><a href="javascript:sortTable(4,1)">Type <i class="fa fa-caret-down"></i></a></th>
<th width="110" class="mdl-style-thead-score text-center"><a href="javascript:sortTable(5,1)">Score <i class="fa fa-caret-down"></i></a></th>
<th width="105" class="mdl-style-thead-progress text-center"><a href="javascript:sortTable(6,1)">Progress <i class="fa fa-caret-down"></i></a></th>
</tr>
</thead>
<tbody id="content_1">
<tr id="ml733445">
<th class="mdl-style-col-num order hidden-sm-down" width="30" align="center" style="border-left-width: 1px;">1</th>
<td class="mdl-style-col-title sort1">
<button class="btn simple btn-manage-list pull-right hidden-sm-down" data-id="733445"><span>edit</span></button> <span class="hidden-lg-up film-info" data-info="title:733445"></span> <a class="title text-primary _600" target="_blank" href="/733445-i-will-die-soon" data-hasqtip="733445-title" oldtitle="Death's Game" title="" aria-describedby="qtip-733445-title"><span>Death's Game</span></a>
<div class="hidden-md-up text-muted">Korean Drama</div>
</td>
<td class="mdl-style-col-country sort2 hidden-sm-down" abbr="3" width="90" align="center">South Korea</td>
<td class="mdl-style-col-year sort3 hidden-sm-down" abbr="2023" width="45" align="center">2023</td>
<td class="mdl-style-col-type sort4 hidden-sm-down" abbr="68" width="50" align="center">Drama</td>
<td class="mdl-style-col-score sort5" abbr="0" align="center"> <span class="rating"><span class="fill" style="width:0%;"></span></span> <span class="score">0.0</span></td>
<td class="mdl-style-col-progress sort6" abbr="220" width="80" align="center"> <span class="btnQuickEpisodeUpdate hidden-sm-down" data-id="733445"><a>-</a> / <a>+</a></span><span class="episode-seen">4</span>/<span class="episode-total">4</span> </td>
</tr>
<tr id="ml695963">
<th class="mdl-style-col-num order hidden-sm-down" width="30" align="center" style="border-left-width: 1px;">9</th>
<td class="mdl-style-col-title sort1">
<button class="btn simple btn-manage-list pull-right hidden-sm-down" data-id="695963"><span>edit</span></button> <span class="hidden-lg-up film-info" data-info="title:695963"></span> <a title="Tomorrow" class="title text-primary _600" data-info="title:695963" target="_blank" href="/695963-tomorrow"><span>Tomorrow</span></a>
<div class="hidden-md-up text-muted">Korean Drama</div>
</td>
<td class="mdl-style-col-country sort2 hidden-sm-down" abbr="3" width="90" align="center">South Korea</td>
<td class="mdl-style-col-year sort3 hidden-sm-down" abbr="2022" width="45" align="center">2022</td>
<td class="mdl-style-col-type sort4 hidden-sm-down" abbr="68" width="50" align="center">Drama</td>
<td class="mdl-style-col-score sort5" abbr="0" align="center"> <span class="rating"><span class="fill" style="width:0%;"></span></span> <span class="score">0.0</span></td>
<td class="mdl-style-col-progress sort6" abbr="240" width="80" align="center"> <span class="btnQuickEpisodeUpdate hidden-sm-down" data-id="695963"><a>-</a> / <a>+</a></span><span class="episode-seen">4</span>/<span class="episode-total">16</span> </td>
</tr>
<tr id="ml743267">
<th class="mdl-style-col-num order hidden-sm-down" width="30" align="center" style="border-left-width: 1px;">10</th>
<td class="mdl-style-col-title sort1">
<button class="btn simple btn-manage-list pull-right hidden-sm-down" data-id="743267"><span>edit</span></button> <span class="hidden-lg-up film-info" data-info="title:743267"></span> <a title="Welcome to Samdal-ri" class="title text-primary _600" data-info="title:743267" target="_blank" href="/743267-welcome-to-samdalri"><span>Welcome to Samdal-ri</span></a> <span class="airing">airing</span>
<div class="hidden-md-up text-muted">Korean Drama</div>
</td>
<td class="mdl-style-col-country sort2 hidden-sm-down" abbr="3" width="90" align="center">South Korea</td>
<td class="mdl-style-col-year sort3 hidden-sm-down" abbr="2023" width="45" align="center">2023</td>
<td class="mdl-style-col-type sort4 hidden-sm-down" abbr="68" width="50" align="center">Drama</td>
<td class="mdl-style-col-score sort5" abbr="0" align="center"> <span class="rating"><span class="fill" style="width:0%;"></span></span> <span class="score">0.0</span></td>
<td class="mdl-style-col-progress sort6" abbr="980" width="80" align="center"> <span class="btnQuickEpisodeUpdate hidden-sm-down" data-id="743267"><a>-</a> / <a>+</a></span><span class="episode-seen">14</span>/<span class="episode-total">16</span> </td>
</tr>
</tbody>
</table>
<!-- LIST FOOTER -->
<div class="mdl-style-list-footer box-footer b-t list-statistics">
<label class="mdl-style-dramas"><span class="name">Dramas</span><span class="cnt">10</span></label>
<label class="mdl-style-tvshows"><span class="name">TV Shows</span><span class="cnt">0</span></label>
<label class="mdl-style-episodes"><span class="name">Episodes</span><span class="cnt">59</span></label>
<label class="mdl-style-movies"><span class="name">Movies</span><span class="cnt">0</span></label>
<label class="mdl-style-days"><span class="name">Days</span><span class="cnt">2.6</span></label>
</div>
</div>
</div>
</body>
</html>
54 changes: 54 additions & 0 deletions tests/test_fetch_dramalist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from api.fetch import FetchDramaList
from pathlib import Path
import pytest
from bs4 import BeautifulSoup


@pytest.fixture
def sample_obj():
dramalist = Path(__file__).parent / "fixture" / "dramalist.html"
html_content = dramalist.read_text()
sample_soup = BeautifulSoup(html_content, "html.parser")
return FetchDramaList(sample_soup, "query", 200, True)


def test_fetch_drama_list(sample_obj):
sample_obj._get_main_container()
breakpoint()
assert sample_obj.info == {
"link": "https://mydramalist.com/query",
"list": {
"Currently Watching": {
"items": [
{
"name": "Death's Game",
"id": "733445-i-will-die-soon",
"score": "0.0",
"episode_seen": "4",
"episode_total": "4",
},
{
"name": "Tomorrow",
"id": "695963-tomorrow",
"score": "0.0",
"episode_seen": "4",
"episode_total": "16",
},
{
"name": "Welcome to Samdal-ri",
"id": "743267-welcome-to-samdalri",
"score": "0.0",
"episode_seen": "14",
"episode_total": "16",
},
],
"stats": {
"Dramas": "10",
"TV Shows": "0",
"Episodes": "59",
"Movies": "0",
"Days": "2.6",
},
}
},
}

1 comment on commit 7fa05fe

@vercel
Copy link

@vercel vercel bot commented on 7fa05fe Jan 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kuryana – ./

kuryana.vercel.app
kuryana-theboringdude.vercel.app
kuryana-git-master-theboringdude.vercel.app

Please sign in to comment.