From 3de78c75c589b679d4c13dc7f566c620e38b87c3 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Sun, 8 Feb 2026 15:14:26 +0000 Subject: [PATCH 1/3] Link article name to Wikipedia on Flickr search results page Co-Authored-By: Claude Opus 4.6 --- main.py | 1 + templates/combined.html | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index e2aef86..111c7bc 100755 --- a/main.py +++ b/main.py @@ -758,6 +758,7 @@ def start() -> str: "combined.html", name=name, enwp=enwp, + wikipedia_url=wikipedia_url, search_result=search_result, cat=cat, flickr_search=flickr_search, diff --git a/templates/combined.html b/templates/combined.html index 1f4ee7f..1b17450 100644 --- a/templates/combined.html +++ b/templates/combined.html @@ -62,7 +62,7 @@ {% if cat %}

← Back to category

{% endif %} -

Wikipedia article: {{ name }}

+

Wikipedia article: {{ name }}

{% if wikipedia_extract %}

{{ wikipedia_extract }}

{% endif %}
@@ -151,7 +151,7 @@ {% if cat %}

← Back to category

{% endif %} -

Wikipedia article: {{ name }}

+

Wikipedia article: {{ name }}

{% if wikipedia_extract %}

{{ wikipedia_extract }}

{% endif %} From b7ba24b567b21138bccff179fa8500d3f699ad1e Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Sat, 22 Aug 2026 21:36:03 +0100 Subject: [PATCH 2/3] Handle Wikipedia category API failures --- main.py | 16 +++++++ templates/category.html | 2 +- tests/test_category_search.py | 85 +++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/test_category_search.py diff --git a/main.py b/main.py index 111c7bc..ee6fee4 100755 --- a/main.py +++ b/main.py @@ -354,6 +354,7 @@ class CategoryResult: articles: list[ArticleWithoutImage] gcmcontinue: str | None + error: str | None = None # Common non-content images to ignore when checking if an article has images @@ -435,6 +436,7 @@ def get_articles_without_images( articles_without_images: list[ArticleWithoutImage] = [] seen_pageids: set[int] = set() next_gcmcontinue: str | None = None + error: str | None = None # Build initial continue params from the external pagination token continue_params: dict[str, str] = {} @@ -451,8 +453,20 @@ def get_articles_without_images( ) response.raise_for_status() data = response.json() + if api_error := data.get("error"): + raise requests.RequestException( + f"{api_error.get('code', 'unknown')}: " + f"{api_error.get('info', 'unknown Wikipedia API error')}" + ) except (requests.RequestException, json.JSONDecodeError) as e: print(f"Wikipedia API error: {e}") + if articles_without_images: + error = ( + "Wikipedia stopped responding before the whole category could " + "be checked. Showing partial results; please try again." + ) + else: + error = "Unable to load articles from Wikipedia. Please try again." break pages = data.get("query", {}).get("pages", {}) @@ -491,6 +505,7 @@ def get_articles_without_images( return CategoryResult( articles=articles_without_images, gcmcontinue=next_gcmcontinue, + error=error, ) @@ -891,6 +906,7 @@ def category_search() -> str: category_name=category_name, articles=result.articles, gcmcontinue=result.gcmcontinue, + error=result.error, ) diff --git a/templates/category.html b/templates/category.html index 62fcb1a..2fe8df8 100644 --- a/templates/category.html +++ b/templates/category.html @@ -50,7 +50,7 @@ {% endif %} - {% else %} + {% elif not error %}
All articles in this category have images!
diff --git a/tests/test_category_search.py b/tests/test_category_search.py new file mode 100644 index 0000000..8a22e1f --- /dev/null +++ b/tests/test_category_search.py @@ -0,0 +1,85 @@ +"""Tests for Wikipedia category searches.""" + +from unittest.mock import patch + +import requests + +from main import CategoryResult, app, get_articles_without_images + + +def test_api_failure_is_not_reported_as_an_empty_success(): + with patch("main.requests.get", side_effect=requests.ConnectionError("offline")): + result = get_articles_without_images("Category:Example") + + assert result.articles == [] + assert result.error == "Unable to load articles from Wikipedia. Please try again." + + +def test_api_error_response_is_not_reported_as_an_empty_success(): + error_response = type( + "Response", + (), + { + "raise_for_status": lambda self: None, + "json": lambda self: { + "error": {"code": "readonly", "info": "Wikipedia is read-only"} + }, + }, + )() + + with patch("main.requests.get", return_value=error_response): + result = get_articles_without_images("Category:Example") + + assert result.articles == [] + assert result.error == "Unable to load articles from Wikipedia. Please try again." + + +def test_api_failure_after_results_marks_them_as_partial(): + first_response = type( + "Response", + (), + { + "raise_for_status": lambda self: None, + "json": lambda self: { + "query": { + "pages": { + "1": {"pageid": 1, "title": "No image", "images": []} + } + }, + "continue": { + "gcmcontinue": "next-page", + "continue": "gcmcontinue||", + }, + }, + }, + )() + + with patch( + "main.requests.get", + side_effect=[first_response, requests.ConnectionError("offline")], + ): + result = get_articles_without_images("Category:Example") + + assert [article.title for article in result.articles] == ["No image"] + assert result.error is not None + assert "partial results" in result.error + + +def test_category_page_does_not_claim_success_after_api_failure(): + result = CategoryResult( + articles=[], + gcmcontinue=None, + error="Unable to load articles from Wikipedia. Please try again.", + ) + + with ( + patch("main.get_articles_without_images", return_value=result), + patch("main.log_interaction"), + app.test_client() as client, + ): + response = client.get("/category?cat=Category:Example") + + page = response.get_data(as_text=True) + assert response.status_code == 200 + assert "Unable to load articles from Wikipedia" in page + assert "All articles in this category have images" not in page From 15bbbecacf8e4033e57b015e9aa8050165ad9112 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Sat, 22 Aug 2026 22:12:29 +0100 Subject: [PATCH 3/3] Show Wikipedia category API errors --- main.py | 5 +++-- tests/test_category_search.py | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index ee6fee4..31fc79a 100755 --- a/main.py +++ b/main.py @@ -463,10 +463,11 @@ def get_articles_without_images( if articles_without_images: error = ( "Wikipedia stopped responding before the whole category could " - "be checked. Showing partial results; please try again." + "be checked. Showing partial results. " + f"Wikipedia API error: {e}" ) else: - error = "Unable to load articles from Wikipedia. Please try again." + error = f"Unable to load articles. Wikipedia API error: {e}" break pages = data.get("query", {}).get("pages", {}) diff --git a/tests/test_category_search.py b/tests/test_category_search.py index 8a22e1f..6a6072a 100644 --- a/tests/test_category_search.py +++ b/tests/test_category_search.py @@ -12,7 +12,7 @@ def test_api_failure_is_not_reported_as_an_empty_success(): result = get_articles_without_images("Category:Example") assert result.articles == [] - assert result.error == "Unable to load articles from Wikipedia. Please try again." + assert result.error == "Unable to load articles. Wikipedia API error: offline" def test_api_error_response_is_not_reported_as_an_empty_success(): @@ -31,7 +31,10 @@ def test_api_error_response_is_not_reported_as_an_empty_success(): result = get_articles_without_images("Category:Example") assert result.articles == [] - assert result.error == "Unable to load articles from Wikipedia. Please try again." + assert result.error == ( + "Unable to load articles. Wikipedia API error: " + "readonly: Wikipedia is read-only" + ) def test_api_failure_after_results_marks_them_as_partial(): @@ -63,13 +66,14 @@ def test_api_failure_after_results_marks_them_as_partial(): assert [article.title for article in result.articles] == ["No image"] assert result.error is not None assert "partial results" in result.error + assert "offline" in result.error def test_category_page_does_not_claim_success_after_api_failure(): result = CategoryResult( articles=[], gcmcontinue=None, - error="Unable to load articles from Wikipedia. Please try again.", + error="Unable to load articles. Wikipedia API error: test failure", ) with ( @@ -81,5 +85,5 @@ def test_category_page_does_not_claim_success_after_api_failure(): page = response.get_data(as_text=True) assert response.status_code == 200 - assert "Unable to load articles from Wikipedia" in page + assert "Wikipedia API error: test failure" in page assert "All articles in this category have images" not in page