Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into search-reapply
Browse files Browse the repository at this point in the history
  • Loading branch information
ericholscher committed Jan 22, 2019
2 parents 12de58b + 7a54182 commit 46c4f20
Show file tree
Hide file tree
Showing 349 changed files with 8,141 additions and 8,544 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
language: python
python:
- 2.7
- 3.6
env:
- ES_VERSION=6.2.4 ES_DOWNLOAD_URL=https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-${ES_VERSION}.tar.gz
matrix:
include:
- python: 3.6
env: TOXENV=py36 ES_VERSION=1.3.9 ES_DOWNLOAD_URL=https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-${ES_VERSION}.tar.gz
- python: 3.6
env: TOXENV=docs
- python: 3.6
Expand Down Expand Up @@ -45,6 +46,6 @@ notifications:

branches:
only:
- master
- master
- rel # Community release branch
- relcorp # Corporate release branch
2 changes: 1 addition & 1 deletion common
5 changes: 1 addition & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import sys

import sphinx_rtd_theme
from recommonmark.parser import CommonMarkParser

sys.path.insert(0, os.path.abspath('..'))
sys.path.append(os.path.dirname(__file__))
Expand All @@ -29,13 +28,11 @@
'doc_extensions',
'sphinx_tabs.tabs',
'sphinx-prompt',
'recommonmark',
]
templates_path = ['_templates']

source_suffix = ['.rst', '.md']
source_parsers = {
'.md': CommonMarkParser,
}

master_doc = 'index'
project = u'Read the Docs'
Expand Down
2 changes: 1 addition & 1 deletion docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ We deploy readthedocs.org from the `rel` branch in our GitHub repository. You ca


How can I avoid search results having a deprecated version of my docs?
---------------------------------------------------------------------
----------------------------------------------------------------------

If readers search something related to your docs in Google, it will probably return the most relevant version of your documentation.
It may happen that this version is already deprecated and you want to stop Google indexing it as a result,
Expand Down
3 changes: 2 additions & 1 deletion readthedocs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-

"""Read the Docs."""

import os.path

from future.moves.configparser import RawConfigParser
from configparser import RawConfigParser


def get_version(setupcfg_path):
Expand Down
6 changes: 4 additions & 2 deletions readthedocs/analytics/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""App init"""
# -*- coding: utf-8 -*-

default_app_config = 'readthedocs.analytics.apps.AnalyticsAppConfig' # noqa
"""App init."""

default_app_config = 'readthedocs.analytics.apps.AnalyticsAppConfig' # noqa
5 changes: 3 additions & 2 deletions readthedocs/analytics/apps.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-

"""Django app config for the analytics app."""

from __future__ import absolute_import
from django.apps import AppConfig


class AnalyticsAppConfig(AppConfig):

"""Analytics app init code"""
"""Analytics app init code."""

name = 'readthedocs.analytics'
verbose_name = 'Analytics'
37 changes: 20 additions & 17 deletions readthedocs/analytics/tasks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Tasks for Read the Docs' analytics"""
# -*- coding: utf-8 -*-

from __future__ import absolute_import
"""Tasks for Read the Docs' analytics."""

from django.conf import settings

Expand All @@ -11,24 +11,24 @@


DEFAULT_PARAMETERS = {
'v': '1', # analytics version (always 1)
'aip': '1', # anonymize IP
'v': '1', # analytics version (always 1)
'aip': '1', # anonymize IP
'tid': settings.GLOBAL_ANALYTICS_CODE,

# User data
'uip': None, # User IP address
'ua': None, # User agent
'uip': None, # User IP address
'ua': None, # User agent

# Application info
'an': 'Read the Docs',
'av': readthedocs.__version__, # App version
'av': readthedocs.__version__, # App version
}


@app.task(queue='web')
def analytics_pageview(url, title=None, **kwargs):
"""
Send a pageview to Google Analytics
Send a pageview to Google Analytics.
:see: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
:param url: the URL of the pageview
Expand All @@ -37,18 +37,21 @@ def analytics_pageview(url, title=None, **kwargs):
"""
data = {
't': 'pageview',
'dl': url, # URL of the pageview (required)
'dt': title, # Title of the page
'dl': url, # URL of the pageview (required)
'dt': title, # Title of the page
}
data.update(DEFAULT_PARAMETERS)
data.update(kwargs)
send_to_analytics(data)


@app.task(queue='web')
def analytics_event(event_category, event_action, event_label=None, event_value=None, **kwargs):
def analytics_event(
event_category, event_action, event_label=None, event_value=None,
**kwargs
):
"""
Send an analytics event to Google Analytics
Send an analytics event to Google Analytics.
:see: https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#event
:param event_category: the category of the event
Expand All @@ -58,11 +61,11 @@ def analytics_event(event_category, event_action, event_label=None, event_value=
:param kwargs: extra event parameters to send to GA
"""
data = {
't': 'event', # GA event - don't change
'ec': event_category, # Event category (required)
'ea': event_action, # Event action (required)
'el': event_label, # Event label
'ev': event_value, # Event value (numeric)
't': 'event', # GA event - don't change
'ec': event_category, # Event category (required)
'ea': event_action, # Event action (required)
'el': event_label, # Event label
'ev': event_value, # Event value (numeric)
}
data.update(DEFAULT_PARAMETERS)
data.update(kwargs)
Expand Down
4 changes: 1 addition & 3 deletions readthedocs/analytics/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from __future__ import absolute_import, unicode_literals

# -*- coding: utf-8 -*-
from django.test import TestCase

from .utils import anonymize_ip_address, anonymize_user_agent
Expand Down Expand Up @@ -29,4 +28,3 @@ def test_anonymize_ua(self):
anonymize_user_agent('Some rare user agent'),
'Rare user agent',
)

33 changes: 15 additions & 18 deletions readthedocs/analytics/utils.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
"""Utilities related to analytics"""
# -*- coding: utf-8 -*-

"""Utilities related to analytics."""

from __future__ import absolute_import, unicode_literals
import hashlib
import ipaddress
import logging

import requests
from django.conf import settings
from django.utils.encoding import force_text, force_bytes
from django.utils.crypto import get_random_string
import requests
from django.utils.encoding import force_bytes, force_text
from user_agents import parse

try:
# Python 3.3+ only
import ipaddress
except ImportError:
from .vendor import ipaddress

log = logging.getLogger(__name__) # noqa
log = logging.getLogger(__name__) # noqa


def get_client_ip(request):
"""Gets the real IP based on a request object"""
"""Gets the real IP based on a request object."""
ip_address = request.META.get('REMOTE_ADDR')

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


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

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


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


def send_to_analytics(data):
"""Sends data to Google Analytics"""
"""Sends data to Google Analytics."""
if data.get('uip') and data.get('ua'):
data['cid'] = generate_client_id(data['uip'], data['ua'])

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

def generate_client_id(ip_address, user_agent):
"""
Create an advertising ID
Create an advertising ID.
This simplifies things but essentially if a user has the same IP and same UA,
this will treat them as the same user for analytics purposes
This simplifies things but essentially if a user has the same IP and same
UA, this will treat them as the same user for analytics purposes
"""
salt = b'advertising-client-id'

Expand Down
Empty file.
Loading

0 comments on commit 46c4f20

Please sign in to comment.