From e070e1d90884b5783bbd462e4c4dd6f923fdbc43 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 07:56:32 -0600 Subject: [PATCH 01/10] PEP8 fixes --- dnt/middleware.py | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dnt/middleware.py b/dnt/middleware.py index 432d1e5..c40d077 100644 --- a/dnt/middleware.py +++ b/dnt/middleware.py @@ -2,10 +2,10 @@ class DoNotTrackMiddleware(object): - + def process_request(self, request): """ - Sets request.DNT to True or False based on the presence of the DNT HTTP header. + Sets flag request.DNT based on DNT HTTP header. """ if 'HTTP_DNT' in request.META and request.META['HTTP_DNT'] == '1': request.DNT = True diff --git a/setup.py b/setup.py index d8e0ff4..dfbcde1 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ license='BSD', packages=['dnt'], include_package_data=True, - package_data = { '': ['README.rst'] }, + package_data={'': ['README.rst']}, zip_safe=False, classifiers=[ 'Development Status :: 4 - Beta', From c272aba0c7c22e59617a4b0850118499efbe3f02 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 10:16:29 -0600 Subject: [PATCH 02/10] Add tests, tox, TravisCI config Add unit and integration tests for DoNotTrackMiddleware. Add tox targets to test across Django versions, and a TravisCI configuration to check PRs. Start on a Makefile for automating maintenance tasks. --- .gitignore | 25 +++++++++++++--- .travis.yml | 34 +++++++++++++++++++++ Makefile | 26 ++++++++++++++++ manage.py | 10 +++++++ requirements.dev.txt | 5 ++++ testapp/__init__.py | 0 testapp/settings.py | 58 ++++++++++++++++++++++++++++++++++++ testapp/templates/index.html | 9 ++++++ testapp/urls.py | 7 +++++ tests/__init__.py | 0 tests/test_app.py | 21 +++++++++++++ tests/test_middleware.py | 56 ++++++++++++++++++++++++++++++++++ tox.ini | 24 +++++++++++++++ 13 files changed, 271 insertions(+), 4 deletions(-) create mode 100644 .travis.yml create mode 100644 Makefile create mode 100755 manage.py create mode 100644 requirements.dev.txt create mode 100644 testapp/__init__.py create mode 100644 testapp/settings.py create mode 100644 testapp/templates/index.html create mode 100644 testapp/urls.py create mode 100644 tests/__init__.py create mode 100644 tests/test_app.py create mode 100644 tests/test_middleware.py create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index a87a7a9..9951677 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,21 @@ -*.pyc -*pip* -*.egg-info -dist +# Cherry-picked from: +# https://github.com/github/gitignore/blob/master/Python.gitignore + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packacking +*.egg-info/ +dist/ + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..764daf5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,34 @@ +sudo: no +language: python +cache: pip +matrix: + include: + - python: "2.7" + env: TOXENV=py27-1.8 + - python: "3.5" + env: TOXENV=py34-1.8 + - python: "2.7" + env: TOXENV=py27-1.9 + - python: "3.5" + env: TOXENV=py35-1.9 + - python: "2.7" + env: TOXENV=py27-1.10 + - python: "3.5" + env: TOXENV=py35-1.10 + - python: "2.7" + env: TOXENV=py27-1.11 + - python: "3.6" + env: TOXENV=py36-1.11 + - python: "3.6" + env: TOXENV=py36-master + allow_failures: + - env: TOXENV=py34-1.8 + - env: TOXENV=py35-1.9 + - env: TOXENV=py35-1.10 + - env: TOXENV=py36-1.11 + - env: TOXENV=py36-master +install: + - pip install coveralls tox +script: + - tox +after_success: coveralls diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b99cac9 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +export DJANGO_SETTINGS_MODULE = testapp.settings +export PYTHONPATH := $(shell pwd) + +clean: + git clean -Xfd + +develop: + pip install -r requirements.dev.txt + +lint: + flake8 . + +test: + ./manage.py test tests + +coverage: clean + coverage erase + coverage run --source=dnt ./manage.py test + +coveragehtml: coverage + coverage html + python -m webbrowser file://$(CURDIR)/htmlcov/index.html + +qa: lint coveragehtml + +.PHONY: clean test qa diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..1859c0a --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +from django.core.management import execute_from_command_line + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testapp.settings') + +if __name__ == "__main__": + execute_from_command_line(sys.argv) diff --git a/requirements.dev.txt b/requirements.dev.txt new file mode 100644 index 0000000..7ffd4b4 --- /dev/null +++ b/requirements.dev.txt @@ -0,0 +1,5 @@ +# Testing and development requirements +flake8 +Django +tox +coverage diff --git a/testapp/__init__.py b/testapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/testapp/settings.py b/testapp/settings.py new file mode 100644 index 0000000..35d4f4d --- /dev/null +++ b/testapp/settings.py @@ -0,0 +1,58 @@ +import os + + +def local_path(path): + return os.path.join(os.path.dirname(__file__), path) + + +SECRET_KEY = "dnt-tests" +DEBUG = True +ALLOWED_HOSTS = [] + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'testapp', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', + 'dnt.middleware.DoNotTrackMiddleware', +) + +ROOT_URLCONF = 'testapp.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:' + } +} diff --git a/testapp/templates/index.html b/testapp/templates/index.html new file mode 100644 index 0000000..484ebe8 --- /dev/null +++ b/testapp/templates/index.html @@ -0,0 +1,9 @@ + + + + Do Not Track + + +

Do Not Track: {{ request.DNT }}

+ + diff --git a/testapp/urls.py b/testapp/urls.py new file mode 100644 index 0000000..c034c93 --- /dev/null +++ b/testapp/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls import url +from django.views.generic import TemplateView + + +urlpatterns = [ + url(r'^$', TemplateView.as_view(template_name="index.html"), name="index"), +] diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 0000000..03f28fd --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +"""Test an application using django-dnt.""" +from __future__ import unicode_literals + +from django.test import TestCase + + +class AppTest(TestCase): + """Test middleware through the Django test client.""" + + def test_request_dnt(self): + """Test a request with header "DNT: 1".""" + response = self.client.get('/', HTTP_DNT='1') + self.assertEqual(response['Vary'], 'DNT') + self.assertInHTML('True', response.content) + + def test_request_no_dnt(self): + """Test a request with no DNT header.""" + response = self.client.get('/') + self.assertEqual(response['Vary'], 'DNT') + self.assertInHTML('False', response.content) diff --git a/tests/test_middleware.py b/tests/test_middleware.py new file mode 100644 index 0000000..68c1b2f --- /dev/null +++ b/tests/test_middleware.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +"""Middleware tests.""" +from __future__ import unicode_literals + +from django.test import TestCase +from django.http import HttpRequest, HttpResponse + +from dnt.middleware import DoNotTrackMiddleware + + +class DoNotTrackMiddlewareTest(TestCase): + """Unit tests for the DoNotTrackMiddleware.""" + + def request(self): + """Create a request object for middleware testing.""" + req = HttpRequest() + req.META = { + 'SERVER_NAME': 'testserver', + 'SERVER_PORT': 80, + } + req.path = req.path_info = "/" + return req + + def response(self): + """Create a response object for middleware testing.""" + resp = HttpResponse() + resp.status_code = 200 + resp.content = b' ' + return resp + + def test_request_dnt(self): + """The header "DNT: 1" sets request.DNT.""" + request = self.request() + request.META['HTTP_DNT'] = '1' + DoNotTrackMiddleware().process_request(request) + self.assertTrue(request.DNT) + + def test_request_dnt_off(self): + """The header "DNT: 0" clears request.DNT.""" + request = self.request() + request.META['HTTP_DNT'] = '0' + DoNotTrackMiddleware().process_request(request) + self.assertFalse(request.DNT) + + def test_request_no_dnt(self): + """If the DNT header is not present, request.DNT is false.""" + request = self.request() + DoNotTrackMiddleware().process_request(request) + self.assertFalse(request.DNT) + + def test_response(self): + """The Vary caching header in the response includes DNT.""" + request = self.request() + response = self.response() + response = DoNotTrackMiddleware().process_response(request, response) + self.assertEqual(response['Vary'], 'DNT') diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..8a1e7e0 --- /dev/null +++ b/tox.ini @@ -0,0 +1,24 @@ +[tox] +skip_missing_interpreters = true +envlist = + py{27,33,34,35}-1.8 + py{27,34,35,36}-{1.9,1.10,1.11} + py{35,36}-master + +[testenv] +basepython = + py27: python2.7 + py33: python3.3 + py34: python3.4 + py35: python3.5 + py36: python3.6 +usedevelop = true +pip_pre = true +commands = make test +deps = + 1.8: Django>=1.8,<1.9 + 1.9: Django>=1.9,<1.10 + 1.10: Django>=1.10,<1.11 + 1.11: Django>=1.11a1,<1.12 + master: https://github.com/django/django/archive/master.tar.gz +whitelist_externals = make From 80f60ffe9d5608c9a72ce96f8ff7350e720f8400 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 10:46:04 -0600 Subject: [PATCH 03/10] Fix test to be compatible with Python 3 --- .travis.yml | 4 ---- tests/test_app.py | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 764daf5..a4fea40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,10 +22,6 @@ matrix: - python: "3.6" env: TOXENV=py36-master allow_failures: - - env: TOXENV=py34-1.8 - - env: TOXENV=py35-1.9 - - env: TOXENV=py35-1.10 - - env: TOXENV=py36-1.11 - env: TOXENV=py36-master install: - pip install coveralls tox diff --git a/tests/test_app.py b/tests/test_app.py index 03f28fd..b347f99 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -12,10 +12,12 @@ def test_request_dnt(self): """Test a request with header "DNT: 1".""" response = self.client.get('/', HTTP_DNT='1') self.assertEqual(response['Vary'], 'DNT') - self.assertInHTML('True', response.content) + content = response.content.decode('utf8') + self.assertInHTML('True', content) def test_request_no_dnt(self): """Test a request with no DNT header.""" response = self.client.get('/') self.assertEqual(response['Vary'], 'DNT') - self.assertInHTML('False', response.content) + content = response.content.decode('utf8') + self.assertInHTML('False', content) From 58dd3aaa192f8cba87f9557356ea4d96e6978e03 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 10:58:07 -0600 Subject: [PATCH 04/10] Support MIDDLEWARE for Django 1.10 and up --- dnt/middleware.py | 10 +++++++++- testapp/settings.py | 34 ++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/dnt/middleware.py b/dnt/middleware.py index c40d077..84cef19 100644 --- a/dnt/middleware.py +++ b/dnt/middleware.py @@ -1,7 +1,15 @@ from django.utils.cache import patch_vary_headers +try: + # Added in Django 1.10 + from django.utils.deprecation import MiddlewareMixin +except ImportError: + _base_class = object +else: + _base_class = MiddlewareMixin -class DoNotTrackMiddleware(object): + +class DoNotTrackMiddleware(_base_class): def process_request(self, request): """ diff --git a/testapp/settings.py b/testapp/settings.py index 35d4f4d..6c678be 100644 --- a/testapp/settings.py +++ b/testapp/settings.py @@ -1,8 +1,4 @@ -import os - - -def local_path(path): - return os.path.join(os.path.dirname(__file__), path) +import django SECRET_KEY = "dnt-tests" @@ -20,7 +16,7 @@ def local_path(path): 'testapp', ) -MIDDLEWARE_CLASSES = ( +_middleware = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -32,6 +28,32 @@ def local_path(path): 'dnt.middleware.DoNotTrackMiddleware', ) +if django.VERSION[:2] < (1, 10): + # Django 1.9 and earlier + MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', + 'dnt.middleware.DoNotTrackMiddleware', + ) +else: + # Django 1.10 and later + MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'dnt.middleware.DoNotTrackMiddleware', + ] + ROOT_URLCONF = 'testapp.urls' TEMPLATES = [ From 2c2b46b35718753ec54335a6126b774ac4509d2f Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 11:35:22 -0600 Subject: [PATCH 05/10] Exclude Django-compat import from coverage --- dnt/middleware.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnt/middleware.py b/dnt/middleware.py index 84cef19..36a5dba 100644 --- a/dnt/middleware.py +++ b/dnt/middleware.py @@ -4,9 +4,9 @@ # Added in Django 1.10 from django.utils.deprecation import MiddlewareMixin except ImportError: - _base_class = object + _base_class = object # pragma: no cover else: - _base_class = MiddlewareMixin + _base_class = MiddlewareMixin # pragma: no cover class DoNotTrackMiddleware(_base_class): From 64edbaf5e6f5b356572d9c0394cdc26fb230bdf5 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 11:53:07 -0600 Subject: [PATCH 06/10] Add badges --- README.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.rst b/README.rst index f406a6a..c87a6e4 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,20 @@ Django-DNT ========== +.. image:: http://img.shields.io/travis/mozilla/django-dnt/master.svg + :alt: The status of Travis continuous integration tests + :target: https://travis-ci.org/mozilla/django-dnt + +.. image:: https://img.shields.io/coveralls/mozilla/django-dnt/master.svg + :target: https://coveralls.io/r/mozilla/django-dnt + :alt: The code coverage + +.. image:: https://img.shields.io/pypi/v/django-dnt.svg + :alt: The PyPI package + :target: https://pypi.python.org/pypi/django-dnt + +.. Omit badges from docs + Do Not Track offers an easy way to pay attention to the ``DNT`` HTTP header. If users are sending ``DNT: 1``, ``DoNotTrackMiddleware`` will set ``request.DNT = True``, else it will set ``request.DNT = False``. From 3c97678df6364c4ddfd6250afbdb4eea1763e05b Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 11:36:07 -0600 Subject: [PATCH 07/10] Update packaging * Add a HISTORY.rst for version history * Check package with check-manifest and pyroma * Add README.rst (w/o badges) and HISTORY.rst to package description * Add more make targets: help, sdist, release, etc. --- .gitignore | 1 + HISTORY.rst | 6 +++++ MANIFEST.in | 9 +++++++ Makefile | 39 ++++++++++++++++++++++++++++- __init__.py | 0 dnt/__init__.py | 6 +++++ requirements.dev.txt | 8 ++++-- setup.cfg | 2 ++ setup.py | 59 +++++++++++++++++++++++++++++++++++++++++--- 9 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 HISTORY.rst delete mode 100644 __init__.py create mode 100644 setup.cfg diff --git a/.gitignore b/.gitignore index 9951677..d616845 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ __pycache__/ # Distribution / packacking *.egg-info/ +build/ dist/ # Installer logs diff --git a/HISTORY.rst b/HISTORY.rst new file mode 100644 index 0000000..756d14e --- /dev/null +++ b/HISTORY.rst @@ -0,0 +1,6 @@ +Release History +--------------- + +v0.1.0 - 2011-02-16 +~~~~~~~~~~~~~~~~~~~ +* Initial Release diff --git a/MANIFEST.in b/MANIFEST.in index 9d5d250..f3279ad 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,11 @@ +include HISTORY.rst include LICENSE +include Makefile include README.rst +include manage.py +include requirements.dev.txt +include tox.ini + +recursive-include testapp *.py +recursive-include testapp/templates *.html +recursive-include tests *.py diff --git a/Makefile b/Makefile index b99cac9..7f22717 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,20 @@ export DJANGO_SETTINGS_MODULE = testapp.settings export PYTHONPATH := $(shell pwd) +.PHONY: help clean coverage coveragehtml develop lint qa qa-all release sdist test test-all + +help: + @echo "clean - remove all artifacts" + @echo "coverage - check code coverage" + @echo "coveragehtml - display code coverage in browser" + @echo "develop - install development requirements" + @echo "lint - check style with flake8" + @echo "qa - run linters and test coverage" + @echo "qa-all - run QA plus tox and packaging" + @echo "release - package and upload a release" + @echo "sdist - package" + @echo "test - run tests" + @echo "test-all - run tests on every Python version with tox" + @echo "test-release - upload a release to the test PyPI server" clean: git clean -Xfd @@ -13,6 +28,9 @@ lint: test: ./manage.py test tests +test-all: + tox --skip_missing_interpreters + coverage: clean coverage erase coverage run --source=dnt ./manage.py test @@ -23,4 +41,23 @@ coveragehtml: coverage qa: lint coveragehtml -.PHONY: clean test qa +qa-all: qa sdist test-all + +sdist: + python setup.py sdist bdist_wheel + ls -l dist + check-manifest + pyroma dist/`ls -t dist | grep tar.gz | head -n1` + +release: clean sdist + twine register dist/*.tar.gz + twine register dist/*.whl + twine upload dist/* + python -m webbrowser -n https://pypi.python.org/pypi/django-dnt + +# Add [test] section to ~/.pypirc, https://testpypi.python.org/pypi +test-release: + twine register --repository test dist/*.tar.gz + twine register --repository test dist/*.whl + twine upload --repository test dist/* + python -m webbrowser -n https://testpypi.python.org/pypi/django-dnt diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/dnt/__init__.py b/dnt/__init__.py index e69de29..c2a1225 100644 --- a/dnt/__init__.py +++ b/dnt/__init__.py @@ -0,0 +1,6 @@ +""" +Django Middleware for DNT (Do Not Track) HTTP header. + +https://en.wikipedia.org/wiki/Do_Not_Track +""" +VERSION = '0.1.0' diff --git a/requirements.dev.txt b/requirements.dev.txt index 7ffd4b4..c20a0f3 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -1,5 +1,9 @@ # Testing and development requirements -flake8 Django -tox +check-manifest coverage +flake8 +pyroma +tox +twine +wheel diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..3c6e79c --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal=1 diff --git a/setup.py b/setup.py index dfbcde1..a9663ed 100644 --- a/setup.py +++ b/setup.py @@ -1,18 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +"""Packaging setup for django-dnt.""" + from setuptools import setup +description = 'Make Django requests aware of the DNT header' + + +def long_description(): + """Create a PyPI long description from docs.""" + readme = open('README.rst').read().decode('utf8') + body_tag = ".. Omit badges from docs" + try: + readme_body_start = readme.index(body_tag) + except ValueError: + readme_body = readme + else: + # Omit the badges and reconstruct the title + readme_text = readme[readme_body_start + len(body_tag):] + readme_body = """\ +%(title_mark)s +%(title)s +%(title_mark)s +%(readme_text)s +""" % { + 'title_mark': '=' * len(description), + 'title': description, + 'readme_text': readme_text, + } + + try: + history = open('HISTORY.rst').read().decode('utf8') + except IOError: + history = '' + + long_description = """\ +%(readme)s + +%(history)s +""" % { + 'readme': readme_body, + 'history': history + } + return long_description + + setup( name='django-dnt', version='0.1.0', - description='Make Django requests aware of the DNT header.', - long_description=open('README.rst').read(), + description=description + '.', + long_description=long_description(), author='James Socol', author_email='james@mozilla.com', url='http://github.com/mozilla/django-dnt', license='BSD', packages=['dnt'], - include_package_data=True, - package_data={'': ['README.rst']}, zip_safe=False, + keywords='django-dnt dnt do not track', classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Web Environment', @@ -23,5 +67,12 @@ 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Software Development :: Libraries :: Python Modules', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', ] ) From 550d53bf508f3f539e8b2f8a0575da23a5dec98d Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 12:28:14 -0600 Subject: [PATCH 08/10] Update README.rst for Django 1.10 --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index c87a6e4..054effa 100644 --- a/README.rst +++ b/README.rst @@ -21,4 +21,5 @@ users are sending ``DNT: 1``, ``DoNotTrackMiddleware`` will set ``request.DNT = True``, else it will set ``request.DNT = False``. Just add ``dnt.middleware.DoNotTrackMiddleware`` to your ``MIDDLEWARE_CLASSES`` -and you're good to go. +(Django 1.9 and earlier) or ``MIDDLEWARE`` (Django 1.10 and later) and you're +good to go. From 3ec1a3ece6c7bd5161abd5a7cd150134f8cf0627 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 12:31:08 -0600 Subject: [PATCH 09/10] Make setup.py file reads Python3 compatible --- setup.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a9663ed..229e39d 100644 --- a/setup.py +++ b/setup.py @@ -7,9 +7,17 @@ description = 'Make Django requests aware of the DNT header' +def read_file(path): + contents = open('README.rst').read() + if hasattr(contents, 'decode'): + return contents.decode('utf8') # Python2 bytes to unicode + else: + return contents # Python3 reads unicode + + def long_description(): """Create a PyPI long description from docs.""" - readme = open('README.rst').read().decode('utf8') + readme = read_file('README.rst') body_tag = ".. Omit badges from docs" try: readme_body_start = readme.index(body_tag) @@ -30,7 +38,7 @@ def long_description(): } try: - history = open('HISTORY.rst').read().decode('utf8') + history = read_file('HISTORY.rst') except IOError: history = '' From a7d9750bb27cd8bca993a0e242340f55ffef32d2 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Fri, 17 Feb 2017 12:34:10 -0600 Subject: [PATCH 10/10] Update to v0.2.0 --- HISTORY.rst | 6 ++++++ dnt/__init__.py | 2 +- setup.py | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 756d14e..5f4ba5c 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,12 @@ Release History --------------- +v0.2.0 - 2017-02-17 +~~~~~~~~~~~~~~~~~~~ +* Supported Django versions: 1.8, 1.9, 1.10, and 1.11 +* Supported Python versions: 2.7, 3.3, 3.4. 3.5, 3.6 +* Add "DNT" to Vary header in response (eillarra) + v0.1.0 - 2011-02-16 ~~~~~~~~~~~~~~~~~~~ * Initial Release diff --git a/dnt/__init__.py b/dnt/__init__.py index c2a1225..b06ce49 100644 --- a/dnt/__init__.py +++ b/dnt/__init__.py @@ -3,4 +3,4 @@ https://en.wikipedia.org/wiki/Do_Not_Track """ -VERSION = '0.1.0' +VERSION = '0.2.0' diff --git a/setup.py b/setup.py index 229e39d..50f76be 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ def long_description(): setup( name='django-dnt', - version='0.1.0', + version='0.2.0', description=description + '.', long_description=long_description(), author='James Socol',