Compare commits

...

2 Commits

Author SHA1 Message Date
Caeden Perelli-Harris
945803f65d
Unmark fetch anime and play as BROKEN and fix type errors (#8988)
* updating DIRECTORY.md

* type(fetch-anime-and-play): Fix type errors and re-enable

* updating DIRECTORY.md

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
2023-08-18 05:19:25 -07:00
Caeden Perelli-Harris
5f7819e1cd
Fix get top billionaires BROKEN file (#8970)
* updating DIRECTORY.md

* fix(get-top-billionaires): Handle timestamp before epoch

* updating DIRECTORY.md

* revert(pyproject): Re-implement ignore lru_cache

* fix(age): Update age to current year

* fix(doctest): Make years since dynamic

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
2023-08-18 05:13:38 -07:00
3 changed files with 59 additions and 41 deletions

View File

@ -1213,6 +1213,7 @@
* [Daily Horoscope](web_programming/daily_horoscope.py) * [Daily Horoscope](web_programming/daily_horoscope.py)
* [Download Images From Google Query](web_programming/download_images_from_google_query.py) * [Download Images From Google Query](web_programming/download_images_from_google_query.py)
* [Emails From Url](web_programming/emails_from_url.py) * [Emails From Url](web_programming/emails_from_url.py)
* [Fetch Anime And Play](web_programming/fetch_anime_and_play.py)
* [Fetch Bbc News](web_programming/fetch_bbc_news.py) * [Fetch Bbc News](web_programming/fetch_bbc_news.py)
* [Fetch Github Info](web_programming/fetch_github_info.py) * [Fetch Github Info](web_programming/fetch_github_info.py)
* [Fetch Jobs](web_programming/fetch_jobs.py) * [Fetch Jobs](web_programming/fetch_jobs.py)
@ -1221,6 +1222,7 @@
* [Get Amazon Product Data](web_programming/get_amazon_product_data.py) * [Get Amazon Product Data](web_programming/get_amazon_product_data.py)
* [Get Imdb Top 250 Movies Csv](web_programming/get_imdb_top_250_movies_csv.py) * [Get Imdb Top 250 Movies Csv](web_programming/get_imdb_top_250_movies_csv.py)
* [Get Imdbtop](web_programming/get_imdbtop.py) * [Get Imdbtop](web_programming/get_imdbtop.py)
* [Get Top Billionaires](web_programming/get_top_billionaires.py)
* [Get Top Hn Posts](web_programming/get_top_hn_posts.py) * [Get Top Hn Posts](web_programming/get_top_hn_posts.py)
* [Get User Tweets](web_programming/get_user_tweets.py) * [Get User Tweets](web_programming/get_user_tweets.py)
* [Giphy](web_programming/giphy.py) * [Giphy](web_programming/giphy.py)

View File

@ -1,7 +1,5 @@
from xml.dom import NotFoundErr
import requests import requests
from bs4 import BeautifulSoup, NavigableString from bs4 import BeautifulSoup, NavigableString, Tag
from fake_useragent import UserAgent from fake_useragent import UserAgent
BASE_URL = "https://ww1.gogoanime2.org" BASE_URL = "https://ww1.gogoanime2.org"
@ -41,25 +39,23 @@ def search_scraper(anime_name: str) -> list:
# get list of anime # get list of anime
anime_ul = soup.find("ul", {"class": "items"}) anime_ul = soup.find("ul", {"class": "items"})
if anime_ul is None or isinstance(anime_ul, NavigableString):
msg = f"Could not find and anime with name {anime_name}"
raise ValueError(msg)
anime_li = anime_ul.children anime_li = anime_ul.children
# for each anime, insert to list. the name and url. # for each anime, insert to list. the name and url.
anime_list = [] anime_list = []
for anime in anime_li: for anime in anime_li:
if not isinstance(anime, NavigableString): if isinstance(anime, Tag):
try: anime_url = anime.find("a")
anime_url, anime_title = ( if anime_url is None or isinstance(anime_url, NavigableString):
anime.find("a")["href"], continue
anime.find("a")["title"], anime_title = anime.find("a")
) if anime_title is None or isinstance(anime_title, NavigableString):
anime_list.append( continue
{
"title": anime_title, anime_list.append({"title": anime_title["title"], "url": anime_url["href"]})
"url": anime_url,
}
)
except (NotFoundErr, KeyError):
pass
return anime_list return anime_list
@ -93,22 +89,24 @@ def search_anime_episode_list(episode_endpoint: str) -> list:
# With this id. get the episode list. # With this id. get the episode list.
episode_page_ul = soup.find("ul", {"id": "episode_related"}) episode_page_ul = soup.find("ul", {"id": "episode_related"})
if episode_page_ul is None or isinstance(episode_page_ul, NavigableString):
msg = f"Could not find any anime eposiodes with name {anime_name}"
raise ValueError(msg)
episode_page_li = episode_page_ul.children episode_page_li = episode_page_ul.children
episode_list = [] episode_list = []
for episode in episode_page_li: for episode in episode_page_li:
try: if isinstance(episode, Tag):
if not isinstance(episode, NavigableString): url = episode.find("a")
if url is None or isinstance(url, NavigableString):
continue
title = episode.find("div", {"class": "name"})
if title is None or isinstance(title, NavigableString):
continue
episode_list.append( episode_list.append(
{ {"title": title.text.replace(" ", ""), "url": url["href"]}
"title": episode.find("div", {"class": "name"}).text.replace(
" ", ""
),
"url": episode.find("a")["href"],
}
) )
except (KeyError, NotFoundErr):
pass
return episode_list return episode_list
@ -140,11 +138,16 @@ def get_anime_episode(episode_endpoint: str) -> list:
soup = BeautifulSoup(response.text, "html.parser") soup = BeautifulSoup(response.text, "html.parser")
try: url = soup.find("iframe", {"id": "playerframe"})
episode_url = soup.find("iframe", {"id": "playerframe"})["src"] if url is None or isinstance(url, NavigableString):
msg = f"Could not find url and download url from {episode_endpoint}"
raise RuntimeError(msg)
episode_url = url["src"]
if not isinstance(episode_url, str):
msg = f"Could not find url and download url from {episode_endpoint}"
raise RuntimeError(msg)
download_url = episode_url.replace("/embed/", "/playlist/") + ".m3u8" download_url = episode_url.replace("/embed/", "/playlist/") + ".m3u8"
except (KeyError, NotFoundErr) as e:
raise e
return [f"{BASE_URL}{episode_url}", f"{BASE_URL}{download_url}"] return [f"{BASE_URL}{episode_url}", f"{BASE_URL}{download_url}"]

View File

@ -3,7 +3,7 @@ CAUTION: You may get a json.decoding error.
This works for some of us but fails for others. This works for some of us but fails for others.
""" """
from datetime import datetime from datetime import UTC, datetime, timedelta
import requests import requests
from rich import box from rich import box
@ -20,18 +20,31 @@ API_URL = (
) )
def calculate_age(unix_date: int) -> str: def calculate_age(unix_date: float) -> str:
"""Calculates age from given unix time format. """Calculates age from given unix time format.
Returns: Returns:
Age as string Age as string
>>> calculate_age(-657244800000) >>> from datetime import datetime, UTC
'73' >>> years_since_create = datetime.now(tz=UTC).year - 2022
>>> calculate_age(46915200000) >>> int(calculate_age(-657244800000)) - years_since_create
'51' 73
>>> int(calculate_age(46915200000)) - years_since_create
51
""" """
birthdate = datetime.fromtimestamp(unix_date / 1000).date() # Convert date from milliseconds to seconds
unix_date /= 1000
if unix_date < 0:
# Handle timestamp before epoch
epoch = datetime.fromtimestamp(0, tz=UTC)
seconds_since_epoch = (datetime.now(tz=UTC) - epoch).seconds
birthdate = (
epoch - timedelta(seconds=abs(unix_date) - seconds_since_epoch)
).date()
else:
birthdate = datetime.fromtimestamp(unix_date, tz=UTC).date()
return str( return str(
TODAY.year TODAY.year
- birthdate.year - birthdate.year