Skip to content

Commit 74e1de8

Browse files
committed
Merge branch 'master' of github.com:readthedocs/readthedocs.org into cache-robotstxt
2 parents 5dcf3b8 + e6cae86 commit 74e1de8

File tree

16 files changed

+384
-83
lines changed

16 files changed

+384
-83
lines changed

readthedocs/builds/constants.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@
100100
},
101101
}
102102

103-
RTD_BUILD_STATUS_API_NAME = 'continuous-documentation/read-the-docs'
104-
105103
GITHUB_EXTERNAL_VERSION_NAME = 'Pull Request'
106104
GITLAB_EXTERNAL_VERSION_NAME = 'Merge Request'
107105
GENERIC_EXTERNAL_VERSION_NAME = 'External Version'
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 2.2.11 on 2020-04-01 20:07
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('builds', '0015_uploading_build_state'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='version',
15+
name='documentation_type',
16+
field=models.CharField(choices=[('sphinx', 'Sphinx Html'), ('mkdocs', 'Mkdocs (Markdown)'), ('sphinx_htmldir', 'Sphinx HtmlDir'), ('sphinx_singlehtml', 'Sphinx Single Page HTML'), ('mkdocs_html', 'Mkdocs Html Pages')], default='sphinx', help_text='Type of documentation the version was built with.', max_length=20, verbose_name='Documentation type'),
17+
),
18+
]

readthedocs/builds/models.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,20 @@
6464
from readthedocs.projects.constants import (
6565
BITBUCKET_COMMIT_URL,
6666
BITBUCKET_URL,
67+
DOCTYPE_CHOICES,
6768
GITHUB_BRAND,
6869
GITHUB_COMMIT_URL,
6970
GITHUB_PULL_REQUEST_COMMIT_URL,
7071
GITHUB_PULL_REQUEST_URL,
7172
GITHUB_URL,
7273
GITLAB_BRAND,
7374
GITLAB_COMMIT_URL,
74-
DOCUMENTATION_CHOICES,
7575
GITLAB_MERGE_REQUEST_COMMIT_URL,
7676
GITLAB_MERGE_REQUEST_URL,
7777
GITLAB_URL,
7878
MEDIA_TYPES,
7979
PRIVACY_CHOICES,
80+
SPHINX,
8081
)
8182
from readthedocs.projects.models import APIProject, Project
8283
from readthedocs.projects.version_handling import determine_stable_version
@@ -145,8 +146,8 @@ class Version(models.Model):
145146
documentation_type = models.CharField(
146147
_('Documentation type'),
147148
max_length=20,
148-
choices=DOCUMENTATION_CHOICES,
149-
default='sphinx',
149+
choices=DOCTYPE_CHOICES,
150+
default=SPHINX,
150151
help_text=_(
151152
'Type of documentation the version was built with.'
152153
),

readthedocs/doc_builder/backends/mkdocs.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import yaml
1212
from django.conf import settings
1313
from django.template import loader as template_loader
14+
from readthedocs.projects.constants import MKDOCS_HTML, MKDOCS
1415

1516
from readthedocs.doc_builder.base import BaseBuilder
1617
from readthedocs.doc_builder.exceptions import MkDocsYAMLParseError
@@ -67,6 +68,17 @@ def __init__(self, *args, **kwargs):
6768
else:
6869
self.DEFAULT_THEME_NAME = 'mkdocs'
6970

71+
def get_final_doctype(self):
72+
"""
73+
Select a doctype based on the ``use_directory_urls`` setting.
74+
75+
https://www.mkdocs.org/user-guide/configuration/#use_directory_urls
76+
"""
77+
with open(self.yaml_file, 'r') as f:
78+
config = yaml.safe_load(f)
79+
use_directory_urls = config.get('use_directory_urls', True)
80+
return MKDOCS if use_directory_urls else MKDOCS_HTML
81+
7082
def get_yaml_config(self):
7183
"""Find the ``mkdocs.yml`` file in the project root."""
7284
mkdocs_path = self.config.mkdocs.configuration

readthedocs/doc_builder/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ def __init__(self, build_env, python_env, force=False):
5151
type_=self.type,
5252
)
5353

54+
def get_final_doctype(self):
55+
"""Some builders may have a different doctype at build time."""
56+
return self.config.doctype
57+
5458
def force(self, **__):
5559
"""An optional step to force a build even when nothing has changed."""
5660
log.info('Forcing a build')

readthedocs/oauth/services/github.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from readthedocs.builds.constants import (
1616
BUILD_STATUS_SUCCESS,
1717
SELECT_BUILD_STATUS,
18-
RTD_BUILD_STATUS_API_NAME
1918
)
2019
from readthedocs.integrations.models import Integration
2120

@@ -438,7 +437,7 @@ def send_build_status(self, build, commit, state):
438437
'state': github_build_state,
439438
'target_url': target_url,
440439
'description': description,
441-
'context': RTD_BUILD_STATUS_API_NAME
440+
'context': settings.RTD_BUILD_STATUS_API_NAME
442441
}
443442

444443
resp = None

readthedocs/oauth/services/gitlab.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
from readthedocs.builds.constants import (
1313
BUILD_STATUS_SUCCESS,
14-
RTD_BUILD_STATUS_API_NAME,
1514
SELECT_BUILD_STATUS,
1615
)
1716
from readthedocs.builds import utils as build_utils
@@ -524,7 +523,7 @@ def send_build_status(self, build, commit, state):
524523
'state': gitlab_build_state,
525524
'target_url': target_url,
526525
'description': description,
527-
'context': RTD_BUILD_STATUS_API_NAME
526+
'context': settings.RTD_BUILD_STATUS_API_NAME
528527
}
529528
url = self.adapter.provider_base_url
530529

readthedocs/projects/constants.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""
42
Project constants.
53
@@ -11,13 +9,20 @@
119

1210
from django.utils.translation import ugettext_lazy as _
1311

14-
12+
SPHINX = 'sphinx'
13+
MKDOCS = 'mkdocs'
14+
SPHINX_HTMLDIR = 'sphinx_htmldir'
15+
SPHINX_SINGLEHTML = 'sphinx_singlehtml'
16+
# This type is defined by the users in their mkdocs.yml file.
17+
MKDOCS_HTML = 'mkdocs_html'
1518
DOCUMENTATION_CHOICES = (
16-
('sphinx', _('Sphinx Html')),
17-
('mkdocs', _('Mkdocs (Markdown)')),
18-
('sphinx_htmldir', _('Sphinx HtmlDir')),
19-
('sphinx_singlehtml', _('Sphinx Single Page HTML')),
19+
(SPHINX, _('Sphinx Html')),
20+
(MKDOCS, _('Mkdocs (Markdown)')),
21+
(SPHINX_HTMLDIR, _('Sphinx HtmlDir')),
22+
(SPHINX_SINGLEHTML, _('Sphinx Single Page HTML')),
2023
)
24+
DOCTYPE_CHOICES = DOCUMENTATION_CHOICES + ((MKDOCS_HTML, _('Mkdocs Html Pages')),)
25+
2126

2227
MEDIA_TYPE_HTML = 'html'
2328
MEDIA_TYPE_PDF = 'pdf'

readthedocs/projects/tasks.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434
BUILD_STATE_FINISHED,
3535
BUILD_STATE_INSTALLING,
3636
BUILD_STATE_UPLOADING,
37-
BUILD_STATUS_SUCCESS,
3837
BUILD_STATUS_FAILURE,
38+
BUILD_STATUS_SUCCESS,
39+
EXTERNAL,
3940
LATEST,
4041
LATEST_VERBOSE_NAME,
4142
STABLE_VERBOSE_NAME,
42-
EXTERNAL,
4343
)
4444
from readthedocs.builds.models import APIVersion, Build, Version
4545
from readthedocs.builds.signals import build_complete
@@ -68,7 +68,7 @@
6868
from readthedocs.doc_builder.python_environments import Conda, Virtualenv
6969
from readthedocs.oauth.models import RemoteRepository
7070
from readthedocs.oauth.notifications import GitBuildStatusFailureNotification
71-
from readthedocs.projects.constants import GITHUB_BRAND, GITLAB_BRAND
71+
from readthedocs.projects.constants import GITHUB_BRAND, GITLAB_BRAND, MKDOCS
7272
from readthedocs.projects.models import APIProject, Feature
7373
from readthedocs.search.utils import index_new_files, remove_indexed_files
7474
from readthedocs.sphinx_domains.models import SphinxDomain
@@ -940,7 +940,7 @@ def store_build_artifacts(
940940
version = api_v2.version(self.version.pk)
941941
version.patch({
942942
'built': True,
943-
'documentation_type': self.config.doctype,
943+
'documentation_type': self.get_final_doctype(),
944944
'has_pdf': pdf,
945945
'has_epub': epub,
946946
'has_htmlzip': localmedia,
@@ -1085,7 +1085,7 @@ def update_app_instances(
10851085
version = api_v2.version(self.version.pk)
10861086
version.patch({
10871087
'built': True,
1088-
'documentation_type': self.config.doctype,
1088+
'documentation_type': self.get_final_doctype(),
10891089
'has_pdf': pdf,
10901090
'has_epub': epub,
10911091
'has_htmlzip': localmedia,
@@ -1206,6 +1206,13 @@ def build_docs_html(self):
12061206

12071207
return success
12081208

1209+
def get_final_doctype(self):
1210+
html_builder = get_builder_class(self.config.doctype)(
1211+
build_env=self.build_env,
1212+
python_env=self.python_env,
1213+
)
1214+
return html_builder.get_final_doctype()
1215+
12091216
def build_docs_search(self):
12101217
"""Build search data."""
12111218
# Search is always run in sphinx using the rtd-sphinx-extension.

readthedocs/projects/views/mixins.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""Mixin classes for project views."""
2+
from urllib.parse import urlparse
43

54
from celery import chain
65
from django.shortcuts import get_object_or_404
76

7+
from readthedocs.core.resolver import resolve, resolve_path
88
from readthedocs.core.utils import prepare_build
99
from readthedocs.projects.models import Project
1010
from readthedocs.projects.signals import project_import
@@ -49,6 +49,44 @@ def get_context_data(self, **kwargs):
4949
return context
5050

5151

52+
class ProjectRelationListMixin:
53+
54+
"""Injects ``subprojects_and_urls`` into the context."""
55+
56+
def get_context_data(self, **kwargs):
57+
context = super().get_context_data(**kwargs)
58+
context['subprojects_and_urls'] = self._get_subprojects_and_urls()
59+
return context
60+
61+
def _get_subprojects_and_urls(self):
62+
"""
63+
Get a tuple of subprojects and its absolute URls.
64+
65+
All subprojects share the domain from the parent,
66+
so instead of resolving the domain and path for each subproject,
67+
we resolve only the path of each one.
68+
"""
69+
subprojects_and_urls = []
70+
71+
project = self.get_project()
72+
main_domain = resolve(project)
73+
parsed_main_domain = urlparse(main_domain)
74+
75+
subprojects = project.subprojects.select_related('child')
76+
for subproject in subprojects:
77+
subproject_path = resolve_path(subproject.child)
78+
parsed_subproject_domain = parsed_main_domain._replace(
79+
path=subproject_path,
80+
)
81+
subprojects_and_urls.append(
82+
(
83+
subproject,
84+
parsed_subproject_domain.geturl(),
85+
)
86+
)
87+
return subprojects_and_urls
88+
89+
5290
class ProjectImportMixin:
5391

5492
"""Helpers to import a Project."""

readthedocs/projects/views/private.py

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import csv
44
import logging
5-
from urllib.parse import urlparse
65

76
from allauth.socialaccount.models import SocialAccount
87
from django.conf import settings
@@ -45,7 +44,6 @@
4544
LoginRequiredMixin,
4645
PrivateViewMixin,
4746
)
48-
from readthedocs.core.resolver import resolve, resolve_path
4947
from readthedocs.core.utils import broadcast, trigger_build
5048
from readthedocs.core.utils.extend import SettingsOverrideObject
5149
from readthedocs.integrations.models import HttpExchange, Integration
@@ -81,7 +79,10 @@
8179
from readthedocs.projects.notifications import EmailConfirmNotification
8280
from readthedocs.projects.utils import Echo
8381
from readthedocs.projects.views.base import ProjectAdminMixin, ProjectSpamMixin
84-
from readthedocs.projects.views.mixins import ProjectImportMixin
82+
from readthedocs.projects.views.mixins import (
83+
ProjectImportMixin,
84+
ProjectRelationListMixin,
85+
)
8586
from readthedocs.search.models import SearchQuery
8687

8788
from ..tasks import retry_domain_verification
@@ -459,41 +460,13 @@ def get_success_url(self):
459460
return reverse('projects_subprojects', args=[self.get_project().slug])
460461

461462

462-
class ProjectRelationshipList(ProjectRelationshipMixin, ListView):
463+
class ProjectRelationshipList(ProjectRelationListMixin, ProjectRelationshipMixin, ListView):
463464

464465
def get_context_data(self, **kwargs):
465466
ctx = super().get_context_data(**kwargs)
466467
ctx['superproject'] = self.project.superprojects.first()
467-
ctx['subprojects_and_urls'] = self.get_subprojects_and_urls()
468468
return ctx
469469

470-
def get_subprojects_and_urls(self):
471-
"""
472-
Get a tuple of subprojects and its absolute URls.
473-
474-
All subprojects share the domain from the parent,
475-
so instead of resolving the domain and path for each subproject,
476-
we resolve only the path of each one.
477-
"""
478-
subprojects_and_urls = []
479-
480-
main_domain = resolve(self.project)
481-
parsed_main_domain = urlparse(main_domain)
482-
483-
subprojects = self.object_list.select_related('child')
484-
for subproject in subprojects:
485-
subproject_path = resolve_path(subproject.child)
486-
parsed_subproject_domain = parsed_main_domain._replace(
487-
path=subproject_path,
488-
)
489-
subprojects_and_urls.append(
490-
(
491-
subproject,
492-
parsed_subproject_domain.geturl(),
493-
)
494-
)
495-
return subprojects_and_urls
496-
497470

498471
class ProjectRelationshipCreate(ProjectRelationshipMixin, CreateView):
499472

0 commit comments

Comments
 (0)