diff --git a/docs/conf.py b/docs/conf.py index 6c8ececa..40de84c7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import sys, os -sys.path.append(os.path.abspath('..')) +sys.path.append(os.path.abspath(os.pardir)) from pelican import __version__, __major__ diff --git a/pelican/__init__.py b/pelican/__init__.py index 0e3db788..2c67c5f3 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -52,7 +52,7 @@ class Pelican(object): signals.initialized.send(self) def init_path(self): - if not any(p in sys.path for p in ['', '.']): + if not any(p in sys.path for p in ['', os.curdir]): logger.debug("Adding current directory to system path") sys.path.insert(0, '') 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 d4b2e231..43127099 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -347,7 +347,7 @@ class ArticlesGenerator(Generator): def generate_drafts(self, write): """Generate drafts pages.""" for article in self.drafts: - write('drafts/%s.html' % article.slug, + write(os.path.join('drafts', '%s.html' % article.slug), self.get_template(article.template), self.context, article=article, category=article.category, all_articles=self.articles) @@ -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={ @@ -588,7 +588,7 @@ class StaticGenerator(Generator): def generate_output(self, writer): self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme, - 'theme', self.output_path, '.') + 'theme', self.output_path, os.curdir) # copy all Static files for sc in self.staticfiles: source_path = os.path.join(self.path, sc.source_path) diff --git a/pelican/settings.py b/pelican/settings.py index d8981a0f..25685d72 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -15,21 +15,22 @@ from os.path import isabs logger = logging.getLogger(__name__) -DEFAULT_THEME = os.sep.join([os.path.dirname(os.path.abspath(__file__)), - "themes/notmyidea"]) -_DEFAULT_CONFIG = {'PATH': '.', +DEFAULT_THEME = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'themes', 'notmyidea') +_DEFAULT_CONFIG = {'PATH': os.curdir, 'ARTICLE_DIR': '', 'ARTICLE_EXCLUDES': ('pages',), 'PAGE_DIR': 'pages', 'PAGE_EXCLUDES': (), 'THEME': DEFAULT_THEME, - 'OUTPUT_PATH': 'output/', + 'OUTPUT_PATH': 'output', 'MARKUP': ('rst', 'md'), 'STATIC_PATHS': ['images', ], 'THEME_STATIC_PATHS': ['static', ], - 'FEED_ALL_ATOM': 'feeds/all.atom.xml', - 'CATEGORY_FEED_ATOM': 'feeds/%s.atom.xml', - 'TRANSLATION_FEED_ATOM': 'feeds/all-%s.atom.xml', + 'FEED_ALL_ATOM': os.path.join('feeds', 'all.atom.xml'), + 'CATEGORY_FEED_ATOM': os.path.join('feeds', '%s.atom.xml'), + 'TRANSLATION_FEED_ATOM': os.path.join( + 'feeds', 'all-%s.atom.xml'), 'FEED_MAX_ITEMS': '', 'SITEURL': '', 'SITENAME': 'A Pelican Blog', @@ -49,17 +50,18 @@ _DEFAULT_CONFIG = {'PATH': '.', 'ARTICLE_LANG_URL': '{slug}-{lang}.html', 'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html', 'PAGE_URL': 'pages/{slug}.html', - 'PAGE_SAVE_AS': 'pages/{slug}.html', + 'PAGE_SAVE_AS': os.path.join('pages', '{slug}.html'), 'PAGE_LANG_URL': 'pages/{slug}-{lang}.html', - 'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html', + 'PAGE_LANG_SAVE_AS': os.path.join( + 'pages', '{slug}-{lang}.html'), 'STATIC_URL': '{path}', 'STATIC_SAVE_AS': '{path}', 'CATEGORY_URL': 'category/{slug}.html', - 'CATEGORY_SAVE_AS': 'category/{slug}.html', + 'CATEGORY_SAVE_AS': os.path.join('category', '{slug}.html'), 'TAG_URL': 'tag/{slug}.html', - 'TAG_SAVE_AS': 'tag/{slug}.html', + 'TAG_SAVE_AS': os.path.join('tag', '{slug}.html'), 'AUTHOR_URL': 'author/{slug}.html', - 'AUTHOR_SAVE_AS': 'author/{slug}.html', + 'AUTHOR_SAVE_AS': os.path.join('author', '{slug}.html'), 'YEAR_ARCHIVE_SAVE_AS': False, 'MONTH_ARCHIVE_SAVE_AS': False, 'DAY_ARCHIVE_SAVE_AS': False, @@ -125,7 +127,7 @@ def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG): def get_settings_from_file(path, default_settings=_DEFAULT_CONFIG): """Loads settings from a file path, returning a dict.""" - name = os.path.basename(path).rpartition('.')[0] + name, ext = os.path.splitext(os.path.basename(path)) module = imp.load_source(name, path) return get_settings_from_module(module, default_settings=default_settings) @@ -141,8 +143,10 @@ def configure_settings(settings): # lookup the theme in "pelican/themes" if the given one doesn't exist if not os.path.isdir(settings['THEME']): - theme_path = os.sep.join([os.path.dirname( - os.path.abspath(__file__)), "themes/%s" % settings['THEME']]) + theme_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'themes', + settings['THEME']) if os.path.exists(theme_path): settings['THEME'] = theme_path else: diff --git a/pelican/tests/test_pelican.py b/pelican/tests/test_pelican.py index 04fd7d2b..c8f1daf5 100644 --- a/pelican/tests/test_pelican.py +++ b/pelican/tests/test_pelican.py @@ -13,9 +13,9 @@ from pelican.settings import read_settings from pelican.tests.support import LoggedTestCase CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) -SAMPLES_PATH = os.path.abspath(os.sep.join((CURRENT_DIR, "..", "..", - "samples"))) -OUTPUT_PATH = os.path.abspath(os.sep.join((CURRENT_DIR, "output"))) +SAMPLES_PATH = os.path.abspath(os.path.join( + CURRENT_DIR, os.pardir, os.pardir, 'samples')) +OUTPUT_PATH = os.path.abspath(os.path.join(CURRENT_DIR, 'output')) INPUT_PATH = os.path.join(SAMPLES_PATH, "content") SAMPLE_CONFIG = os.path.join(SAMPLES_PATH, "pelican.conf.py") @@ -23,11 +23,11 @@ SAMPLE_CONFIG = os.path.join(SAMPLES_PATH, "pelican.conf.py") def recursiveDiff(dcmp): diff = { - 'diff_files': [os.sep.join((dcmp.right, f)) + 'diff_files': [os.path.join(dcmp.right, f) for f in dcmp.diff_files], - 'left_only': [os.sep.join((dcmp.right, f)) + 'left_only': [os.path.join(dcmp.right, f) for f in dcmp.left_only], - 'right_only': [os.sep.join((dcmp.right, f)) + 'right_only': [os.path.join(dcmp.right, f) for f in dcmp.right_only], } for sub_dcmp in dcmp.subdirs.values(): @@ -74,7 +74,7 @@ class TestPelican(LoggedTestCase): }) pelican = Pelican(settings=settings) pelican.run() - dcmp = dircmp(self.temp_path, os.sep.join((OUTPUT_PATH, "basic"))) + dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'basic')) self.assertFilesEqual(recursiveDiff(dcmp)) self.assertLogCountEqual( count=10, @@ -90,5 +90,5 @@ class TestPelican(LoggedTestCase): }) pelican = Pelican(settings=settings) pelican.run() - dcmp = dircmp(self.temp_path, os.sep.join((OUTPUT_PATH, "custom"))) + dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'custom')) self.assertFilesEqual(recursiveDiff(dcmp)) diff --git a/pelican/tests/test_settings.py b/pelican/tests/test_settings.py index d9bca2e5..5f1f4ede 100644 --- a/pelican/tests/test_settings.py +++ b/pelican/tests/test_settings.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import copy +import os from os.path import dirname, abspath, join from pelican.settings import (read_settings, configure_settings, @@ -62,7 +63,7 @@ class TestSettingsConfiguration(unittest.TestCase): settings = { 'SITEURL': 'http://blog.notmyidea.org/', 'LOCALE': '', - 'PATH': '.', + 'PATH': os.curdir, 'THEME': DEFAULT_THEME, } configure_settings(settings) diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index ab9ae226..78c90aeb 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -71,9 +71,10 @@ class TestUtils(LoggedTestCase): def test_get_relative_path(self): - samples = (('test/test.html', '..'), - ('test/test/test.html', '../..'), - ('test.html', '.')) + 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: self.assertEquals(utils.get_relative_path(value), expected) diff --git a/pelican/tools/pelican_quickstart.py b/pelican/tools/pelican_quickstart.py index 6d4264d3..02aa62d3 100755 --- a/pelican/tools/pelican_quickstart.py +++ b/pelican/tools/pelican_quickstart.py @@ -18,7 +18,7 @@ _TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), CONF = { 'pelican': 'pelican', 'pelicanopts': '', - 'basedir': '.', + 'basedir': os.curdir, 'ftp_host': 'localhost', 'ftp_user': 'anonymous', 'ftp_target_dir': '/', @@ -146,7 +146,7 @@ def main(): parser = argparse.ArgumentParser( description="A kickstarter for Pelican", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument('-p', '--path', default=".", + parser.add_argument('-p', '--path', default=os.curdir, help="The path to generate the blog into") parser.add_argument('-t', '--title', metavar="title", help='Set the title of the website') @@ -166,7 +166,8 @@ needed by Pelican. '''.format(v=__version__)) - project = os.path.join(os.environ.get('VIRTUAL_ENV', '.'), '.project') + project = os.path.join( + os.environ.get('VIRTUAL_ENV', os.curdir), '.project') if os.path.isfile(project): CONF['basedir'] = open(project, 'r').read().rstrip("\n") print('Using project associated with current virtual environment.' diff --git a/pelican/tools/templates/publishconf.py.in b/pelican/tools/templates/publishconf.py.in old mode 100644 new mode 100755 index 7115a6a1..8fd2a4f7 --- a/pelican/tools/templates/publishconf.py.in +++ b/pelican/tools/templates/publishconf.py.in @@ -4,8 +4,9 @@ # This file is only used if you use `make publish` or # explicitly specify it as your config file. +import os import sys -sys.path.append('.') +sys.path.append(os.curdir) from pelicanconf import * SITEURL = '$siteurl' diff --git a/pelican/utils.py b/pelican/utils.py index 4e1c8156..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: - return '.' + components = split_all(path) + if len(components) <= 1: + return os.curdir else: - return '/'.join(['..'] * 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='...'): @@ -429,7 +438,7 @@ def files_changed(path, extensions, ignores=[]): def file_times(path): """Return the last time files have been modified""" for root, dirs, files in os.walk(path): - dirs[:] = [x for x in dirs if x[0] != '.'] + dirs[:] = [x for x in dirs if x[0] != os.curdir] for f in files: if any(f.endswith(ext) for ext in extensions) \ and not any(fnmatch.fnmatch(f, ignore) 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)