From 6852356014471e1e4aece792c1cd9248a105a483 Mon Sep 17 00:00:00 2001 From: fri Date: Fri, 3 Oct 2014 14:16:00 +0200 Subject: [PATCH 1/4] Fix using {filename} on Windows --- pelican/contents.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pelican/contents.py b/pelican/contents.py index 2e17b56f..0249351c 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -221,11 +221,11 @@ class Content(object): # XXX Put this in a different location. if what == 'filename': if path.startswith('/'): - path = path[1:] + path = os.path.join(*path[1:].split('/')) else: # relative to the source path of this content path = self.get_relative_source_path( - os.path.join(self.relative_dir, path) + os.path.join(self.relative_dir, os.path.join(*path.split('/'))) ) if path not in self._context['filenames']: From 0d6daf0509a98676b184eedeee9947b4acb27805 Mon Sep 17 00:00:00 2001 From: fri Date: Fri, 2 Jan 2015 13:51:25 +0100 Subject: [PATCH 2/4] Allow using both the '\\' and the '/' as valid path separators for {filename} links --- pelican/contents.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pelican/contents.py b/pelican/contents.py index 1e31a57b..a495327f 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -90,7 +90,7 @@ class Content(object): self.in_default_lang = (self.lang == default_lang) - # create the slug if not existing, generate slug according to + # create the slug if not existing, generate slug according to # setting of SLUG_ATTRIBUTE if not hasattr(self, 'slug'): if settings['SLUGIFY_SOURCE'] == 'title' and hasattr(self, 'title'): @@ -225,12 +225,18 @@ class Content(object): # XXX Put this in a different location. if what in {'filename', 'attach'}: - if path.startswith('/'): - path = os.path.join(*path[1:].split('/')) + # On Windows the path separator (os.sep) is '\\', whereas on other platforms the path # separator is '/'. + # Source files can have either character as the path separator on {filename} links. + # In order to make everything work in a platform-independent way, let's accept both characters + # as valid path separators for {filename} links, and rebuild the correct path internally by + # using os.path.join, so that the resulting path will have the correct separator for this platform. + if re.match(path, r'[\\/]'): + # Path begins with the separator character, so it is relative to the root of the website + path = os.path.join(*re.split(r'[\\/]', path[1:])) else: # relative to the source path of this content path = self.get_relative_source_path( - os.path.join(self.relative_dir, os.path.join(*path.split('/'))) + os.path.join(self.relative_dir, os.path.join(*re.split(r'[\\/]', path))) ) if path not in self._context['filenames']: From 1cfe61184975f486fe7e48c0c02c3aee33ae9111 Mon Sep 17 00:00:00 2001 From: fri Date: Sat, 3 Jan 2015 08:17:26 +0100 Subject: [PATCH 3/4] Fix inverted parameters in regex match --- pelican/contents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pelican/contents.py b/pelican/contents.py index a495327f..b885091e 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -230,7 +230,7 @@ class Content(object): # In order to make everything work in a platform-independent way, let's accept both characters # as valid path separators for {filename} links, and rebuild the correct path internally by # using os.path.join, so that the resulting path will have the correct separator for this platform. - if re.match(path, r'[\\/]'): + if re.match(r'[\\/]', path): # Path begins with the separator character, so it is relative to the root of the website path = os.path.join(*re.split(r'[\\/]', path[1:])) else: From 3ee823173c1f8b115bcc43a1d6d77b96cf5e86b7 Mon Sep 17 00:00:00 2001 From: fri Date: Sat, 3 Jan 2015 13:36:58 +0100 Subject: [PATCH 4/4] Precompile the path separator regex in order to improve performance, readability and amintainability --- pelican/contents.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pelican/contents.py b/pelican/contents.py index b885091e..77c87970 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -23,6 +23,7 @@ from pelican.utils import (slugify, truncate_html_words, memoized, strftime, from pelican.urlwrappers import (URLWrapper, Author, Category, Tag) # NOQA logger = logging.getLogger(__name__) +path_sep_regexp = re.compile(r'[\\/]') class Content(object): @@ -230,13 +231,13 @@ class Content(object): # In order to make everything work in a platform-independent way, let's accept both characters # as valid path separators for {filename} links, and rebuild the correct path internally by # using os.path.join, so that the resulting path will have the correct separator for this platform. - if re.match(r'[\\/]', path): + if path_sep_regexp.match(path): # Path begins with the separator character, so it is relative to the root of the website - path = os.path.join(*re.split(r'[\\/]', path[1:])) + path = os.path.join(*path_sep_regexp.split(path[1:])) else: # relative to the source path of this content path = self.get_relative_source_path( - os.path.join(self.relative_dir, os.path.join(*re.split(r'[\\/]', path))) + os.path.join(self.relative_dir, os.path.join(*path_sep_regexp.split(path))) ) if path not in self._context['filenames']: