Browse Source

Ensure external urls are encoded properly. (Issue #158).

-   BREAKING:  While this change will correct the weird encoding
    behavior, this also changes the way `xxx_url` macros work.
-   Do not encode the url bases (`base_url`, `media_url`). Only
    the path component needs to be encoded.
main
Lakshmi Vyasarajan 11 years ago
parent
commit
2480012b3d
6 changed files with 53 additions and 32 deletions
  1. +13
    -3
      CHANGELOG.rst
  2. +1
    -1
      README.rst
  3. +19
    -21
      hyde/site.py
  4. +3
    -2
      hyde/tests/ext/test_textlinks.py
  5. +16
    -4
      hyde/tests/test_site.py
  6. +1
    -1
      hyde/version.py

+ 13
- 3
CHANGELOG.rst View File

@@ -1,11 +1,21 @@
Version 0.8.7a9
============================================================

* Ensure external urls are encoded properly. (Issue #158).

- BREAKING: While this change will correct the weird encoding
behavior, this also changes the way `xxx_url` macros work.
- Do not encode the url bases (`base_url`, `media_url`). Only
the path component needs to be encoded.

Version 0.8.7a8
============================================================

* Fix subfolders for root paths on windows. (Issue #167).

- Using subfolders for `layout_root`, `content_root`,
`media_root` and `deploy_root` now works reliably
on windows.
- Ensure that subfolders for `layout_root`, `content_root`,
`media_root` and `deploy_root` works reliably
on windows. Use `fully_expanded_path` for all path components.


Version 0.8.7a7


+ 1
- 1
README.rst View File

@@ -1,4 +1,4 @@
Version 0.8.7a8
Version 0.8.7a9

A brand new **hyde**
====================


+ 19
- 21
hyde/site.py View File

@@ -383,6 +383,13 @@ class RootNode(Node):
if dont_ignore(afile.name):
self.add_resource(afile)


def _encode_path(base, path, safe):
base = base.strip().replace(os.sep, '/').encode('utf-8')
path = path.strip().replace(os.sep, '/').encode('utf-8')
path = quote(path, safe) if safe is not None else quote(path)
return base.rstrip('/') + '/' + path.lstrip('/')

class Site(object):
"""
Represents the site to be generated.
@@ -425,35 +432,28 @@ class Site(object):
"""
self.content.load()

def _safe_chars(self, safe=None):
if safe is not None:
return safe
elif self.config.encode_safe is not None:
return self.config.encode_safe
else:
return None

def content_url(self, path, safe=None):
"""
Returns the content url by appending the base url from the config
with the given path. The return value is url encoded.
"""
fpath = Folder(self.config.base_url) \
.child(path) \
.replace(os.sep, '/').encode("utf-8")
if safe is not None:
return quote(fpath, safe)
elif self.config.encode_safe is not None:
return quote(fpath, self.config.encode_safe)
else:
return quote(fpath)
return _encode_path(self.config.base_url, path, self._safe_chars(safe))


def media_url(self, path, safe=None):
"""
Returns the media url by appending the media base url from the config
with the given path. The return value is url encoded.
"""
fpath = Folder(self.config.media_url) \
.child(path) \
.replace(os.sep, '/').encode("utf-8")
if safe is not None:
return quote(fpath, safe)
elif self.config.encode_safe is not None:
return quote(fpath, self.config.encode_safe)
else:
return quote(fpath)
return _encode_path(self.config.media_url, path, self._safe_chars(safe))

def full_url(self, path, safe=None):
"""
@@ -461,11 +461,9 @@ class Site(object):
configuration and returns the appropriate url. The return value
is url encoded.
"""
if safe is None and self.config.encode_safe is not None:
safe = self.config.encode_safe
if urlparse.urlparse(path)[:2] != ("",""):
return path

if self.is_media(path):
relative_path = File(path).get_relative_path(
Folder(self.config.media_root))


+ 3
- 2
hyde/tests/ext/test_textlinks.py View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Use nose
`$ pip install nose`
@@ -49,6 +48,7 @@ class TestTextlinks(object):
site.config.media_url = '/media'
tlink = File(site.content.source_folder.child('tlink.html'))
tlink.write(text % d)
print tlink.read_all()
gen = Generator(site)
gen.generate_all()
f = File(site.config.deploy_root_path.child(tlink.name))
@@ -56,5 +56,6 @@ class TestTextlinks(object):
html = f.read_all()
assert html
for name, path in d.items():
assert quote(site.config.base_url + path) in html

assert site.config.base_url + quote(path) in html
assert '/media/img/hyde-logo.png' in html

+ 16
- 4
hyde/tests/test_site.py View File

@@ -60,9 +60,19 @@ def test_node_full_url():
r = RootNode(TEST_SITE_ROOT.child_folder('content'), s)
assert not r.module
n = r.add_node(TEST_SITE_ROOT.child_folder('content/blog'))
assert n.full_url == quote('http://localhost/blog')
assert n.full_url == 'http://localhost/blog'
c = r.add_node(TEST_SITE_ROOT.child_folder('content/blog/2010/december'))
assert c.full_url == quote('http://localhost/blog/2010/december')
assert c.full_url == 'http://localhost/blog/2010/december'

def test_node_full_url_quoted():
s = Site(TEST_SITE_ROOT)
s.config.base_url = 'http://localhost'
r = RootNode(TEST_SITE_ROOT.child_folder('content'), s)
assert not r.module
n = r.add_node(TEST_SITE_ROOT.child_folder('content/blo~g'))
assert n.full_url == 'http://localhost/' + quote('blo~g')
c = r.add_node(TEST_SITE_ROOT.child_folder('content/blo~g/2010/december'))
assert c.full_url == 'http://localhost/' + quote('blo~g/2010/december')

def test_node_relative_path():
s = Site(TEST_SITE_ROOT)
@@ -200,13 +210,15 @@ class TestSiteWithConfig(object):
s = Site(self.SITE_PATH, config=self.config)
s.load()
path = '".jpg'
assert s.content_url(path) == quote("/" + path)
assert s.content_url(path) == "/" + quote(path)

def test_content_url_encoding_safe(self):
s = Site(self.SITE_PATH, config=self.config)
s.load()
path = '".jpg/abc'
assert s.content_url(path, "") == quote("/" + path, "")
print s.content_url(path, "")
print "/" + quote(path, "")
assert s.content_url(path, "") == "/" + quote(path, "")

def test_media_url(self):
s = Site(self.SITE_PATH, config=self.config)


+ 1
- 1
hyde/version.py View File

@@ -2,4 +2,4 @@
"""
Handles hyde version.
"""
__version__ = '0.8.7a8'
__version__ = '0.8.7a9'

Loading…
Cancel
Save