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

View file

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

View file

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

View file

@ -304,11 +304,20 @@ def clean_output_dir(path):
def get_relative_path(path): def get_relative_path(path):
"""Return the relative path from the given path to the root path.""" """Return the relative path from the given path to the root path."""
nslashes = path.count('/') components = split_all(path)
if nslashes == 0: if len(components) <= 1:
return os.curdir return os.curdir
else: 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='...'): def truncate_html_words(s, num, end_text='...'):

View file

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