From 1afb03d8df830aaaabc9fe2ee3a9a8dc5fc33a41 Mon Sep 17 00:00:00 2001 From: Brian Perrett Date: Thu, 7 Nov 2024 09:13:18 -0800 Subject: [PATCH] Import and add in-progress release notes. (#1416) - fixes #1155 - add in-progress release notes import to the import_release_notes task --- config/settings.py | 4 +++ config/urls.py | 7 +++- .../versions/in_progress_release_notes.html | 21 +++++++++++ versions/releases.py | 36 +++++++++++++++++++ versions/tasks.py | 12 ++++++- versions/views.py | 29 ++++++++++++--- 6 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 templates/versions/in_progress_release_notes.html diff --git a/config/settings.py b/config/settings.py index 1ea1b3e7..8ac30ec2 100755 --- a/config/settings.py +++ b/config/settings.py @@ -533,6 +533,10 @@ MINIMUM_BOOST_VERSION = "1.16.1" # The highest Boost version with its docs stored in S3 MAXIMUM_BOOST_DOCS_VERSION = "boost-1.30.2" +# In Progress Release Notes URL +RELEASE_NOTES_IN_PROGRESS_URL = "https://raw.githubusercontent.com/boostorg/website/master/users/history/in_progress.html" +RELEASE_NOTES_IN_PROGRESS_CACHE_KEY = "release-notes-in-progress" + # Boost Google Calendar BOOST_CALENDAR = "5rorfm42nvmpt77ac0vult9iig@group.calendar.google.com" CALENDAR_API_KEY = env("CALENDAR_API_KEY", default="changeme") diff --git a/config/urls.py b/config/urls.py index e1871e43..327aa591 100755 --- a/config/urls.py +++ b/config/urls.py @@ -70,7 +70,7 @@ from users.views import ( ) from versions.api import ImportVersionsView, VersionViewSet from versions.feeds import AtomVersionFeed, RSSVersionFeed -from versions.views import VersionDetail +from versions.views import InProgressReleaseNotesView, VersionDetail router = routers.SimpleRouter() @@ -135,6 +135,11 @@ urlpatterns = ( path("calendar/", CalendarView.as_view(), name="calendar"), # Boost versions views path("releases/", VersionDetail.as_view(), name="releases-most-recent"), + path( + "releases/boost-in-progress/", + InProgressReleaseNotesView.as_view(), + name="release-in-progress", + ), path("releases//", VersionDetail.as_view(), name="release-detail"), path( "donate/", diff --git a/templates/versions/in_progress_release_notes.html b/templates/versions/in_progress_release_notes.html new file mode 100644 index 00000000..92014d2c --- /dev/null +++ b/templates/versions/in_progress_release_notes.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load i18n %} +{% load static %} +{% block title %}{% blocktrans %}In Progress{% endblocktrans %}{% endblock %} +{% block description %}{% blocktrans %}Discover what's new in Boost{% endblocktrans %}{% endblock %} +{% block content %} +
+
+
+ + {% include "libraries/includes/version_alert.html" %} + +
+ {{ release_notes|safe|default:"No data for in-progress release notes yet. Come back soon!" }} +
+ +
+{% endblock %} diff --git a/versions/releases.py b/versions/releases.py index 305ba313..72c80663 100644 --- a/versions/releases.py +++ b/versions/releases.py @@ -195,6 +195,20 @@ def get_release_notes_for_version(version_pk): return response.content +def get_in_progress_release_notes(): + try: + response = session.get(settings.RELEASE_NOTES_IN_PROGRESS_URL) + response.raise_for_status() + except requests.exceptions.HTTPError as e: + logger.error( + "get_in_progress_release_notes_error", + exc_msg=str(e), + url=settings.RELEASE_NOTES_IN_PROGRESS_URL, + ) + raise + return response.content + + def process_release_notes(content): stripped_content = modernize_release_notes(content) return stripped_content @@ -233,6 +247,28 @@ def store_release_notes_for_version(version_pk): return rendered_content +def store_release_notes_for_in_progress(): + """Retrieve and store the release notes for a given version""" + # Get the release notes content + content = get_in_progress_release_notes() + stripped_content = process_release_notes(content) + + # Save the result to the rendered content model with the key + rendered_content, _ = RenderedContent.objects.update_or_create( + cache_key=settings.RELEASE_NOTES_IN_PROGRESS_CACHE_KEY, + defaults={ + "content_type": "text/html", + "content_original": content, + "content_html": stripped_content, + }, + ) + logger.info( + "store_release_notes_in_progress_success", + rendered_content_pk=rendered_content.id, + ) + return rendered_content + + def store_release_downloads_for_version(version, release_data): """Store the release download information for a Version instance. diff --git a/versions/tasks.py b/versions/tasks.py index a0384c51..3d70eef9 100644 --- a/versions/tasks.py +++ b/versions/tasks.py @@ -14,7 +14,10 @@ from libraries.models import Library, LibraryVersion from libraries.tasks import get_and_store_library_version_documentation_urls_for_version from libraries.utils import version_within_range from versions.models import Version -from versions.releases import store_release_notes_for_version +from versions.releases import ( + store_release_notes_for_in_progress, + store_release_notes_for_version, +) logger = structlog.getLogger(__name__) @@ -72,6 +75,7 @@ def import_release_notes(): release notes in the repository.""" for version in Version.objects.active().filter(full_release=True): store_release_notes_task.delay(str(version.pk)) + store_release_notes_in_progress_task.delay() @app.task @@ -87,6 +91,12 @@ def store_release_notes_task(version_pk): store_release_notes_for_version(version_pk) +@app.task +def store_release_notes_in_progress_task(): + """Fetches and store in-progress release notes in RenderedContent.""" + store_release_notes_for_in_progress() + + @app.task def import_version( name, diff --git a/versions/views.py b/versions/views.py index 0d76c1e2..73c674fa 100755 --- a/versions/views.py +++ b/versions/views.py @@ -1,12 +1,15 @@ import structlog +from itertools import groupby +from operator import attrgetter from django.db.models import Q, Count -from django.views.generic import DetailView +from django.views.generic import DetailView, TemplateView from django.views.generic.edit import FormMixin from django.shortcuts import redirect, get_object_or_404 from django.contrib import messages -from itertools import groupby -from operator import attrgetter +from django.conf import settings +from django.utils.decorators import method_decorator +from django.views.decorators.csrf import csrf_exempt from core.models import RenderedContent from libraries.constants import LATEST_RELEASE_URL_PATH_STR @@ -19,8 +22,6 @@ from libraries.utils import ( library_doc_latest_transform, ) from versions.models import Version -from django.utils.decorators import method_decorator -from django.views.decorators.csrf import csrf_exempt logger = structlog.get_logger(__name__) @@ -154,3 +155,21 @@ class VersionDetail(FormMixin, VersionAlertMixin, DetailView): return Version.objects.most_recent() return get_object_or_404(Version, slug=version_slug) + + +class InProgressReleaseNotesView(TemplateView): + template_name = "versions/in_progress_release_notes.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["release_notes"] = self.get_in_progress_release_notes() + return context + + def get_in_progress_release_notes(self): + try: + rendered_content = RenderedContent.objects.get( + cache_key=settings.RELEASE_NOTES_IN_PROGRESS_CACHE_KEY + ) + return rendered_content.content_html + except RenderedContent.DoesNotExist: + return