mirror of
https://github.com/jazzband/django-analytical.git
synced 2026-03-16 22:20:25 +00:00
Updated supported versions of Python and Django
Dropped Python2.7/3.5 and Django 1.11 from test matrix Removed Py2 code and updated for Py3 features Replaced assertRaisesRegexp with AsserRaisesRegex Updated setup.py for currently supported versions Removed _timestamp
This commit is contained in:
parent
3eb17007ad
commit
74ddb4f0e0
41 changed files with 32 additions and 116 deletions
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
strategy:
|
||||
max-parallel: 5
|
||||
matrix:
|
||||
python-version: ['2.7', '3.5', '3.6', '3.7', '3.8']
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Analytical template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
from django import template
|
||||
|
|
@ -72,8 +70,7 @@ class AnalyticalNode(Node):
|
|||
|
||||
|
||||
def _load_template_nodes():
|
||||
template_nodes = dict((loc, dict((pos, []) for pos in TAG_POSITIONS))
|
||||
for loc in TAG_LOCATIONS)
|
||||
template_nodes = {loc: {pos: [] for pos in TAG_POSITIONS} for loc in TAG_LOCATIONS}
|
||||
|
||||
def add_node_cls(location, node, position=None):
|
||||
template_nodes[location][position].append(node)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Chartbeat template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Clickmap template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Clicky template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Crazy Egg template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"""
|
||||
Facebook Pixel template tags and filters.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Gaug.es template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ Google Analytics template tags and filters.
|
|||
DEPRECATED
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import decimal
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Google Analytics template tags and filters, using the new analytics.js library.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Google Analytics template tags and filters, using the new analytics.js library.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import decimal
|
||||
import re
|
||||
from django.conf import settings
|
||||
|
|
@ -134,7 +132,7 @@ class GoogleAnalyticsJsNode(Node):
|
|||
try:
|
||||
float(value)
|
||||
except ValueError:
|
||||
value = "'{}'".format(value)
|
||||
value = f"'{value}'"
|
||||
commands.append(CUSTOM_VAR_CODE.format(
|
||||
name=name,
|
||||
value=value,
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
GoSquared template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"""
|
||||
Hotjar template tags and filters.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
HubSpot template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,14 +2,10 @@
|
|||
intercom.io template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
import time
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
@ -29,14 +25,6 @@ TRACKING_CODE = """
|
|||
register = Library()
|
||||
|
||||
|
||||
def _timestamp(when):
|
||||
"""
|
||||
Python 2 compatibility for `datetime.timestamp()`.
|
||||
"""
|
||||
return (time.mktime(when.timetuple()) if sys.version_info < (3,) else
|
||||
when.timestamp())
|
||||
|
||||
|
||||
def _hashable_bytes(data):
|
||||
"""
|
||||
Coerce strings to hashable bytes.
|
||||
|
|
@ -109,7 +97,7 @@ class IntercomNode(Node):
|
|||
|
||||
params.setdefault('user_id', user.pk)
|
||||
|
||||
params['created_at'] = int(_timestamp(user.date_joined))
|
||||
params['created_at'] = int(user.date_joined.timestamp())
|
||||
else:
|
||||
params['created_at'] = None
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
KISSinsights template tags.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
KISSmetrics template tags.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Matomo template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from collections import namedtuple
|
||||
from itertools import chain
|
||||
import re
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Mixpanel template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Olark template tags.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Optimizely template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Performable template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Piwik template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from collections import namedtuple
|
||||
from itertools import chain
|
||||
import re
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Rating@Mail.ru template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
SnapEngage template tags.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Spring Metrics template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
UserVoice template tags.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Woopra template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Yandex.Metrica template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Dummy testing template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.templatetags.analytical import TAG_LOCATIONS
|
||||
|
|
@ -19,7 +17,7 @@ def _location_node(location):
|
|||
return DummyNode
|
||||
|
||||
|
||||
_location_nodes = dict((loc, _location_node(loc)) for loc in TAG_LOCATIONS)
|
||||
_location_nodes = {loc: _location_node(loc) for loc in TAG_LOCATIONS}
|
||||
|
||||
|
||||
def _location_tag(location):
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class AnalyticsTagTestCase(TagTestCase):
|
|||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(AnalyticsTagTestCase, self).setUp()
|
||||
super().setUp()
|
||||
self._tag_modules = analytical.TAG_MODULES
|
||||
analytical.TAG_MODULES = ['analytical.tests.dummy']
|
||||
analytical.template_nodes = analytical._load_template_nodes()
|
||||
|
|
@ -22,7 +22,7 @@ class AnalyticsTagTestCase(TagTestCase):
|
|||
def tearDown(self):
|
||||
analytical.TAG_MODULES = self._tag_modules
|
||||
analytical.template_nodes = analytical._load_template_nodes()
|
||||
super(AnalyticsTagTestCase, self).tearDown()
|
||||
super().tearDown()
|
||||
|
||||
def render_location_tag(self, location, vars=None):
|
||||
if vars is None:
|
||||
|
|
|
|||
|
|
@ -56,13 +56,13 @@ class FacebookPixelTagTestCase(TagTestCase):
|
|||
self.assertEqual(expected_body_html, html)
|
||||
|
||||
def test_tags_take_no_args(self):
|
||||
self.assertRaisesRegexp(
|
||||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'facebook_pixel_head' takes no arguments$",
|
||||
lambda: (Template('{% load facebook_pixel %}{% facebook_pixel_head "arg" %}')
|
||||
.render(Context({}))),
|
||||
)
|
||||
self.assertRaisesRegexp(
|
||||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'facebook_pixel_body' takes no arguments$",
|
||||
lambda: (Template('{% load facebook_pixel %}{% facebook_pixel_body "arg" %}')
|
||||
|
|
@ -72,15 +72,15 @@ class FacebookPixelTagTestCase(TagTestCase):
|
|||
@override_settings(FACEBOOK_PIXEL_ID=None)
|
||||
def test_no_id(self):
|
||||
expected_pattern = r'^FACEBOOK_PIXEL_ID setting is not set$'
|
||||
self.assertRaisesRegexp(AnalyticalException, expected_pattern, FacebookPixelHeadNode)
|
||||
self.assertRaisesRegexp(AnalyticalException, expected_pattern, FacebookPixelBodyNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelHeadNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelBodyNode)
|
||||
|
||||
@override_settings(FACEBOOK_PIXEL_ID='invalid')
|
||||
def test_invalid_id(self):
|
||||
expected_pattern = (
|
||||
r"^FACEBOOK_PIXEL_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
||||
self.assertRaisesRegexp(AnalyticalException, expected_pattern, FacebookPixelHeadNode)
|
||||
self.assertRaisesRegexp(AnalyticalException, expected_pattern, FacebookPixelBodyNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelHeadNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelBodyNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
def test_render_internal_ip(self):
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class HotjarTagTestCase(TagTestCase):
|
|||
self.assertEqual(expected_html, html)
|
||||
|
||||
def test_tags_take_no_args(self):
|
||||
self.assertRaisesRegexp(
|
||||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'hotjar' takes no arguments$",
|
||||
lambda: (Template('{% load hotjar %}{% hotjar "arg" %}')
|
||||
|
|
@ -49,13 +49,13 @@ class HotjarTagTestCase(TagTestCase):
|
|||
@override_settings(HOTJAR_SITE_ID=None)
|
||||
def test_no_id(self):
|
||||
expected_pattern = r'^HOTJAR_SITE_ID setting is not set$'
|
||||
self.assertRaisesRegexp(AnalyticalException, expected_pattern, HotjarNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, HotjarNode)
|
||||
|
||||
@override_settings(HOTJAR_SITE_ID='invalid')
|
||||
def test_invalid_id(self):
|
||||
expected_pattern = (
|
||||
r"^HOTJAR_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
||||
self.assertRaisesRegexp(AnalyticalException, expected_pattern, HotjarNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, HotjarNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
def test_render_internal_ip(self):
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from django.http import HttpRequest
|
|||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from analytical.templatetags.intercom import IntercomNode, intercom_user_hash, _timestamp
|
||||
from analytical.templatetags.intercom import IntercomNode, intercom_user_hash
|
||||
from analytical.tests.utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ class IntercomTagTestCase(TagTestCase):
|
|||
) # type: User
|
||||
attrs = IntercomNode()._get_custom_attrs(Context({'user': user}))
|
||||
self.assertEqual({
|
||||
'created_at': int(_timestamp(user.date_joined)),
|
||||
'created_at': int(user.date_joined.timestamp()),
|
||||
'email': 'test@example.com',
|
||||
'name': '',
|
||||
'user_hash': intercom_user_hash(str(user.pk)),
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class OlarkTestCase(TagTestCase):
|
|||
"introduction_messages",
|
||||
"introduction_submit_button_text",
|
||||
]
|
||||
vars = dict(('olark_%s' % m, m) for m in messages)
|
||||
vars = {'olark_%s' % m: m for m in messages}
|
||||
r = OlarkNode().render(Context(vars))
|
||||
for m in messages:
|
||||
self.assertTrue("olark.configure('locale.%s', \"%s\");" % (m, m) in r, r)
|
||||
|
|
|
|||
|
|
@ -27,17 +27,8 @@ class SettingDeletedTestCase(TestCase):
|
|||
Make sure using get_required_setting fails in the right place.
|
||||
"""
|
||||
|
||||
# available in python >= 3.2
|
||||
if hasattr(self, 'assertRaisesRegex'):
|
||||
with self.assertRaisesRegex(AnalyticalException, "^USER_ID setting is not set$"):
|
||||
get_required_setting("USER_ID", r"\d+", "invalid USER_ID")
|
||||
# available in python >= 2.7, deprecated in 3.2
|
||||
elif hasattr(self, 'assertRaisesRegexp'):
|
||||
with self.assertRaisesRegexp(AnalyticalException, "^USER_ID setting is not set$"):
|
||||
get_required_setting("USER_ID", r"\d+", "invalid USER_ID")
|
||||
else:
|
||||
self.assertRaises(AnalyticalException,
|
||||
get_required_setting, "USER_ID", r"\d+", "invalid USER_ID")
|
||||
with self.assertRaisesRegex(AnalyticalException, "^USER_ID setting is not set$"):
|
||||
get_required_setting("USER_ID", r"\d+", "invalid USER_ID")
|
||||
|
||||
|
||||
class MyUser(AbstractBaseUser):
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Testing utilities.
|
||||
"""
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
from django.template import Template, Context, RequestContext
|
||||
from django.test.testcases import TestCase
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing
|
||||
# directory.
|
||||
|
|
@ -14,8 +13,8 @@ import analytical # noqa
|
|||
|
||||
# -- General configuration --------------------------------------------------
|
||||
|
||||
project = u'django-analytical'
|
||||
copyright = u'2011-2016, Joost Cassee <joost@cassee.net>'
|
||||
project = 'django-analytical'
|
||||
copyright = '2011-2020, Joost Cassee <joost@cassee.net>'
|
||||
|
||||
release = analytical.__version__
|
||||
# The short X.Y version.
|
||||
|
|
@ -45,6 +44,6 @@ htmlhelp_basename = 'analyticaldoc'
|
|||
# -- Options for LaTeX output -----------------------------------------------
|
||||
|
||||
latex_documents = [
|
||||
('index', 'django-analytical.tex', u'Documentation for django-analytical',
|
||||
u'Joost Cassee', 'manual'),
|
||||
('index', 'django-analytical.tex', 'Documentation for django-analytical',
|
||||
'Joost Cassee', 'manual'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Django>=1.7.0
|
||||
Django>=2.2.*
|
||||
|
|
|
|||
7
setup.py
7
setup.py
|
|
@ -27,23 +27,20 @@ setup(
|
|||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Web Environment',
|
||||
'Framework :: Django',
|
||||
'Framework :: Django :: 1.11',
|
||||
'Framework :: Django :: 2.2',
|
||||
'Framework :: Django :: 3.0',
|
||||
'Framework :: Django :: 3.1',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
],
|
||||
platforms=['any'],
|
||||
url='https://github.com/jazzband/django-analytical',
|
||||
|
|
|
|||
10
tox.ini
10
tox.ini
|
|
@ -1,9 +1,7 @@
|
|||
[tox]
|
||||
envlist =
|
||||
# Python/Django combinations that are officially supported
|
||||
py{27,35,36,37}-django111
|
||||
py{35,36,37,38}-django22
|
||||
py{36,37,38}-django30
|
||||
py{36,37,38,39}-django{22,30,31}
|
||||
py37-{flake8,bandit,readme,docs}
|
||||
|
||||
[testenv]
|
||||
|
|
@ -11,20 +9,20 @@ description = Unit tests
|
|||
deps =
|
||||
coverage
|
||||
pytest-django
|
||||
django111: Django>=1.11,<2.0
|
||||
django22: Django>=2.2,<3.0
|
||||
django30: Django>=3.0,<3.1
|
||||
django31: Django>=3.1,<3.2
|
||||
|
||||
commands =
|
||||
coverage run -m pytest
|
||||
coverage xml
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
2.7: py27
|
||||
3.5: py35
|
||||
3.6: py36
|
||||
3.7: py37
|
||||
3.8: py38
|
||||
3.9: py39
|
||||
|
||||
[testenv:py37-bandit]
|
||||
description = PyCQA security linter
|
||||
|
|
|
|||
Loading…
Reference in a new issue