From ae4fc5a25ebefbe1c2a5f80f2bb45b55ee727065 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 11 Mar 2013 08:38:33 -0400 Subject: [PATCH] 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. --- pelican/contents.py | 4 ++-- pelican/generators.py | 2 +- pelican/tests/test_utils.py | 5 +++-- pelican/utils.py | 15 ++++++++++++--- pelican/writers.py | 12 +++++++----- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/pelican/contents.py b/pelican/contents.py index 05761be6..38300914 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -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()), diff --git a/pelican/generators.py b/pelican/generators.py index 97315a26..43127099 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -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={ diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index ae2e0a13..78c90aeb 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -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: diff --git a/pelican/utils.py b/pelican/utils.py index a0473ecb..417e5b15 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -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='...'): diff --git a/pelican/writers.py b/pelican/writers.py index 8e611556..ea93dae6 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -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)