Skip to content

Commit 3dee53d

Browse files
committed
Fix #2685: Redirect Latest News links to blog.python.org
- Updates python.org RSS parser to rewrite pythoninsider.blogspot.com URLs over to the canonical blog.python.org host. - Adds data migration to fix existing BlogEntry links previously imported from the old blogger domain. - Covers URL domain replacement inside test_parser.py.
1 parent 7d86d4c commit 3dee53d

3 files changed

Lines changed: 44 additions & 1 deletion

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 5.2.11 on 2026-02-22 08:34
2+
3+
from django.db import migrations
4+
5+
6+
def rewrite_blog_urls(apps, schema_editor):
7+
BlogEntry = apps.get_model("blogs", "BlogEntry")
8+
for entry in BlogEntry.objects.filter(url__contains="pythoninsider.blogspot.com"):
9+
entry.url = entry.url.replace("pythoninsider.blogspot.com", "blog.python.org")
10+
entry.save()
11+
12+
13+
class Migration(migrations.Migration):
14+
15+
dependencies = [
16+
('blogs', '0003_alter_relatedblog_creator_and_more'),
17+
]
18+
19+
operations = [
20+
migrations.RunPython(rewrite_blog_urls, migrations.RunPython.noop),
21+
]

apps/blogs/parser.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ def get_all_entries(feed_url):
1818
for e in d["entries"]:
1919
published = datetime.datetime(*e["published_parsed"][:7], tzinfo=datetime.UTC)
2020

21+
# Rewrite Blogger domains to canonical python.org domain (Issue #2685)
22+
url = e["link"].replace(
23+
"//pythoninsider.blogspot.com",
24+
"//blog.python.org"
25+
)
2126
entry = {
2227
"title": e["title"],
2328
"summary": e.get("summary", ""),
2429
"pub_date": published,
25-
"url": e["link"],
30+
"url": url,
2631
}
2732

2833
entries.append(entry)

apps/blogs/tests/test_parser.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22
import unittest
3+
from unittest.mock import patch
34

45
from apps.blogs.parser import get_all_entries
56
from apps.blogs.tests.utils import get_test_rss_path
@@ -24,3 +25,19 @@ def test_entries(self):
2425
self.entries[0]["url"],
2526
"http://feedproxy.google.com/~r/PythonInsider/~3/tGNCqyOiun4/introducing-electronic-contributor.html",
2627
)
28+
29+
@patch("apps.blogs.parser.feedparser.parse")
30+
def test_rewrites_blogspot_url(self, mock_parse):
31+
mock_parse.return_value = {
32+
"entries": [
33+
{
34+
"title": "Test Title",
35+
"summary": "Summary",
36+
"published_parsed": (2026, 2, 22, 12, 0, 0, 0, 0, 0),
37+
"link": "https://pythoninsider.blogspot.com/2026/02/test.html",
38+
}
39+
]
40+
}
41+
entries = get_all_entries("http://fake.url")
42+
self.assertEqual(len(entries), 1)
43+
self.assertEqual(entries[0]["url"], "https://blog.python.org/2026/02/test.html")

0 commit comments

Comments
 (0)