Skip to content

Commit 5c7e401

Browse files
committed
Merge branch 'master' into allow-query-params-in-redirects
2 parents 6d05ea5 + 59d9e3e commit 5c7e401

File tree

359 files changed

+7580
-8451
lines changed

Some content is hidden

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

359 files changed

+7580
-8451
lines changed

.github/mergeable.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# ProBot Mergeable Bot
2+
# https://github.com/jusx/mergeable
3+
4+
mergeable:
5+
pull_requests:
6+
approvals:
7+
# Minimum of approvals needed.
8+
min: 1
9+
message: 'The PR must have a minimum of 1 approvals.'
10+
11+
description:
12+
no_empty:
13+
# Do not allow empty descriptions on PR.
14+
enabled: false
15+
message: 'Description can not be empty.'
16+
17+
must_exclude:
18+
# Do not allow 'DO NOT MERGE' phrase on PR's description.
19+
regex: 'DO NOT MERGE'
20+
message: 'Description says that the PR should not be merged yet.'
21+
22+
# Do not allow 'WIP' on PR's title.
23+
title: 'WIP'
24+
25+
label:
26+
# Do not allow PR with label 'PR: work in progress'
27+
must_exclude: 'PR: work in progress'
28+
message: 'This PR is work in progress.'

.travis.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
language: python
22
python:
3-
- 2.7
43
- 3.6
5-
env:
6-
- ES_VERSION=1.3.9 ES_DOWNLOAD_URL=https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-${ES_VERSION}.tar.gz
74
matrix:
85
include:
6+
- python: 3.6
7+
env: TOXENV=py36 ES_VERSION=1.3.9 ES_DOWNLOAD_URL=https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-${ES_VERSION}.tar.gz
98
- python: 3.6
109
env: TOXENV=docs
1110
- python: 3.6
@@ -45,6 +44,6 @@ notifications:
4544

4645
branches:
4746
only:
48-
- master
47+
- master
4948
- rel # Community release branch
5049
- relcorp # Corporate release branch

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2010-2017 Read the Docs, Inc & contributors
1+
Copyright (c) 2010-2019 Read the Docs, Inc & contributors
22

33
Permission is hereby granted, free of charge, to any person
44
obtaining a copy of this software and associated documentation

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,6 @@ when you push to GitHub.
7878
License
7979
-------
8080

81-
`MIT`_ © 2010-2017 Read the Docs, Inc & contributors
81+
`MIT`_ © 2010-2019 Read the Docs, Inc & contributors
8282

8383
.. _MIT: LICENSE

common

docs/faq.rst

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,49 @@ What commit of Read the Docs is in production?
230230
----------------------------------------------
231231

232232
We deploy readthedocs.org from the `rel` branch in our GitHub repository. You can see the latest commits that have been deployed by looking on GitHub: https://github.com/rtfd/readthedocs.org/commits/rel
233+
234+
235+
How can I avoid search results having a deprecated version of my docs?
236+
---------------------------------------------------------------------
237+
238+
If readers search something related to your docs in Google, it will probably return the most relevant version of your documentation.
239+
It may happen that this version is already deprecated and you want to stop Google indexing it as a result,
240+
and start suggesting the latest (or newer) one.
241+
242+
To accomplish this, you can add a ``robots.txt`` file to your documentation's root so it ends up served at the root URL of your project
243+
(for example, https://yourproject.readthedocs.io/robots.txt).
244+
245+
246+
Minimal example of ``robots.txt``
247+
+++++++++++++++++++++++++++++++++
248+
249+
::
250+
251+
User-agent: *
252+
Disallow: /en/deprecated-version/
253+
Disallow: /en/2.0/
254+
255+
.. note::
256+
257+
See `Google's docs`_ for its full syntax.
258+
259+
This file has to be served as is under ``/robots.txt``.
260+
Depending if you are using Sphinx or MkDocs, you will need a different configuration for this.
261+
262+
263+
Sphinx
264+
~~~~~~
265+
266+
Sphinx uses `html_extra`_ option to add static files to the output.
267+
You need to create a ``robots.txt`` file and put it under the path defined in ``html_extra``.
268+
269+
270+
MkDocs
271+
~~~~~~
272+
273+
MkDocs needs the ``robots.txt`` to be at the directory defined at `docs_dir`_ config.
274+
275+
276+
.. _Google's docs: https://support.google.com/webmasters/answer/6062608
277+
.. _html_extra: https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_extra_path
278+
.. _docs_dir: https://www.mkdocs.org/user-guide/configuration/#docs_dir

docs/webhooks.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ that your VCS provider is not configured correctly. If there is payload
161161
information on your Read the Docs project, you might need to verify that your
162162
versions are configured to build correctly.
163163

164-
Either way, it may help to either resync your webhook intergration (see
164+
Either way, it may help to either resync your webhook integration (see
165165
`Resyncing webhooks`_ for information on this process), or set up an entirely
166-
new webhook intergration.
166+
new webhook integration.
167167

168168
.. _webhook-github-services:
169169

@@ -180,7 +180,7 @@ In order for your project to continue automatically building, you will need to
180180
configure your GitHub repository with a new webhook. You can use either a
181181
connected GitHub account and a :ref:`GitHub webhook integration <webhook-integration-github>`
182182
on your Read the Docs project, or you can use a
183-
:ref:`generic webhook integraiton <webhook-integration-generic>` without a connected
183+
:ref:`generic webhook integration <webhook-integration-generic>` without a connected
184184
account.
185185

186186
.. [1] https://developer.github.com/changes/2018-04-25-github-services-deprecation/

readthedocs/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# -*- coding: utf-8 -*-
2+
23
"""Read the Docs."""
34

45
import os.path
56

6-
from future.moves.configparser import RawConfigParser
7+
from configparser import RawConfigParser
78

89

910
def get_version(setupcfg_path):

readthedocs/analytics/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
"""App init"""
1+
# -*- coding: utf-8 -*-
22

3-
default_app_config = 'readthedocs.analytics.apps.AnalyticsAppConfig' # noqa
3+
"""App init."""
4+
5+
default_app_config = 'readthedocs.analytics.apps.AnalyticsAppConfig' # noqa

readthedocs/analytics/apps.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
# -*- coding: utf-8 -*-
2+
13
"""Django app config for the analytics app."""
24

3-
from __future__ import absolute_import
45
from django.apps import AppConfig
56

67

78
class AnalyticsAppConfig(AppConfig):
89

9-
"""Analytics app init code"""
10+
"""Analytics app init code."""
1011

1112
name = 'readthedocs.analytics'
1213
verbose_name = 'Analytics'

readthedocs/analytics/tasks.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
"""Tasks for Read the Docs' analytics"""
1+
# -*- coding: utf-8 -*-
22

3-
from __future__ import absolute_import
3+
"""Tasks for Read the Docs' analytics."""
44

55
from django.conf import settings
66

@@ -11,24 +11,24 @@
1111

1212

1313
DEFAULT_PARAMETERS = {
14-
'v': '1', # analytics version (always 1)
15-
'aip': '1', # anonymize IP
14+
'v': '1', # analytics version (always 1)
15+
'aip': '1', # anonymize IP
1616
'tid': settings.GLOBAL_ANALYTICS_CODE,
1717

1818
# User data
19-
'uip': None, # User IP address
20-
'ua': None, # User agent
19+
'uip': None, # User IP address
20+
'ua': None, # User agent
2121

2222
# Application info
2323
'an': 'Read the Docs',
24-
'av': readthedocs.__version__, # App version
24+
'av': readthedocs.__version__, # App version
2525
}
2626

2727

2828
@app.task(queue='web')
2929
def analytics_pageview(url, title=None, **kwargs):
3030
"""
31-
Send a pageview to Google Analytics
31+
Send a pageview to Google Analytics.
3232
3333
:see: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
3434
:param url: the URL of the pageview
@@ -37,18 +37,21 @@ def analytics_pageview(url, title=None, **kwargs):
3737
"""
3838
data = {
3939
't': 'pageview',
40-
'dl': url, # URL of the pageview (required)
41-
'dt': title, # Title of the page
40+
'dl': url, # URL of the pageview (required)
41+
'dt': title, # Title of the page
4242
}
4343
data.update(DEFAULT_PARAMETERS)
4444
data.update(kwargs)
4545
send_to_analytics(data)
4646

4747

4848
@app.task(queue='web')
49-
def analytics_event(event_category, event_action, event_label=None, event_value=None, **kwargs):
49+
def analytics_event(
50+
event_category, event_action, event_label=None, event_value=None,
51+
**kwargs
52+
):
5053
"""
51-
Send an analytics event to Google Analytics
54+
Send an analytics event to Google Analytics.
5255
5356
:see: https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#event
5457
:param event_category: the category of the event
@@ -58,11 +61,11 @@ def analytics_event(event_category, event_action, event_label=None, event_value=
5861
:param kwargs: extra event parameters to send to GA
5962
"""
6063
data = {
61-
't': 'event', # GA event - don't change
62-
'ec': event_category, # Event category (required)
63-
'ea': event_action, # Event action (required)
64-
'el': event_label, # Event label
65-
'ev': event_value, # Event value (numeric)
64+
't': 'event', # GA event - don't change
65+
'ec': event_category, # Event category (required)
66+
'ea': event_action, # Event action (required)
67+
'el': event_label, # Event label
68+
'ev': event_value, # Event value (numeric)
6669
}
6770
data.update(DEFAULT_PARAMETERS)
6871
data.update(kwargs)

readthedocs/analytics/tests.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from __future__ import absolute_import, unicode_literals
2-
1+
# -*- coding: utf-8 -*-
32
from django.test import TestCase
43

54
from .utils import anonymize_ip_address, anonymize_user_agent
@@ -29,4 +28,3 @@ def test_anonymize_ua(self):
2928
anonymize_user_agent('Some rare user agent'),
3029
'Rare user agent',
3130
)
32-

readthedocs/analytics/utils.py

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
1-
"""Utilities related to analytics"""
1+
# -*- coding: utf-8 -*-
2+
3+
"""Utilities related to analytics."""
24

3-
from __future__ import absolute_import, unicode_literals
45
import hashlib
6+
import ipaddress
57
import logging
68

9+
import requests
710
from django.conf import settings
8-
from django.utils.encoding import force_text, force_bytes
911
from django.utils.crypto import get_random_string
10-
import requests
12+
from django.utils.encoding import force_bytes, force_text
1113
from user_agents import parse
1214

13-
try:
14-
# Python 3.3+ only
15-
import ipaddress
16-
except ImportError:
17-
from .vendor import ipaddress
1815

19-
log = logging.getLogger(__name__) # noqa
16+
log = logging.getLogger(__name__) # noqa
2017

2118

2219
def get_client_ip(request):
23-
"""Gets the real IP based on a request object"""
20+
"""Gets the real IP based on a request object."""
2421
ip_address = request.META.get('REMOTE_ADDR')
2522

2623
# Get the original IP address (eg. "X-Forwarded-For: client, proxy1, proxy2")
@@ -32,7 +29,7 @@ def get_client_ip(request):
3229

3330

3431
def anonymize_ip_address(ip_address):
35-
"""Anonymizes an IP address by zeroing the last 2 bytes"""
32+
"""Anonymizes an IP address by zeroing the last 2 bytes."""
3633
# Used to anonymize an IP by zero-ing out the last 2 bytes
3734
ip_mask = int('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000', 16)
3835

@@ -46,7 +43,7 @@ def anonymize_ip_address(ip_address):
4643

4744

4845
def anonymize_user_agent(user_agent):
49-
"""Anonymizes rare user agents"""
46+
"""Anonymizes rare user agents."""
5047
# If the browser family is not recognized, this is a rare user agent
5148
parsed_ua = parse(user_agent)
5249
if parsed_ua.browser.family == 'Other' or parsed_ua.os.family == 'Other':
@@ -56,7 +53,7 @@ def anonymize_user_agent(user_agent):
5653

5754

5855
def send_to_analytics(data):
59-
"""Sends data to Google Analytics"""
56+
"""Sends data to Google Analytics."""
6057
if data.get('uip') and data.get('ua'):
6158
data['cid'] = generate_client_id(data['uip'], data['ua'])
6259

@@ -74,7 +71,7 @@ def send_to_analytics(data):
7471
resp = requests.post(
7572
'https://www.google-analytics.com/collect',
7673
data=data,
77-
timeout=3, # seconds
74+
timeout=3, # seconds
7875
)
7976
except requests.Timeout:
8077
log.warning('Timeout sending to Google Analytics')
@@ -85,10 +82,10 @@ def send_to_analytics(data):
8582

8683
def generate_client_id(ip_address, user_agent):
8784
"""
88-
Create an advertising ID
85+
Create an advertising ID.
8986
90-
This simplifies things but essentially if a user has the same IP and same UA,
91-
this will treat them as the same user for analytics purposes
87+
This simplifies things but essentially if a user has the same IP and same
88+
UA, this will treat them as the same user for analytics purposes
9289
"""
9390
salt = b'advertising-client-id'
9491

readthedocs/analytics/vendor/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)