summaryrefslogtreecommitdiff
path: root/repoze
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-07-29 01:54:50 +0000
committerChris McDonough <chrism@agendaless.com>2008-07-29 01:54:50 +0000
commit35ff8e696a2c983cee119c936ea12ecb2f7da2c3 (patch)
tree2c4873cac17bc122ed0011574c0551f7370b5927 /repoze
parent339c73892ba00d640ac7a22dccbd56e360cfea0d (diff)
downloadpyramid-35ff8e696a2c983cee119c936ea12ecb2f7da2c3.tar.gz
pyramid-35ff8e696a2c983cee119c936ea12ecb2f7da2c3.tar.bz2
pyramid-35ff8e696a2c983cee119c936ea12ecb2f7da2c3.zip
0.2.5: add model_url.
Diffstat (limited to 'repoze')
-rw-r--r--repoze/bfg/tests/test_traversal.py31
-rw-r--r--repoze/bfg/traversal.py23
2 files changed, 49 insertions, 5 deletions
diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py
index 5cc7551c0..1ae92dcf7 100644
--- a/repoze/bfg/tests/test_traversal.py
+++ b/repoze/bfg/tests/test_traversal.py
@@ -169,6 +169,33 @@ class FindInterfaceTests(unittest.TestCase):
result = finder(baz, IFoo)
self.assertEqual(result.__name__, 'root')
+class ModelURLTests(unittest.TestCase):
+ def _getFUT(self):
+ from repoze.bfg.traversal import model_url
+ return model_url
+
+ def test_it(self):
+ baz = DummyContext()
+ bar = DummyContext(baz)
+ foo = DummyContext(bar)
+ root = DummyContext(foo)
+ root.__parent__ = None
+ root.__name__ = None
+ foo.__parent__ = root
+ foo.__name__ = 'foo '
+ bar.__parent__ = foo
+ bar.__name__ = 'bar'
+ baz.__parent__ = bar
+ baz.__name__ = 'baz'
+ request = DummyRequest()
+ model_url = self._getFUT()
+ request = DummyRequest()
+ result = model_url(baz, request, 'this/theotherthing', 'that')
+
+ self.assertEqual(
+ result,
+ 'http://example.com:5432/foo%20/bar/baz/this/theotherthing/that')
+
class DummyContext(object):
def __init__(self, next=None):
self.next = next
@@ -179,8 +206,8 @@ class DummyContext(object):
return self.next
class DummyRequest:
- pass
-
+ application_url = 'http://example.com:5432/'
+
class DummyTraverser:
def __init__(self, context):
self.context = context
diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py
index d0e140375..c72c90e5e 100644
--- a/repoze/bfg/traversal.py
+++ b/repoze/bfg/traversal.py
@@ -1,4 +1,5 @@
import urllib
+import urlparse
from zope.interface import classProvides
from zope.interface import implements
@@ -66,9 +67,25 @@ class ModelGraphTraverser(object):
return ob, name, path
def find_interface(context, interface):
- """ Return an object providing 'interface' anywhere in the parent
- chain of 'context' or None if no object providing that interface
- can be found in the parent chain """
+ """ Return an object providing ``interface`` anywhere in the
+ parent chain of ``context`` or ``None`` if no object providing
+ that interface can be found in the parent chain"""
for location in LocationIterator(context):
if interface.providedBy(location):
return location
+
+def model_url(model, request, *elements):
+ """ Return the absolute URL of the model object based on the
+ ``wsgi.url_scheme``, ``HTTP_HOST`` or ``SERVER_NAME`` in the
+ request, plus any ``SCRIPT_NAME``. Any positional passed in as
+ ``elements`` will be joined by slashes and appended to the
+ generated URL. The passed in elements are *not* URL-quoted. The
+ ``model`` passed in must be :term:`location`-aware."""
+ rpath = []
+ for location in LocationIterator(model):
+ if location.__name__:
+ rpath.append(urllib.quote(location.__name__))
+ path = list(reversed(rpath))
+ path.extend(elements)
+ path = '/'.join(path)
+ return urlparse.urljoin(request.application_url, path)