diff --git a/pi/webapp/templates/history.html b/pi/webapp/templates/history.html index 23fbaa0..eb6711f 100644 --- a/pi/webapp/templates/history.html +++ b/pi/webapp/templates/history.html @@ -125,6 +125,16 @@ font-size: 0.9em; } + .history-title a { + color: var(--primary); + text-decoration: underline; + } + + .history-title a:hover { + color: var(--bg); + background-color: var(--primary); + } + .history-meta { color: var(--help); font-size: 0.75em; @@ -195,7 +205,7 @@

[ PRINTPULSE ]

{% for item in items %}
-
> {{ 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"] == ""