-
> {{ item.title }}
+
> {% if item.link %}
{{ item.title }}{% else %}{{ item.title }}{% endif %}
{% if item.source %}{{ item.source }} — {% endif %}{{ item.timestamp }}
diff --git a/printpulse/watch.py b/printpulse/watch.py
index dc60ace..f741909 100644
--- a/printpulse/watch.py
+++ b/printpulse/watch.py
@@ -68,6 +68,7 @@ def fetch_new_items(feed_url: str, max_items: int = 3) -> list[dict]:
"id": entry_id,
"title": title,
"summary": entry.get("summary", ""),
+ "link": getattr(entry, "link", ""),
"_entry": entry, # raw feedparser entry for image extraction
"_source": feed_title,
})
@@ -107,6 +108,7 @@ def _append_history(items: list[dict]):
history.append({
"title": item["title"],
"source": item.get("_source", ""),
+ "link": item.get("link", ""),
"timestamp": now_str,
})
# Trim to max
@@ -144,6 +146,7 @@ def _add_to_retry(item: dict):
"id": item.get("id", ""),
"title": item.get("title", ""),
"summary": item.get("summary", ""),
+ "link": item.get("link", ""),
"_source": item.get("_source", ""),
"attempts": 1,
})
@@ -183,6 +186,7 @@ def _enqueue_quiet_items(items: list[dict]):
"id": item.get("id", ""),
"title": item.get("title", ""),
"summary": item.get("summary", ""),
+ "link": item.get("link", ""),
"_source": item.get("_source", ""),
})
existing_ids.add(item.get("id"))
@@ -326,6 +330,7 @@ def run_watch_loop(feed_urls: list[str], interval: int, max_prints: int,
fake_item = {
"id": q_item["id"], "title": title,
"summary": q_item.get("summary", ""),
+ "link": q_item.get("link", ""),
"_source": source,
}
try:
@@ -361,6 +366,7 @@ def run_watch_loop(feed_urls: list[str], interval: int, max_prints: int,
fake_item = {
"id": r_item["id"], "title": title,
"summary": r_item.get("summary", ""),
+ "link": r_item.get("link", ""),
"_source": r_item.get("_source", ""),
}
try:
diff --git a/tests/test_watch.py b/tests/test_watch.py
index 31f30b3..b2203b9 100644
--- a/tests/test_watch.py
+++ b/tests/test_watch.py
@@ -9,11 +9,13 @@
from printpulse.watch import (
QUIET_QUEUE_FILE,
+ _append_history,
_enqueue_quiet_items,
_filter_quiet_queue_latest,
_is_in_quiet_hours,
_load_quiet_queue,
_save_quiet_queue,
+ load_history,
)
@@ -125,6 +127,12 @@ def test_enqueue_adds_new_items(self):
assert queue[0]["id"] == "a1"
assert queue[1]["id"] == "a2"
+ def test_enqueue_preserves_link(self):
+ items = [{"id": "link1", "title": "Story", "summary": "", "link": "https://example.com/story", "_source": "Feed"}]
+ _enqueue_quiet_items(items)
+ queue = _load_quiet_queue()
+ assert queue[0]["link"] == "https://example.com/story"
+
def test_enqueue_skips_duplicates(self):
item = {"id": "dup", "title": "Dupe Story", "summary": "", "_source": "X"}
_enqueue_quiet_items([item])
@@ -195,3 +203,24 @@ def test_empty_source_treated_as_one_group(self):
result = _filter_quiet_queue_latest(queue)
assert len(result) == 1
assert result[0]["id"] == "2"
+
+
+class TestHistoryLink:
+ """Test that history entries persist the article link."""
+
+ @pytest.fixture(autouse=True)
+ def _use_tmp_history(self, monkeypatch, tmp_path):
+ monkeypatch.setattr("printpulse.watch.HISTORY_FILE", str(tmp_path / "history.json"))
+
+ def test_append_history_stores_link(self):
+ items = [{"title": "Breaking News", "_source": "BBC", "link": "https://bbc.com/story"}]
+ _append_history(items)
+ history = load_history()
+ assert len(history) == 1
+ assert history[0]["link"] == "https://bbc.com/story"
+
+ def test_append_history_missing_link_defaults_empty(self):
+ items = [{"title": "No Link Item", "_source": "Manual"}]
+ _append_history(items)
+ history = load_history()
+ assert history[0]["link"] == ""