2025-01-18 15:53:06 -05:00
|
|
|
from urllib.parse import quote_plus
|
|
|
|
|
|
|
|
import httpx
|
|
|
|
from loguru import logger
|
2023-08-10 11:27:31 -04:00
|
|
|
|
2022-12-07 19:09:05 -05:00
|
|
|
from catalog.common import *
|
2022-12-08 16:59:03 +00:00
|
|
|
from catalog.models import *
|
2023-08-10 11:27:31 -04:00
|
|
|
|
2023-01-29 20:05:30 -05:00
|
|
|
from .rss import RSS
|
2022-12-07 19:09:05 -05:00
|
|
|
|
|
|
|
|
2022-12-15 17:29:35 -05:00
|
|
|
@SiteManager.register
|
2022-12-07 19:09:05 -05:00
|
|
|
class ApplePodcast(AbstractSite):
|
2025-01-18 15:53:06 -05:00
|
|
|
SITE_NAME = SiteName.ApplePodcast
|
2022-12-07 19:09:05 -05:00
|
|
|
ID_TYPE = IdType.ApplePodcast
|
|
|
|
URL_PATTERNS = [r"https://[^.]+.apple.com/\w+/podcast/*[^/?]*/id(\d+)"]
|
2022-12-29 23:57:02 -05:00
|
|
|
WIKI_PROPERTY_ID = "P5842"
|
2022-12-07 19:09:05 -05:00
|
|
|
DEFAULT_MODEL = Podcast
|
|
|
|
|
|
|
|
@classmethod
|
2023-01-29 20:05:30 -05:00
|
|
|
def id_to_url(cls, id_value):
|
2022-12-07 19:09:05 -05:00
|
|
|
return "https://podcasts.apple.com/us/podcast/id" + id_value
|
|
|
|
|
|
|
|
def scrape(self):
|
2022-12-29 23:57:02 -05:00
|
|
|
api_url = f"https://itunes.apple.com/lookup?id={self.id_value}"
|
2022-12-07 19:09:05 -05:00
|
|
|
dl = BasicDownloader(api_url)
|
|
|
|
resp = dl.download()
|
2022-12-29 23:57:02 -05:00
|
|
|
r = resp.json()["results"][0]
|
2023-12-31 08:32:19 -05:00
|
|
|
feed_url = r["feedUrl"]
|
2024-07-13 00:16:47 -04:00
|
|
|
title = r["trackName"]
|
2022-12-29 23:57:02 -05:00
|
|
|
pd = ResourceContent(
|
|
|
|
metadata={
|
2024-07-13 00:16:47 -04:00
|
|
|
"title": title,
|
2023-12-31 08:32:19 -05:00
|
|
|
"feed_url": feed_url,
|
2024-07-13 00:16:47 -04:00
|
|
|
"host": [r["artistName"]],
|
2022-12-29 23:57:02 -05:00
|
|
|
"genres": r["genres"],
|
|
|
|
"cover_image_url": r["artworkUrl600"],
|
|
|
|
}
|
|
|
|
)
|
2023-12-31 08:32:19 -05:00
|
|
|
pd.lookup_ids[IdType.RSS] = RSS.url_to_id(feed_url)
|
2022-12-07 19:09:05 -05:00
|
|
|
return pd
|
2025-01-18 15:53:06 -05:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
async def search_task(
|
|
|
|
cls, q: str, page: int, category: str
|
|
|
|
) -> list[ExternalSearchResultItem]:
|
|
|
|
if category != "podcast":
|
|
|
|
return []
|
|
|
|
SEARCH_PAGE_SIZE = 5 if category == "all" else 10
|
|
|
|
results = []
|
|
|
|
search_url = f"https://itunes.apple.com/search?entity=podcast&limit={page * SEARCH_PAGE_SIZE}&term={quote_plus(q)}"
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
|
|
try:
|
|
|
|
response = await client.get(search_url, timeout=2)
|
|
|
|
r = response.json()
|
|
|
|
for p in r["results"][(page - 1) * SEARCH_PAGE_SIZE :]:
|
|
|
|
if p.get("feedUrl"):
|
|
|
|
results.append(
|
|
|
|
ExternalSearchResultItem(
|
|
|
|
ItemCategory.Podcast,
|
|
|
|
SiteName.RSS,
|
|
|
|
p["feedUrl"],
|
|
|
|
p["trackName"],
|
|
|
|
p["artistName"],
|
|
|
|
"",
|
|
|
|
p["artworkUrl600"],
|
|
|
|
)
|
|
|
|
)
|
|
|
|
except Exception as e:
|
|
|
|
logger.error(
|
|
|
|
"ApplePodcast search error", extra={"query": q, "exception": e}
|
|
|
|
)
|
|
|
|
return results
|