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