84 lines
2.5 KiB
Python
84 lines
2.5 KiB
Python
from fastapi import APIRouter, HTTPException
|
|
import feedparser
|
|
import httpx
|
|
from pydantic import BaseModel
|
|
from typing import List, Optional
|
|
from datetime import datetime
|
|
|
|
router = APIRouter()
|
|
|
|
RSS_FEED_URL = "https://rss.libsyn.com/shows/563180/destinations/4867845.xml"
|
|
|
|
class PodcastEpisode(BaseModel):
|
|
id: str
|
|
title: str
|
|
description: str
|
|
audio_url: str
|
|
published_at: str
|
|
duration: Optional[str] = None
|
|
image_url: Optional[str] = None
|
|
|
|
class PodcastFeed(BaseModel):
|
|
title: str
|
|
description: str
|
|
image_url: Optional[str] = None
|
|
episodes: List[PodcastEpisode]
|
|
|
|
@router.get("/", response_model=PodcastFeed)
|
|
async def get_podcasts():
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get(RSS_FEED_URL)
|
|
response.raise_for_status()
|
|
rss_content = response.text
|
|
|
|
feed = feedparser.parse(rss_content)
|
|
|
|
if feed.bozo:
|
|
# Log warning but try to proceed if possible, or raise error
|
|
print(f"Warning: Feed parsing error: {feed.bozo_exception}")
|
|
|
|
episodes = []
|
|
for entry in feed.entries:
|
|
# Extract audio URL
|
|
audio_url = ""
|
|
for link in entry.links:
|
|
if link.type == "audio/mpeg":
|
|
audio_url = link.href
|
|
break
|
|
|
|
if not audio_url:
|
|
continue # Skip episodes without audio
|
|
|
|
# Extract image
|
|
image_url = None
|
|
if 'image' in entry:
|
|
image_url = entry.image.href
|
|
elif 'itunes_image' in entry:
|
|
image_url = entry.itunes_image.href
|
|
|
|
episodes.append(PodcastEpisode(
|
|
id=entry.id,
|
|
title=entry.title,
|
|
description=entry.summary,
|
|
audio_url=audio_url,
|
|
published_at=entry.published,
|
|
duration=entry.get('itunes_duration'),
|
|
image_url=image_url
|
|
))
|
|
|
|
feed_image = None
|
|
if 'image' in feed.feed:
|
|
feed_image = feed.feed.image.href
|
|
elif 'itunes_image' in feed.feed:
|
|
feed_image = feed.feed.itunes_image.href
|
|
|
|
return PodcastFeed(
|
|
title=feed.feed.title,
|
|
description=feed.feed.description,
|
|
image_url=feed_image,
|
|
episodes=episodes
|
|
)
|
|
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Failed to fetch podcasts: {str(e)}")
|