Repository: getpelican/pelican

Issue:
"Mixed content in the same directory" broken on Windows
When a folder is both in `STATIC_PATHS` and `ARTICLE_PATHS` only non-source files are supposed to be copied raw. This does not seem to work on Windows, where articles are both parsed and copied.

The problem might be in _generators.py_ with `add_source_path()`, which unlike `_is_potential_source_path()` does not perform a `os.path.normpath()` on the path, leading to slash/backslash mismatches. While adding it in fixes the problem, that breaks `{filename}` (and similar) links due to them not using `os.path.normpath()` either.

I'm using the latest master.

I'd appreciate if someone could verify this, I'm only just starting to use pelican and noticed this in the middle of developing a plugin (which I did disable to check I wasn't causing it, but still...) so this may not be the cleanest of test cases.



Discussion:
I just noticed that this means that the context["filenames"] entry gets overwritten, causing {filename} links to point to the mistakenly copied source file and not the generated one.

Avaris in IRC suggested these changes, which seem to work.

``` diff
diff --git a/pelican/generators.py b/pelican/generators.py
index 75bd6b2..0ce6439 100644
--- a/pelican/generators.py
+++ b/pelican/generators.py
@@ -22,7 +22,8 @@ from jinja2 import (Environment, FileSystemLoader, PrefixLoader, ChoiceLoader,
 from pelican.contents import Article, Draft, Page, Static, is_valid_content
 from pelican.readers import Readers
 from pelican.utils import (copy, process_translations, mkdir_p, DateFormatter,
-                           FileStampDataCacher, python_2_unicode_compatible)
+                           FileStampDataCacher, python_2_unicode_compatible,
+                           posixize_path)
 from pelican import signals


@@ -160,7 +161,7 @@ class Generator(object):
         (For example, one that was missing mandatory metadata.)
         The path argument is expected to be relative to self.path.
         """
-        self.context['filenames'][os.path.normpath(path)] = None
+        self.context['filenames'][posixize_path(os.path.normpath(path))] = None

     def _is_potential_source_path(self, path):
         """Return True if path was supposed to be used as a source file.
@@ -168,7 +169,7 @@ class Generator(object):
         before this method is called, even if they failed to process.)
         The path argument is expected to be relative to self.path.
         """
-        return os.path.normpath(path) in self.context['filenames']
+        return posixize_path(os.path.normpath(path)) in self.context['filenames']

     def _update_context(self, items):
         """Update the context with the given items from the currrent
```


Resolving patch:
diff --git a/pelican/generators.py b/pelican/generators.py
--- a/pelican/generators.py
+++ b/pelican/generators.py
@@ -22,7 +22,8 @@
 from pelican.contents import Article, Draft, Page, Static, is_valid_content
 from pelican.readers import Readers
 from pelican.utils import (copy, process_translations, mkdir_p, DateFormatter,
-                           FileStampDataCacher, python_2_unicode_compatible)
+                           FileStampDataCacher, python_2_unicode_compatible,
+                           posixize_path)
 from pelican import signals
 
 
@@ -160,7 +161,7 @@ def _add_failed_source_path(self, path):
         (For example, one that was missing mandatory metadata.)
         The path argument is expected to be relative to self.path.
         """
-        self.context['filenames'][os.path.normpath(path)] = None
+        self.context['filenames'][posixize_path(os.path.normpath(path))] = None
 
     def _is_potential_source_path(self, path):
         """Return True if path was supposed to be used as a source file.
@@ -168,7 +169,7 @@ def _is_potential_source_path(self, path):
         before this method is called, even if they failed to process.)
         The path argument is expected to be relative to self.path.
         """
-        return os.path.normpath(path) in self.context['filenames']
+        return posixize_path(os.path.normpath(path)) in self.context['filenames']
 
     def _update_context(self, items):
         """Update the context with the given items from the currrent


Test patch: