Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/1374.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RSS feeds now reflect the most recently added file for each release, produce unique guids when content is updated, and support up to 500 entries in `updates.xml`.
12 changes: 6 additions & 6 deletions pulp_python/app/pypi/feeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from email.utils import getaddresses
from urllib.parse import urljoin

from django.db.models import F, FilteredRelation, Min, Q
from django.db.models import F, FilteredRelation, Max, Min, Q
from django.http.response import HttpResponse, HttpResponseNotFound
from django.utils.decorators import method_decorator
from django.utils.feedgenerator import Rss201rev2Feed
Expand All @@ -15,7 +15,7 @@
from pulp_python.app.cache import PythonApiCache, find_base_path_cached
from pulp_python.app.pypi.views import PyPIMixin, _etag_func

UPDATES_LIMIT = 100
UPDATES_LIMIT = 500
PACKAGES_LIMIT = 40
PROJECT_RELEASES_LIMIT = 40
RSS_CONTENT_TYPE = "application/rss+xml; charset=utf-8"
Expand Down Expand Up @@ -66,7 +66,7 @@ def iter_releases(content, repo_ver, name_normalized=None, limit=UPDATES_LIMIT):
qs.order_by()
.values("name_normalized", "version")
.annotate(
added_at=Min("file_added_at"),
added_at=Max("file_added_at"),
name=Min("name"),
summary=Min("summary"),
author_email=Min("author_email"),
Expand All @@ -82,7 +82,7 @@ def iter_projects(content, repo_ver, limit=PACKAGES_LIMIT):
qs.order_by()
.values("name_normalized")
.annotate(
added_at=Min("file_added_at"),
added_at=Max("file_added_at"),
name=Min("name"),
summary=Min("summary"),
author_email=Min("author_email"),
Expand All @@ -98,7 +98,7 @@ def _item_dict(title, link, description, author_email, pubdate):
"description": sanitize_xml_text(description),
"author_email": format_author(author_email),
"pubdate": pubdate,
"unique_id": link,
"unique_id": f"{link}#{pubdate.isoformat()}",
}


Expand All @@ -118,7 +118,7 @@ def render_rss(title, link, description, items):
author_email=item["author_email"],
pubdate=item["pubdate"],
unique_id=item["unique_id"],
unique_id_is_permalink=True,
unique_id_is_permalink=False,
)
return feed.writeString("utf-8")

Expand Down
34 changes: 33 additions & 1 deletion pulp_python/tests/functional/api/test_pypi_feeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,40 @@ def test_pinned_version_feeds(

item = _parse_items(_get_feed(distro, "rss/updates.xml", bindings_cfg))[0]
assert item.findtext("link").endswith("pypi/shelf-reader/0.1/json")
assert item.findtext("guid").endswith("pypi/shelf-reader/0.1/json")
assert "pypi/shelf-reader/0.1/json#" in item.findtext("guid")

python_content_factory(TWINE_WHEEL_FILENAME, url=TWINE_WHEEL_URL, repository=repo)
update_titles = _titles(_parse_items(_get_feed(distro, "rss/updates.xml", bindings_cfg)))
assert update_titles == ["shelf-reader 0.1"]


@pytest.mark.parallel
def test_new_file_for_existing_version_updates_guid(
bindings_cfg, python_content_factory, python_empty_repo_distro
):
"""Adding a new file for an existing (name, version) produces a new guid and updated date."""
repo, distro = python_empty_repo_distro()

python_content_factory(PYTHON_EGG_FILENAME, url=PYTHON_EGG_URL, repository=repo)

items = _parse_items(_get_feed(distro, "rss/updates.xml", bindings_cfg))
assert len(items) == 1
first_guid = items[0].findtext("guid")
first_date = items[0].findtext("pubDate")
assert "pypi/shelf-reader/0.1/json" in first_guid

python_content_factory(PYTHON_WHEEL_FILENAME, url=PYTHON_WHEEL_URL, repository=repo)

items = _parse_items(_get_feed(distro, "rss/updates.xml", bindings_cfg))
assert len(items) == 1
second_guid = items[0].findtext("guid")
second_date = items[0].findtext("pubDate")

assert second_guid != first_guid
assert second_date >= first_date

release_items = _parse_items(
_get_feed(distro, "rss/project/shelf-reader/releases.xml", bindings_cfg)
)
assert len(release_items) == 1
assert release_items[0].findtext("guid") == second_guid
Loading