From c884493494e5a29691bc85cb6c085c9cb0caecf8 Mon Sep 17 00:00:00 2001 From: "Jonathan S. Katz" Date: Tue, 12 Feb 2019 20:50:48 +0100 Subject: [PATCH 1/2] Create Release Notes archive in the Documentation section. This creates a consolidated area to reference all of the notes from previous releases of PostgreSQL, as current releases only keep the the notes for that specific major release of PostgreSQL. --- media/css/main.css | 29 ++++++++++ pgweb/core/templatetags/pgfilters.py | 9 +++ pgweb/docs/views.py | 98 +++++++++++++++++++++++++++++++++ pgweb/urls.py | 2 + pgweb/util/contexts.py | 1 + pgweb/util/db.py | 7 +++ templates/docs/release_notes.html | 104 +++++++++++++++++++++++++++++++++++ 7 files changed, 250 insertions(+) create mode 100644 pgweb/util/db.py create mode 100644 templates/docs/release_notes.html diff --git a/media/css/main.css b/media/css/main.css index e0462ad2..489ac916 100644 --- a/media/css/main.css +++ b/media/css/main.css @@ -1294,6 +1294,35 @@ table.sponsor-table tbody tr td:nth-child(3) { width: 30%; } +/** Release Notes */ +#release-notes .navheader, +#release-notes .navfooter, +#release-notes .NAVHEADER, +#release-notes .NAVFOOTER, +#release-notes .titlepage, +#release-notes h1.SECT1, +#release-notes .toc { + display: none; +} + +#release-notes .version-list h2:after { + content: none; +} + +.release-notes-list { + list-style-type: none; +} + +.release-notes-list :not(.collapsed) > .right, +.release-notes-list .collapsed > .down { + display: none; +} + +.release-notes-list .collapsed > .right, +.release-notes-list :not(.collapsed) > .down { + display: block; +} + /** ALL RESPONSIVE QUERIES HERE */ /* Small devices (landscape phones, 576px and up)*/ diff --git a/pgweb/core/templatetags/pgfilters.py b/pgweb/core/templatetags/pgfilters.py index 13f2470c..4edeb95c 100644 --- a/pgweb/core/templatetags/pgfilters.py +++ b/pgweb/core/templatetags/pgfilters.py @@ -70,3 +70,12 @@ def dictlookup(value, key): @register.filter(name='json') def tojson(value): return json.dumps(value) + +@register.filter() +def release_notes_pg_minor_version(minor_version, major_version): + """Formats the minor version number to the appropriate PostgreSQL version. + This is particularly for very old version of PostgreSQL. + """ + if str(major_version) in ['0', '1']: + return str(minor_version)[2:4] + return minor_version diff --git a/pgweb/docs/views.py b/pgweb/docs/views.py index 4577f0ce..62f0abb3 100644 --- a/pgweb/docs/views.py +++ b/pgweb/docs/views.py @@ -13,6 +13,7 @@ from pgweb.util.helpers import template_to_string from pgweb.util.misc import send_template_mail from pgweb.core.models import Version +from pgweb.util.db import exec_to_dict from .models import DocPage from .forms import DocCommentForm @@ -140,6 +141,103 @@ def manualarchive(request): 'versions': [_VersionPdfWrapper(v) for v in versions], }) +def release_notes(request, major_version=None, minor_version=None): + """Contains the main archive of release notes.""" + # this query gets a list of a unique set of release notes for each version of + # PostgreSQL. From PostgreSQL 9.4+, release notes are only present for their + # specific version of PostgreSQL, so all legacy release notes are present in + # 9.3 and older + # First the query identifies all of the release note files that have been loaded + # into the docs. We will limit our lookup to release notes from 9.3 on up, + # given 9.3 has all the release notes for PostgreSQL 9.3 and older + # From there, it parses the version the release notes are for + # from the file name, and breaks it up into "major" and "minor" version from + # our understanding of how PostgreSQL version numbering is handled, which is + # in 3 camps: 1 and older, 6.0 - 9.6, 10 - current + # It is then put into a unique set + # Lastly, we determine the next/previous versions (lead/lag) so we are able + # to easily page between the different versions in the unique release note view + # We only include the content if we are doing an actual lookup on an exact + # major/minor release pair, to limit how much data we load into memory + sql = """ + SELECT + {content} + file, major, minor, + lag(minor) OVER (PARTITION BY major ORDER BY minor) AS previous, + lead(minor) OVER (PARTITION BY major ORDER BY minor) AS next + FROM ( + SELECT DISTINCT ON (file, major, minor) + {content} + file, + CASE + WHEN v[1]::int >= 10 THEN v[1]::numeric + WHEN v[1]::int <= 1 THEN v[1]::int + ELSE array_to_string(v[1:2], '.')::numeric END AS major, + COALESCE( + CASE + WHEN v[1]::int >= 10 THEN v[2] + WHEN v[1]::int <= 1 THEN '.' || v[2] + ELSE v[3] + END::numeric, 0 + ) AS minor + FROM ( + SELECT + {content} + file, + string_to_array(regexp_replace(file, 'release-(.*)\.htm.*', '\\1'), '-') AS v + FROM docs + WHERE file ~ '^release-\d+' AND version >= 9.3 + ) r + ) rr + """ + params = [] + # if the major + minor version are provided, then we want to narrow down + # the results to all the release notes for the minor version, as we need the + # list of the entire set in order to generate the nice side bar in the release + # notes + # otherwise ensure the release notes are returned in order + if major_version is not None and minor_version is not None: + # at this point, include the content + sql = sql.format(content="content,") + # restrict to the major version, order from latest to earliest minor + sql = """{} + WHERE rr.major = %s + ORDER BY rr.minor DESC""".format(sql) + params += [major_version] + else: + sql = sql.format(content="") + sql += """ + ORDER BY rr.major DESC, rr.minor DESC; + """ + # run the query, loading a list of dict that contain all of the release + # notes that are filtered out by the query + release_notes = exec_to_dict(sql, params) + # determine which set of data to pass to the template: + # if both major/minor versions are present, we will load the release notes + # if neither are present, we load the list of all of the release notes to list out + if major_version is not None and minor_version is not None: + # first, see if any release notes were returned; if not, raise a 404 + if not release_notes: + raise Http404() + # next, see if we can find the specific release notes we are looking for + # format what the "minor" version should look like + try: + minor = Decimal('0.{}'.format(minor_version) if major_version in ['0', '1'] else minor_version) + except TypeError: + raise Http404() + release_note = [r for r in release_notes if r['minor'] == minor][0] + # of course, if nothing is found, return a 404 + if not release_note: + raise Http404() + context = { + 'major_version': major_version, + 'minor_version': minor_version, + 'release_note': release_note, + 'release_notes': release_notes + } + else: + context = { 'release_notes': release_notes } + return render_pgweb(request, 'docs', 'docs/release_notes.html', context) @login_required def commentform(request, itemid, version, filename): diff --git a/pgweb/urls.py b/pgweb/urls.py index d8c664f2..80913c3f 100644 --- a/pgweb/urls.py +++ b/pgweb/urls.py @@ -58,6 +58,8 @@ urlpatterns = [ url(r'^docs/$', pgweb.docs.views.root), url(r'^docs/manuals/$', pgweb.docs.views.manuals), url(r'^docs/manuals/archive/$', pgweb.docs.views.manualarchive), + url(r'^docs/release/$', pgweb.docs.views.release_notes), + url(r'^docs/release/((?P(\d+\.\d+)|\d+)\.(?P\d+))/$', pgweb.docs.views.release_notes), # Legacy URLs for accessing the docs page; provides a permanent redirect url(r'^docs/(current|devel|\d+(?:\.\d)?)/(static|interactive)/((.*).html?)?$', pgweb.docs.views.docspermanentredirect), url(r'^docs/(current|devel|\d+(?:\.\d)?)/(.*).html?$', pgweb.docs.views.docpage), diff --git a/pgweb/util/contexts.py b/pgweb/util/contexts.py index 25c4787e..c38f2480 100644 --- a/pgweb/util/contexts.py +++ b/pgweb/util/contexts.py @@ -34,6 +34,7 @@ sitenav = { {'title': 'Japanese', 'link': 'http://www.postgresql.jp/document/'}, {'title': 'Russian', 'link': 'https://postgrespro.ru/docs/postgresql'}, ]}, + {'title': 'Release Notes', 'link': '/docs/release/'}, {'title': 'Books', 'link': '/docs/books/'}, {'title': 'Online Resources', 'link': '/docs/online-resources/'}, {'title': 'Wiki', 'link': 'https://wiki.postgresql.org'}, diff --git a/pgweb/util/db.py b/pgweb/util/db.py new file mode 100644 index 00000000..a1efae0a --- /dev/null +++ b/pgweb/util/db.py @@ -0,0 +1,7 @@ +from django.db import connection + +def exec_to_dict(query, params=None): + curs = connection.cursor() + curs.execute(query, params) + columns = [col[0] for col in curs.description] + return [dict(list(zip(columns, row))) for row in curs.fetchall()] diff --git a/templates/docs/release_notes.html b/templates/docs/release_notes.html new file mode 100644 index 00000000..ca74e8d1 --- /dev/null +++ b/templates/docs/release_notes.html @@ -0,0 +1,104 @@ +{% extends "base/page.html" %} +{% load pgfilters %} + +{% block extrahead %} +{% if major_version is not None and minor_version is not None %} + +{% endif %} +{% endblock extrahead %} + +{%block title%}Release Notes{%endblock%} + +{% block contents %} +{% regroup release_notes by major as release_note_groups %} + +
+ {% if major_version is not None and minor_version is not None %} +
+
+

Release Notes

+

+ {% if major_version == '0' %}Postgres95{% else %}PostgreSQL{% endif %} + {{ major_version }}.{{ release_note.minor|release_notes_pg_minor_version:major_version }} +

+
+
+ {{ release_note.content|safe }} +
+
+
+ {% if release_note.previous is not None %} + + Previous + + {% endif %} +
+ +
+ {% if release_note.next is not None %} + + Next + + {% endif %} +
+
+
+
+
+

Versions

+
+ +
+ {% else %} +
+
+

Release Notes

+
+

Below is the complete archive of release notes for every version of PostgreSQL.

+ +
+ {% endif %} +
+ +{% endblock %} -- 2.14.3 (Apple Git-98)