Skip to content

Commit 08d7369

Browse files
committed
Merge branch 'main' into index-generic-doctype
2 parents 5f5793e + 7e0c82d commit 08d7369

File tree

71 files changed

+7446
-5747
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+7446
-5747
lines changed

.tx/config

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
[readthedocs.readthedocs]
2-
file_filter = readthedocs/locale/<lang>/LC_MESSAGES/django.po
3-
source_file = readthedocs/locale/en/LC_MESSAGES/django.po
4-
source_lang = en
5-
61
[main]
72
host = https://www.transifex.com
8-
type = PO
93

4+
[o:readthedocs:p:readthedocs:r:readthedocs]
5+
file_filter = readthedocs/locale/<lang>/LC_MESSAGES/django.po
6+
source_file = readthedocs/locale/en/LC_MESSAGES/django.po
7+
source_lang = en

CHANGELOG.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
Version 8.2.0
2+
-------------
3+
4+
:Date: June 14, 2022
5+
6+
* `@ericholscher <https://github.com/ericholscher>`__: Docs: Small edits to add a couple keywords and clarify headings (`#9329 <https://github.com/readthedocs/readthedocs.org/pull/9329>`__)
7+
* `@humitos <https://github.com/humitos>`__: Translations: integrate Transifex into our Docker tasks (`#9326 <https://github.com/readthedocs/readthedocs.org/pull/9326>`__)
8+
* `@humitos <https://github.com/humitos>`__: EmbedAPIv3: make usage of CDN (`#9321 <https://github.com/readthedocs/readthedocs.org/pull/9321>`__)
9+
* `@stsewd <https://github.com/stsewd>`__: Subscriptions: handle subscriptions with multiple products/plans/items (`#9320 <https://github.com/readthedocs/readthedocs.org/pull/9320>`__)
10+
* `@benjaoming <https://github.com/benjaoming>`__: Update the team page (`#9309 <https://github.com/readthedocs/readthedocs.org/pull/9309>`__)
11+
* `@stsewd <https://github.com/stsewd>`__: Stripe: use new api version (`#9308 <https://github.com/readthedocs/readthedocs.org/pull/9308>`__)
12+
* `@humitos <https://github.com/humitos>`__: Build: avoid overwriting a variable (`#9305 <https://github.com/readthedocs/readthedocs.org/pull/9305>`__)
13+
* `@humitos <https://github.com/humitos>`__: Integrations: handle `ping` event on GitHub (`#9303 <https://github.com/readthedocs/readthedocs.org/pull/9303>`__)
14+
* `@ericholscher <https://github.com/ericholscher>`__: Release 8.1.2 (`#9300 <https://github.com/readthedocs/readthedocs.org/pull/9300>`__)
15+
* `@ericholscher <https://github.com/ericholscher>`__: Fix Docs CI (`#9299 <https://github.com/readthedocs/readthedocs.org/pull/9299>`__)
16+
* `@stsewd <https://github.com/stsewd>`__: Tests: test build views with organizations (`#9298 <https://github.com/readthedocs/readthedocs.org/pull/9298>`__)
17+
* `@agjohnson <https://github.com/agjohnson>`__: Update mentions of our roadmap to be current (`#9293 <https://github.com/readthedocs/readthedocs.org/pull/9293>`__)
18+
* `@stsewd <https://github.com/stsewd>`__: lsremote: set max split when parsing remotes (`#9292 <https://github.com/readthedocs/readthedocs.org/pull/9292>`__)
19+
* `@humitos <https://github.com/humitos>`__: Tests: make `tests-embedapi` require regular `tests` first (`#9289 <https://github.com/readthedocs/readthedocs.org/pull/9289>`__)
20+
* `@ericholscher <https://github.com/ericholscher>`__: Truncate output that we log from commands to 10 lines (`#9286 <https://github.com/readthedocs/readthedocs.org/pull/9286>`__)
21+
* `@stsewd <https://github.com/stsewd>`__: Docs: update custom domains docs (`#9266 <https://github.com/readthedocs/readthedocs.org/pull/9266>`__)
22+
* `@stsewd <https://github.com/stsewd>`__: Requirements: update django-allauth (`#9249 <https://github.com/readthedocs/readthedocs.org/pull/9249>`__)
23+
124
Version 8.1.2
225
-------------
326

dockerfiles/Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ RUN apt-get -y update
1212
RUN apt-get -y install \
1313
curl \
1414
g++ \
15+
gettext \
1516
git-core \
1617
libevent-dev \
1718
libpq-dev \
@@ -30,6 +31,13 @@ RUN apt-get -y install \
3031
telnet \
3132
lsb-release
3233

34+
# Gets the MinIO mc client used to add buckets upon initialization
35+
# If this client should have issues running inside this image, it is also
36+
# fine to defer it to a separate image.
37+
# The current minio/mc Docker image could be a lot smaller
38+
RUN curl -s -q https://dl.min.io/client/mc/release/linux-amd64/archive/mc.RELEASE.2022-06-11T21-10-36Z -o /usr/bin/mc && \
39+
chmod +x /usr/bin/mc
40+
3341
# Uncomment en_US.UTF-8 locale and generate it
3442
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
3543
locale-gen

docs/conf.py

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

6868
master_doc = "index"
6969
copyright = "2010, Read the Docs, Inc & contributors"
70-
version = "8.1.2"
70+
version = "8.2.0"
7171
release = version
7272
exclude_patterns = ["_build"]
7373
default_role = "obj"
-2.5 KB
Binary file not shown.
-2.27 KB
Binary file not shown.
-5.68 KB
Binary file not shown.
Binary file not shown.
-5.68 KB
Binary file not shown.
-14.5 KB
Binary file not shown.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "readthedocs",
3-
"version": "8.1.2",
3+
"version": "8.2.0",
44
"description": "Read the Docs build dependencies",
55
"author": "Read the Docs, Inc <[email protected]>",
66
"scripts": {

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ filterwarnings =
2525
ignore:.*:django.utils.deprecation.RemovedInDjango40Warning
2626
ignore:.*:django.utils.deprecation.RemovedInDjango41Warning
2727
ignore:.*:elasticsearch.exceptions.ElasticsearchWarning
28+
ignore:.*:PendingDeprecationWarning

readthedocs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Read the Docs."""
22

33

4-
__version__ = "8.1.2"
4+
__version__ = "8.2.0"

readthedocs/api/v2/mixins.py renamed to readthedocs/api/mixins.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import functools
2+
13
import structlog
4+
from django.shortcuts import get_object_or_404
5+
from django.utils.functional import cached_property
26

7+
from readthedocs.core.unresolver import unresolve
38
from readthedocs.core.utils import get_cache_tag
9+
from readthedocs.projects.models import Project
410

511
log = structlog.get_logger(__name__)
612

@@ -25,7 +31,7 @@ def dispatch(self, request, *args, **kwargs):
2531
response = super().dispatch(request, *args, **kwargs)
2632
cache_tags = self._get_cache_tags()
2733
if cache_tags:
28-
response['Cache-Tag'] = ','.join(cache_tags)
34+
response["Cache-Tag"] = ",".join(cache_tags)
2935
return response
3036

3137
def _get_cache_tags(self):
@@ -55,3 +61,46 @@ def _get_cache_tags(self):
5561
if project and self.project_cache_tag:
5662
tags.append(get_cache_tag(project.slug, self.project_cache_tag))
5763
return tags
64+
65+
66+
class EmbedAPIMixin:
67+
68+
"""
69+
Helper for EmbedAPI v2 and v3.
70+
71+
Used in combination with ``CDNCacheTagsMixin`` to add project/version slug
72+
in the response to be cached.
73+
74+
Note that these methods are cached (``lru_cache`` and ``cached_property``)
75+
to avoid hitting the database multiple times on the same request.
76+
"""
77+
78+
@cached_property
79+
def unresolved_url(self):
80+
url = self.request.GET.get("url")
81+
if not url:
82+
return None
83+
return unresolve(url)
84+
85+
@functools.lru_cache(maxsize=1)
86+
def _get_project(self):
87+
if self.external:
88+
return
89+
90+
if self.unresolved_url:
91+
project_slug = self.unresolved_url.project.slug
92+
else:
93+
project_slug = self.request.GET.get("project")
94+
return get_object_or_404(Project, slug=project_slug)
95+
96+
@functools.lru_cache(maxsize=1)
97+
def _get_version(self):
98+
if self.external:
99+
return
100+
101+
if self.unresolved_url:
102+
version_slug = self.unresolved_url.version_slug
103+
else:
104+
version_slug = self.request.GET.get("version", "latest")
105+
project = self._get_project()
106+
return get_object_or_404(project.versions.all(), slug=version_slug)

readthedocs/api/v2/views/footer_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from rest_framework.views import APIView
1313
from rest_framework_jsonp.renderers import JSONPRenderer
1414

15-
from readthedocs.api.v2.mixins import CDNCacheTagsMixin
15+
from readthedocs.api.mixins import CDNCacheTagsMixin
1616
from readthedocs.api.v2.permissions import IsAuthorizedToViewVersion
1717
from readthedocs.builds.constants import LATEST, TAG
1818
from readthedocs.builds.models import Version

readthedocs/embed/v3/tests/examples/default/bibtex-cite.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
sphinxcontrib-bibtex
24
====================
35

readthedocs/embed/v3/tests/examples/default/configuration.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Configuration
24
=============
35

readthedocs/embed/v3/tests/examples/default/glossary.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
:orphan:
2+
13
Glossary
24
--------
35

readthedocs/embed/v3/tests/examples/default/index.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@ Sub-title
77
---------
88

99
This is a reference to :ref:`sub-title`.
10+
11+
12+
.. _manual-reference:
13+
14+
Manual Reference Section
15+
------------------------
16+
17+
This is a reference to a manual reference :ref:`manual-reference`.

readthedocs/embed/v3/tests/test_external_pages.py

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import docutils
2-
import os
3-
42
import pytest
53
import sphinx
6-
7-
from packaging.version import Version
8-
9-
from django.conf import settings
104
from django.core.cache import cache
115
from django.urls import reverse
6+
from packaging.version import Version
127

138
from .utils import srcdir
149

@@ -42,12 +37,18 @@ def test_default_main_section(self, app, client, requests_mock):
4237
response = client.get(self.api_url, params)
4338
assert response.status_code == 200
4439

40+
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
41+
if sphinx.version_info < (5, 0, 0):
42+
title = "Permalink to this headline"
43+
else:
44+
title = "Permalink to this heading"
45+
4546
# The output is different because docutils is outputting this,
46-
# and we're not sanitizing it, but just passing it through.
47+
# and we're not sanitizing it, but just passing it through.
4748
if Version(docutils.__version__) >= Version('0.17'):
48-
content = '<div class="body" role="main">\n \n <section id="title">\n<h1>Title<a class="headerlink" href="https://docs.project.com#title" title="Permalink to this headline">¶</a></h1>\n<p>This is an example page used to test EmbedAPI parsing features.</p>\n<section id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="Permalink to this headline">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</section>\n</section>\n\n\n </div>'
49+
content = f'<div class="body" role="main">\n \n <section id="title">\n<h1>Title<a class="headerlink" href="https://docs.project.com#title" title="{title}">¶</a></h1>\n<p>This is an example page used to test EmbedAPI parsing features.</p>\n<section id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</section>\n<section id="manual-reference-section">\n<span id="manual-reference"></span><h2>Manual Reference Section<a class="headerlink" href="https://docs.project.com#manual-reference-section" title="{title}">¶</a></h2>\n<p>This is a reference to a manual reference <a class="reference internal" href="https://docs.project.com#manual-reference"><span class="std std-ref">Manual Reference Section</span></a>.</p>\n</section>\n</section>\n\n\n </div>'
4950
else:
50-
content = '<div class="body" role="main">\n \n <div class="section" id="title">\n<h1>Title<a class="headerlink" href="https://docs.project.com#title" title="Permalink to this headline">¶</a></h1>\n<p>This is an example page used to test EmbedAPI parsing features.</p>\n<div class="section" id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="Permalink to this headline">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</div>\n</div>\n\n\n </div>'
51+
content = f'<div class="body" role="main">\n \n <div class="section" id="title">\n<h1>Title<a class="headerlink" href="https://docs.project.com#title" title="{title}">¶</a></h1>\n<p>This is an example page used to test EmbedAPI parsing features.</p>\n<div class="section" id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</div>\n<div class="section" id="manual-reference-section">\n<span id="manual-reference"></span><h2>Manual Reference Section<a class="headerlink" href="https://docs.project.com#manual-reference-section" title="{title}">¶</a></h2>\n<p>This is a reference to a manual reference <a class="reference internal" href="https://docs.project.com#manual-reference"><span class="std std-ref">Manual Reference Section</span></a>.</p>\n</div>\n</div>\n\n\n </div>'
5152

5253
assert response.json() == {
5354
'url': 'https://docs.project.com',
@@ -70,10 +71,16 @@ def test_specific_identifier(self, app, client, requests_mock):
7071
response = client.get(self.api_url, params)
7172
assert response.status_code == 200
7273

73-
if Version(docutils.__version__) >= Version('0.17'):
74-
content = '<section id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="Permalink to this headline">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</section>'
74+
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
75+
if sphinx.version_info < (5, 0, 0):
76+
title = "Permalink to this headline"
77+
else:
78+
title = "Permalink to this heading"
79+
80+
if Version(docutils.__version__) >= Version("0.17"):
81+
content = f'<section id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</section>'
7582
else:
76-
content = '<div class="section" id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="Permalink to this headline">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</div>'
83+
content = f'<div class="section" id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</div>'
7784

7885
assert response.json() == {
7986
'url': 'https://docs.project.com#sub-title',
@@ -164,7 +171,13 @@ def test_dl_identifier_doctool_sphinx(self, app, client, requests_mock):
164171
'external': True,
165172
}
166173

167-
@pytest.mark.sphinx('html', srcdir=srcdir, freshenv=True)
174+
# TODO: make the test to behave properly with docutils>17. The structure of
175+
# the HTML has changed and the ids are not generated as `idX` anymore.
176+
@pytest.mark.skipif(
177+
Version(docutils.__version__) >= Version("0.18"),
178+
reason="docutils>0.18 is not yet supported",
179+
)
180+
@pytest.mark.sphinx("html", srcdir=srcdir, freshenv=True)
168181
def test_citation_identifier_doctool_sphinx(self, app, client, requests_mock):
169182
app.build()
170183
path = app.outdir / 'bibtex-cite.html'
@@ -241,14 +254,71 @@ def test_glossary_identifier_doctool_sphinx(self, app, client, requests_mock):
241254
response = client.get(self.api_url, params)
242255
assert response.status_code == 200
243256

257+
if Version(docutils.__version__) >= Version("0.18"):
258+
classes = "simple glossary"
259+
else:
260+
classes = "glossary simple"
261+
244262
if sphinx.version_info >= (3, 5, 0):
245-
content = f'<dl class="glossary simple">\n<dt id="{fragment}">Read the Docs<a class="headerlink" href="https://docs.project.com/glossary.html#{fragment}" title="Permalink to this term">¶</a></dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
263+
content = f'<dl class="{classes}">\n<dt id="{fragment}">Read the Docs<a class="headerlink" href="https://docs.project.com/glossary.html#{fragment}" title="Permalink to this term">¶</a></dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
246264
else:
247-
content = f'<dl class="glossary simple">\n<dt id="{fragment}">Read the Docs</dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
265+
content = f'<dl class="{classes}">\n<dt id="{fragment}">Read the Docs</dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
248266

249267
assert response.json() == {
250268
'url': url,
251269
'content': content,
252270
'fragment': fragment,
253271
'external': True,
254272
}
273+
274+
@pytest.mark.sphinx("html", srcdir=srcdir, freshenv=True)
275+
def test_manual_references(self, app, client, requests_mock):
276+
app.build()
277+
path = app.outdir / "index.html"
278+
assert path.exists() is True
279+
content = open(path).read()
280+
requests_mock.get("https://docs.project.com/", text=content)
281+
282+
# Calling the API without doctool
283+
fragment = "manual-reference"
284+
url = f"https://docs.project.com/#{fragment}"
285+
params = {
286+
"url": url,
287+
}
288+
response = client.get(self.api_url, params)
289+
assert response.status_code == 200
290+
291+
content = f'<span id="{fragment}"></span>'
292+
assert response.json() == {
293+
"url": url,
294+
"fragment": fragment,
295+
"content": content,
296+
"external": True,
297+
}
298+
299+
# Calling the API with doctool
300+
params = {
301+
"url": url,
302+
"doctool": "sphinx",
303+
}
304+
response = client.get(self.api_url, params)
305+
assert response.status_code == 200
306+
307+
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
308+
if sphinx.version_info < (5, 0, 0):
309+
title = "Permalink to this headline"
310+
else:
311+
title = "Permalink to this heading"
312+
313+
# Note the difference between `<section>` and `<div class="section">`
314+
if Version(docutils.__version__) >= Version("0.17"):
315+
content = f'<section id="manual-reference-section">\n<span id="manual-reference"></span><h2>Manual Reference Section<a class="headerlink" href="https://docs.project.com/#manual-reference-section" title="{title}">¶</a></h2>\n<p>This is a reference to a manual reference <a class="reference internal" href="https://docs.project.com/#manual-reference"><span class="std std-ref">Manual Reference Section</span></a>.</p>\n</section>'
316+
else:
317+
content = f'<div class="section" id="manual-reference-section">\n<span id="manual-reference"></span><h2>Manual Reference Section<a class="headerlink" href="https://docs.project.com/#manual-reference-section" title="{title}">¶</a></h2>\n<p>This is a reference to a manual reference <a class="reference internal" href="https://docs.project.com/#manual-reference"><span class="std std-ref">Manual Reference Section</span></a>.</p>\n</div>'
318+
319+
assert response.json() == {
320+
"url": url,
321+
"content": content,
322+
"fragment": fragment,
323+
"external": True,
324+
}

0 commit comments

Comments
 (0)