summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2015-02-17 01:05:04 -0600
committerMichael Merickel <michael@merickel.org>2015-02-17 01:05:04 -0600
commit780889f18d17b86fc12625166a245c7f9947cbe6 (patch)
treefcabc170710985e8e758530094518e9b7dfe6b12
parent6ea099ded65ff671c26753b9b30e4d19b3c47b81 (diff)
downloadpyramid-780889f18d17b86fc12625166a245c7f9947cbe6.tar.gz
pyramid-780889f18d17b86fc12625166a245c7f9947cbe6.tar.bz2
pyramid-780889f18d17b86fc12625166a245c7f9947cbe6.zip
remove the token from the ICacheBuster api
This exposes the QueryStringCacheBuster and PathSegmentCacheBuster public APIs alongside the md5-variants. These should be more cleanly subclassed by people wishing to extend their implementations.
-rw-r--r--docs/api/static.rst6
-rw-r--r--docs/narr/assets.rst15
-rw-r--r--pyramid/config/views.py4
-rw-r--r--pyramid/interfaces.py13
-rw-r--r--pyramid/static.py65
-rw-r--r--pyramid/tests/test_config/test_views.py12
-rw-r--r--pyramid/tests/test_static.py16
7 files changed, 82 insertions, 49 deletions
diff --git a/docs/api/static.rst b/docs/api/static.rst
index 543e526ad..b6b279139 100644
--- a/docs/api/static.rst
+++ b/docs/api/static.rst
@@ -9,6 +9,12 @@
:members:
:inherited-members:
+ .. autoclass:: PathSegmentCacheBuster
+ :members:
+
+ .. autoclass:: QueryStringCacheBuster
+ :members:
+
.. autoclass:: PathSegmentMd5CacheBuster
:members:
diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst
index fc908c2b4..d6bc8cbb8 100644
--- a/docs/narr/assets.rst
+++ b/docs/narr/assets.rst
@@ -446,19 +446,20 @@ In order to implement your own cache buster, you can write your own class from
scratch which implements the :class:`~pyramid.interfaces.ICacheBuster`
interface. Alternatively you may choose to subclass one of the existing
implementations. One of the most likely scenarios is you'd want to change the
-way the asset token is generated. To do this just subclass an existing
-implementation and replace the :meth:`~pyramid.interfaces.ICacheBuster.token`
-method. Here is an example which just uses Git to get the hash of the
-currently checked out code:
+way the asset token is generated. To do this just subclass either
+:class:`~pyramid.static.PathSegmentCacheBuster` or
+:class:`~pyramid.static.QueryStringCacheBuster` and define a
+``tokenize(pathspec)`` method. Here is an example which just uses Git to get
+the hash of the currently checked out code:
.. code-block:: python
:linenos:
import os
import subprocess
- from pyramid.static import PathSegmentMd5CacheBuster
+ from pyramid.static import PathSegmentCacheBuster
- class GitCacheBuster(PathSegmentMd5CacheBuster):
+ class GitCacheBuster(PathSegmentCacheBuster):
"""
Assuming your code is installed as a Git checkout, as opposed to as an
egg from an egg repository like PYPI, you can use this cachebuster to
@@ -470,7 +471,7 @@ currently checked out code:
['git', 'rev-parse', 'HEAD'],
cwd=here).strip()
- def token(self, pathspec):
+ def tokenize(self, pathspec):
return self.sha1
Choosing a Cache Buster
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 85e252f2f..24c592f7a 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -1980,9 +1980,9 @@ class StaticURLInfo(object):
cb = self._default_cachebust()
if cb:
def cachebust(subpath, kw):
- token = cb.token(spec + subpath)
subpath_tuple = tuple(subpath.split('/'))
- subpath_tuple, kw = cb.pregenerate(token, subpath_tuple, kw)
+ subpath_tuple, kw = cb.pregenerate(
+ spec + subpath, subpath_tuple, kw)
return '/'.join(subpath_tuple), kw
else:
cachebust = None
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index d7422bdde..1508f282e 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -1192,18 +1192,11 @@ class ICacheBuster(Interface):
.. versionadded:: 1.6
"""
- def token(pathspec):
- """
- Computes and returns a token string used for cache busting.
- ``pathspec`` is the path specification for the resource to be cache
- busted. """
-
- def pregenerate(token, subpath, kw):
+ def pregenerate(pathspec, subpath, kw):
"""
Modifies a subpath and/or keyword arguments from which a static asset
- URL will be computed during URL generation. The ``token`` argument is
- a token string computed by
- :meth:`~pyramid.interfaces.ICacheBuster.token` for a particular asset.
+ URL will be computed during URL generation. The ``pathspec`` argument
+ is the path specification for the resource to be cache busted.
The ``subpath`` argument is a tuple of path elements that represent the
portion of the asset URL which is used to find the asset. The ``kw``
argument is a dict of keywords that are to be passed eventually to
diff --git a/pyramid/static.py b/pyramid/static.py
index c4a9e3cc4..460639a89 100644
--- a/pyramid/static.py
+++ b/pyramid/static.py
@@ -174,7 +174,7 @@ class Md5AssetTokenGenerator(object):
def __init__(self):
self.token_cache = {}
- def token(self, pathspec):
+ def tokenize(self, pathspec):
# An astute observer will notice that this use of token_cache doesn't
# look particularly thread safe. Basic read/write operations on Python
# dicts, however, are atomic, so simply accessing and writing values
@@ -192,38 +192,55 @@ class Md5AssetTokenGenerator(object):
self.token_cache[pathspec] = token = _generate_md5(pathspec)
return token
-class PathSegmentMd5CacheBuster(Md5AssetTokenGenerator):
+class PathSegmentCacheBuster(object):
"""
An implementation of :class:`~pyramid.interfaces.ICacheBuster` which
- inserts an md5 checksum token for cache busting in the path portion of an
- asset URL. Generated md5 checksums are cached in order to speed up
- subsequent calls.
+ inserts a token for cache busting in the path portion of an asset URL.
+
+ To use this class, subclass it and provide a ``tokenize`` method which
+ accepts a ``pathspec`` and returns a token.
.. versionadded:: 1.6
"""
- def pregenerate(self, token, subpath, kw):
+ def pregenerate(self, pathspec, subpath, kw):
+ token = self.tokenize(pathspec)
return (token,) + subpath, kw
def match(self, subpath):
return subpath[1:]
-class QueryStringMd5CacheBuster(Md5AssetTokenGenerator):
+class PathSegmentMd5CacheBuster(PathSegmentCacheBuster,
+ Md5AssetTokenGenerator):
+ """
+ An implementation of :class:`~pyramid.interfaces.ICacheBuster` which
+ inserts an md5 checksum token for cache busting in the path portion of an
+ asset URL. Generated md5 checksums are cached in order to speed up
+ subsequent calls.
+
+ .. versionadded:: 1.6
+ """
+ def __init__(self):
+ PathSegmentCacheBuster.__init__(self)
+ Md5AssetTokenGenerator.__init__(self)
+
+class QueryStringCacheBuster(object):
"""
An implementation of :class:`~pyramid.interfaces.ICacheBuster` which adds
- an md5 checksum token for cache busting in the query string of an asset
- URL. Generated md5 checksums are cached in order to speed up subsequent
- calls.
+ a token for cache busting in the query string of an asset URL.
The optional ``param`` argument determines the name of the parameter added
to the query string and defaults to ``'x'``.
+ To use this class, subclass it and provide a ``tokenize`` method which
+ accepts a ``pathspec`` and returns a token.
+
.. versionadded:: 1.6
"""
def __init__(self, param='x'):
- super(QueryStringMd5CacheBuster, self).__init__()
self.param = param
- def pregenerate(self, token, subpath, kw):
+ def pregenerate(self, pathspec, subpath, kw):
+ token = self.tokenize(pathspec)
query = kw.setdefault('_query', {})
if isinstance(query, dict):
query[self.param] = token
@@ -231,7 +248,24 @@ class QueryStringMd5CacheBuster(Md5AssetTokenGenerator):
kw['_query'] = tuple(query) + ((self.param, token),)
return subpath, kw
-class QueryStringConstantCacheBuster(QueryStringMd5CacheBuster):
+class QueryStringMd5CacheBuster(QueryStringCacheBuster,
+ Md5AssetTokenGenerator):
+ """
+ An implementation of :class:`~pyramid.interfaces.ICacheBuster` which adds
+ an md5 checksum token for cache busting in the query string of an asset
+ URL. Generated md5 checksums are cached in order to speed up subsequent
+ calls.
+
+ The optional ``param`` argument determines the name of the parameter added
+ to the query string and defaults to ``'x'``.
+
+ .. versionadded:: 1.6
+ """
+ def __init__(self, param='x'):
+ QueryStringCacheBuster.__init__(self, param=param)
+ Md5AssetTokenGenerator.__init__(self)
+
+class QueryStringConstantCacheBuster(QueryStringCacheBuster):
"""
An implementation of :class:`~pyramid.interfaces.ICacheBuster` which adds
an arbitrary token for cache busting in the query string of an asset URL.
@@ -245,9 +279,8 @@ class QueryStringConstantCacheBuster(QueryStringMd5CacheBuster):
.. versionadded:: 1.6
"""
def __init__(self, token, param='x'):
+ QueryStringCacheBuster.__init__(self, param=param)
self._token = token
- self.param = param
- def token(self, pathspec):
+ def tokenize(self, pathspec):
return self._token
-
diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py
index d1eb1ed3c..36c86f78c 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -3995,7 +3995,7 @@ class TestStaticURLInfo(unittest.TestCase):
def test_add_cachebust_default(self):
config = self._makeConfig()
inst = self._makeOne()
- inst._default_cachebust = DummyCacheBuster
+ inst._default_cachebust = lambda: DummyCacheBuster('foo')
inst.add(config, 'view', 'mypackage:path', cachebust=True)
cachebust = config.registry._static_url_registrations[0][3]
subpath, kw = cachebust('some/path', {})
@@ -4014,7 +4014,7 @@ class TestStaticURLInfo(unittest.TestCase):
config = self._makeConfig()
inst = self._makeOne()
inst.add(config, 'view', 'mypackage:path',
- cachebust=DummyCacheBuster())
+ cachebust=DummyCacheBuster('foo'))
cachebust = config.registry._static_url_registrations[0][3]
subpath, kw = cachebust('some/path', {})
self.assertEqual(subpath, 'some/path')
@@ -4127,10 +4127,10 @@ class DummyMultiView:
""" """
class DummyCacheBuster(object):
- def token(self, pathspec):
- return 'foo'
- def pregenerate(self, token, subpath, kw):
- kw['x'] = token
+ def __init__(self, token):
+ self.token = token
+ def pregenerate(self, pathspec, subpath, kw):
+ kw['x'] = self.token
return subpath, kw
def parse_httpdate(s):
diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py
index 2f4de249e..a3df74b44 100644
--- a/pyramid/tests/test_static.py
+++ b/pyramid/tests/test_static.py
@@ -393,13 +393,13 @@ class TestMd5AssetTokenGenerator(unittest.TestCase):
return cls()
def test_package_resource(self):
- fut = self._makeOne().token
+ fut = self._makeOne().tokenize
expected = '76d653a3a044e2f4b38bb001d283e3d9'
token = fut('pyramid.tests:fixtures/static/index.html')
self.assertEqual(token, expected)
def test_filesystem_resource(self):
- fut = self._makeOne().token
+ fut = self._makeOne().tokenize
expected = 'd5155f250bef0e9923e894dbc713c5dd'
with open(self.fspath, 'w') as f:
f.write("Are we rich yet?")
@@ -407,7 +407,7 @@ class TestMd5AssetTokenGenerator(unittest.TestCase):
self.assertEqual(token, expected)
def test_cache(self):
- fut = self._makeOne().token
+ fut = self._makeOne().tokenize
expected = 'd5155f250bef0e9923e894dbc713c5dd'
with open(self.fspath, 'w') as f:
f.write("Are we rich yet?")
@@ -425,11 +425,11 @@ class TestPathSegmentMd5CacheBuster(unittest.TestCase):
def _makeOne(self):
from pyramid.static import PathSegmentMd5CacheBuster as cls
inst = cls()
- inst.token = lambda pathspec: 'foo'
+ inst.tokenize = lambda pathspec: 'foo'
return inst
def test_token(self):
- fut = self._makeOne().token
+ fut = self._makeOne().tokenize
self.assertEqual(fut('whatever'), 'foo')
def test_pregenerate(self):
@@ -448,11 +448,11 @@ class TestQueryStringMd5CacheBuster(unittest.TestCase):
inst = cls(param)
else:
inst = cls()
- inst.token = lambda pathspec: 'foo'
+ inst.tokenize = lambda pathspec: 'foo'
return inst
def test_token(self):
- fut = self._makeOne().token
+ fut = self._makeOne().tokenize
self.assertEqual(fut('whatever'), 'foo')
def test_pregenerate(self):
@@ -490,7 +490,7 @@ class TestQueryStringConstantCacheBuster(TestQueryStringMd5CacheBuster):
return inst
def test_token(self):
- fut = self._makeOne().token
+ fut = self._makeOne().tokenize
self.assertEqual(fut('whatever'), 'foo')
def test_pregenerate(self):