utils: Add path_to_url() and generalize get_relative_path()

The old get_relative_path() implementation assumed os.sep == '/',
which doesn't hold on MS Windows.  The new implementation uses
split_all() for a more general component count.

I added path_to_url(), because the:

  '/'.join(split_all(path))

idiom was showing up in a number of cases, and it's easier to
understand what's going on when that reads:

  path_to_url(path)

This will fix a number of places where I think paths and URLs were
conflated, and should improve MS Windows support.
This commit is contained in:
W. Trevor King 2013-03-11 08:38:33 -04:00
commit ae4fc5a25e
5 changed files with 25 additions and 13 deletions

View file

@ -17,7 +17,7 @@ from pelican import signals
from pelican.settings import _DEFAULT_CONFIG
from pelican.utils import (slugify, truncate_html_words, memoized, strftime,
python_2_unicode_compatible, deprecated_attribute,
split_all)
path_to_url)
# Import these so that they're avalaible when you import from pelican.contents.
from pelican.urlwrappers import (URLWrapper, Author, Category, Tag) # NOQA
@ -139,7 +139,7 @@ class Content(object):
metadata = copy.copy(self.metadata)
path = self.metadata.get('path', self.get_relative_source_path())
metadata.update({
'path': '/'.join(split_all(path)),
'path': path_to_url(path),
'slug': getattr(self, 'slug', ''),
'lang': getattr(self, 'lang', 'en'),
'date': getattr(self, 'date', datetime.now()),

View file

@ -565,7 +565,7 @@ class StaticGenerator(Generator):
f_rel = os.path.relpath(f, self.path)
# TODO remove this hardcoded 'static' subdirectory
dest = os.path.join('static', f_rel)
url = '/'.join(pelican.utils.split_all(dest))
url = pelican.utils.path_to_url(dest)
sc = Static(
content=None,
metadata={

View file

@ -71,8 +71,9 @@ class TestUtils(LoggedTestCase):
def test_get_relative_path(self):
samples = (('test/test.html', os.pardir),
('test/test/test.html', os.path.join(os.pardir, os.pardir)),
samples = ((os.path.join('test', 'test.html'), os.pardir),
(os.path.join('test', 'test', 'test.html'),
os.path.join(os.pardir, os.pardir)),
('test.html', os.curdir))
for value, expected in samples:

View file

@ -304,11 +304,20 @@ def clean_output_dir(path):
def get_relative_path(path):
"""Return the relative path from the given path to the root path."""
nslashes = path.count('/')
if nslashes == 0:
components = split_all(path)
if len(components) <= 1:
return os.curdir
else:
return '/'.join([os.pardir] * nslashes)
parents = [os.pardir] * (len(components) - 1)
return os.path.join(*parents)
def path_to_url(path):
"""Return the URL corresponding to a given path."""
if os.sep == '/':
return path
else:
'/'.join(split_all(path))
def truncate_html_words(s, num, end_text='...'):

View file

@ -10,7 +10,7 @@ from codecs import open
from feedgenerator import Atom1Feed, Rss201rev2Feed
from jinja2 import Markup
from pelican.paginator import Paginator
from pelican.utils import get_relative_path, set_date_tzinfo
from pelican.utils import get_relative_path, path_to_url, set_date_tzinfo
logger = logging.getLogger(__name__)
@ -60,7 +60,9 @@ class Writer(object):
old_locale = locale.setlocale(locale.LC_ALL)
locale.setlocale(locale.LC_ALL, str('C'))
try:
self.site_url = context.get('SITEURL', get_relative_path(path))
self.site_url = context.get(
'SITEURL', path_to_url(get_relative_path(path)))
self.feed_domain = context.get('FEED_DOMAIN')
self.feed_url = '{}/{}'.format(self.feed_domain, path)
@ -125,9 +127,9 @@ class Writer(object):
localcontext = context.copy()
if relative_urls:
relative_path = get_relative_path(name)
context['localsiteurl'] = relative_path
localcontext['SITEURL'] = relative_path
relative_url = path_to_url(get_relative_path(name))
context['localsiteurl'] = relative_url
localcontext['SITEURL'] = relative_url
localcontext['output_file'] = name
localcontext.update(kwargs)