diff --git a/aggregators/kagi-news/src/html_parser.py b/aggregators/kagi-news/src/html_parser.py index 9d04b22..7ddc60e 100644 --- a/aggregators/kagi-news/src/html_parser.py +++ b/aggregators/kagi-news/src/html_parser.py @@ -78,7 +78,8 @@ class KagiHTMLParser: Perspective( actor=p['actor'], description=p['description'], - source_url=p['source_url'] + source_url=p['source_url'], + source_name=p.get('source_name', '') ) for p in parsed['perspectives'] ] @@ -230,9 +231,10 @@ class KagiHTMLParser: actor, rest = full_text.split(':', 1) actor = actor.strip() - # Find the tag for source URL + # Find the tag for source URL and name a_tag = li.find('a') source_url = a_tag['href'] if a_tag and a_tag.get('href') else "" + source_name = a_tag.get_text(strip=True) if a_tag else "" # Extract description (between colon and source link) # Remove the source citation part in parentheses @@ -250,7 +252,8 @@ class KagiHTMLParser: return { 'actor': actor, 'description': description, - 'source_url': source_url + 'source_url': source_url, + 'source_name': source_name } def _extract_sources(self, soup: BeautifulSoup) -> List[Dict]: diff --git a/aggregators/kagi-news/src/models.py b/aggregators/kagi-news/src/models.py index f3806a1..c8b3d39 100644 --- a/aggregators/kagi-news/src/models.py +++ b/aggregators/kagi-news/src/models.py @@ -20,6 +20,7 @@ class Perspective: actor: str description: str source_url: str + source_name: str = "" # Name of the source (e.g., "The Straits Times") @dataclass diff --git a/aggregators/kagi-news/src/richtext_formatter.py b/aggregators/kagi-news/src/richtext_formatter.py index 4e24f65..504d796 100644 --- a/aggregators/kagi-news/src/richtext_formatter.py +++ b/aggregators/kagi-news/src/richtext_formatter.py @@ -42,7 +42,7 @@ class RichTextFormatter: builder.add_bold("Highlights:") builder.add_text("\n") for highlight in story.highlights: - builder.add_text(f"• {highlight}\n") + builder.add_text(f"• {highlight}\n\n") builder.add_text("\n") # Perspectives (if present) @@ -53,12 +53,16 @@ class RichTextFormatter: # Bold the actor name actor_with_colon = f"{perspective.actor}:" builder.add_bold(actor_with_colon) - builder.add_text(f" {perspective.description} (") + builder.add_text(f" {perspective.description}") - # Add link to source - source_link_text = "Source" - builder.add_link(source_link_text, perspective.source_url) - builder.add_text(")\n") + # Add link to source if available + if perspective.source_url: + builder.add_text(" (") + source_link_text = perspective.source_name if perspective.source_name else "Source" + builder.add_link(source_link_text, perspective.source_url) + builder.add_text(")") + + builder.add_text("\n\n") builder.add_text("\n") # Quote (if present) @@ -74,7 +78,7 @@ class RichTextFormatter: for source in story.sources: builder.add_text("• ") builder.add_link(source.title, source.url) - builder.add_text(f" - {source.domain}\n") + builder.add_text(f" - {source.domain}\n\n") builder.add_text("\n") # Kagi News attribution