Skip to content

Commit cdd5005

Browse files
authored
Merge pull request #143 from matagus/bug-fixes-may-2026
Bug fixes
2 parents 5301f5d + edecdb7 commit cdd5005

14 files changed

Lines changed: 237 additions & 92 deletions

File tree

planet/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = "1.0.0"
1+
version = "1.1.0"

planet/admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class BlogAdmin(admin.ModelAdmin):
166166
list_display = ("title", "url", "date_created")
167167
search_fields = ["title", "url"]
168168
list_filter = (
169-
("feed__language", admin.RelatedOnlyFieldListFilter),
170-
("feed__is_active", admin.RelatedOnlyFieldListFilter),
169+
"feed__language",
170+
"feed__is_active",
171171
)
172172
inlines = [FeedInlineReadOnly]

planet/context_processors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77

88
def context(request):
9-
if request.method == "GET" and request.GET.get("search"):
9+
if request.method == "GET" and request.GET.get("q"):
1010
search_form = SearchForm(request.GET)
1111
else:
1212
search_form = SearchForm()

planet/locale/es/LC_MESSAGES/django.po

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: PACKAGE VERSION\n"
99
"Report-Msgid-Bugs-To: \n"
10-
"POT-Creation-Date: 2026-03-20 15:22+0000\n"
10+
"POT-Creation-Date: 2026-05-09 18:48+0000\n"
1111
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1212
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313
"Language-Team: LANGUAGE <[email protected]>\n"
@@ -54,7 +54,7 @@ msgid "Feed Status"
5454
msgstr "Feeds"
5555

5656
#: admin.py:81 admin.py:124 forms.py:9 models.py:218 templates/base.html:36
57-
#: templates/base.html:43 templates/planet/authors/blocks/list.html:5
57+
#: templates/planet/authors/blocks/list.html:5
5858
#: templates/planet/authors/detail.html:21 templates/planet/authors/list.html:7
5959
#: templates/planet/authors/list.html:13 templates/planet/authors/list.html:19
6060
msgid "Authors"
@@ -79,12 +79,12 @@ msgstr "Feeds"
7979
msgid "No feeds"
8080
msgstr "Feeds"
8181

82-
#: forms.py:7 models.py:182 templates/base.html:33 templates/base.html:41
82+
#: forms.py:7 models.py:182 templates/base.html:33
8383
#: templates/planet/feeds/detail.html:55 templates/planet/posts/list.html:20
8484
msgid "Posts"
8585
msgstr "Posts"
8686

87-
#: forms.py:8 models.py:35 templates/base.html:34 templates/base.html:42
87+
#: forms.py:8 models.py:35 templates/base.html:34
8888
#: templates/planet/blogs/detail.html:22 templates/planet/blogs/list.html:7
8989
#: templates/planet/blogs/list.html:13 templates/planet/blogs/list.html:19
9090
#: templates/planet/feeds/detail.html:15 templates/planet/posts/detail.html:17

planet/managers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def create_from(self, feed_data, blog):
5656
feed.title = feed_data.feed.get("title") or urlparse(feed_data.href).netloc
5757
feed.subtitle = feed_data.feed.get("subtitle")
5858
feed.rights = feed_data.feed.get("rights") or feed_data.feed.get("license")
59-
feed.guid = md5_hash(feed_data.feed.get("id") or feed.url)
59+
feed.guid = md5_hash(feed.url)
6060
feed.language = normalize_language(feed_data.feed.get("language"))
6161
feed.etag = feed_data.get("etag") or None
6262
feed.last_modified = to_datetime(feed_data.get("updated_parsed"))
@@ -174,6 +174,10 @@ def create_from(self, entry_data, feed):
174174
post.url = post_url
175175
post.guid = md5_hash(post.url)
176176

177+
if self.model.objects.filter(guid=post.guid).exists():
178+
logger.debug("Skipping post %r: URL already exists in another feed", post.url)
179+
return None
180+
177181
try:
178182
post.content = entry_data.summary
179183
except AttributeError:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import hashlib
2+
3+
from django.db import migrations
4+
5+
6+
def recompute_feed_guids(apps, schema_editor):
7+
Feed = apps.get_model("planet", "Feed")
8+
9+
for feed in Feed.objects.all():
10+
feed.guid = hashlib.md5(feed.url.encode("utf-8")).hexdigest()
11+
feed.save(update_fields=["guid"])
12+
13+
14+
class Migration(migrations.Migration):
15+
16+
dependencies = [
17+
("planet", "0002_post_original_content"),
18+
]
19+
20+
operations = [
21+
migrations.RunPython(recompute_feed_guids, migrations.RunPython.noop),
22+
]

planet/templates/base.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@
3636
<li class="nav-item"><a href="{% url 'planet:author-list' %}" class="nav-link text-success">{% trans "Authors" %}</a></li>
3737
</ul>
3838
<form class="d-flex mt-2 mt-md-0" role="search" method="GET" action="{% url 'planet:search' %}">
39-
<input name="q" class="form-control me-2" type="search" placeholder="{% trans 'Search' %}" aria-label="{% trans 'Search' %}">
39+
<input name="q" value="{{ search_form.q.value|default_if_none:'' }}" class="form-control me-2" type="search" placeholder="{% trans 'Search' %}" aria-label="{% trans 'Search' %}">
4040
<select name="w" class="form-select me-2" aria-label="{% trans 'Search for...' %}">
41-
<option selected value="posts">{% trans 'Posts' %}</option>
42-
<option value="blogs">{% trans 'Blogs' %}</option>
43-
<option value="authors">{% trans 'Authors' %}</option>
41+
{% for value, label in search_form.w.field.choices %}
42+
<option value="{{ value }}"{% if value == search_form.w.value %} selected{% endif %}>{{ label }}</option>
43+
{% endfor %}
4444
</select>
4545
<button class="btn btn-outline-success" type="submit">{% trans 'Search' %}</button>
4646
</form>

project/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Django==6.0.5
22
django-environ==0.12.0
33
django-extensions==4.1
44
django-pagination-py3==1.2.0
5-
django-planet==1.0.0
5+
django-planet==1.1.0
66
feedparser==6.0.12
77
gunicorn==23.0.0
88
ipython==8.10.0

tests/mocks.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from unittest.mock import MagicMock
2+
3+
4+
def _make_feed_data(
5+
href="https://example.com/feed.xml",
6+
title="",
7+
link="",
8+
feed_id="feed-id",
9+
subtitle="",
10+
):
11+
"""Create a mock feedparser feed_data object."""
12+
feed_data = MagicMock()
13+
feed_data.href = href
14+
feed_data.status = 200
15+
feed_data.bozo = False
16+
feed_data.entries = []
17+
feed_data.feed = {
18+
"title": title,
19+
"link": link,
20+
"subtitle": subtitle,
21+
"id": feed_id,
22+
"language": "en",
23+
}
24+
feed_data.get = lambda key, default=None: {
25+
"etag": None,
26+
"updated_parsed": None,
27+
}.get(key, default)
28+
return feed_data
29+
30+
31+
def _make_entry_data(link="", title="", authors=None, author=""):
32+
"""Create a mock feedparser entry_data object."""
33+
if authors is None:
34+
authors = []
35+
36+
class MockEntryData(dict):
37+
def get(self, key, default=""):
38+
data = {
39+
"link": link,
40+
"title": title,
41+
"authors": authors,
42+
"author": author,
43+
}
44+
return data.get(key, default)
45+
46+
@property
47+
def published_parsed(self):
48+
raise AttributeError("published_parsed")
49+
50+
@property
51+
def summary_detail(self):
52+
raise AttributeError("summary_detail")
53+
54+
@property
55+
def summary(self):
56+
return "Test summary"
57+
58+
return MockEntryData()

tests/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,16 @@
6666
"django.template.context_processors.request",
6767
"django.contrib.auth.context_processors.auth",
6868
"django.contrib.messages.context_processors.messages",
69+
"planet.context_processors.context",
6970
],
7071
},
7172
},
7273
]
7374

7475
WSGI_APPLICATION = "example_project.wsgi.application"
7576

77+
SITE_ID = 1
78+
7679

7780
# Database
7881
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases

0 commit comments

Comments
 (0)